Skip to content

Commit

Permalink
using type hinting for backend functions
Browse files Browse the repository at this point in the history
  • Loading branch information
serengil committed Dec 24, 2023
1 parent 58945bd commit f23ab85
Show file tree
Hide file tree
Showing 29 changed files with 335 additions and 130 deletions.
10 changes: 7 additions & 3 deletions deepface/DeepFace.py
Original file line number Diff line number Diff line change
Expand Up @@ -889,8 +889,12 @@ def extract_faces(

@deprecated(version="0.0.78", reason="Use DeepFace.extract_faces instead of DeepFace.detectFace")
def detectFace(
img_path, target_size=(224, 224), detector_backend="opencv", enforce_detection=True, align=True
):
img_path: Union[str, np.ndarray],
target_size: tuple = (224, 224),
detector_backend: str = "opencv",
enforce_detection: bool = True,
align: bool = True,
) -> np.ndarray:
"""
Deprecated function. Use extract_faces for same functionality.
Expand Down Expand Up @@ -942,7 +946,7 @@ def detectFace(
functions.initialize_folder()


def cli():
def cli() -> None:
"""
command line interface function will be offered in this block
"""
Expand Down
14 changes: 5 additions & 9 deletions deepface/basemodels/ArcFace.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@
tf_version = int(tf.__version__.split(".", maxsplit=1)[0])

if tf_version == 1:
from keras.models import Model
from keras.engine import training
import keras
from keras.layers import (
ZeroPadding2D,
Input,
Expand All @@ -28,8 +28,8 @@
Dense,
)
else:
from tensorflow.keras.models import Model
from tensorflow.python.keras.engine import training
from tensorflow import keras
from tensorflow.keras.layers import (
ZeroPadding2D,
Input,
Expand All @@ -41,15 +41,11 @@
Flatten,
Dense,
)
# --------------------------------


# url = "https://drive.google.com/uc?id=1LVB3CdVejpmGHM28BpqqkbZP5hDEcdZY"


def loadModel(
url="https://github.com/serengil/deepface_models/releases/download/v1.0/arcface_weights.h5",
):
) -> Model:
base_model = ResNet34()
inputs = base_model.inputs[0]
arcface_model = base_model.outputs[0]
Expand All @@ -62,7 +58,7 @@ def loadModel(
embedding = BatchNormalization(momentum=0.9, epsilon=2e-5, name="embedding", scale=True)(
arcface_model
)
model = keras.models.Model(inputs, embedding, name=base_model.name)
model = Model(inputs, embedding, name=base_model.name)

# ---------------------------------------
# check the availability of pre-trained weights
Expand All @@ -84,7 +80,7 @@ def loadModel(
return model


def ResNet34():
def ResNet34() -> Model:

img_input = Input(shape=(112, 112, 3))

Expand Down
2 changes: 1 addition & 1 deletion deepface/basemodels/DeepID.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@

def loadModel(
url="https://github.com/serengil/deepface_models/releases/download/v1.0/deepid_keras_weights.h5",
):
) -> Model:

myInput = Input(shape=(55, 47, 3))

Expand Down
12 changes: 9 additions & 3 deletions deepface/basemodels/DlibResNet.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,14 @@
class DlibResNet:
def __init__(self):

# this is not a must dependency
import dlib # 19.20.0
## this is not a must dependency. do not import it in the global level.
try:
import dlib
except ModuleNotFoundError as e:
raise ImportError(
"Dlib is an optional dependency, ensure the library is installed."
"Please install using 'pip install dlib' "
) from e

self.layers = [DlibMetaData()]

Expand Down Expand Up @@ -49,7 +55,7 @@ def __init__(self):

# return None # classes must return None

def predict(self, img_aligned):
def predict(self, img_aligned: np.ndarray) -> np.ndarray:

# functions.detectFace returns 4 dimensional images
if len(img_aligned.shape) == 4:
Expand Down
3 changes: 2 additions & 1 deletion deepface/basemodels/DlibWrapper.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
from typing import Any
from deepface.basemodels.DlibResNet import DlibResNet


def loadModel():
def loadModel() -> Any:
return DlibResNet()
7 changes: 2 additions & 5 deletions deepface/basemodels/Facenet.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ def scaling(x, scale):
return x * scale


def InceptionResNetV2(dimension=128):
def InceptionResNetV2(dimension=128) -> Model:

inputs = Input(shape=(160, 160, 3))
x = Conv2D(32, 3, strides=2, padding="valid", use_bias=False, name="Conv2d_1a_3x3")(inputs)
Expand Down Expand Up @@ -1618,12 +1618,9 @@ def InceptionResNetV2(dimension=128):
return model


# url = 'https://drive.google.com/uc?id=1971Xk5RwedbudGgTIrGAL4F7Aifu7id1'


def loadModel(
url="https://github.com/serengil/deepface_models/releases/download/v1.0/facenet_weights.h5",
):
) -> Model:
model = InceptionResNetV2()

# -----------------------------------
Expand Down
11 changes: 10 additions & 1 deletion deepface/basemodels/Facenet512.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,23 @@
import os
import gdown
import tensorflow as tf
from deepface.basemodels import Facenet
from deepface.commons import functions
from deepface.commons.logger import Logger

logger = Logger(module="basemodels.Facenet512")

tf_version = int(tf.__version__.split(".", maxsplit=1)[0])

if tf_version == 1:
from keras.models import Model
else:
from tensorflow.keras.models import Model


def loadModel(
url="https://github.com/serengil/deepface_models/releases/download/v1.0/facenet512_weights.h5",
):
) -> Model:

model = Facenet.InceptionResNetV2(dimension=512)

Expand Down
2 changes: 1 addition & 1 deletion deepface/basemodels/FbDeepFace.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@

def loadModel(
url="https://github.com/swghosh/DeepFace/releases/download/weights-vggface2-2d-aligned/VGGFace2_DeepFace_weights_val-0.9034.h5.zip",
):
) -> Model:
base_model = Sequential()
base_model.add(
Convolution2D(32, (11, 11), activation="relu", name="C1", input_shape=(152, 152, 3))
Expand Down
2 changes: 1 addition & 1 deletion deepface/basemodels/OpenFace.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@

def loadModel(
url="https://github.com/serengil/deepface_models/releases/download/v1.0/openface_weights.h5",
):
) -> Model:
myInput = Input(shape=(96, 96, 3))

x = ZeroPadding2D(padding=(3, 3), input_shape=(96, 96, 3))(myInput)
Expand Down
6 changes: 4 additions & 2 deletions deepface/basemodels/SFace.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import os
from typing import Any

import numpy as np
import cv2 as cv
import gdown
Expand All @@ -25,7 +27,7 @@ def __init__(self, model_path):

self.layers = [_Layer()]

def predict(self, image):
def predict(self, image: np.ndarray) -> np.ndarray:
# Preprocess
input_blob = (image[0] * 255).astype(
np.uint8
Expand All @@ -39,7 +41,7 @@ def predict(self, image):

def load_model(
url="https://github.com/opencv/opencv_zoo/raw/main/models/face_recognition_sface/face_recognition_sface_2021dec.onnx",
):
) -> Any:

home = functions.get_deepface_home()

Expand Down
14 changes: 2 additions & 12 deletions deepface/basemodels/VGGFace.py
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@
# ---------------------------------------


def baseModel():
def baseModel() -> Sequential:
model = Sequential()
model.add(ZeroPadding2D((1, 1), input_shape=(224, 224, 3)))
model.add(Convolution2D(64, (3, 3), activation="relu"))
Expand Down Expand Up @@ -83,31 +83,21 @@ def baseModel():
return model


# url = 'https://drive.google.com/uc?id=1CPSeum3HpopfomUEK1gybeuIVoeJT_Eo'


def loadModel(
url="https://github.com/serengil/deepface_models/releases/download/v1.0/vgg_face_weights.h5",
):
) -> Model:

model = baseModel()

# -----------------------------------

home = functions.get_deepface_home()
output = home + "/.deepface/weights/vgg_face_weights.h5"

if os.path.isfile(output) != True:
logger.info("vgg_face_weights.h5 will be downloaded...")
gdown.download(url, output, quiet=False)

# -----------------------------------

model.load_weights(output)

# -----------------------------------

# TO-DO: why?
vgg_face_descriptor = Model(inputs=model.layers[0].input, outputs=model.layers[-2].output)

return vgg_face_descriptor
19 changes: 15 additions & 4 deletions deepface/commons/distance.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,25 @@
from typing import Union
import numpy as np


def findCosineDistance(source_representation, test_representation):
def findCosineDistance(
source_representation: Union[np.ndarray, list], test_representation: Union[np.ndarray, list]
) -> np.float64:
if isinstance(source_representation, list):
source_representation = np.array(source_representation)

if isinstance(test_representation, list):
test_representation = np.array(test_representation)

a = np.matmul(np.transpose(source_representation), test_representation)
b = np.sum(np.multiply(source_representation, source_representation))
c = np.sum(np.multiply(test_representation, test_representation))
return 1 - (a / (np.sqrt(b) * np.sqrt(c)))


def findEuclideanDistance(source_representation, test_representation):
def findEuclideanDistance(
source_representation: Union[np.ndarray, list], test_representation: Union[np.ndarray, list]
) -> np.float64:
if isinstance(source_representation, list):
source_representation = np.array(source_representation)

Expand All @@ -21,11 +32,11 @@ def findEuclideanDistance(source_representation, test_representation):
return euclidean_distance


def l2_normalize(x):
def l2_normalize(x: np.ndarray) -> np.ndarray:
return x / np.sqrt(np.sum(np.multiply(x, x)))


def findThreshold(model_name, distance_metric):
def findThreshold(model_name: str, distance_metric: str) -> float:

base_threshold = {"cosine": 0.40, "euclidean": 0.55, "euclidean_l2": 0.75}

Expand Down
Loading

0 comments on commit f23ab85

Please sign in to comment.