Icyface 人脸识别平台上线
Wed, Jun 14, 2017 in Interesting Python
icyface是一个人脸识别平台,提供基础的人脸检测和人脸比较方案,icyface 目前在lfw数据集上达到95%的准确率,仍需要后续的迭代,同时icyface 完全开源,从网站,api,到训练模型的代码,一方面是希望作为一个baseline 可能会对真正研究这方面的同学有一些启发,其次是由于并没有很深入地研究人脸识别这块,很多可以做的事情也都暂时没做(下面会提到),所以也希望有更多地人可以参与进来,提出一些有用的意见,或在github者提交自己的pr,这样相信对大家都会很有收益。
icyface可以通过下面这个链接访问:http://face.icybee.cn/
平台现在已经开源在github上,icyface的开源项目包括下面这三个:
- 模型训练部分: https://github.com/bupticybee/icyface_offline 这个部分提供需要下载的数据,数据预处理,模型训练的代码,产出一个人脸识别模型
- api接口部分: https://github.com/bupticybee/icyface_api 这部分将模型训练的产出封装成一个REST api
- icyface 平台网站本身: https://github.com/bupticybee/icyface_website
icyface平台和api都是围绕着模型构建的,所以在这里也就不多提了,有兴趣的同学可以自行阅读代码,这篇文章会将重点集中在如何构建一个人脸识别模型上。
概述
这几年人脸识别作为所谓“人工智能”的先驱迅速商业化,只要是大公司都多多少少在人脸识别方面有投入,lfw榜也是常年被刷爆,前几名都达到了99.5%以上的准确率,相关的创业公司就像野草一样疯长,水很深。
但是人脸识别这个问题离解决还差很远,lfw数据集的参考性很有限,在face++ 2015年的论文《Naive-Deep Face Recognition: Touching the Limit of LFW Benchmark or Not?》中,face++ 仅凭借一个10层的简单cnn结构,加上内部抓取的5million的图片作为训练集,根本不用之前被证明很有效的一些trick,直接就达到了99.5%的准确率,是当时最好的模型,但就是在这一篇文章中,face++的研究员将这一个模型放在实际场景中,结果表现得很糟糕。因为实际场景非常复杂,光照,人脸的角度,年龄,发饰,化妆等都可以给模型带来很大难度。并且,许多文章解决的也只是人脸识别的一部分问题,人脸识别的流程大概是这样的:
各个步骤都有很多论文可以参考,而且右边的三个步骤在有了深度学习之后可以交给cnn解决。活体识别不在今天的话题范围内,其他的多多少少会涉及一些。
数据集
这部分往下的具体实现都可以在 https://github.com/bupticybee/icyface_offline找到。
一般来说,人脸识别的数据集是越大越好的,经常被学术界使用的CASIA-WebFace有50万张图片,微软的MS-1M数据集有100万张图片构成,这次在训练模型时我选用了两个不同量级的数据集:
(1)CACD dataset 一份跨年龄的人脸图片库,含有2000个名人的160000张照片
(2)CASIA-webface 一份常用的人脸识别数据库,含有50万张来自1万个名人的图片。
我在两个数据集上都进行了训练,CACD使用同样方法训练出的模型比CASIA在lfw上低了4个百分点。所以,尽可能用更大的数据集,会给你省下很多麻烦。
预处理
人脸检测
人脸检测和对齐是两个困难的课题,人脸检测是目标检测问题的一个子集,目标检测就又是一个完整的研究方向了,这部分我只看过一小部分论文,在2015年MSRA提出来的fast rcnn(论文链接《Fast R-CNN》)中,研究人员使用ROI卷积加上softmax和bounding box做目标检测和边界回归。对具体方法感兴趣的可以看论文。
除了fast rcnn外,还有很多方法可以进行人脸检测,只要顺着fastrcnn的引用就可以找到…
在icyface的实现中,我直接“偷”了另一个人脸检测开源项目facenet的人脸检测部分,facenet的人脸检测部分用的是mtcnn,当然了,mtcnn是一个很范的称呼,但是人家开源项目里这么叫,我就也这么跟着叫了。
人脸对齐
然后是人脸对齐部分,这部分也有很多种做法,而且可以做得很复杂,像14年的《DeepFace: Closing the Gap to Human-Level Performance in Face Verification》这篇论文中,就采用了传说中的3d建模align,很厉害:
还有就是2d align,不需要3d建模,只要计算一个亲和矩阵就可以了。github中的脚本里包含了2d align的代码,但是实际模型训练的时候还暂时并没有使用,效果大概是这样的:
会通过亲和矩阵把图片做一个2d矩阵运算,让鼻子眼睛呆在图片种相对固定的位置,不过这么align的结果就是图片可能会有些失真。
丢弃图片
根据face++《Naive-Deep Face Recognition: Touching the Limit of LFW Benchmark or Not?》的研究,似乎如果数据集种含有一些出现次数比较少的人,模型的效果会降低,所以我抛弃了出现频率小于30的人(不够有名就会被抛弃的)。
模型
至于人脸识别模型,我选择怎么简单怎么来,我选择训练一个比face++那篇论文更加naive的模型,不对人脸作裁剪,不对隐含层作pca,直接训练一个34层的resnet(最后的1000size的全连接层改成160的size)对人脸图片作分类,在使用CASIA-webface时这就是一个10000分类问题。
等等,我们的问题不应该是怎么判断两张照片中的人是不是同一个吗?怎么会训练一个分类器?有这个问题的童鞋可以看一看论文,习惯性做法是训练一个分类器,然后把图片经过分类器时的隐含层拿出来做图片的特征向量,经过处理以后作对比。
我使用了学习速率0.01的momentum,训练10轮后将学习速率减小到十分之一,共训练20轮,在1080ti的显卡上训练时间大概是半天左右,这样一个naive的模型在casia的接近10000分类上达到了75左右的准确率,要知道这是一个很高的准确率了,这样训练的模型对lfw的6000对抽取隐含层后每对对比cosin夹角,大于0.5的判为是同一个人,否则判为不同点人,这样简单的处理后,模型在lfw上达到了95的准确率。
没做什么
还有很多可以改进模型的手段,但是我都还没有采用,其中包括:
- 使用center loss 或者triplet loss 或者joint byes 来改进模型
- 使用人脸的不同部位训练分类器,然后emsemble(常用trick)
- Data argument
- 使用更大的数据集
- …
这些没有做的原因,有的是因为懒,有的是因为没有能力,所以也希望更多的人参与进来~
the end
这些大概就是icyface的全部内容,代码在github上可以找到, 有问题联系 icybee@yeah.net.