人脸识别算法
一、前言
人脸识别目前已经很常见了,涉及到我们生活中的方方面面,比如高铁火车站过闸的时候人脸和身份证对比识别、手机解锁的人脸识别、支付宝微信各种app的人脸身份验证,这些都是经过人脸识别算法来实现的。
我们身边最最常见的例子就是公司每层楼门口的人脸识别开门,通过人脸和工卡照片的对比来确认身份,那么人脸识别算法是怎么通过识别身份信息的呢?
二、人脸识别的流程
人脸识别一般流程包括
1、人脸检测
2、人脸矫正
3、人脸特征提取
4、人脸特征计算相似度(milvus人脸特征库检索)
如下图
通常会有一个获取人像的设备(手机、摄像头)获取到人像的图片,然后进入人脸检测算法,人脸检测算法会检测人脸的位置和人脸五官的关键点。
通过人脸检测算法得到五官关键点位置后,对人脸进行一个五官的矫正也就是人脸对齐(一般采用仿射变换来对齐人脸,这个是为了提高识别准确率,如果不对齐人脸五官的话,头歪歪扭扭的话会影响识别准确率)。
人脸对齐后有的算法会加一个活体检测,主要是为了防止一些不法分子利用静态人脸照片进行人脸识别。活体检测算法会对人脸获取一段连续的视频,判断是否有活体动作(摇头、张嘴、眨眼、点头等),活体检测比较常见于政府业务相关的验证,比如广州住房公积金管理中心登陆,广州公安,广州交警等等都需要活体检测,这一步不加说明,感兴趣的可以自行了解。
对齐resize之后的人脸图片会经过一个预训练好的人脸reID算法模型进行人脸特征的提取。
提取到当前人脸的特征之后(比如512维特征),会与人脸库(一般是一个milvus人脸特征数据库)的特征向量进行特征距离相似度计算,当特征相似度超过设定的阈值就认为是同一个人。
当前比较好的开源项目有
Deepface
CompreFace
Face Recognition
InsightFace
FaceNet
接下来就以InsightFace为例子来说说人脸识别算法
三、人脸识别算法
1、人脸检测
RetinaFace(CVPR'2020)是一种实用的单级SOTA人脸检测器,相关论文入选CVPR2020,检测效果相当不错,对于很小的人脸也可以检测到。
RetinaFace可以输出人脸的检测框和人脸的五官的五个关键点
RetinaFace于19年5月份出现,当时取得了state-of-the-art,可以说是目前开源的最强人脸检测算法,它主要在以下五个方面作出贡献:
在single-stage设计的基础上,提出了一种新的基于像素级的人脸定位方法RetinaFace,该方法采用多任务学习策略,同时预测人脸评分、人脸框、五个人脸关键点以及每个人脸像素的三维位置和对应关系。
在WILDER FACE hard子集上,RetinaFace的性能比目前the state of the art的two-stage方法(ISRN)的AP高出1.1% (AP等于91.4%)。
在IJB-C数据集上,RetinaFace有助于提高ArcFace的验证精度(FAR=1e-6时TAR等于89.59%)。这表明更好的人脸定位可以显著提高人脸识别,人脸验证准确率各项指标可以参考https://blog.csdn.net/liuweiyuxiang/article/details/81259492。
通过使用轻量级backbone网络,RetinaFace可以在VGA分辨率的图片上实时运行
开源了代码并有额外的注释,开源精神respect!
RetinaFace的结构如下图
一共有四个模块,分别是Backbone,FPN,Context Module和Multi-task Loss。其中Multi-task Loss对应下图detect head的四个并行分支Loss(人脸分类 Lcls,框回归Lbox,关键点检测Lpts和人脸像素的三维位置和对应关系Lpixel)
FPN
RetinaFace采用从P2到P6的特征金字塔层,其中P2到P5通过使用自顶向下和横向连接计算相应的ResNet残差阶段(C2到C5)的输出。P6是在C5处通过一个步长2的3x3卷积计算得到。C1-C5是在ImageNet-11k数据集上预先训练好的ResNet-152分类网络,P6是用“Xavier”方法随机初始化的。
Context Module(SSH)
受SSH 和PyramidBox 的启发,RetinaFace在五个特征金字塔层应用单独的上下文模块来提高感受野并增加刚性上下文建模的能力。从2018年 WIDER Face 冠军方案中受到的启发, 在横向连接和使用可变形卷积网络(DCN)的上下文模块中替换所有 3x3的卷积,进一步加强非刚性的上下文建模能力。
Multi-task Loss
对于任何训练的anchor i,RetinaFace的目标是最小化下面的多任务的 loss:
RetinaFace的detect head有四个并行的分支:人脸分类 Lcls,框回归Lbox,关键点检测Lpts和人脸像素的三维位置和对应关系Lpixel
包含四个部分:
人脸分类loss Lcls(pi,pi*)。这里的pi是anchor i为人脸的预测概率,对于pi * 是1 代表为positive anchor,0代表为negative anchor。分类loss Lcls采用softmax loss,即softmax loss在二分类的情况(人脸/非人脸)的应用。
人脸框回归loss,Lbox(ti,ti*),这里的ti={tx,ty,tw,th},ti * ={tx *,ty *,tw * ,th *}分别代表positive anchor相关的预测框和真实框(ground-truth box)的坐标。按照 Fast r-cnn的方法对回归框目标(中心坐标,宽和高)进行归一化,使用Lbox(ti,ti *)=R(ti-ti *),这里R 是 smooth-L1 Loss
人脸的landmark回归loss Lpts(li,li *),这里li={lx1, ly1, …lx5, ly5},li *={lx1*, ly1*, …lx5*, ly5*}代表预测的五个人脸关键点和基准点(ground-truth)。五个人脸关键点的回归也采用了基于anchor中心的目标归一化。
Dense回归loss Lpixel。
loss调节参数 λ1-λ3 设置为0.25,0.1和0.01,这意味着在监督信号中,RetinaFace增加了边界框和关键点定位的重要性
anchors设置
如上表所示,RetinaFace从P2到P6的特征金字塔级别上使用特定比例的anchor,P2旨在通过平铺小anchors来捕获微小的面部,但要花费更多的计算时间,并且要冒更多的误报风险。RetinaFace将scale step设置为2^(1/3),aspect ratio设置为1:1。输入图像大小为 640*640 , anchors可以 覆盖 从16x16 到 406x406的特征金字塔层。从五个下采样(4,8,16,32,64)的feature map平铺anchors,每个feature map中的点预测3个anchors,总共有(160 * 160 + 80 * 80+40 * 40+400+100) * 3 = 102300个anchors,其中75%来自P2。不过在代码中,只用了8,16,32这三个下采样层的输出feature map,且每个点只放两个anchors。
所以,对于640 * 640的输入,32,16,8的下采样输出,每个点的输出是【(1,4,20,20),(1,8,20,20),(1,20,20,20)】,【(1,4,40,40),(1,8,40,40),(1,20,40,40)】,【(1,4,80,80),(1,8,80,80),(1,20,80,80)】。
其中4,8,20分别代表一个点两个anchors的类别数(2 anchors * 2类),(2 anchors * 框的信息),(2 anchors * 5个关键点信息(一个点x,y))
其他tricks
数据增强
WIDER FACE训练集中大约 有 20% 的小人脸 , RetinaFace遵循 X. Tang, D. K. Du, Z. He, and J. Liu. Pyramidbox: A context-assisted single shot face detector. In ECCV, 2018和S. Zhang, X. Zhu, Z. Lei, H. Shi, X. Wang, and S. Z. Li. S3fd: Single shot scale-invariant face detector. In ICCV, 2017. 并从原始图像随机crop方形patches并调整这些 patches到 640*640 产生更大的训练人脸。更具体地说,在原始图像的短边[0.3,1]之间随机裁剪正方形patches。对于crop边界上的人脸,如果人脸框的中心在crop patches内,则保持人脸框的重叠部分。除了随机裁剪,还通过0.5概率的随机水平翻转和光度颜色蒸馏来增加训练数据。
学习率调整
使用warmup learning 策略,学习速率从10e-3,在5个epoch后上升到10e-2,然后在第55和第68个epochs时除以10。训练过程在第80个epochs结束。
RetinaFace与其他24个SOTA的人脸检测算法对比。RetinaFace在所有的验证集和测试集都达到的最好的AP,在验证集上的AP是96.9%(easy),96.1%(Medium)和91.8%(hard)。在测试集的AP是96.3%,95.6%,91.4%.相比与当时最好的方法(Improved selective refinement network for face detection)在困难的数据集(包含大量的小人脸)的AP对比(91.4% vs 90.3%)。如下图
同时与mtcnn相比,在加上Arcface算法也能得到更高的准确率
除此之外,模型结构中的resnet152的backbone换成mobilenet可以达到实时检测
2、人脸对齐
上述讲了那么多人脸检测,检测到人脸和人脸的五个关键点之后,就需要对人脸进行对齐,人脸对齐分为
普通的opencv仿射变换对齐,这个用得比较多
基于人脸2d 106个关键点 和3d68个关键点进行人脸对齐,这里不加赘述,感兴趣可以自行了解
人脸对齐通俗来讲就是将歪歪扭扭的人脸通过关键点来进行仿射变换来矫正人脸,使人脸变成正,这样做可以很大程度上提高识别准确率,如下图。
用的比较多的还是普通的仿射变换对齐人脸,opencv有函数可以调用
cv2.warpAffine(src, M, dsize[, dst[, flags[, borderMode[, borderValue]]]]) → dst
其中:
src - 输入图像。
M - 变换矩阵。
dsize - 输出图像的大小。
flags - 插值方法的组合(int 类型!)
borderMode - 边界像素模式(int 类型!)
borderValue - (重点!)边界填充值; 默认情况下,它为0。
上述参数中:M作为仿射变换矩阵,一般反映平移或旋转的关系,为InputArray类型的2×3的变换矩阵。
这里将人脸对齐为112*112的人脸
3、人脸特征提取
人脸对齐之后就需要对人脸进行一个特征提取,一般是输出一个1*512的特征数组,人脸特征提取的模型是预训练好的人脸ReID模型,数据集都是标好了人脸ID的数据集,训练的时候输出的ID与label ID进行对比。
然后用这个预训练好的模型进行人脸的特征提取。
这里就一定要提经典的ArcFace算法。
论文题目:《ArcFace Additive Angular Margin Loss for Deep Face Recognition 》
论文地址:https://arxiv.org/pdf/1801.07698.pdf
该论文提出一种新的用于人脸识别的损失函数:additive angular margin loss,基于该损失函数训练得到人脸识别算法ArcFace(开源代码中为该算法取名为insightface)。ArcFace的思想(additive angular margin)和SphereFace以及不久前的CosineFace(additive cosine margin )有一定的共同点,重点在于:在ArcFace中是直接在角度空间(angular space)中最大化分类界限,而CosineFace是在余弦空间中最大化分类界限,这也是为什么这篇文章叫ArcFace的原因,因为arc含义和angular一样。除了损失函数外,本文的作者还清洗了公开数据集MS-Celeb-1M的数据,并强调了干净数据的对实验结果的影响,同时还对网络结构和参数做了优化。总体来说ArcFace这篇文章做了很多实验来验证additive angular margin、网络结构设计和数据清洗的重要性。
主要思想:
ArcFace loss:Additive Angular Margin Loss(附加角度间隔损失函数),对特征向量和权重归一化,对θ加上角度间隔m,角度间隔比余弦间隔在对角度的影响更加直接。几何上有恒定的线性角度margen。
ArcFace中是直接在角度空间θ中最大化分类界限,而CosFace是在余弦空间cos(θ)中最大化分类界限。
预处理(人脸对齐):人脸关键点由MTCNN检测(insightface里是retinaface),再通过仿射变换得到了被裁剪的对齐人脸。
训练(人脸分类器):backbone:ResNet50 + ArcFace loss
测试:从人脸分类器resnet50 FC1层的输出中提取512维的嵌入特征,对输入的两个特征计算余弦距离,再来进行人脸验证和人脸识别。
实际代码中训练时分为resnet model+arc head+softmax loss。resnet model输出特征;arc head将特征与权重间加上角度间隔后,再输出预测标签,求ACC是就用这个输出标签;softmax loss求预测标签和实际的误差。
LFW数据集上99.83%,YTF数据上98.02%
优点:
性能高,易于编程实现,复杂性低,训练效率高
ArcFace直接优化geodesic distance margin(弧度),因为归一化超球体中的角和弧度的对应。
为了性能的稳定,ArcFace不需要与其他loss函数实现联合监督,可以很容易地收敛于任何训练数据集。
缺点:
模型很大
Angular Margin Loss
不管是SphereFace、CosineFace还是ArcFace的损失函数,都是基于传统的softmax loss进行修改得到的。
公式(1)就是softmax loss损失函数。
首先把公式(1)偏置b_j设置为0,接着将特征向量x归一化,权重w归一化,然后乘以缩放系数s就得到公式(2)
公式(3)便为最终的Angular Margin Loss。
公式解释如下:
在xi和Wji之间的θ上加上角度间隔m(注意是加在了角θ上),以加法的方式惩罚深度特征与其相应权重之间的角度,从而同时增强了类内紧度和类间差异。
惩罚θ角度的意思就是:训练时加上m就会使θ降低
解释Margin是如何使类内聚合类间分离的:比如训练时降到某一固定损失值时,有Margin和无Margin的e指数项是相等的,则有Margin的θ_yi就需要相对的减少了。这样来看有 Margin的训练就会把 i 类别的输入特征和权重间的夹角θ_yi缩小了,从一些角度的示图中可以看出,Margin把θ_yi挤得更类内聚合了,θ_yi和其他θ类间也就更分离了。
L2归一化来修正单个权重||W_j||=1,还通过L2归一化来固定嵌入特征||x_i|,并将其重新缩放成s。特征和权重的归一化步骤使预测仅取决于特征和权重之间的角度。因此,所学的嵌入特征分布在半径为s的超球体上。
由于提出的加性角度间隔(additive angular margin)惩罚与测地线距离间隔(geodesic distance margin)惩罚在归一化的超球面上相等,因此我们将该方法命名为ArcFace。
人脸分类器训练过程
先将ResNet50 FC1层的输出中提取512维的特征向量L2归一化,权重L2归一化,他俩的夹角为θ,计算cos(θj),之后通过一个max pooling提取最大的相似度的特征,求反余弦arccos(θyi)得到特征xi与真实权值Wyi之间的夹角θyi,添加角度间隔m,再求余弦cos(θyj+m),将所有的log乘以特征尺度s,然后将log送到softmax函数得到各类别概率。再用Ground Truth和One Hot Vector一起算出交叉熵损失。即DCNN特征和最后一个全连接层之间的点积等于特征和权重归一化后的余弦距离。我们利用arc-cosine函数来计算当前特征和目标权重之间的角度。然后,在目标角上加上一个附加的角度间隔,用余弦函数重新计算逻辑回归的反向传播过程。然后,我们用一个固定的特征范数重新缩放所有的逻辑,随后的步骤与Softmax loss 中的步骤完全相同。这里的n class就是人脸ID个数。
4、人脸特征计算相似度(milvus人脸特征库检索)
提取到人脸特征后,我们需要和人脸库中的特征计算相似度,一般会使用milvus数据库来存储特征向量。
Milvus 创建于 2019 年,其唯一目标是:存储、索引和管理由深度神经网络和其他机器学习 (ML) 模型生成的大量嵌入向量。
作为专门设计用于处理输入向量查询的数据库,它能够在万亿规模上对向量进行索引。与现有的关系数据库主要处理遵循预定义模式的结构化数据不同,Milvus 是自下而上设计的,用于处理从非结构化数据转换而来的嵌入向量。
milvus不仅速度快而且支持多种特征距离的计算,支持余弦距离、欧式距离、汉明距离等等。
我们首先需要事先插入一些已知ID的人脸特征到milvus库
提取到的当前人脸特征进行正则化,并检索milvus向量库,获得命中的第一个人脸ID和距离得分
设定阈值,大于阈值认为匹配到了人脸,小于则认为不匹配
参考文献
https://github.com/deepinsight/insightface
https://arxiv.org/pdf/1905.00641.pdf
https://arxiv.org/pdf/1801.07698.pdf
https://blog.csdn.net/c2250645962/article/details/106331720
https://blog.csdn.net/Roaddd/article/details/114595688
https://milvus.io/docs/overview.md
T.-Y. Lin, P. Dollar, R. Girshick, K. He, B. Hariharan, and ´ S. Belongie. Feature pyramid networks for object detection. In CVPR, 2017.
T.-Y. Lin, P. Goyal, R. Girshick, K. He, and P. Dollar. Focal ´ loss for dense object detection. In ICCV, 2017.
X. Glorot and Y. Bengio. Understanding the difficulty of training deep feedforward neural networks. In AISTATS, 2010.
M. Najibi, P. Samangouei, R. Chellappa, and L. S. Davis. Ssh: Single stage headless face detector. In ICCV, 2017.
X. Tang, D. K. Du, Z. He, and J. Liu. Pyramidbox: A context-assisted single shot face detector. In ECCV, 2018.