FaceNet

FaceNet是一种先进的人脸识别系统,能直接将人脸图像映射到欧几里得空间,利用空间距离评估相似度,适用于人脸验证、识别及聚类。采用基于深度卷积神经网络的模型,使用三联子(triplets)loss函数训练,有效解决了传统方法的不足。

本文来源于山人七的博客,在其基础上做了一定修改便于阅读

原文链接:https://zhuanlan.zhihu.com/p/24837264


近年来,人脸识别技术取得了飞速的进展,但是人脸验证和识别在自然条件中应用仍然存在困难。本文中,作者开发了一个新的人脸识别系统:FaceNet,可以直接将人脸图像映射到欧几里得空间,空间距离的长度代表了人脸图像的相似性。只要该映射空间生成,人脸识别,验证和聚类等任务就可以轻松完成。文章的方法是基于深度卷积神经网络。FaceNet在LFW数据集上,准确率为0.9963,在YouTube Faces DB数据集上,准确率为0.9512。

1,前言
FaceNet是一个通用的系统,可以用于人脸验证(是否是同一人?),识别(这个人是谁?)和聚类(寻找类似的人?)。FaceNet采用的方法是通过卷积神经网络学习将图像映射到欧几里得空间。空间距离直接和图片相似度相关:同一个人的不同图像在空间距离很小,不同人的图像在空间中有较大的距离。只要该映射确定下来,相关的人脸识别任务就变得很简单。

当前存在的基于深度神经网络的人脸识别模型使用了分类层(classification layer):中间层为人脸图像的向量映射,然后以分类层作为输出层。这类方法的弊端是不直接和效率低。

与当前方法不同,FaceNet直接使用基于triplets的LMNN(最大边界近邻分类)的loss函数训练神经网络,网络直接输出为128维度的向量空间。我们选取的triplets(三联子)包含两个匹配脸部缩略图和一个非匹配的脸部缩略图,loss函数目标是通过距离边界区分正负类,如图1-1所示。
图1-1 模型结构

脸部缩略图为紧密裁剪的脸部区域,没有使用2d,3d对齐以及放大转换等预处理。
本文中,作者探索了两类深度卷积神经网络。第一类为 Zeiler&Fergus研究中使用的神经网络 ,我们在网络后面加了多个1*1*d卷积层;第二类为 Inception网络 。模型结构的末端使用triplet loss来直接分类。triplet loss 的启发是传统loss函数趋向于将有一类特征的人脸图像映射到同一个空间。而triplet loss尝试将一个个体的人脸图像和其它人脸图像分开。下文包含以下内容:
  • 三联子(triplets)loss
  • triplets筛选方法
  • 模型结构描述
  • 实验结果
  • 评论
2,三联子(triplets)loss

模型的目的是将人脸图像X embedding入d维度的欧几里得空间f(x)\in R^{d} 。在该向量空间内,我们希望保证单个个体的图像x_{i}^{a} (anchor) 和该个体的其它图像x_{i}^{p} (positive) 距离近,与其它个体的图像x_{i}^{n} (negtive) 距离远。

loss函数目标是通过距离边界区分正负类:

(1)

变换一下,得到损失函数:

图2-1 triplet loss示意图

其中, \alpha 为positive/negtive的边界。

3, triplets筛选

triplets 的选择对模型的收敛非常重要。如公式1所示,对于 x_{i}^{a} ,我们我们需要选择同一个体的不同图片 x_{i}^{p} ,使 argmax_{x_{i}^{p} } \left| \left| f(x_{i}^{a} )-f(x_{i}^{p} )\right|  \right| _{2}^{2} ;同时,还需要选择不同个体的图片 x_{i}^{n} ,使得 argmin_{x_{i}^{n} } \left| \left| f(x_{i}^{a} )-f(x_{i}^{n} )\right|  \right| _{2}^{2} 。在实际训练中,跨越所有训练样本来计算argmin和argmax是不现实的,还会由于错误标签图像导致训练收敛困难。实际训练中,有两种方法来进行筛选:一,每隔n步,计算子集的argmin和argmax。
二,在线生成triplets,即在每个mini-batch中进行筛选positive/negative样本。
本文中,我们采用在线生成triplets的方法。我们选择了大样本的mini-batch(1800样本/batch)来增加每个batch的样本数量。每个mini-batch中,我们对单个个体选择40张人脸图片作为正样本,随机筛选其它人脸图片作为负样本。负样本选择不当也可能导致训练过早进入局部最小。为了避免,我们采用如下公式来帮助筛选负样本:
4, 深度卷积神经网络
采用adagrad优化器,使用随机梯度下降法训练CNN模型。在cpu集群上训练了1000-2000小时。边界值 \alpha 设定为0.2。总共实验了两类模型:

  • 第一种是Zeiler&Fergus架构,22层,140M参数,1.6billion FLOPS(FLOPS是计算量?)。称之为NN1。
  • 第二种是GoogleNet式的Inception模型。模型参数是第一个的20分之一,FLOPS是第一个的五分之一。
  • 基于Inception模型,减小模型大小,形成两个小模型。 
    • NNS1:26M参数,220M FLOPS。
    • NNS2:4.3M参数,20M FLOPS。
  • NN3与NN4和NN2结构一样,但输入变小了。 
    • NN2原始输入:224×224
    • NN3输入:160×160
    • NN4输入:96×96
5, 实验结果
作者采用了约8million个个体的将近100million-200million张人脸缩略图。人脸缩略图通过脸部检测器紧密裁剪生成。最后,在四类数据集上评价零FaceNet:
  • hold-out 测试集:从训练集中分出100million图像作为测试集。
  • 个人照片:总共包括12k个人照片。
  • 学术数据集:我们采用了LFW数据集和Youtube Faces DB。
5.1 计算量与准确率权衡 
在测试中,随着神经网络深度增加,计算量增加,准确率也增加,如表5-1和图5-1所示。
表5-1 深度神经网络结构与VAL

图5-1 计算量(FLOPS)与准确率关系

5.2 CNN模型结构对loss的影响
作者考察了不同CNN模型对结果的影响,如图5-2所示。
图5-2 网络结构对VAL的影响

5.3 图像质量对结果的影响
模型对图像质量(像素值)不敏感,即使80*80像素的图片生成的结果也可以接受,如表5-2所示。
表5-2 图像质量(像素值)对结果的影响


5.4 Embedding维度对结果的影响
作者测试了不同的embedding维度,结果如表5-3所示,发现128维度是最为合适的。
表5-3 不同输出维度对结果的影响


5.5 训练数据量对结果的影响
随着训练数据量的增加,准确率也随之增加,如表5-4所示。
表5-4 训练数据量与VAL


5.6 评价结果
FaceNet在LFW数据集上取得了99.63% \pm 0.09的准确率;在Youtube Faces DB数据集上获得了95.12% \pm 0.39的结果。在个人照片的数据集上,对单个个体进行embeding后聚类测试,结果如图5-3所示。 图5-3 对单个个体的不同照片进行聚类的结果

6, 评论
FaceNet是google的工作,工作量非常大,结果也很好。FaceNet是一种直接将人脸图像embedding进入欧几里得空间的方法。该模型的优点是只需要对图片进行很少量的处理(只需要裁剪脸部区域,而不需要额外预处理,比如3d对齐等),即可作为模型输入。同时,该模型在数据集上准确率非常高。未来的工作可以有几个方向:
一,分析错误的样本,进一步提高识别精度,特别是增加模型在现实场景中的识别精度。
二,以该模型为基础,将其用于现实应用开发中。(预告:后续文章中,我将对使用FaceNet进行人脸识别的项目源码进行解析,敬请关注)
三,减少模型大小,减少对cpu计算量的消耗,以及减少训练时间(作者在cpu集群上需要1000-2000小时的训练。)
05-07
### Facenet 深度学习人脸识别库简介 Facenet 是一种由 Google 提出的人脸识别算法,其核心思想在于通过深度神经网络将人脸映射到一个欧几里得空间中的向量表示(即嵌入),使得同一个人的不同照片之间的距离更近,而不同人的照片之间距离更远。这种方法显著提高了人脸识别的准确性,并成为许多现代人脸识别系统的基石。 #### 工作原理 Facenet 使用三元组损失函数 (Triplet Loss) 来训练模型。具体来说,在训练过程中,模型会接收三个输入:锚点图片 (Anchor),正样本图片 (Positive),以及负样本图片 (Negative)。目标是最小化锚点与正样本之间的距离,同时最大化锚点与负样本之间的距离[^1]。这种机制确保了同一身份的照片在嵌入空间中更加接近,而不同身份的照片则被推得更远。 以下是实现 Facenet 的基本流程: ```python import tensorflow as tf def triplet_loss(y_true, y_pred, alpha=0.2): """ Implementation of the triplet loss function. Arguments: y_true -- true labels, required when you define a loss in Keras, not used here. y_pred -- python list containing three objects: anchor -- the encodings for the anchor images, shape (None, embedding_size) positive -- the encodings for the positive images, shape (None, embedding_size) negative -- the encodings for the negative images, shape (None, embedding_size) alpha -- margin parameter Returns: loss -- real number, value of the loss """ total_lenght = y_pred.shape.as_list()[-1] anchor = y_pred[:, 0:int(total_lenght * 1 / 3)] positive = y_pred[:, int(total_lenght * 1 / 3):int(total_lenght * 2 / 3)] negative = y_pred[:, int(total_lenght * 2 / 3):int(total_lenght)] pos_dist = tf.reduce_sum(tf.square(anchor - positive), axis=-1) neg_dist = tf.reduce_sum(tf.square(anchor - negative), axis=-1) basic_loss = pos_dist - neg_dist + alpha loss = tf.maximum(basic_loss, 0.0) return tf.reduce_mean(loss) ``` 此代码片段展示了如何定义三元组损失函数来优化 Facenet 模型的表现。 #### 数据预处理 为了使 Facenet 能够高效运行,数据预处理是非常重要的一步。通常情况下,需要对面部区域进行检测并裁剪,随后调整大小至固定尺寸(如 160×160 像素)。此外,还需要对图像像素值进行标准化处理以提高模型收敛速度和稳定性[^4]。 #### 集成到 Android 应用程序 如果计划将 Facenet 整合进 Android 平台上的应用程序,则可以考虑利用 TensorFlow Lite 或其他轻量化框架对其进行转换以便于部署。另外也可以参考 `Android-Face-Recognition-with-Deep-Learning-Library` 这样的开源项目作为起点[^4]。 ### 结论 综上所述,Facenet 不仅提供了强大的理论支持还具备实际操作可行性,对于希望深入研究或者应用人脸识别技术的人来说都是极佳的选择之一。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值