RetinaFace: Single-stage Dense Face Localisation in the Wild

论文:http://xxx.itp.ac.cn/abs/1905.00641
代码:https://github.com/deepinsight/insightface/tree/master/RetinaFace
https://github.com/biubug6/Pytorch_Retinaface

1 核心思想

RetinaFace是基于FPN + SSH context module + 可变形卷积 + 多任务损失,完成了一阶段的密集场景下的人脸检测、五个关键点定位及三维人脸模型构建,因为RetinaNet是基于FPN实现了一阶段的目标检测任务,所以作者将本文针对人脸检测的RetinaNet称之为RetinaFace。

在这里插入图片描述FPN:FPN目前基本上成为了目标检测领域的通用网络结构,以实现多尺度的目标检测。其实现包含了自上向下的上采样和横向连接。

context module:为了结合关注目标的领域信息以实现小尺寸人脸的检测,SSH在feature map上应用了context module以增大感受野的尺寸,具体如下图所示,对输入feature map应用了多个级联的卷积,并将不同感受野的输出进行concatenate操作。

在这里插入图片描述上图共有两条通路,第一条感受野是两个3 * 3的级联,即 5 * 5;第二条感受野是3个3 * 3的级联,即7 * 7。

SSH的context module是以增大感受野的方式关注目标的邻域区域,但其还是在规整的euclidean grid上进行操作的。

可变形卷积:为了增强模型对于非规则变换的拟合能力,作者使用了可变形卷积网络(DCN)对目标的几何形变进行建模。作者之所以这样做,是受widerface挑战赛2018年冠军的提示,在这篇文章中,作者证实了通过在规则化网格上和非规则化网格上的扩展(扩大感受野 和 拟合几何形变)有助于提升人脸检测效果。

多任务损失:作者受Mask-RCNN中通过添加实例分割分分支提升了检测效果的启示,在人脸检测的任务上添加了人脸关键点定位和3D的人脸模型构建。总体训练损失为:
在这里插入图片描述
分类损失 L c l s ( p i , p i ∗ ) L_{cls}(p_i,p_i^*) Lcls(pi,pi)是目标预测概率与实际label之间的softmax交叉熵损失,当然这里的类别只有是否为人脸两类;

定位损失 L b o x ( t i , t i ∗ ) L_{box}(t_i,t_i^*) Lbox(ti,ti)是预测的模板位置与实际位置之间的smooth-l1损失,作者是按照Fast R-CNN中的做法,预测的是归一化的人脸图像中心点及图像宽高的实际值与预测值之间的损失;

关键点定位损失 L p t s ( l i , l i ∗ ) L_{pts}(l_i,l_i^*) Lpts(li,li)是对人脸的五个关键点通过图像的宽高进行归一化之后的位置差异;

密集回归损失 L p i x e l L_{pixel} Lpixel是用于三维人脸建模的损失(GCN部分暂时不理解)。

加权系数 λ 1 = 0.25 , λ 2 = 0.1 , λ 3 = 0.01 \lambda_1 = 0.25,\lambda_2 = 0.1,\lambda_3 = 0.01 λ1=0.25,λ2=0.1,λ3=0.01,更加强调分类、定位和关键点位置。

2 实验

数据集:wider face数据集包含32203幅图像,393703个人脸,包含了丰富的尺度、姿态、表情、遮挡和光线变化。训练集:验证集:测试集 = 4:1 :5。数据集根据人脸检测的难度,分成了easy、medium和hard三个子集。

原始的wider face数据集是没有标注人脸关键点的位置的,作者对其进行了人工标注,对训练集标注了84.6k个人脸的关键点,对验证集标注了18.5k个人脸的关键点。

Anchor:作者参考FAN进行了anchor设计,对FPN的P2到P6设计了anchor。

不同于传统目标检测,人脸检测的anchor box的长宽比一般为1:1到1:1.5之间,但是往往尺度变化更大(从几个像素到数千像素)。这里作者设计anchor的长宽比为1:1,一个feature map点对应3个anchor,各层级的anchor的尺度增大比例为 2 1 3 2^{\frac{1}{3}} 231。对于一个大小为640 * 640的输入图像,其anchor的大小范围为16 * 16到406 * 406。总的anchor尺寸如下表所示:
在这里插入图片描述训练过程中,如果某anchor与ground-truth之间的IOU大于0.5,则标记为正样本,若IOU小于0.3,则标记为负类。剩余的anchor在训练过程中忽略。

使用OHEM解决正负样本不均衡的问题,具体做法是选取损失最大的负样本,使得负正样本比例为3:1。

数据增广:使用了随机裁剪、随机水平翻转和颜色变换。

随机裁剪是按照原始图像短边的0.3到1倍设置裁剪块的尺寸,然后从图像中随机裁剪正方形图像块,对于裁剪边界上的人脸,如果人脸中心点位于裁剪块内,则保留该人脸的标注框。随机裁剪有助于检测被部分遮挡的人脸。

在这里插入图片描述
人脸检测效果:
在这里插入图片描述在这里插入图片描述关键点定位效果:
在这里插入图片描述用于人脸识别时的效果:
在这里插入图片描述
在这里插入图片描述推理时间:
在这里插入图片描述

3 代码分析

本节学习https://github.com/biubug6/Pytorch_Retinaface版本的代码。

主要分析以mobilenet0.25为骨干网络的训练代码。

网络结构
网络的backbone为mobilenet0.25,共分成了3个stage,最后经过一个自适应平均池化层后,输出1 * 1 * 256的feature map,然后再经过一个256 * 1000的全连接层,输出图像属于1000个类别的logits。使用了在ImageNet上预训练的分类模型。

这里并不是要使用分类结果,而是通过_utils.IntermediateLayerGetter函数得到backbone中三个尺度的输出特征,然后基于三个尺度的特征实现FPN,具体的做法是对分辨率最大的特征直接使用1 * 1卷积得到channel数为64的输出特征;对两个分辨率较小的输出特征使用1 * 1卷积,将其channel数目变成64,然后对低分辨率的特征使用最近邻插值将其分辨率方法加倍,和前一尺度的特征逐元素相加,相加后的特征再使用3 * 3的卷积 + BN + leakyrelu得到这一尺度的最终输出特征。

三个尺度的输出特征分别再使用SSH的context module,具体来说就是对特征分别经过三条路径的卷积,第一条路径是一个3 * 3的卷积,输出channel数为输入特征channel数目的二分之一,第二个路径是两个3 * 3共5 * 5的卷积,第三个路径是3个3 * 3共7 * 7的卷积,后两条路径的输出channel数为输入特征channel数目的四分之一。最后将三条路径的输出特征在channel维度拼接作为最终输出。(这里并没有使用可变形卷积)

对输出的三个尺度的feature map分别应用三个网络头分别实现cls,box和landmark的预测,并没有预测密集的3维点。预测时是针对feature map上的每一个点的每一个anchor,分类预测两个cls输出,box预测四个输出,landmark预测10个输出。所有的预测都是通过一个1 * 1的卷积层实现的。

Anchor设置:代码中默认只用了三个尺度的feature map,对应的stride分别为8,16,32,每个feature map点对应于两个长宽比为1的anchor,anchor的长度分别为16,32;64,128;256,512。因为默认输入图像的尺寸为640 * 640,因此三个尺度的feature map大小分别为80 * 80,40 * 40,20 * 20,共计(80 * 80 + 40 * 40 + 20 * 20) * 2 =16800个anchor。

数据增强

随机裁剪:随机从[0.3,0.45,0.6,0.8,1.0]中选择一个图像块和短边的系数,随机决定一个裁剪的起点位置,当然要保证裁剪的区域不会超过图像的边界。要保证裁剪的图像子块中至少要包含一个完整的人脸,也要保证人脸的中心点位于裁剪的子块内,对于超过了图像子块边界的人脸只保留部分人脸box和关键点。

颜色变换:随机亮度变换 + 饱和度 + 色彩 + 对比度变换;

随机水平镜像;

随机的图像插值算法。

损失计算
首先要根据各anchor与ground truth之间的IOU决定该anchor的label。然后计算三项损失的和,作者对定位损失乘以了2,其他两项损失未使用加权系数。

网络训练
训练过程中是针对所有的网络层应用同样的学习率使用带动量的SGD进行训练的。

学习率没有进行warmup,只是在190,220个epoch后衰减为原来的0.1倍。

针对边缘设备的RetinaFace

作者还开放了针对边缘设备的RetinaFace,代码:https://github.com/biubug6/Face-Detector-1MB-with-landmark

主要的改变是针对mobilenet0.25,重新设计了anchor的大小。另外,重新设计了网络结构,并且引入了RFB,设计了slim和RFB另外两个版本的检测网络。

训练好的pytorch模型,转换为onnx,使用ncnn进行推理。当然也可以转换为Tengine的模型,在EAIDK310上测试下推理速度。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值