人脸识别技术是现代AI领域的一大亮点,而 Facenet 作为该领域的明星项目之一,现以全面升级的姿态在 PyTorch 中重新启航。本文旨在带你深入了解 Facenet 的魅力,探讨其技术核心。
FaceNet是由Google研究团队于2015年提出的一种革命性的人脸识别技术。它通过深度卷积神经网络,将人脸图像直接映射到128维的欧几里得空间中,形成一个紧凑的向量表示。在这个空间中,同一个人的不同图像会被映射到相近的点,而不同人的图像则会被映射到较远的点。这种表示方法使得人脸识别任务变得简单而高效。
FaceNet的核心思想是学习一个从人脸图像到欧几里得空间的映射函数,使得同一个人的人脸图像之间的距离小于不同人之间的距离。这种方法被称为"三元组损失"(triplet loss)。通过最小化三元组损失,FaceNet可以学习到一个高度判别性的人脸表示。
一套基本的人脸识别系统主要包含三部分:检测器、识别器和分类器,流程架构如下图所示:

检测器负责检测图片中的人脸,再将检测出来的人脸感兴趣区域(Region of Interests,ROI)导入识别器中,识别器输出结果为一组特征向量。再通过分类器对特征向量进行分类匹配,最终得出人脸结果。识别器采用FaceNet,一个有一定历史的源自谷歌的人脸识别系统,如下图所示:

FaceNet只负责提取128维的人脸特征向量,通过对比输入人脸向量与数据库中人脸向量的欧式距离来确定人脸的相似性。通常可以通过实验拟定合适的距离阈值直接判断出人脸类别。谷歌人脸识别算法发表于CVPR 2015,利用相同人脸在不同角度等姿态的照片下有高内聚性,不同人脸有低耦合性,在LFW数据集上准确度达到99.63%。
通过神经网络将人脸映射到欧式空间的特征向量上,实质上不同图片的人脸特征距离较大,而通过相同个体的人脸距离总是小于不同个体的人脸。测试时只需要计算人脸特征,然后计算距离,使用阈值即可判定两幅人脸照片是否属于相同的个体。人脸识别的关键在于如何通过神经网络生成一个“好”的特征。特征的“好”体现在两点: (1)同一个人的人脸特征要尽可能相似; (2)不同人的人脸之间的特征要尽可能不同。
本项目使用FaceNet进行识别,执行pip install facenet-pytorch 命令即可安装并使用它。项目代码如下:
安装facenet-pytorch。
pip install facenet-pytorch
代码实现:
############face_demo.py#############################
import cv2
import torch
from facenet_pytorch import MTCNN, InceptionResnetV1
# 获得人脸特征向量
def load_known_faces(dstImgPath, mtcnn, resnet):
aligned = []
knownImg = cv2.imread(dstImgPath) # 读取图片
face = mtcnn(knownImg) # 使用mtcnn检测人脸,返回人脸数组
if face is not None:
aligned.append(face[0])
aligned = torch.stack(aligned).to(device)
with torch.no_grad():
known_faces_emb = resnet(aligned).detach().cpu()
# 使用ResNet模型获取人脸对应的特征向量
print("\n人脸对应的特征向量为:\n", known_faces_emb)
return known_faces_emb, knownImg
# 计算人脸特征向量间的欧氏距离,设置阈值,判断是否为同一张人脸
def match_faces(faces_emb, known_faces_emb, threshold):
isExistDst = False
distance = (known_faces_emb[0] - faces_emb[0]).norm().item()
print("\n两张人脸的欧式距离为:%.2f" % distance)
if (distance < threshold):
isExistDst = True
return isExistDst
if __name__ == '__main__':
# help(MTCNN)
# help(InceptionResnetV1)
# 获取设备
device = torch.device('cuda:0' if torch.cuda.is_available() else 'cpu')
# mtcnn模型加载设置网络参数,进行人脸检测
mtcnn = MTCNN(min_face_size=12, thresholds=[0.2, 0.2, 0.3],
keep_all=True, device=device)
# InceptionResnetV1模型加载用于获取人脸特征向量
resnet = InceptionResnetV1(pretrained='vggface2').eval().to(device)
MatchThreshold = 0.8 # 人脸特征向量匹配阈值设置
known_faces_emb, _ = load_known_faces('./img/1_001.jpg', mtcnn, resnet) # 已知人物图
faces_emb, img = load_known_faces('./img/2_001.jpg', mtcnn, resnet) # 待检测人物图
isExistDst = match_faces(faces_emb, known_faces_emb, MatchThreshold) # 人脸匹配
print("设置的人脸特征向量匹配阈值为:", MatchThreshold)
if isExistDst:
boxes, prob, landmarks = mtcnn.detect(img, landmarks=True)
print('由于欧氏距离小于匹配阈值,故是同一个人!')
else:
print('由于欧氏距离大于匹配阈值,故不是同一个人!')
第一次运行时系统需要下载预训练的VGGFace模型,时间会比较久,耐心等待,下载好之后程序便可以运行。# InceptionResnetV1提供了两个预训练模型,分别在VGGFace数据集和CASIA数据集上训练。如果不手动下载预训练模型,可能速度会很慢,可以从作者提供的源代码文件链接中下载,然后放到C:\Users\你的用户名.cache\torch\checkpoints这个文件夹下面,如下图所示。
运行效果如下:

人脸对应的特征向量为:
tensor([[ 0.0061, 0.0419, 0.0353, -0.0348, 0.0081, -0.0414, -0.0767, 0.0543,
0.0079, 0.0011, 0.0158, 0.0123, -0.0454, -0.0406, -0.1148, 0.0305,
-0.0126, -0.0629, -0.0580, -0.0225, 0.0830, 0.0424, -0.0283, -0.0232,
-0.0723, -0.0352, 0.0367, 0.0423, -0.0464, 0.0112, 0.0048, 0.0129,
0.0607, -0.0266, -0.0074, 0.0275, -0.0052, -0.0424, 0.0030, 0.0012,
0.0048, 0.0430, 0.1093, 0.0675, -0.0019, 0.0452, -0.0488, 0.0521,
-0.0473, 0.0069, 0.0099, 0.0129, 0.0783, -0.0320, 0.0569, 0.0902,
0.0172, 0.0499, 0.0736, -0.0660, 0.0192, 0.0080, -0.0212, -0.0514,
-0.0176, 0.0694, -0.0581, 0.0836, 0.0303, 0.0237, 0.0176, -0.0450,
0.0338, 0.0192, 0.0434, -0.0204, -0.0695, 0.0300, -0.0645, 0.0196,
-0.0377, 0.0130, -0.0114, 0.0186, -0.0228, -0.0885, 0.0330, -0.0027,
0.0004, -0.0100, -0.0550, 0.0079, 0.0622, -0.0403, -0.1031, -0.0106,
0.0165, 0.0504, 0.0441, 0.0321, 0.0353, 0.0788, -0.0463, -0.0115,
0.0307, 0.0164, 0.0578, -0.0341, 0.0230, -0.0124, 0.0605, 0.0409,
-0.0250, 0.0017, 0.0473, 0.0316, 0.0456, 0.0160, 0.0358, -0.0774,
-0.0420, 0.0165, -0.0832, 0.0348, 0.0388, 0.0371, 0.0871, 0.0327,
0.0602, 0.0299, -0.1039, -0.0112, 0.0215, -0.0236, 0.0064, 0.0123,
-0.0298, 0.0358, 0.0199, 0.0099, 0.0224, -0.0733, -0.0624, -0.0357,
0.0225, 0.0006, -0.0057, -0.0187, 0.0506, 0.0715, 0.0446, -0.0455,
-0.0598, -0.0345, 0.0230, 0.0369, -0.0189, -0.0317, -0.0347, 0.0124,
0.0464, -0.0783, -0.0023, 0.0239, 0.0113, -0.0342, 0.0635, 0.0474,
-0.0506, -0.0209, 0.0543, -0.0395, -0.0550, 0.0143, 0.0141, 0.0479,
0.0408, 0.0433, -0.0231, -0.0206, 0.0234, -0.0298, -0.0176, -0.0807,
0.0271, 0.0780, -0.0984, 0.0530, -0.0011, 0.0333, 0.0643, 0.0041,
-0.0271, -0.0658, 0.1012, 0.0174, 0.0251, 0.0343, -0.0439, -0.0315,
-0.0692, 0.0189, 0.0091, -0.0705, 0.0365, 0.0180, -0.0035, -0.0219,
-0.0059, 0.0133, 0.0892, 0.0707, 0.0937, 0.0394, -0.0368, 0.0646,
-0.0346, -0.0418, -0.0184, -0.0797, -0.0176, 0.0323, 0.0309, 0.0562,
0.0355, 0.0015, -0.0939, -0.0008, 0.0772, 0.0621, -0.0120, -0.0542,
-0.0383, -0.0183, 0.0409, -0.0358, -0.0197, -0.0086, 0.0121, 0.0024,
0.0735, 0.0448, 0.0577, -0.0541, 0.0321, -0.0054, -0.0105, 0.0077,
0.0447, -0.0836, -0.0507, 0.0038, -0.0642, -0.0680, 0.1154, -0.0421,
0.0171, 0.0330, 0.0245, 0.0027, -0.0220, -0.0071, -0.0053, 0.0365,
-0.0132, -0.0920, -0.0057, -0.0208, 0.0166, 0.0035, -0.0209, 0.0642,
-0.0198, -0.0368, -0.0160, 0.0061, 0.0821, 0.0159, 0.0318, -0.0644,
0.0642, 0.0369, 0.0723, -0.0917, 0.0374, 0.0328, 0.0123, -0.0345,
-0.0042, 0.0122, -0.0390, 0.0957, -0.0324, 0.0114, 0.0361, 0.0163,
0.0393, -0.0198, 0.0251, 0.0454, 0.0185, 0.0783, -0.0409, -0.0265,
-0.0145, 0.0571, 0.0918, -0.1085, -0.0142, -0.0036, 0.0187, -0.0611,
-0.0619, -0.0544, 0.0108, -0.0460, 0.0115, -0.0089, 0.0678, -0.0102,
0.0155, 0.0106, -0.0624, -0.0244, 0.0248, -0.0062, 0.0431, -0.0006,
-0.0051, -0.0291, 0.0064, 0.0096, 0.0060, 0.0313, 0.0312, 0.0192,
-0.0503, -0.0590, -0.0035, -0.0833, 0.0021, 0.0403, 0.0633, 0.0317,
-0.0769, 0.0205, 0.0017, -0.0154, 0.0478, 0.0033, -0.0254, -0.0273,
0.0130, 0.0174, -0.0514, -0.0672, -0.0103, 0.0365, -0.0463, 0.0078,
0.0217, 0.0296, -0.0423, -0.0159, 0.0373, -0.0030, -0.0302, 0.0025,
-0.0349, -0.0642, 0.0150, -0.0255, -0.0672, -0.0211, -0.0339, -0.0009,
-0.0911, -0.0364, -0.0269, 0.0149, -0.0280, -0.0036, -0.0159, 0.0148,
-0.0347, 0.0440, 0.0985, -0.0556, -0.0116, -0.0201, 0.0553, -0.0031,
-0.0092, -0.0264, 0.0124, 0.0250, 0.0870, -0.0030, 0.0460, -0.0194,
0.0940, 0.0283, 0.0093, -0.0593, 0.0163, 0.0117, -0.0768, -0.0156,
0.0492, 0.0576, 0.0411, 0.0342, -0.0268, 0.0167, -0.0330, -0.0020,
-0.0017, 0.0619, -0.0169, 0.0942, -0.0067, -0.0075, 0.0093, -0.0985,
-0.0006, -0.0816, 0.0231, -0.0440, 0.0470, 0.0081, -0.0746, 0.0005,
-0.0078, -0.0265, 0.0125, -0.0704, 0.0402, 0.0670, 0.0557, -0.0060,
0.0728, 0.0021, 0.0091, -0.0124, -0.0165, 0.0483, -0.0389, 0.0067,
-0.0020, -0.0780, 0.0276, 0.0065, -0.0113, 0.0322, -0.0694, -0.0032,
-0.0276, -0.0844, -0.0039, 0.0033, 0.0481, -0.0200, 0.0406, -0.0737,
-0.0066, 0.0086, 0.0043, 0.0217, -0.0734, -0.0218, 0.0122, 0.0769,
0.0531, -0.0854, -0.0608, 0.0122, -0.0062, 0.0302, -0.0086, -0.0662,
-0.0785, 0.0094, 0.0062, -0.0079, 0.0144, -0.0605, -0.0013, 0.0090,
-0.0115, -0.0850, 0.0752, -0.0064, 0.0301, 0.0040, -0.0319, 0.0499,
0.0307, -0.0399, 0.0011, -0.0062, -0.1107, 0.1140, -0.0271, 0.0022,
0.0128, 0.0204, 0.0458, -0.0755, -0.0624, 0.0327, 0.0338, -0.0132]])
人脸对应的特征向量为:
tensor([[ 3.3543e-02, -8.8032e-02, -6.9044e-02, 3.6813e-02, -2.8797e-03,
-3.7768e-02, -3.2163e-02, 1.5562e-02, -2.4934e-02, 2.0853e-02,
-1.4130e-02, 5.1140e-02, -2.0256e-02, -3.3247e-02, 1.8598e-02,
1.2677e-01, -2.9600e-02, -4.7129e-02, 7.5055e-02, 1.3913e-03,
3.3346e-02, -1.7877e-02, 2.0692e-03, 4.8299e-02, 1.5661e-02,
-9.5446e-02, 2.8364e-02, 1.9534e-02, -7.7755e-02, 1.2728e-02,
-2.4902e-03, -1.1353e-01, -6.0058e-02, 4.6619e-03, -6.3028e-02,
-1.1803e-02, 2.8038e-02, 6.6298e-02, -2.2182e-02, -4.6837e-02,
2.3211e-03, 7.2192e-02, 2.3491e-02, 2.0095e-02, 4.5617e-02,
1.1344e-01, 2.3014e-02, -5.2391e-02, -3.1191e-03, 9.8014e-02,
6.0024e-02, 1.1183e-02, -1.0492e-02, -9.6912e-02, -6.9366e-02,
-6.9076e-04, 8.8027e-02, -8.1172e-02, 1.9742e-03, 6.1093e-02,
-7.0845e-02, -2.9455e-02, 5.1325e-02, 4.7522e-02, 1.3669e-02,
2.9137e-02, 1.9718e-02, -3.4132e-02, 1.1049e-03, -5.3611e-02,
-2.5305e-02, -2.1102e-02, 8.4771e-02, 1.7271e-02, -1.0845e-02,
1.1910e-02, -1.6379e-02, -1.7591e-02, 5.8098e-02, 4.4457e-02,
1.8798e-02, -2.7210e-02, -1.9898e-02, 1.9698e-02, -2.4371e-02,
3.7895e-03, -2.8681e-02, 3.1144e-02, -4.4639e-02, -1.2016e-02,
-5.0298e-02, 6.2575e-02, -4.6172e-02, -2.6037e-02, -1.0840e-01,
-5.8819e-02, 1.2988e-02, -1.5071e-02, 3.9122e-02, 2.6822e-03,
-2.9633e-02, 1.8904e-02, -3.5937e-02, 4.8019e-02, -5.4989e-03,
-4.0365e-02, -8.5679e-02, -2.4746e-02, 4.5990e-02, 1.4224e-02,
-1.7988e-02, -4.4761e-02, 3.4295e-02, 6.3975e-02, 9.8531e-02,
-1.4865e-02, -1.7311e-02, -1.9610e-03, 1.2539e-02, 5.0590e-03,
1.6822e-02, -8.4183e-03, 3.9937e-02, -7.7504e-02, 9.8535e-02,
2.3054e-02, -2.1977e-02, 5.1721e-02, 2.0135e-02, 5.8437e-03,
-1.0104e-02, -5.3504e-02, 3.5240e-03, 3.0812e-02, -1.1153e-02,
6.0000e-02, -6.4351e-02, 8.6926e-02, 2.0694e-02, 1.0655e-02,
3.0771e-02, 1.7407e-02, 6.5905e-02, -3.6580e-02, 5.8341e-02,
-2.4627e-02, -1.4229e-02, 6.9523e-02, 5.8185e-02, 3.2184e-02,
-8.8987e-02, 3.7073e-02, 5.3467e-02, -4.3048e-02, -6.5073e-02,
-3.3846e-02, 2.6579e-02, 4.4734e-04, -7.0820e-02, 2.5913e-02,
-2.0412e-02, -3.9362e-02, 3.6515e-02, -2.4927e-02, -4.0261e-02,
-1.9025e-02, -4.7609e-02, -9.5098e-03, 1.7557e-03, -8.0711e-02,
1.4007e-02, -2.9867e-03, 1.0386e-01, 6.7648e-02, 7.0399e-02,
1.5198e-02, 8.4707e-02, 5.1517e-03, 2.6528e-02, 1.2366e-02,
-4.9748e-02, -3.8484e-04, 2.5923e-02, -6.4061e-02, -7.7612e-02,
-4.9115e-02, 4.0673e-03, 3.4419e-02, -1.8323e-02, -3.8302e-02,
-4.9654e-02, -1.8894e-02, 1.0568e-01, 4.9006e-02, 2.6398e-02,
6.5068e-02, 6.7796e-02, 5.8380e-02, -2.4082e-02, 1.7286e-02,
-3.7145e-02, 9.0059e-03, 1.3364e-02, -3.2137e-02, 2.5431e-02,
5.6964e-02, 9.0613e-02, 6.5207e-02, 2.4875e-02, -2.1289e-02,
-1.4737e-02, 1.4986e-01, -4.7624e-02, 3.7624e-03, 4.3329e-02,
3.6470e-02, -4.5267e-02, -6.4303e-02, 4.0422e-02, 4.0484e-04,
-1.5064e-02, 4.4640e-02, 3.5942e-02, 2.4126e-02, 7.1140e-02,
-1.5964e-02, -4.8497e-02, -4.0202e-02, 1.2041e-02, 7.6518e-02,
-1.1180e-02, -1.8428e-02, 8.7813e-02, -4.1122e-03, -3.1694e-02,
-3.8333e-02, 2.4744e-02, 2.8293e-02, -2.4804e-02, -1.8060e-02,
3.2725e-02, 5.1452e-03, 2.7131e-02, -6.9825e-02, -4.1586e-02,
6.5771e-02, -6.6102e-02, 9.5911e-02, 4.6990e-02, 1.9879e-02,
-5.6543e-02, 5.2774e-03, -2.1437e-02, 1.9303e-02, 1.1167e-03,
-1.3129e-02, -7.0132e-02, -9.8088e-03, -2.5191e-02, -3.8359e-03,
-5.5840e-02, -2.8796e-02, -1.2210e-01, 1.4422e-03, 1.2604e-02,
5.7832e-03, -3.6149e-02, -6.8970e-02, 2.1771e-02, 3.5378e-02,
-6.0384e-02, 1.8108e-02, 1.4196e-02, -4.4006e-02, -1.0462e-01,
-5.6335e-03, 8.4414e-03, -1.8908e-02, 2.4361e-02, 4.2731e-02,
-2.3671e-02, -1.8246e-02, 5.4384e-02, -4.9826e-02, 5.6290e-02,
7.2033e-02, 4.3437e-03, -2.8649e-02, 2.0222e-02, 4.8640e-02,
1.6669e-02, 1.3647e-02, 2.1239e-02, 8.3867e-02, 1.4667e-02,
-9.1157e-03, -2.1234e-02, 6.5306e-02, 3.4587e-02, -2.8146e-02,
6.5018e-04, 4.3938e-02, -1.5526e-02, -2.7845e-02, -3.0202e-02,
6.8595e-02, 1.8979e-02, -1.5932e-02, 1.2001e-02, -1.7010e-02,
2.7627e-02, 4.4585e-03, -7.2906e-02, -1.6468e-02, -1.0170e-02,
-1.5930e-02, 1.3961e-02, -2.7000e-02, 4.9355e-02, 1.7380e-04,
4.1093e-02, -7.0721e-02, 1.1795e-02, -5.8935e-02, 9.1929e-02,
5.1295e-02, 1.2691e-02, -4.8641e-02, -1.7196e-03, 4.0794e-03,
3.4128e-02, -1.0901e-02, -4.2003e-02, -4.9630e-02, -7.1599e-03,
4.7440e-02, -1.4467e-02, 3.3170e-02, -3.8200e-02, 5.8810e-02,
-6.5436e-03, -4.8124e-03, 3.8097e-02, 1.0728e-01, -3.7850e-02,
-2.4602e-02, -1.5647e-02, 3.2945e-02, -9.4761e-03, 8.1156e-02,
-8.4427e-04, -2.4926e-02, -1.8680e-02, 1.4719e-02, -5.9616e-02,
-4.8329e-02, -7.5250e-02, 2.2071e-02, -5.8876e-02, -8.9067e-02,
1.1350e-01, -2.3427e-02, 9.3359e-03, -1.9457e-02, -1.4483e-02,
-1.6767e-02, -3.5950e-02, -3.1816e-02, -6.9539e-03, -4.3960e-02,
-2.7581e-02, 6.6427e-02, -4.7042e-02, -1.7036e-02, 1.0761e-02,
-3.7299e-02, -1.3761e-02, -7.1429e-02, -4.7095e-03, 3.4581e-02,
-5.2250e-02, 5.5824e-02, 2.2732e-02, 1.0378e-02, -6.8806e-02,
-1.2876e-02, 4.8312e-02, -2.9384e-03, -2.6518e-02, -1.0101e-01,
6.4851e-02, -6.3231e-02, 1.0269e-02, -5.0695e-02, 6.5531e-02,
-1.2133e-02, 9.5250e-03, -1.3014e-02, 1.8395e-02, -1.1136e-02,
4.6250e-02, -6.6906e-03, -1.1817e-02, -2.5936e-02, 5.2408e-02,
-2.6789e-02, 1.7241e-02, 2.7322e-02, -4.0031e-02, 2.5849e-02,
-2.9893e-02, 2.6169e-02, -5.7047e-03, 5.3270e-02, 5.8622e-02,
-3.3872e-02, 1.1252e-02, 1.8479e-02, -2.9311e-02, 4.8065e-02,
-5.1340e-02, 2.9405e-03, 8.8737e-03, -3.0981e-02, -1.5985e-02,
2.8925e-02, 3.6612e-02, 1.7964e-02, 4.3866e-02, -2.1786e-04,
-4.5359e-02, -6.0637e-03, 4.6161e-02, -3.9163e-02, -2.5212e-02,
6.1961e-03, 4.8043e-02, 2.4627e-02, -5.4405e-02, 5.1658e-03,
-4.2498e-02, -3.6694e-02, 2.7922e-02, 6.4991e-04, -1.2903e-02,
-3.4904e-03, 2.9215e-02, -3.2276e-02, 3.0977e-03, -3.2735e-02,
-7.0627e-05, 1.1107e-02, 2.4129e-03, 1.2811e-01, -5.6253e-02,
-6.8432e-03, 8.1598e-02, -3.6566e-02, -3.4933e-02, 1.3571e-03,
3.0311e-03, -8.2157e-02, -1.4175e-02, 1.8638e-02, -4.4986e-02,
-3.5951e-02, -1.0473e-02, -3.8763e-03, -2.7008e-02, 2.5313e-02,
7.8753e-02, 3.7753e-02, 3.7382e-02, -1.2763e-02, -7.5317e-02,
-4.6656e-03, 1.6881e-02, 9.6589e-03, 4.9052e-02, 2.9452e-03,
-1.1742e-01, -6.3618e-02, 3.4652e-02, -2.1944e-02, 1.3105e-04,
3.5976e-02, -3.4382e-02, -2.8052e-02, -1.3442e-03, 1.0763e-02,
7.9599e-04, -6.3334e-02, 7.6939e-03, -1.3669e-02, 4.9836e-03,
4.8787e-02, 6.4227e-02, -1.0494e-02, -9.9216e-03, 3.7789e-03,
7.3440e-02, 3.3627e-02, -5.8688e-02, 3.2784e-02, -1.7286e-02,
1.4452e-02, 5.2882e-03, 3.0313e-02, -4.1720e-02, 2.5918e-02,
-1.7766e-03, -9.0062e-02]])
两张人脸的欧式距离为:1.29
设置的人脸特征向量匹配阈值为: 0.8
由于欧氏距离大于匹配阈值,故不是同一个人!