写点什么

既要高精度也要高性能,人脸识别主流算法大合集

人脸识别技术专栏文章 - 第二篇

  • 2019-05-13
  • 本文字数:7335 字

    阅读完需:约 24 分钟

既要高精度也要高性能,人脸识别主流算法大合集

上一篇文章中,我们回顾了人脸识别算法的发展历程,介绍了人脸识别算法从传统机器学习算法到现在的深度学习算法的演进历程。接下来,我们将详细介绍一下人脸识别常见的应用方式,以及现在主流的人脸识别算法。

1.人脸识别的主要应用方式

为了讲清楚人脸识别算法的设计思路,有必要首先介绍人脸识别在实际场景中的主要的三种不同的应用方式。这三种方式我们会习惯的称之为:“1:1”、“1:N”,“1:n”。

1.1 验证场景

在验证场景下,人脸识别算法主要用于回答“这是否为某人”。


用于回答“这是否为某人”时,该人的身份是确定,人脸识别需要做的工作是确认当前的照片是否与该人的身份一致。此时会将给定的人脸图像与计算机中存储的某人的图像比较,回答给定的图像是否为该人的。通常,一个人在计算机中会存储一幅正面或多幅不同角度的图像,我们称之为注册照。而给定的人脸图像我们一般称之为验证照。


这种应用模式适用于门禁、出入境通关、网络实名制、办证机构等应用场所,通过证件信息获取某人身份,然后根据证件使用者的照片,保证他与证件所有者是同一个人,即实名认证下的人证合一。


因为验证场景下,通常是直接比较两幅人脸图像提取出来的两个特征的相似度,所以我们常称之为 1:1。



图 1 验证流程


1.2 辨认场景

在辨认场景下,人脸识别算法主要回答“这是谁”。


在这种场景下,人员的身份信息是未知的。我们需要将给定的人脸图像与计算机中存储的 N 个人的图像逐个比较,输出 M 幅图像,这些图像的相似度按从大到小排列,再由人来确定这是谁。当然,因为现在人脸识别算法的精度非常高,所以在一些不太严谨的场合,可以直接用相似度最大的那张图像来自动判定这是谁。


通常,一个人在计算机中会存储一幅正面或多幅不同角度的图像。为了提高辨认的速度,注册照往往会预先提取特征并将之存储在计算机中。而给定的人脸图像,我们称之为查询照。


这种应用模式适用于人员身份的查询和核查,比对目标库通常是常住人口库、逃犯库等覆盖面非常广泛,容量非常庞大的人脸数据库,库容量 N 通常能够达到上千万、甚至上亿级别。


因为辨认场景下,通常需要将给定的一副人脸图像与计算机中存储的 N 个人的图像比较,所以我们常称之为 1:N。



图 2 辨认流程


1.3 监控场景

监控场景从名字上来看就知道,人脸识别是用于监控(watch list)系统(目标人筛查)。而监控场景同时具有辨认和验证的特点,人脸识别算法需要回答“这是否为要找的人”。


在这种情况下,人员的身份信息同样是未知的。我们需要将给定的人的图像与监控目标人员进行比较,确定该人是否在监控列表中,同时确定该人身份。


为什么说它同时具有辨认和验证的特点呢?是因为它需要搜索整个监控列表,这与辨认场景是类似的;同时他需要确定该人是否在监控列表中,如果将监控列表看作 1:1 中的 1 的话,这又类似于验证场景。


但是它又完全不同于辨认或者验证。验证场景与它的差异很明显,我们就不说了。而它与辨认场景的差异主要在于以下几点:


(1)在辨认场景下,给定的人虽然身份信息未知,但是他肯定存在一张(或多张)注册照存储在计算机中;


(2)辨认场景下可以有人工进行参与;


(3)监控列表的容量通常远远小于辨认场景下的人脸数据库的容量。


这种应用模式适用于视频监控,比对目标一般是逃犯、管控人员或者恐怖分子、重点关注人员等布控人员,也可是白名单和红名单等目标人员,库容量一般为几千人甚至万人级别。


因为监控场景下,库容量相对辨认场景要小,所以我们称之为 1:n。



图 3 监控流程


2.人脸识别的主流算法

从人脸识别的三种主要应用方式可以看到,比较两张人脸的图像是否为同一个人是所有应用的基础。从这个角度来说,所有的人脸识别应用其实都是验证场景,而人脸识别算法的验证性能是衡量该算法精度高低的最直接的指标。在数据库已知的情况下,根据验证性能可以推算出该算法在三种不同场景下的精度性能。


而比较两张人脸图像是否为同一人,主要依靠从这两张图像中分别提取到的两个特征的相似度高低来进行衡量。因此人脸识别算法的关键,就是通过训练一个特征提取模型,从人脸图像中得到一个具有鉴别能力的特征,而相似度的计算则一般采用余弦距离。


如何更加有效的训练出一个能够提取具有鉴别力特征的模型呢?一种思路通过搜集更多的数据去提升模型的性能(从数据上挖掘),另外一种思路通过更加有效的利用数据去提升模型的性能(从模型上挖掘)。当然,实际情况往往是两种思路同时采用。

2.1 从数据上提高识别性能

深度学习相比传统机器学习,一个最重大的优势就是对海量数据的利用能力。虽然对于深度学习来说,不一定总是数据越多,效果越好,但是在人脸识别领域,绝大多数情况是数据越多,效果越好。如果让我选择,我肯定会选择要更多的数据。


在吴恩达的深度学习课程中,他曾经给出一个经典的数据与深度学习模型性能的关系曲线。



图 4 数据与深度学习


因此在人脸识别行业内,大家往往会通过获取或者制造海量的人脸数据,去充分训练人脸识别模型,来获得更好的结果。


以商汤为例,早在 2017 年的时候,他们就已经使用了多达 30 台计算机,240 个 GPU 对 10 亿个标注样本(包含 1 亿个不同的人)并行训练,总训练时间为 1 个月左右。而现在他们的数据量的累积到达了一个什么程度,可想而知。


虽然数据规模已经到达这样一个恐怖的地步,但是人脸识别中的数据红利还远远没有殆尽,如何进一步从数据中挖掘性能红利依然是当下人脸识别研究的热点之一。因为人脸识别应用场景的特殊性,它往往要求极低错误接受率下的正确识别率,这就更是对模型的性能提出了极高的挑战。所以可以针对不同的应用场景,如商场监控、移动办公打卡、互联网身份认证等等,采集不同场景下的大量数据进行针对性的微调。采用这样的方法,我们依然能够非常有效的提升模型在特定场景下的识别性能。


除了获取数据以外,业内往往还采用增加噪声、颜色变化、随机裁剪或者缩放、局部区域组合、随机遮挡等等种种图像变换手段,进一步产生更多的数据,以增强模型的泛化能力,防止过拟合。

2.2 从模型上提高识别性能

数据是有限的,在有限数据的情况下,如何更加有效的利用数据,从而获得比别人更好的性能,这就要求我们从模型上充分挖掘已有数据的潜力,获得更好的性能。


一般来讲,业内通常有两种做法,一种是使用更好的骨干网络,一种是利用测度学习的手段对提取的特征进行优化。

2.2.1 骨干网络设计上提高性能

1)残差结构


在 2016 年以前,大家的主要研究方向集中在如何设计更高效的网络去识别人脸。在这段期间出现了如 VGG、Inception 等一系列从骨干网络入手去提升模型性能的算法。但是到了 2016 年,残差网络的面世几乎可以说是终结了各种千奇百怪的骨干网络设计,顺便从事实上终结了 image net 比赛。


后续几乎所有的深度网络都离不开残差结构的身影,相比较之前的几层,几十层的深度网络,在残差网络面前都不值一提,残差结构可以很轻松的构建几百层,一千多层的网络而不用担心梯度消失过快的问题,原因就在于残差结构的捷径(shortcut)部分。



图 5 残差结构


在残差结构出现以前,影响深度学习特别是深层神经网络训练的一个最主要的因素是由于反向传播算法的链式法则导致的梯度消失和梯度爆炸,其中往往是梯度消失出现的更多一些。


通过权重正则化或梯度剪切,可以在一定程度上解决梯度爆炸的问题。


而残差结构利用捷径这样一个跨层连接的机制,无损地传播梯度,解决了深层网络训练中的梯度消失的问题。从此,深度学习的网络可以轻松到达上百乃至上千层,而不用担心难以训练的问题。


2)BN 层


另外一个具有重要影响力的网络结构设计就是 BN 层的提出。现在添加 BN 层,在几乎所有的深度学习骨干网络设计中都已经成为了一个标准操作,它具有加速网络收敛速度,提升训练稳定性的效果。


BN 全名是 batch normalization 即批规范化,通过规范化操作将输出信号规范化保证网络的稳定性。具体的 BN 原理非常复杂,在这里不做详细展开。我们需要知道的是,它通过对每一层的输出规范为均值和方差一致的方法,消除了网络权重参数带来的放大缩小的影响,进而解决梯度消失和爆炸的问题,或者可以理解为 BN 层将输出从饱和区拉倒了非饱和区。它带来的优点主要有:


(1)可以放心的使用大学习率而不用小心的调参了,较大的学习率极大的提高了学习速度;


(2)BN 本身上也是一种正则化的方式,能够增加模型的泛化能力;


(3)BN 降低了数据之间的绝对差异,有一个去相关的性质,更多的考虑相对差异性,因此在分类任务上具有更好的效果。


3)Dropout 层


此外,在网络特征输出层的后面,分类器前面添加一个 Dropout 层也是训练人脸识别网络的一个常规操作。


Dropout 层是 Hinton 在 2014 年提出来的一个神器,专门用于应对神经网络的过拟合问题。它的操作非常简单,灵感来自于繁殖中的遗传和突变,相当于是每次训练,每个神经元只有概率 p 来参与单次神经网络的训练,等效于最后的输出层乘以一个 mask 矩阵,该矩阵有百分比为 p 的元素被置 0,其余为 1。有无 Dropout,最后的分类准确率会有明显的差异。



图 6 Dropout 对分类性能的影响


它唯一的缺点就是会明显增加训练时间,因为引入 Dropout 之后相当于每次只是训练的原先网络的一个子网络,为了达到同样的精度需要的训练次数会增多。

2.2.2 测度学习

1)DeepID


最早用测度学习的方式来提升模型性能的尝试,我认为应该是 DeepID 的工作。它为了使模型提取出来的特征更具有区分性,在训练网络的结构设计上,采用了类似 Contrastive Loss(对比损失)这样的思路。



图 7 DeepID 的结构



图 8 DeepID2+


通过在 softmaxloss 的基础上,添加验证信号并与识别信号加权,有效的提升了特征的鉴别能力,在一定程度上缩小了类内差异,增大了类间差异。然而 DeepID 训练的时候需要大量的数据,而且对比损失本身也不是很好训练,需要小心调参才能获得很好的结果。


2)三元组损失



图 9 三元组损失


伴随着 DeepID 的尝试,接下来就是谷歌的 Triplet Loss(三元组损失)。三元组损失在物理意义上就是通过学习,使得同类样本的 Positive 样本更靠近 Anchor,而不同类的样本 Negative 则远离 Anchor。


它在数学表达上也直观简单,损失函数定义为同类样本的距离减去不同类样本的距离。缩小该损失函数,就意味着缩小同类样本的距离或者增大不同类样本的距离。它的实际使用效果也非常的好,特别是用在迁移学习上面。


早期三元组损失使用欧氏距离,但是因为人脸识别中常用余弦距离衡量特征之间的相似程度,所以后面很快就有人使用余弦距离对三元组损失进行了改造。


3)InsightFace


接下来测度学习的应用集中在了对训练过程中的分类器的改造上面。因为分类器采用的全连接形式等效于计算余弦距离,而余弦距离衡量的是不同特征之间的夹角,但是在这种形式下 Softmax 函数并没有直接作用在角度上面,对决策边界的影响很小,所以导致优化 Softmax 函数并不能保证真正缩小类内差异。



图 10 分类器的计算



图 11 SoftmaxLoss


在这种情况下,就有人提出,能不能通过改造最后的分类器,使得 Softmax 函数直接作用到角度上,从而在优化的同时能够保证缩小类内距离,增加类间距离。



图 12 InsightFace 的损失函数


InsightFace 就在这种思想下应运而生,它的损失函数如图 12 所示,直接作用在了角度距离上,能够更加有效的从角度来优化最后的决策边界,使得同一类样本提取到的特征更加聚合。参数 m 则保证了不同类样本之间的特征存在一定的间隔。

2.2.3 其他改进

除了上述的一些流行的改进以外,业内为了提高人脸识别特征提取的精度和速度,也做了一些其它的改进。


比如最近的改进是商汤利用深度学习增加从侧脸到正脸的映射,来提高模型的精度,即 Deep Residual EquivAriant Mapping (DREAM)的模块。


此外还有将语音语义上常用的注意力机制引入到人脸识别中的一些改进等等。


为了提高特征提取速度,业内提出了 mobileFaceNet、shufflenet 等轻量级网络,利用知识蒸馏的手段去压缩网络模型结构等。


上述这些改进也都取得了非常好的效果。

3.人脸识别性能的评价标准

那么,如何评价一个人脸识别模型性能的好坏呢?这里介绍一下人脸识别性能常用的评价标准。


前面介绍过,评价一个人脸识别模型性能好坏最直接的就是它验证性能的好坏。评价模型的验证性能的主要指标包括注册失败率,基本等同于模板提取失败率,验证的 ROC 曲线及等误率值。




图 13 验证性能的等误率和 ROC 曲线


具体指标的计算如下:


(1)注册失败率


注册失败率 = 特征提取失败次数 / 特征提取总次数 × 100%;


(2)错误拒绝率


相似度值范围内等分为若干档,得到若干个不同的阈值 S,计算不同阈值 S 的 FRR 如下:


FRR(S) = 同人比对相似度中低于阈值 S 的数量 / 同一人比对总数 × 100%;


(3)错误接受率


相似度值范围内等分为若干档,得到若干个不同的阈值 S,计算不同阈值 S 的 FAR 如下:


FAR(S) = 非同人比对相似度中不低于阈值 S 的数量 / 非同人比对总数 ×100%;


(4)等误率


计算不同阈值时的错误接受率和错误拒绝率。相似度阈值为横坐标,错误接受率和错误拒绝率为纵坐标,用不同阈值的错误接受率和错误拒绝率数据绘制曲线,如图 13 所示,错误接受率等于错误拒绝率点的纵坐标值为等错误率。

4.苏宁在人脸识别上的探索

4.1 苏宁人脸识别的主要用用场景

人脸识别在苏宁的各种应用场景下都得到了广泛的应用。最典型的应用如员工打卡和苏宁园区内部的监控,相对来说人脸数据库的规模比较小,场景比较受控,而且人员的配合度比较高。我们的算法在这上面都取得了非常高的识别精度,千万分之一 FAR 下的 FRR 在 5%以内。


但是,对人脸识别来说,最具有挑战性的场景还是大规模的 1:N 的人脸应用。N 的规模通常在千万级别或者亿级别,直接从绝对数字上放大了人脸识别的产生的各种错误。这种场景通常会出现在公安系统的安防场景下,其他情况下的具体应用还几乎没有。但是其实在智慧零售中也需要大规模 1:N 的人脸识别能力。


苏宁线下门店人脸识别应用的难度又进一步增加:首先这是一个非用户配合的场景;其次苏宁有几亿会员,这个 N 是很恐怖的;再次,从业务上希望能够对用户进行分组,能够去除店员的信息,识别出 VIP 会员,还要能对新用户进行挖掘,同时要能做到黑名单的安防布控;除此之外,有几千家门店的数据推流,系统的流量也是很大的。要设计这样的解决方案是非常恐怖的。



图 14 苏宁北斗系统的演进


早期苏宁的人脸识别系统还不完善,这样的庞大工作量几乎完全由人工处理。但是随着苏宁人脸识别算法的日益成熟,现在 AI 已经取代人,实现了完全自动化的客流分析统计、VIP 客户识别等功能,并应用在了苏宁线下门店中。



图 15 苏宁北斗系统


这里我们不再过多讨论系统架构的复杂,而是接着介绍一下苏宁在人脸识别上的一些实战经验。

4.2 数据上的探索

对于苏宁来说,如何获取更多更丰富的人脸数据并进行有效清洗也始终是工作的重点之一。有了丰富的图像来源还不够,因为采集到的人脸图像往往有很严重的噪声;虽然算法模型对一定的人脸噪声足够鲁棒,但我们研究发现,更加高质量的数据集的确可以提高算法模型性能,所以仍需要通过清洗标注来去除这些噪声数据。


为此,苏宁专门成立了数据处理部门,用于获取、清洗和标注数据。除了已知常见的那些公开数据集,如 MS_celeb_1M、VggFace2、CASIA_WebFace 等。我们也利用苏宁多样化的内部场景,构建了丰富的针对不同场景的人脸数据库资源,这样训练出的模型在实际场景中有更好的区分能力。


此外,我们也利用多种图像处理手段,以及利用对抗式生成网络生成了丰富多彩的人脸样本,进一步提高了模型精度。

4.3 模型上的探索

苏宁在人脸识别算法上,尤其是模型上也做出了许多的探索。美国普渡大学生物工程学教授 Eugenio Culurciello 在他的神经网络设计史中给出了一张有关不同的骨干网络在 ImageNet 上的表现的分析图。我们在它的基础上重点测试了 resnet、mobilenet 等几种骨干网络,根据速度和精度选出了最适合我们应用场景的模型。



图 16 ImageNet 上不同骨干网络的比较


而在损失函数上,我们选择了使用 InsightFace 进行预训练,使用三元组损失针对不同的应用场景进行微调。



图 17 常用微调方法


微调过程中,会首先固定所有层的参数,只微调最后一层特征,在调整到一定程度之后,才会放开所有的参数,微调整个模型。



图 18 SCA-CNN 结构


此外,我们还添加了一些注意力机制,如 SCA-CNN 中提出的空间和通道注意力机制等,使得我们的模型更多的关注有鉴别力的区域,能够更加有效的去识别不同身份的人脸,针对化妆、眼镜、发型等干扰因素也能有很好的效果。

5.总结

至此,我们介绍了人脸识别在业内主要的三种应用方式以及目前主流的算法。同时我们还介绍了苏宁的人脸识别在新零售中的主要应用,以及我们对于人脸识别算法的一些有益探索。


但是一个完整的人脸识别系统并不是只有人脸识别算法就能够正常的工作运行的,它还需要诸如人脸检测、关键点定位等诸多算法的配合。



图 19 人脸识别系统的一般流程


在下一篇文章,我们将拓展介绍一下这些相关的算法以及它们在行业内的主流方法及相关应用。

作者简介

苏宁科技人工智能实验室 图像技术专家何智翔


毕业于清华大学 THOCR 实验室,师从国内著名人工智能专家 IEEE fellow 丁晓青教授,十余年来一直从事人脸相关算法的研究。现任苏宁科技人工智能实验室图像技术专家,主要研究方向为人脸属性的识别、商品的检测和识别。


2019-05-13 17:3116494

评论 1 条评论

发布
用户头像
很完备
2019-07-19 09:17
回复
没有更多了
发现更多内容

SpringBoot技术专题—来看看异步处理返回方案

洛神灬殇

Java WebAsyncTask 5月日更 AsyncContext DeferredResult

音视频在智能手表上的应用

anyRTC开发者

音视频 WebRTC IoT RTC

微服务转型系列4:理念指导实践,厘清微服务建设的主要内容和顺序

BoCloud博云

微服务

GitHub开源:狗屁不通文章生成器

不脱发的程序猿

GitHub 开源 狗屁不通文章生成器

python str模块

若尘

Python编程 str 5月日更

test1

靠谱哥

PyQt5 实现可空值的 QDateTimeEdit

一代咩神

Python PyQt QDateTimeEdit

51CTO熊平:HarmonyOS是大势所趋

科技汇

Java开发5年,我为什么选择从蚂蚁金服离职?浅谈经历和经验!

Java架构追梦

Java 架构 面试 蚂蚁金服 经历分享

抱歉,“行业毒瘤”这个锅,低/无代码不背

陈思

低代码 无代码 低代码平台 无代码平台

百信银行基于 Apache Hudi 实时数据湖演进方案

Apache Flink

大数据 flink

华为中国生态大会2021举行在即,GaussDB将重磅发布5大解决方案

华为云开发者联盟

数据库 opengauss 华为云 GaussDB 云数据库

真实的DevOps落地,应该是这样的 ↓

BoCloud博云

DevOps 敏捷开发

【死磕JVM】用Arthas排查JVM内存 真爽!我从小用到大

牧小农

JVM

雀食蟀!Java Netty实战入门

北游学Java

Java Netty 网络 框架

Fluid 进入 CNCF Sandbox,加速大数据和 AI 应用拥抱云原生

阿里巴巴云原生

人工智能 容器 云原生 调度 弹性计算

聊聊人像抠图背后的算法技术

华为云开发者联盟

hilens 抠图 工程 抠图算法 baseline

参照STM32时钟树配置STM32CubeMX Clock Configuration(STM32L011G4U6为例)

不脱发的程序猿

单片机 STM32微控制器 时钟树 STM32CubeMX STM32时钟配置

音视频实战(6)- RTSP媒体协议流的录制方案及其覆盖策略详解

liuzhen007

音视频 5月日更 签约计划第二季

iOS 面试策略之语言工具-Xcode使用

iOSer

ios xcode 语言 & 开发

Golang command source code

escray

学习 极客时间 Go 语言 5月日更

KubeVela + KEDA:为应用带来“与生俱来”的弹性伸缩能力

阿里巴巴云原生

容器 开发者 云原生 监控 中间件

双非渣硕,是如何拿到苏宁、阿里的offer的?(分享学习心得)

Java 程序员 架构 面试

SecSolar:为代码“捉虫”,让你能更专心写代码

华为云开发者联盟

代码 华为云 CloudIDE 代码安全检测 SecSolar

华为云官网负责人明哥:我们是如何做到门面不倒,8个月挑战业界翘楚?

华为云开发者联盟

JavaScript node.js Serverless 云原生 大前端

单片机I/O控制方式(UART中断和DMA中断的区别)

不脱发的程序猿

嵌入式 单片机 GPIO的原理、特性 单片机I/O设备的控制方式

灵魂拷问:后端业务开发要会用 K8s 到什么程度?

阿里巴巴云原生

容器 运维 云原生 k8s 存储

Flink+Clickhouse构建实时数仓的最佳实践

Wping

大数据 flink 实时数仓 Clickhouse

Nginx性能分析之gpreftools

运维研习社

nginx 性能分析 5月日更

🕋【Redis干货领域】彻底走进主从架构的世界(入门篇)

洛神灬殇

主从同步 Redis 核心技术与实战 5月日更 Redis系列专题 原理篇

这个好用的分布式应用配置中心,我们把它开源了

百度Geek说

分布式 大前端 服务器

既要高精度也要高性能,人脸识别主流算法大合集_AI&大模型_何智翔_InfoQ精选文章