算法和码力是核心能力。
3.7 人脸识别简介
先看几个容易混淆的概念,区分清楚。
- 人脸检测(Face Detection)
人脸检测是一种特殊的目标检测,它只检测人脸。它的任务是从一张图片中找到人脸的Bounding Box。 - 人脸验证(Face Verification)
人脸验证的任务是判断两张人脸图片是否是同一个人,这是一个两分类问题,通常用于基于人脸的登录控制、访问控制、身份确认等方面,比如基于人脸的手机解锁,操作系统登录。 - 人脸鉴别(Face Identification)
人脸鉴别任务是判断一个人脸是属于哪一个人,确定其身份,属于多分类问题。人脸鉴别又分为开放的(open)和封闭的(closed)两种,后者假设输入的人脸照片一定属于预先定义的人群中的一个;而前者有可能输入的是任何人的照片。封闭的人脸鉴别通常用于人脸搜索,比如警察用照片搜索犯罪嫌疑人。它不要求搜索出来的一定就是正确的,因为后面还会有人来确认,算法只是进行初筛,提供可能的候选。而后者除了要找到最相似的候选人之外还需要确认这两个人是同一个人(也就是人脸验证),比如前面介绍的门禁系统,我们肯定不能假设输入就一定是公司的某一个员工的照片。 - 人脸识别(Face Recognition)
人脸识别是人脸验证和人脸鉴别的合称,有的时候人脸鉴别也被称为人脸识别。人脸识别是计算机视觉的一个经典任务,有很多的算法,我们这里只介绍基于深度学习的FaceNet。
3.7.1 FaceNet
人脸识别问题和常见识别问题的区别,也就是人脸识别问题的特殊性--训练数据少。因此一般采用聚类算法。
来介绍第一个选手Siamese Network。
图1 Siamese Network网络架构但是如果要比对的图片很多,Siamese Network就爆炸了,因此需要改进。方法称为Face Embedding。即用一个降维的向量来表示人脸。然后就有了FaceNet。
图2 FaceNet模型结构这里损失函数为Triplet Loss。
图3Face Embedding将输入图像映射为维欧式空间的一个点,表示为。另外在这个基础上增加一个归一化约束,即将Face Embedding都限制在半径为1的超平面上。
公式描述为:
其中表示第个triplet中的anchor,表示第个triplet中和anchor同一个人的另一张图片,表示第个triplet中其他人的图片。表示margin。
总之,可以表述为:同一个人的图片的距离加上一个margin()仍然要小于不同人图片的距离。于是损失函数可以写为:
其中。其意思为:如果相同人的图片的Embedding的距离加上小于不同人,那么就没有loss(零),否则loss就是它们的差值,并且差值越大损失也越大。因此这样的损失函数迫使模型让相同人的照片尽量聚集在一起,而不同人的照片尽量远离彼此。提高类间距离,减小类内距离。
定义好了损失函数,那么接下来的问题如何选择这个Triplet。一般来讲如果要遍历所有的组合,那是很难为人的,接近NP-hard吧!
那么怎么选择这个Triplet呢?
首先想到的是随机挑选,真的是hin随意呀?
这个方法从统计上而言还可以,但是直观的思考,并不能很好的提高人脸识别的性能。
FaceNet作者给出的方法是找最难的样本,那么怎么定义最难呢?请看下式。
最难的正样本(和anchor最远的正样本):
最难的负样本(和anchor最近的负样本):
但是用最困难样本存在运算量大的问题,同时由于样本很难,导致学习困难。于是取一个折中的方案,先易后难,逐步训练的方法。
- 小子集(计算可行性)。离线的在某个子集(subset)上使用最新保持的模型选择argmin和argmax;
- 大子集(从易到难样本)。在线的在一个大的mini-batch里使用当前最新的模型寻找argmin和argmax。
FaceNet的方法为(上面的第二种,也即从易到难样本):
- 随机的选择40张的一张作为anchor;
- 随机选择40张的另外一张作为正样本;
- 使用当前的模型参数,在所有(mini-batch)负样本中选择距离anchor最近的作为负样本。
上面的步骤来得到Triplet样本集。有时候也会用到semi-hard样本。semi-hard样本的具体概念请参考原论文。
最后,这里的人脸图像特征提取,可以使用已有的CNN来做迁移学习,提取特征。
网友评论