Face Recognition

好久没写博客了。

最近做了快一个月的人脸识别问题,也算有点经验了。首先放出几个觉得真的有用的paper(至少我能验证有效的):

  1. Deep Learning Face Representation by Joint Identification-Verification
  2. A Unified Embedding for Face Recognition and Clustering
  3. Bayesian Face Revisited: A Joint Formulation

趁着Deep Learning的浪潮,用它来做人脸识别的文章很多,比如DeepID/DeepID2/DeepID2+,DeepFace,FaceNet,Deep Face Recognition(VGG),大家的效果都做的很不错,DeepFace不好实现,没3D alignment,其他的都还好。前三个是cuhk做的,FaceNet是google做的,Deep Face Recognition是VGG做的,后两个都是训练一个end to end的网络,区别在于VGG还会引入softmax(不同的人为不同的类别,训练一个多元分类器)。

DeepID2

DeepID2比较复杂,大概的训练流程如下:

  1. 先训练200个网络(每一个网络都会有两个loss,一个是identification一个是verification),每个网络产生160维特征,每个网络都是同样的结构,但是输入不一样,区别在于:
    • 人脸占图片的比例不一样
    • 会以不同的关键点为图像中心
    • 图像可以是彩图也可以是灰度图
    • 左右翻转(这个我觉得应该不会额外训练网络,而是为同一个网络增加训练数据)
  2. 然后选择比较有效的25个网络出来,就可以得到25 * 160 = 4000维特征,
  3. 对4k特征做PCA得到180维特征,
  4. 对这180维特征做Joint Bayesian。

FaceNet && VGG

总的来说,这两个工作很类似,都是用triplet loss,而DeepID2是用Contrastive Loss,而我认为两种形式在一定程度上是等价的(两个pair能转化成triplet)。

FaceNet跟VGG的区别在于:

  1. FaceNet有很多很多的数据,
  2. FaceNet没有用softmax,
  3. FaceNet加上了hard mining,
  4. FaceNet的features加上了L2 Norm。

实验

我做实验的时候,大体的框架是:多网络+L2Norm+triplet loss,多网络的features直接拼起来用两个全连接层再训练一次triplet。由于我是用我之前landmark的工作来对齐人脸的,那个工作只有5个点,所以每个尺度我只产生了5个网络,然后我用了两个尺度,所以总共有10个网络,目前我在LFW上是做到98.7167%。

下面是简单的记录一下我的实验结论(好像不止这些,心血来潮的时候写这篇博客,记得多少写多少吧),face-0.5表示以人脸中心作为图像的中心且眼距占输入图像的0.5。

多网络

多尺度是否有效

单个:face-0.5是0.951667,face-0.3是 0.958167,
联合是:0.9640
联合后加PCA(95% eigenvalues,158 / 320):0.9652
联合后加PCA再加Joint Bayesian:0.9673

不同的点为中心:

单个:face-0.5是0.951667,left-0.3是0.946667,
联合是:0.9605
联合后加PCA(95% eigenvalues,134 / 320):0.9622
联合后加PCA再加Joint Bayesian:0.9655

测试的时候加flip

face-0.5是0.951667,加了flip之后是0.9565
flip的加法是:对于A和B两张图片,A1跟A2表示图片A flip前后的照片,对应特征为fa1跟fa2
那么最终两张图片的diff为 |fa1-fb1|^2 + |fa1-fb2|^2 + |fa2-fb1|^2 + |fa2-fb2|^2
若是直接|fa1-fb1|^2 + |fa2-fb2|^2的准确率是0.956167

FC代替Joint Bayesian

Joint Bayesian的公式很漂亮,但是毕竟是个生成模型,并不能像判别性模型那样极大的为目标服务,而且用Joint Bayesian也会有一些问题,比如:

  1. 维度一高很难收敛,需要先用PCA降维,但是PCA对维度也很敏感,究竟要降多少维呢?反正每次我用不同维度,结果都不一样。
  2. Flip的图像后的特征很难统一到模型里面,只能分开算。

此外我的实验结果也表明用两个全连接层就可以代替Joint Bayesian。

pair vs triplet

triplet收敛很快,快很多,迟点上图。

分类作用

没用!不知道是不是我调网络不好,确实真没用。有朋友也尝试过,发现没用。

此外,假设我有2W个人,像DeepID2这么简单的网络怎么对2w类进行分类?不现实。后面的所有的实验我都不加分类了。FaceNet就很明智的没加了。

Hard Mining

有用!训练大网络(ZF-net)亲测有效,可以加快收敛。不过我后来也发现你训着训着,剩下不符合margin的基本都是很hard的,所以我后面也不加了…

学习率

啊,不说什么了,loss稳定降学习率,所有网络都必须有一个点的提升。

L2 Norm

好用!加快收敛之余让你训练更加方便,不容易发散。

数据–数据–数据

太重要了。。。。。。。。。。。。。。。。。。。谁有更多的数据欢迎共享,MegaFace的数据看起来很难的样子。

(我感觉是未完待续,不过我感觉自己会懒得来更新了)

坚持原创技术分享,您的支持将鼓励我继续创作!