这就是神经网络 16:深度学习-人脸检测-FaceBoxes
概述
FaceBoxes是SSD类的检测器,为人脸检测做了相应优化和修改。即使放在今年(2019)也是SOTA级的存在。
(本来打算把SSH、S3FD也一起总结了,但是最近时间比较紧张,先放FaceBoxes,另外两个后续再补)
借用《人脸检测背景介绍和发展现状》里的一张图:
FaceBoxes
FaceBoxes是一个快速的人脸检测器。论文里贴的速度是VGA分辨率(640×480)在CPU上20fps。比MTCNN的速度略快。
提到快速的人脸检测网络,MTCNN是一个绕不过去的坎。但是作者罗列了级联人脸检测器的几大不足:1.检测速度会受到人脸数量的影响;2.多阶段训练,过程复杂;3.VGA上速度也就那样(16fps),也不是很高呀。
那么速度够快、速度不受人脸数量影响、端到端训练的人脸检测器哪里有呢?等灯登登,就是今天推出的这款FaceBoxes…
整体网络结构
FaceBoxes的创新点主要有三:
- 使用RDCL模块快速降低特征图大小,为检测速度提供了保证
- MSCL模块使用多尺度特征图预测,解决了多尺度的问题
- 使用anchor稠密化策略提高小脸的召回率
网络结构主要分RDCL和MSCL这两部分。
Rapidly Digested Convolutional Layers (简称RDCL)
翻译应该叫‘快速消化卷积层’。这个模块主要为了快速的将原图32倍下采样。共4个卷积层,步长分别是4、2、2、2。
RDCL快速的技巧有以下几个:
- 合理的搭配卷积核大小和步长。第一层卷积核是7x7的,步长为4,一次性就进行了卷积和4倍下采样,连池化都省了。后续的卷积都是步长为2,卷积的同时进行下采样。
- 用CRELU在很小的代价下使通道数增加一倍。CRELU的原始论文发现网络早期的卷积核往往是负相关的(也就是说有一半得到的值是另一半的负数),有很大冗余,那还计算那么多干啥,将卷积核数减半然后直接取负拼接起来不就行了吗。
作者在RDCL里用了两次CRELU,RELU的方式很简单,就是和-1相乘然后拼接:
我这里有个疑问,论文里作者说第一层用7x7是为了保持效率和效果的平衡,但是并没有对比实验。两层3x3_s2和一层7x7_s4下采样效果一样,但是计算量更少,作者没有对比这两种结构对最终效果的点数有多少影响。
Multiple Scale Convolutional Layers (简称MSCL)
翻译应该叫‘多尺度卷积层’。类似SSD的最后阶段,利用不同大小的特征图预测人脸位置,解决人脸多尺度的问题。
two_stage的检测器里,RPN其实就是一个单类别检测器(区分前景和背景)。但是直接使用RPN检测人脸效果并不好,因为:1.RPN使用的特征图分辨率太低,对小脸很不友好(我觉得定位精度也会受影响),无法适应多尺度;2.感知野是固定的,无法适应人脸的多尺度变化;
盾有了,下面就开始造矛了。怎么解决RPN的不足呢?方法有:1.使用不同大小的特征图进行预测,不同特征图上使用不同大小的锚框;2.使用inception模块产生多种感知野的特征给后续检测使用,让网络自主学习如何使用;
可以看到,用于预测的第一个特征图来自inception3,它前面还有两个同样的inception模块。inception模块的结构如下:
个人理解:这里的inception模块起到的作用和语义分割里的ASSP(空间金字塔池化)起到的作用类似,即提供不同粒度的上下文。深度学习中能融合丰富语义(或上下文)往往能提升最终的效果。
anchor框稠密化
作者使用的anchor框都是正方形,在inception3处使用了3个尺度的anchor框,在conv3_2和conv4_2处各使用了一个尺度的anchor框。大小如下图:
其中scale表示anchor框边长,interval便是anchor框中心点在原图上对应的距离,这个距离等于特征图下采样的倍数。作者采用了一个公式来计算anchor框的稠密度(density):
上面表格里已经把各个尺度的anchor的稠密度计算出来的。可以看到,最小的两个anchor框稠密度偏小,这相对大框来说这样的分布不平衡,影响小脸的召回率。
怎么解决呢?那就是对最小的anchor框,在锚点周围偏移增加一些框,让所有的anchor框具有相同的稠密度。作者自己的实现是对32x32做了4倍稠密,对64x64做2倍稠密。稠密化方法如下:
我自己的理解:以最小的32x32anchor框来说,此时anchor interval为32,这意味着相邻的两个anchor没有任何重叠,如果人脸处于两个anchor框交界的地方,那么没有一个anchor框会得到较高的分数(因为每个框只能看到一半),在NMS阶段可能就被过滤掉了,这就影响了小脸的召回率(大脸由大anchor负责检测)。稠密化之后,anchor之间有重叠,无论人脸在什么位置,总有一个anchor能覆盖到脸的大部分,分类时得到一个不错的分数。
训练和实验
作者训练的时候使用了以下技巧去做数据增广:
- 颜色失真
- 随机裁剪(裁剪掉的尺度相对原图是0.3到1)
- resize。裁剪掉的图统一resize到1024x1024
- 5成概率水平翻转
- 上面处理后脸的中心必须在图片内,且长宽都要大于20像素,否则丢弃
匹配策略:IOU大于0.35则认为匹配
LOSS函数:参考Faster-RCNN,用softmax交叉熵做分类损失,用smooth-L1做bbox坐标的损失。
高难度样本挖掘:由于大部分anchor都是负样本,导致正负样本不均衡。因此对负样本按照loss大小进行排序,选择最高的那部分,保证正负样本比例为1:3。(个人补充:MTCNN也有类似的技巧,不过是利用分类的LOSS选取前面的70%)。
针对主要trick,作者做了对比实验:
稠密化策略:第二列和第一列比,作者去掉了稠密化策略,可以看到掉了1.1%,这说明稠密化策略非常重要。
MSCL:用三个3x3卷积替换掉MSCL,最终输出特征和inception3一样大,所有的anchor都用在最后那个特征图上。第三列和第二列相比点数掉了1%。(其实这里给我们一个启发,这个办法可以用来加速FaceBoxes,毕竟点数损失可以接受)
RDCL:去掉CRELU,倍增输出通道,虽然点数涨了一点点,但是时间多了很多,这说明CRELU的性价比很高,可以在影响很小的基础上大幅减少时间。
个人总结:相对coco分类比赛的那些网络,FaceBoxes是很小只的,因为这是但目标分类,相对比较简单,而且人脸接近刚体,变形相对不大,这也觉定了这种任务可以采用更紧凑的网络来完成。所以FaceBoxes还有优化空间,可以更进一步裁剪层数。
效果
快是基本要求,好是追求目标。
论文
FaceBoxes: A CPU Real-time Face Detector with High Accuracy
Single Stage Headless Face Detector
S3FD: Single Shot Scale-invariant Face Detector
Recurrent Scale Approximation for Object Detection in CNN
代码
一个公司的复现:zeusees/FaceBoxes(caffe)
TropComplique/FaceBoxes-tensorflow
DetectionTeamUCAS/SSH_Tensorflow
S3FD官方代码(caffe):sfzhang15/SFD
(FaceBoxes作者之一sfzhang15也是S3FD作者呀)
sciencefans/RSA-for-object-detection
参考资料
[WIDER FACE官网:WIDER FACE: A Face Detection Benchmark
[论文翻译]据传比MTCCN的FaceBoxes《FaceBoxes: A CPU Real-time Face Detector with High Accuracy》