源码链接:https://github.com/davidsandberg/facenet
论文链接:https://arxiv.org/pdf/1503.03832.pdf
B站大神视频解读论文:https://www.bilibili.com/video/av17281188
FaceNet是一个用于人脸识别的网络。关于人脸,往往分为2个任务:
1.人脸检测(在图中找到人脸,找特征,矫正)
2.人脸识别(看看这是谁)
在本系列的随笔里,人脸检测使用MTCNN,人脸识别采用FaceNet。下面就谈谈FaceNet.
FaceNet的3个任务
- 人脸判断(是不是这个人,是?不是)
- 人脸识别(这人是谁?)
- 人脸聚类(和这张脸相似的脸有哪些?)
FaceNet的大致流程
(经提取的,无需矫正)待判断人脸 -> FaceNet网络 -> embedding(脸的特征向量)
--- 任务1 ---> 和已知人脸的特征向量求L2距离 -> 距离小于阈值就是同一张脸。
--- 任务2 ---> KNN最近邻分类,求是谁的脸(最近邻检索,参考其他随笔)。
--- 任务3 ---> K-means聚类,求相似的脸集合。
FaceNet的技术
上面可以看出,最核心的,应该就是FaceNet网络怎么设计了。3个任务,都是在网络输出的 有代表性的 脸特征embedding 的基础上,使用传统的一些技术实现的。
FaceNet的技术之一:
- 三元组 triplets
所谓的 triplets,可见我的随笔“04-人脸识别-triplets loss 的解释(转载)”
在使用中,一个训练数据样本由3张图组成:
(anchor-要判定的脸,positive-和anchor一类的脸,negative-和anchor不同类的脸)
这就是一个 triplet 。
FaceNet的技术之二:
- Triplets Loss 损失函数
可见我的随笔“04-人脸识别-triplets loss 的解释(转载)”
这里,triplet 中的核心,是anchor。
04-随笔中,L函数=0的意义,就是 anchor 到 positive 的距离+alpha <= anchor 到 negative 的距离。这就我们想要的结果。也就是优化的方向。
所以呢,在FaceNet的网络设计中,将训练数据和损失函数,都使用了以上的两种新技术。这是一个改进。
那接下来就要谈谈,网络是怎么设计的。
FaceNet的网络可以是什么样的
FaceNet其实不是一种网络,它应该是使用了以上2个技术,在各种 CNN(AlexNet/GoogleNet...)基础上,修改的一系列的网络。所以,在论文中,作者测试了各种网络,提出来在数据中心(data center)使用的“巨型”网络,也有能在手机上跑的小型网络。小型网络,我会在后续的随笔中,测试一下。
那,简单的说,使用的网络,就是各种 CNN 网络的修改。(我是这么理解的,如有不当,请指出,谢谢)
FaceNet的训练过程
关于训练,其实有很多注意事项,因为修改了 损失函数形式 以及 数据样本的格式。
- 样本挑选
为什么要挑,因为 loss 函数太容易等于零了(回看一下04随笔,L函数等于零,对大多数样本都满足)。
hard-positive样本:positive 到 anchor 的距离反常(太大)
hard-negative样本:negative 到 anchor 的距离反常(太小)
但是
用 hard-positive 样本容易陷入局部最优。
用 hard-negative 样本(有些是标注错误、拍照不好等),会造成训练失败。
所以,又调整了一下
用所有 positive 样本
在hard-negative 样本中加了限制:anchor 到 negative 必须 > anchor 到 positive,得到 semi-negative。
最终采用的:所有positive样本 + 部分 semi-negative 样本
具体训练过程,将在后续的随笔中给出。
这里只是感性认识,实践方出真知。