FaceNet人脸特征提取
FaceNet是一种用于提取人脸图像特征的深度神经网络。它由谷歌研究人员 Schroff 等人提出。
论文地址:https://arxiv.org/abs/1503.03832
FaceNet 的工作原理是,输入一张人脸图像,将其压缩并输出为一个由128 位数组成的向量,表示人脸的基本特征。这个向量被称为嵌入,(来自面部图像的所有相关信息都嵌入到向量中)。
那么,如何通过FaceNet实现人脸识别呢?
通常的做法是,获取图像嵌入并计算与已知人脸的图片的距离。通常使用余弦定理或欧几里得距离公式计算。如果计算出的人脸距离与已知人脸的嵌入足够接近,我们就假设这张脸是同一个人的。
那么问题就是,FaceNet 如何知道需要从人脸图像中提取什么东西?
为了训练一个人脸识别器,我们需要很多人脸图像。像每个机器学习问题一样,训练通常需要数千张不同的图像。当我们开始训练过程时,模型会为每张图像生成随机向量,这意味着图像是随机分布的。
学习步骤:
- 随机选择一个锚点图像;
- 随机选择同一个人的正样本图像作为基础图像;
- 随机选择与主图像不同的人的负样本图像;
- 调整 FaceNet 神经网络参数,使正样本比负样本更靠近锚点。
我们重复这四个步骤,直到不再需要更改或这些更改非常小以至于没有影响。训练完成后,同一个人的所有面孔在距离上都彼此靠近,而与不同的面孔相距很远。
faceNet.py
完整的对象代码:
# faceNet.py
import cv2import cv2
import stow
import typing
import numpy as np
import onnxruntime as ort
class FaceNet:
"""FaceNet class object, which can be used for simplified face recognition
"""
def __init__(
self,
detector: object,
onnx_model_path: str = "models/faceNet.onnx",
anchors: typing.Union[str, dict] = 'faces',
force_cpu: bool = False,
threshold: float = 0.5,
color: tuple = (255, 255, 255),
thickness: int = 2,
) -> None:
"""Object for face recognition
Params:
detector: (object) - detector object to detect faces in image
onnx_model_path: (str) - path to onnx model
force_cpu: (bool) - if True, onnx model will be run on CPU
anchors: (str or dict) - path to directory with faces or dictionary with anchor names as keys and anchor encodings as values
threshold: (float) - threshold for face recognition
color: (tuple) - color of bounding box and text
thickness: (int) - thickness of bounding box and text