Joint Face Detection and Alignment using Multi-task Cascaded Convolutional Networks》论文解读。
本文来自于中国科学院深圳先进技术研究院,目前发表在arXiv上,是2016年4月份的文章,算是比较新的文章。
论文地址:
https://kpzhang93.github.io/MTCNN_face_detection_alignment/
用于人脸检测和对齐。因为现实中的图片一般还有其他背景,所以我们要检测出人脸部分,不能遗漏,不能错检。
然后为了人脸识别更加精准,所以一般还要人脸对齐,通过检测出人脸的五官:眼睛,鼻子,嘴巴等这些关键点位置来
进行仿射变换将人脸统一校准。
本文提出的unified cascaded CNNs by multi-task learning,包含三个阶段:
1) 利用一个浅层的CNN快速产生候选窗口
2) 利用一个更复杂的CNN排除掉大量非人脸窗口
3) 利用一个更强大的CNN进一步改善结果,并输出人脸关键点位置。
本文的贡献:
1) 提出一个新的基于CNN的级联型框架,用于联和(joint)人脸检测和对齐;还设计轻量级的CNN架构使得速度上可以达到实时。
2) 提出一个有效的online hard sample mining方法来提高表现能力
3) 在人脸检测和人脸对齐上提高了不少精度
首先图像经过金字塔,生成多个尺度的图像,然后输入PNet, PNet由于尺寸很小,所以可以很快的选出候选区域,但是准确率不高,然后采用NMS算法,合并去掉冗余候选框。然后根据候选框提取图像,作为RNet的输入,RNet可以精确的选取边框,一般最后只剩几个边框。最后输入ONet,ONet虽然速度较慢,但是由于经过前两个网络,已经得到了高概率的边框,所以输入ONet的图像较少,然后ONet输出精确的边框和关键点信息(关键点信息似乎神经网络里代码并没用到,也就是如果矫正的话,应该使用OpenCV之类实现的).
1. MTCNN关键参数
NMS去冗余框用的:
nms_threshold:非极大值抑制nms筛选人脸框时的IOU阈值,三个网络可单独设定阈值,值设置的过小,nms合并的少,会产生较多冗余计算。示例nms_threshold[3] = { 0.5, 0.7, 0.7 };。
threshold:人脸框得分阈值(即softmax预测的结果),三个网络可单独设定阈值,值设置的太小,会有很多框通过,也就增加了计算量,还有可能导致最后不是人脸的框错认为人脸。示例threshold[3] = {0.8, 0.8, 0.8};
p-net作为输入 金字塔图像时:
minsize :最小可检测图像,该值大小,可控制图像金字塔的阶层数的参数之一,越小,阶层越多,计算越多。示例minsize = 40;
factor :生成图像金字塔时候的缩放系数, 范围(0,1),可控制图像金字塔的阶层数的参数之一,越大,阶层越多,计算越多。示例factor = 0.709;
输入图片的尺寸,minsize和factor共同影响了图像金字塔的阶层数。用户可根据自己的精度需求进行调控。
接下来对使用过程进行详细说明:
2. 生成图像金字塔
前面提到,输入图片的尺寸,minsize和factor共同影响了图像金字塔的阶层数。也就是说决定能够生成多少张图。
缩放后的尺寸minL=org_L*(12/minisize)*factor^(n),n={0,1,2,3,...,N},缩放尺寸最小不能小于12,也就是缩放到12为止。n的数量也就是能够缩放出图片的数量。即金字塔的阶层数,一层代表一张图。
看到上面这个公式应该就明白为啥那三个参数能够影响阶层数了吧。
3. P-net运算
一般P-net只做检测和人脸框回归两个任务。忽略下图中的Facial landmark,确实p-net代码里面也没有这步。
虽然网络定义的时候input的size是12*12*3,由于Pnet只有卷积层,我们可以直接将resize后的金字塔各种尺寸的图像喂给网络进行前传,只是得到的结果就不是1*1*2和1*1*4,而是m*m*2和m*m*4了。这样就不用先从resize的图上截取各种12*12*3的图再送入网络了,而是一次性送入,再根据结果回推每个结果对应的12*12的图在输入图片的什么位置。
针对金字塔中每张图,网络forward计算后都得到了人脸得分以及人脸框回归的结果。人脸分类得分是两个通道的三维矩阵m*m*2,其实对应在网络输入图片上m*m个12*12的滑框,结合当前图片在金字塔图片中的缩放scale,可以推算出每个滑框(即定位框也)在原始图像中的具体坐标。
首先要根据得分进行筛选,得分低于阈值的滑框(定位框),排除。
然后利用nms非极大值抑制,对剩下的滑框进行合并。nms具体解释,可以参照我上一篇博客:NMS非极大值抑制:用擂台赛带你从原理到代码脑洞大开恍然大悟
当金字塔中所有图片处理完后,再利用nms对汇总的滑框进行合并,然后利用最后剩余的滑框对应的Bbox结果转换成原始图像中像素坐标,也就是得到了人脸框的坐标。
所以,P-net最终能够得到了一批人脸框(预测结果只是给iou用的)。
4. R-net
R-net仍然只做检测和人脸框回归两个任务。忽略下图中的Facial landmark。
R-net的作用是对P-net得到的人脸框进一步打分筛选,回归人脸框,把多余的候选框尽量再筛除。
将P-net运算出来的人脸框从原图上截取下来,并且resize到24*24*3,作为R-net的输入。输出仍然是得分和BBox回归结果。
对得分低于阈值的候选框进行抛弃,剩下的候选框做nms进行合并,然后再将BBox回归结果映射到原始图像的像素坐标上。
所以,R-net最终得到的是在P-net结果中精选出来的人脸框。
5. O-net
O-net将检测到的人脸框回归和特征点定位(直到这里才有),一起做了。
O-net的作用是对R-net得到的人脸框进一步打分筛选,回归人脸框。同时在每个框上都计算特征点位置。
将R-net运算出来的人脸框从原图上截取下来,并且resize到48*48*3,作为O-net的输入。输出是得分,BBox回归结果以及landmark位置数据。
分数超过阈值的候选框对应的Bbox回归数据以及landmark数据进行保存。
将Bbox回归数据以及landmark数据映射到原始图像坐标上。
再次实施nms对人脸框进行合并。
经过这层层筛选合并后,最终剩下的Bbox以及其对应的landmark就是我们苦苦追求的结果了。
6.loss训练
利用三个任务来训练CNN检测器:人脸/非人脸 分类 ,bounding box regression 和人脸关键点定位(facial landmark localization)
1) 人脸分类器。这是一个二分类问题,对于每个样本xi,我们使用交叉熵损失:
习惯上大家喜欢上面的写法。
在TensorFlow采用上面的这种形式:
cross_entropy = -tf.reduce_mean(y_ * tf.log(tf.clip_by_value(y, 1e-10, 1.0)))
但是本文中采用的是这种写法,2种都可以的。为啥用下面的这种?因为输入一副图片可能含有人脸,可能不含人脸。
所以就写成了下面这种形式的交叉熵损失,当你做纯粹的分类时候,自然用上面的简洁方便些。
其中,表示网络预测该样本是人脸的概率,是ground-truth label。
2) 边界框回归(Bounding box regression)。对于每个候选窗口,我们预测该候选窗口与其最近的ground truth(the bounding boxes’ left top, height, and width)的偏移。这是一个回归问题,对每个样本xi,使用欧式损失(Euclidean loss):
其中,表示从网络中获得目标的坐标,表示ground-truth坐标。有4个坐标,包括左上角x,y坐标,高度和宽度,因此
3) Facial landmark localization。与Bounding box regression相似,损失函数如下:
其中,是网络预测的人脸关键点的坐标,是ground-truth坐标(不太理解,是提前标记好了??原论文也没提)。有5个人脸关键点,包括左眼,右眼,鼻子,嘴边左边角,嘴巴右边角,因此
4) Multi-source training。由于在每个CNN网络中,我们使用了不同的任务,因此,在学习阶段有不同种类的训练图像,比如人脸,非人脸,部分对齐的人脸。在这种情况下,一些损失函数(公式1-3)用不到。比如说,对于背景区域图片,我们只计算,另外两个loss都设为0。整体的学习目标如下:
其中,N表示训练样本的数量,表示任务的重要性。在P-Net和R-Net中,;在O-Net中,。is the sample type indicator,比如说,对于背景样本,我们只计算,(即没有人脸时刻)另外两个loss都设为0,即此时。
在这种情况下,使用SGD来训练网络。
5) Online Hard sample mining。与传统的hard sample mining after original classifier had been trained不同,我们在人脸分类中采用在线的hard sample mining来自适应训练。
在每个mini-batch中,我们从所有样本的前向传播中将计算得到的loss排序,然后只取其中loss最高的前70%作为hard samples。然后在反向传播(BP)中只计算这些hard samples,忽略那些简单的样本。
推荐这篇也写的很好:https://www.jianshu.com/p/2f749b07e09f
这2篇博主们的实验成果:https://blog.51cto.com/gloomyfish/2319246
https://www.cnblogs.com/cpuimage/p/8995600.html
参考:
https://blog.csdn.net/fuwenyan/article/details/77573755?locationNum=5&fps=1
https://www.cnblogs.com/hejunlin1992/p/7856414.html