facenet 512

This commit is contained in:
Sefik Ilkin Serengil 2021-07-12 23:25:37 +03:00
parent 5d33bae2a4
commit 922682c1fa
7 changed files with 65 additions and 19 deletions

View File

@ -51,7 +51,7 @@ df = DeepFace.find(img_path = "img1.jpg", db_path = "C:/workspace/my_db")
Deepface is a **hybrid** face recognition package. It currently wraps many **state-of-the-art** face recognition models: [`VGG-Face`](https://sefiks.com/2018/08/06/deep-face-recognition-with-keras/) , [`Google FaceNet`](https://sefiks.com/2018/09/03/face-recognition-with-facenet-in-keras/), [`OpenFace`](https://sefiks.com/2019/07/21/face-recognition-with-openface-in-keras/), [`Facebook DeepFace`](https://sefiks.com/2020/02/17/face-recognition-with-facebook-deepface-in-keras/), [`DeepID`](https://sefiks.com/2020/06/16/face-recognition-with-deepid-in-keras/), [`ArcFace`](https://sefiks.com/2020/12/14/deep-face-recognition-with-arcface-in-keras-and-python/) and [`Dlib`](https://sefiks.com/2020/07/11/face-recognition-with-dlib-in-python/). The default configuration uses VGG-Face model.
```python
models = ["VGG-Face", "Facenet", "OpenFace", "DeepFace", "DeepID", "ArcFace", "Dlib"]
models = ["VGG-Face", "Facenet", "Facenet512", "OpenFace", "DeepFace", "DeepID", "ArcFace", "Dlib"]
result = DeepFace.verify("img1.jpg", "img2.jpg", model_name = models[1])
df = DeepFace.find(img_path = "img1.jpg", db_path = "C:/workspace/my_db", model_name = models[1])
```
@ -62,7 +62,7 @@ FaceNet, VGG-Face, ArcFace and Dlib [overperforms](https://youtu.be/i_MOwvhbLdI)
**Similarity**
Face recognition models are regular [convolutional neural networks](https://sefiks.com/2018/03/23/convolutional-autoencoder-clustering-images-with-neural-networks/) and they are responsible to represent faces as vectors. We expect that a face pair of same person should be [more similar](https://sefiks.com/2020/05/22/fine-tuning-the-threshold-in-face-recognition/) than a face pair of different persons.
Face recognition models are regular [convolutional neural networks](https://sefiks.com/2018/03/23/convolutional-autoencoder-clustering-images-with-neural-networks/) and they are responsible to represent faces as vectors. We expect that a face pair of same person should be [more similar](https://sefiks.com/2020/05/22/fine-tuning-the-threshold-in-face-recognition/) than a face pair of different persons.
Similarity could be calculated by different metrics such as [Cosine Similarity](https://sefiks.com/2018/08/13/cosine-similarity-in-machine-learning/), Euclidean Distance and L2 form. The default configuration uses cosine similarity.

View File

@ -12,7 +12,7 @@ import pandas as pd
from tqdm import tqdm
import pickle
from deepface.basemodels import VGGFace, OpenFace, Facenet, FbDeepFace, DeepID, DlibWrapper, ArcFace, Boosting
from deepface.basemodels import VGGFace, OpenFace, Facenet, Facenet512, FbDeepFace, DeepID, DlibWrapper, ArcFace, Boosting
from deepface.extendedmodels import Age, Gender, Race, Emotion
from deepface.commons import functions, realtime, distance as dst
@ -41,6 +41,7 @@ def build_model(model_name):
'VGG-Face': VGGFace.loadModel,
'OpenFace': OpenFace.loadModel,
'Facenet': Facenet.loadModel,
'Facenet512': Facenet512.loadModel,
'DeepFace': FbDeepFace.loadModel,
'DeepID': DeepID.loadModel,
'Dlib': DlibWrapper.loadModel,

View File

@ -3,24 +3,42 @@ from pathlib import Path
import gdown
from functools import partial
from tensorflow.keras.models import Model
from tensorflow.keras.layers import Activation
from tensorflow.keras.layers import BatchNormalization
from tensorflow.keras.layers import Concatenate
from tensorflow.keras.layers import Conv2D
from tensorflow.keras.layers import Dense
from tensorflow.keras.layers import Dropout
from tensorflow.keras.layers import GlobalAveragePooling2D
from tensorflow.keras.layers import Input
from tensorflow.keras.layers import Lambda
from tensorflow.keras.layers import MaxPooling2D
from tensorflow.keras.layers import add
from tensorflow.keras import backend as K
import tensorflow as tf
tf_version = int(tf.__version__.split(".")[0])
if tf_version == 1:
from keras.models import Model
from keras.layers import Activation
from keras.layers import BatchNormalization
from keras.layers import Concatenate
from keras.layers import Conv2D
from keras.layers import Dense
from keras.layers import Dropout
from keras.layers import GlobalAveragePooling2D
from keras.layers import Input
from keras.layers import Lambda
from keras.layers import MaxPooling2D
from keras.layers import add
from keras import backend as K
else:
from tensorflow.keras.models import Model
from tensorflow.keras.layers import Activation
from tensorflow.keras.layers import BatchNormalization
from tensorflow.keras.layers import Concatenate
from tensorflow.keras.layers import Conv2D
from tensorflow.keras.layers import Dense
from tensorflow.keras.layers import Dropout
from tensorflow.keras.layers import GlobalAveragePooling2D
from tensorflow.keras.layers import Input
from tensorflow.keras.layers import Lambda
from tensorflow.keras.layers import MaxPooling2D
from tensorflow.keras.layers import add
from tensorflow.keras import backend as K
def scaling(x, scale):
return x * scale
def InceptionResNetV2():
def InceptionResNetV2(dimension = 128):
inputs = Input(shape=(160, 160, 3))
x = Conv2D(32, 3, strides=2, padding='valid', use_bias=False, name= 'Conv2d_1a_3x3') (inputs)
@ -522,7 +540,7 @@ def InceptionResNetV2():
x = GlobalAveragePooling2D(name='AvgPool')(x)
x = Dropout(1.0 - 0.8, name='Dropout')(x)
# Bottleneck
x = Dense(128, use_bias=False, name='Bottleneck')(x)
x = Dense(dimension, use_bias=False, name='Bottleneck')(x)
x = BatchNormalization(momentum=0.995, epsilon=0.001, scale=False, name='Bottleneck_BatchNorm')(x)
# Create model

View File

@ -0,0 +1,26 @@
from deepface.basemodels import Facenet
from pathlib import Path
import os
import gdown
def loadModel(url = 'https://github.com/serengil/deepface_models/releases/download/v1.0/facenet512_weights.h5'):
model = Facenet.InceptionResNetV2(dimension = 512)
#-------------------------
home = str(Path.home())
if os.path.isfile(home+'/.deepface/weights/facenet512_weights.h5') != True:
print("facenet512_weights.h5 will be downloaded...")
output = home+'/.deepface/weights/facenet_weights.h5'
gdown.download(url, output, quiet=False)
#-------------------------
model.load_weights(home+'/.deepface/weights/facenet512_weights.h5')
#-------------------------
return model

View File

@ -29,6 +29,7 @@ def findThreshold(model_name, distance_metric):
'VGG-Face': {'cosine': 0.40, 'euclidean': 0.55, 'euclidean_l2': 0.75},
'OpenFace': {'cosine': 0.10, 'euclidean': 0.55, 'euclidean_l2': 0.55},
'Facenet': {'cosine': 0.40, 'euclidean': 10, 'euclidean_l2': 0.80},
'Facenet512': {'cosine': 0.3088582207770799, 'euclidean': 23.564685968740186, 'euclidean_l2': 1.0461709266148662},
'DeepFace': {'cosine': 0.23, 'euclidean': 64, 'euclidean_l2': 0.64},
'DeepID': {'cosine': 0.015, 'euclidean': 45, 'euclidean_l2': 0.17},
'Dlib': {'cosine': 0.07, 'euclidean': 0.6, 'euclidean_l2': 0.6},

BIN
tests/dataset/img22.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 72 KiB

View File

@ -182,7 +182,7 @@ dataset = [
#models = ['VGG-Face', 'Facenet', 'OpenFace', 'DeepFace', 'DeepID', 'Dlib', 'ArcFace']
metrics = ['cosine', 'euclidean', 'euclidean_l2']
models = ['VGG-Face', 'Facenet', 'Dlib', 'ArcFace'] #those are robust models
models = ['VGG-Face', 'Facenet', 'Facenet512', 'Dlib', 'ArcFace'] #those are robust models
#metrics = ['cosine']
passed_tests = 0; test_cases = 0