长文干货!走近人脸检测:从VJ到深度学习(上)(下)

长文干货!走近人脸检测:从VJ到深度学习(下)

http://mp.weixin.qq.com/s?__biz=MzI1NTE4NTUwOQ==&mid=2650324508&idx=1&sn=b103ea69129c794194e395076a97cf04&scene=2&srcid=0420RNaafMBcivD8XumNMnoq&from=timeline&isappinstalled=0#wechat_redirect
2016-04-20  深度学习大讲堂
点击上方“公众号”可订阅哦!
深度学习给目标检测带来的变革     人脸检测作为一种特定类型目标的检测任务,一方面具有其自己鲜明的特点,需要考虑人脸这一目标的特殊性,另一方面其也和其它类型目标的检测任务具有一定的共性,能够直接借鉴在通用目标检测方法上的研究经验。    目标检测任务作为一个分类问题,其不仅受益于计算机视觉领域相关技术的不断发展,在机器学习领域的研究进展同样也对目标检测任务具有推波助澜的作用。事实上,从2006年开始逐步蔓延开的深度学习大爆发给目标检测的研究带来了强劲的助推力,使得通用的目标检测以及各种特定类型目标的检测任务得到了跨越式地发展。  从神经网络到深度学习    深度学习本质上并不是一项新的技术,作为其物理核心的神经网络早在上个世纪中叶就已经有人开始研究,并且在上世纪末已经经历过一次研究高潮。        从“深度学习”这一字面上可以看到,神经网络改头换面重出江湖,关键在一个“ ”字上。神经网络是一种受大脑结构启发而设计出的层级模型,其由一系列按照一定规则相连接的节点组成,形成一种层次化的结构。最简单的一个神经网络只包含3层:输入层、隐层(和外部的输入、输出没有直接关联)和输出层,相邻两层之间的节点通过有向边相连接,其中每条边对应有一个权值。       为了说明神经网络所表示的函数,我们考虑一个更为简单的结构:只有一个输入层和一个输出层,其中 输入层有 d 个节点,输出层只有一个节点,这个节点和所有的输入层节点相连。输入层节点从外部接受输入x = (x1, x2, · · · , xd),其和输出层节点的连接对应的权值是 w = (w1, w2, · · · , wd),输出层节点会对自己的输入做一个变换 g,得到输出 y,那么有      其中变换 g 通常称为节点的 激活函数,是一个非线性函数,如      通常我们还会在求和时增加一个偏 置项 b,即有      类似地,我们可以写出 3 层神经网络所表示的函数      其中 W2 和 W3 分别是输入层节点与隐层节点之间、隐层节点和输出层节点之间的连接的权值所构成的矩阵,而 b2 和 b3 则是对应的偏置项所构成的向量。依次类推,我们可以推广到 n 层的神经网络。可以看到,神经网络有一个非常大的特点,就是 非线性激活函数的引入和层层嵌套,这使得其能够表示高度非线性(相对于输入而言)的函数,因而对于复杂的数据变化模式具有更强的建模能力。      早期的神经网络一般层数比较少(如3层的浅层网络),因为多层的深度网络学习起来非常困难,在各种任务上难以取得令人满意的表现,这一状况直到 2006 年才被打破。在2006年,机器学习领域的泰斗 Geoffrey E.Hinton 教授在《科学》杂志上发表了题为《Reducing the Dimensionality of Data with Neural Networks》的论文,这一工作为深度网络的学习提供了一种有效的解决方案:采用无监督的方式对网络进行逐层预训练,从而打开了学习深度网络的大门。在接下来的几年中,人们对深度网络的热情已经高涨到了无以复加的地步,有关设计和学习深度网络的各种问题也逐一被解决,从初始化方式到优化方法,从激活函数到网络结构,科研工作者们对此产生了全方位的研究,使得深度网络的训练能够做得又快又好。由于对神经网络本身的探讨并不在本文所涉及的范畴之内,因此这里不再展开讨论,读者只需要将神经网络看成是一种具有更强非线性建模能力的模型即可。    神经网络分为很多种,上面提到的只是其中最简单一种:前馈神经网络——也经常被简称为神经网络,因此神经网络这个名字很多时候指的仅仅是前馈网络这一种。在计算机视觉领域,应用最成功的一种神经网络是卷积神经网络(CNN),其最大的特点就是引入了卷积操作,将前馈网络中的全连接替换为 局部连接,在不同的连接之间进行 权值共享——将一个卷积核作用于一张图像时,卷积核就像检测时的观察窗口,其从图像的左上角逐步滑动到右下角,其滑动的每个位置对应于一个输出节点,这个节点只和窗口内的输入节点(图像上每一个点都对应于一个输入节点)相连接,而不同输出节点和对应输入节点连接的权值是相同的。      卷积神经网络在处理图像问题上具有得天独厚的优势,因为卷积操作可以自然地保留图像的空间信息,其只作 用域局部,因而输出节点的空间结构和输入节点的空间结构是对应的,而前馈神经网络则做不到这一点:输入节点的排列顺序甚至可以是任意的,只要相应地调换连接的权值,就能保证输出不变。CNN早在上世纪末就由著名的机器学习研究者Yann LeCun设计出来,并应用于手写数字的识别问题,不过其在计算机视觉领域大规模得到应用则源于2012年CNN在一般的图像分类任务上的巨大成功。 
R-CNN 系列     在2013年底,深度学习给目标检测任务点起了一把火,这个火种就是R-CNN,其中R对应于“Region(区域)”,意指CNN以图像区域作为输入,这个工作最终发展成了一个系列,也启发和衍生出了大量的后续工作,这一场大火简直烧红了计算机视觉领域的半边天。    R-CNN的提出变革了目标检测方法中很多旧有的做法,同时在标准的目标检测评测数据集上使检测精度得到了前所未有的提升。在检测方法上的变革,首当其冲的是抛弃了滑动窗口范式,取而代之的是一个新的生成候选窗口的环节。对于给定的图像,不再用一个滑动窗口去对图像进行扫描,枚举所有可能的情况,而是采用某种方式“提名”出一些候选窗口,在获得对待检测目标可接受的召回率的前提下,候选窗口的数量可以控制在几千个或者几百个。从某种意义上讲,VJ 人脸检测器中多个分类器相级联,每一级分类器都在为接下来的一级分类器提名候选窗口,但是这和 R-CNN 所采用的生成候选窗口的方式有一个重要的区别:实际上所有的窗口仍然都被检查了一遍,只是不断在排除,这是一种减法式的方案。相比之下,R-CNN 采用的候选窗口生成方式,是根据图像的某些特征来猜测可能有哪些地方存在待检测的目标,以及这些目标有多大,这是一种从无到有的加法式的方案。Selective Search是一种典型的候选窗口生成方法,其采用了图像分割的思路,简单地说,Selective Search方法先基于各种颜色特征将图像划分为多个小块,然后自底向上地对不同的块进行合并,在这个过程中,合并前后的每一个块都对应于一个候选窗口,最后挑出最有可能包含待检测目标的窗口作为候选窗口。    除了引入候选窗口生成方法,第二点非常大的改变在特征提取上:不再采用人工设计的特征,而是用 CNN来自动学习特征。特征提取过程就是从原始的输入图像(像素颜色值构成的矩阵)变换到特征向量的过程,之前的如 Haar 特征等是科研工作者根据自己的经验和对研究对象的认识设计出来的,换言之人工定义了一个变换,而新的做法是只限定这个变换能够用CNN来表示——事实上 CNN 已经可以表示足够多足够复杂的变换,而不具体设计特征提取的细节,用训练数据来取代人的角色。这种自动学习特征的做法是深度学习一个非常鲜明的特色。自动去学习合适的特征,这种做法的好处和让分类器自动去学习自己的参数的好处是类似的,不仅避免了人工干预,解放了人力,而且有利于学习到更契合实际数据和目标的特征来,特征提取和分类两个环节可以相互促进,相辅相成;不过缺点也是有的,自动学习出的特征往往可解释性比较差,不能让人直观地去理解为什么这样提取出特征会更好,另外就是对训练集会产生一定程度的依赖。    还有一点值得一提的是,R-CNN在检测过程中引入了一个新的环节:边框回归(友情提醒:“框”念第四声,不是多音字!),检测不再仅仅是一个分类问题,它还是一个回归问题——回归和分类的区别就在于回归模型输出的不是离散的类别标签,而是连续的实数值。边框回归指的是在给定窗口的基础上去预测真实检测框的位置和大小,也就是说,有了候选窗口之后,如果其被判别成了一个人脸窗口,那就会进一步被调整以得到更加精确的位置和大小——和待检测目标贴合得更好。边框回归一方面提供了一个新的角度来定义检测任务,另一方面对于提高检测结果的精确度有比较显著的作用。    用R-CNN进行目标检测的流程是:先采用如 Selective Search等方法生成候选窗口,然后用学习好的CNN提取候选窗口对应的特征,接着训练分类器基于提取的特征对候选窗口进行分类,最后对判别为人脸的窗口采用边框回归进行修正。    虽然R-CNN带来了目标检测精度的一次巨大提升,然而由于所采用的候选窗口生成方法和深度网络都具有比较高的计算复杂度,因而检测速度非常慢。为了解决R-CNN的速度问题,紧接着出现了Fast R-CNN和Faster R-CNN,从名字上可以看到,它们的速度一个比一个快。第一步加速是采用了类似于 VJ 人脸检测器中积分图的策略,积分图是对应整张输入图像计算的,它就像一张表,在提取单个窗口的特征时,直接通过查表 来获取所需要的数据,然后进行简单的计算即可,在R-CNN中每个候选窗口都需要单独通过CNN来提取特征,当两个窗口之间有重叠部分时,重叠部分实际上被重复计算了两次,而在 Fast R-CNN 中,直接以整张图像作为输入,先得到整张图对应的卷积特征图,然后对于每一个候选窗口,在提取特征时直接去整张图对应的卷积特征图上取出窗口对应的区域,从而避免重复计算,之后只需要通过所谓的RoIPooling层来将所有的区域放缩到相同大小即可,这一策略的使用可以提供几十甚至上百倍的加速。第二步加速,Fast R-CNN利用了一种名为 SVD 的矩阵分解技术,其作用是将一个大的矩阵(近似)拆解为三个小的矩阵的乘积,使得拆解之后三个矩阵的元素数目远小于原来大矩阵的元素数目,从而达到在计算矩阵乘法时降低计算量的目的,通过将 SVD应用于全连接层的权值矩阵,处理一张图片所需要的时间能够降低30%。      第三步加速,Faster R-CNN开始着眼于生成候选窗口的环节,其采用 CNN 来生成候选窗口,同时让其和分类、边框回归所使用的 CNN 共享卷积层,这样使得两个步骤中可以使用同样的卷积特征图,从而极大地减少计算量。      除了采用各种策略进行加速,从R-CNN到Faster R-CNN,检测的框架和网络结构也在不断发生改变。R-CNN从整体框架上来说,和传统的检测方法没有本质区别,不同的环节由单独的模块来完成:一个模块生成候选窗口(Selective Search),一个模块进行特征提取(CNN),一个模块对窗口进行分类(SVM),除此之外还增加了一个模块做边框回归。到Fast R-CNN的时候,后面三个模块合并成了一个模块,全部都用CNN来完成,因此整个系统实际上只剩下两个模块:一个模块生成候选窗口,另一个模块直接对窗口进行分类和修正。再到Faster R-CNN,所有的模块都整合到了一个CNN中来完成,形成了一种端到端的框架:直接从输入图像通过一个模型得到最终的检测结果,这种多任务在同一个模型中共同学习的做法,能够有效利用任务之间的相关性,达到相辅相成、相得益彰的效果。从 R-CNN 到 Faster R-CNN,这是一个化零为整的过程,其之所以能够成功,一方面得益于CNN强大的非线性建模能力,能够学习出契合各种不同子任务的特征,另一方面也是因为人们认识和思考检测问题的角度在不断发生改变,打破旧有滑动窗口的框架,将检测看成一个回归问题,不同任务之间的耦合。尽管目前 Faster R-CNN在速度上仍然无法和采用非深度学习方法的检测器相比,但是随着硬件计算能力的不断提升和新的CNN加速策略的接连出现,速度问题在不久的将来一定能够得到解决。      全卷积网络和 DenseBox     卷积层是CNN区别于其它类型神经网络的本质特点,不过CNN通常也不仅仅只包含卷积层,其也会包含全连接层,全连接层的坏处就在于其会破坏图像的空间结构,因此人们便开始用卷积层来“替代”全连接层,通常采用1 × 1的卷积核,这种不包含全连接层的CNN称为全卷积网络(FCN)。FCN最初是用于图像分割任务,之后开始在计算机视觉领域的各种问题上得到应用,事实上,Faster R-CNN中用来生成候选窗口的CNN就是一个FCN。    FCN 的特点就在于输入和输出都是二维的图像,并且输出和输入具有相对应的空间结构,在这种情况下,我们可以将 FCN 的输出看成是一张热度图,用热度来指示待检测目标的位置和覆盖的区域:在目标所处的区域内显示较高的热度,而在背景区域显示较低的热度,这也可以看成是对图像上的每一个像素点都进行了分类:这个点是否位于待检测的目标上。 DenseBox是一个典型的基于全卷积网络的目标检测器,其通过 FCN得到待检测目标的热度图,然后根据热度图来获得目标的位置和大小,这给目标检测又提供了一种新的问题解决思路。(下面这张图其实来源于另一篇论文,放在这里仅用来帮助读者了解人脸热度图长什么样子。)     在DenseBox中,还有一点值得一提,其在分类的同时还会预测特征点的位置——就像上篇中提到的 JointCascade一样,DenseBox将检测和特征点定位两个任务集成在同一个网络中,并且也用热图的方式来确定每个点的位置。
基于CNN的人脸检测器    上面提到的都是通用的目标检测器,这些检测器可以直接通过人脸图像来学习从而得到人脸检测器,虽然它们没有考虑人脸本身的特殊性,但是也能够获得非常好的精度,这反映出不同类型目标的检测其实是相通的,存在一套通用的机制来处理目标检测问题。也有一部分工作是专门针对人脸检测任务的,有的考虑了人脸自身的特点,有的其实也是比较通用的目标检测方法,可以自然地迁移到各种类型目标的检测任务中去。    FacenessNet是专门针对人脸设计的一个检测器,其考虑了头发、眼睛、鼻子、嘴巴和胡子这五个脸部特征,简单地说,对于一个候选窗口,FacenessNet 先分析这五个部分是否存在,然后再进一步判断是不是一张人脸。      这种方法一方面同时利用了整体和局部的信息,能够从不同的角度对图像内容进行刻画,使得人脸和非人脸能够更好地被区分;另一方面增强了对遮挡的鲁棒性,人脸的局部遮挡会影响整体表现出的特征,但是并不会对所有的局部区域造成影响,因而增强了检测器对遮挡的容忍度。
检测精度的大跃进     随着越来越多的检测器开始采用深度网络,人脸检测的精度也开始大幅地提升。在2014年,学术界在FDDB上取得的最好检测精度是在100个误检时达到84%的检测率,达到这一精度的是JointCascade 人脸检测器。到2015年,这一纪录被FacenessNet 打破,在100个误检时,检测率接近88%,提升了几乎4个百分点。不仅如此,工业界的最好记录已经达到了100个误检时92.5%的检测率,检测率达到 90%以上的公司还不止一家,并且这些结果都是通过基于深度网络的人脸检测器所获得的。    在大幅提升人脸检测精度的同时,深度学习实际上还降低了包括人脸检测技术在内的各种目标检测技术的门槛,几乎到了只要采用深度网络就能获得不错的检测精度的地步;在精度方面,相比于基于非深度学习方法的检测器,基于深度学习方法的检测器在起点上就要高出一截。不过在检测速度方面,基于深度学习方法的检测器还难以达到实际应用的需求,即使是在GPU上,也还不能以实时的速度(25fps)运行;而反过来看,一旦速度问题能够得到解决,那么深度学习也一定会在目标检测任务上有更广泛和更大规模的应用。 传统人脸检测技术和 CNN 的结合     VJ人脸检测器自提出以来,启发和影响了后续的大量工作,所引入的积分图、AdaBoost方法、级联结构等至今仍在各种各样的检测器中以不同的形式被使用。传统的人脸检测技术优势在于速度,而在精度上则相比基于深度网络的方法要略输一筹,在这种情况下,一个自然的想法就是:能否将传统的人脸检测技术和深度网络(如CNN)相结合,在保证检测速度的情况下进一步提升精度?    Cascade CNN可以认为是传统技术和深度网络相结合的一个代表,和VJ人脸检测器一样,其包含了多个分类器,这些分类器采用级联结构进行组织,然而不同的地方在于,Cascade CNN采用CNN作为每一级的分类器,而不是用AdaBoost方法通过多个弱分类器组合成的强分类器,并且也不再有单独的特征提取过程,特征提取和分类都由CNN来统一完成。在检测过程中,Cascade CNN采用的还是传统的滑动窗口范式,为了避免过高的计算开销,第一级的CNN仅包含一个卷积层和一个全连接层,并且输入图像的尺寸控制在12*12,同时滑动窗口的步长设置为4个像素,在这种情况下,一方面每张图像上候选窗口的数量变少了,窗口数量随着滑动步长的增大是按照平方规律下降的,另一方面每个窗口提取特征和分类的计算开销也受到了严格控制。经过第一级CNN之后,由于通过的窗口中人脸和非人脸窗口之间更加难以区分,因此第二级CNN将输入图像的尺寸增大到了24*24,以利用更多的信息,并且提高了网络复杂度——虽然仍然只包含一个卷积层和一个全连接层,但是卷积层有更多的卷积核,全连接层有更多的节点。第三级CNN也采用了类似的思路,增大输入图像大小的同时提高网络的复杂度——采用了两个卷积层和一个全连接层。通过引入CNN,传统的级联结构也焕发出了新的光彩,在FDDB上,Cascade CNN在产生100个误检的时候达到了85%的检测率,而在速度上,对于大小为640*480的图像,在限定可检测的最小人脸大小为80*80的条件下,Cascade CNN在CPU上能够保持接近10fps的处理速度。Cascade CNN中还采用了一些其它的技术来保证检测的精度和速度,如多尺度融合、边框校准、非极大值抑制等,限于篇幅,这里不再继续展开。     吸取传统人脸检测技术中的精华,借鉴深度学习研究的最新成果,在对问题的深刻思考和理解上,探寻旧瓶装新酒的最佳模式,这是一条值得去继续探索的道路。对现状和未来的简单思考     经过几十年的研究和发展,人脸检测方法正日趋成熟,在现实场景中也已经得到了比较广泛的应用,但是人脸检测问题还并没有被完全解决,复杂多样的姿态变化,千奇百怪的遮挡情况,捉摸不定的光照条件,不同的分辨率,迥异的清晰度,微妙的肤色差,各种内外因素的共同作用让人脸的变化模式变得极其丰富,而目前还没有检测器可以同时对所有的变化模式都足够鲁棒。     目前的人脸检测器在FDDB上已经能够取得不错的性能,不少检测器在100个误检时的检测率达到了80%以上,这意味着它们检测出40个以上的人脸才会出现一个误检。到目前为止,本文所提到的误检和召回率都对应于FDDB上的离散型得分ROC曲线,所谓“离散型”是指每个人脸是否被检测到是分别用1和0来表示的;相对应地也有连续型得分ROC曲线,而“连续型”指的是人脸被检测到与否是通过检测框和标注框之间的交并比来表示的,从某种意义上来说,连续型得分试图评判的是检测框的准确程度,即检测框的位置和大小与实际人脸的位置和大小的接近程度。对于两个不同的检测器而言,两类曲线的相对关系并非是完全一致的:离散型得分ROC曲线接近的两个检测器,其对应的连续型得分ROC曲线可能存在明显的差异。最直接地,这说明有的检测器虽然检测出了人脸,但是检测框的准确度比较低,但其实造成这种不一致性的另一个重要原因还在于检测框与标注框之间的差异性。在FDDB中人脸是通过椭圆来进行标注的,大多数情况下,几乎会包含整个头部,相比之下,检测器给出的检测结果是矩形的人脸框,并且通常只包含脸部区域——尤其是对于采用滑动窗口范式的检测器,这就很容易导致检测框和标注椭圆之间的交并比过小,甚至可能小于0.5。对不同的检测器来说,其能够最好地区分人脸和非人脸窗口的情况所对应的框的大小会有所不同,从而不同检测器给出的检测框也会存在差别,部分方法会采用扩大检测框或者回归椭圆的方式,以尽量减小由标注框和检测框的不一致性所造成的影响,保证评测的公平性。    除了标注框的问题之外,要更为客观地看待FDDB上的评测结果,我们还需要考虑另外一点:FDDB测试图像上的人脸和实际应用场景的差异性,换言之,我们需要思考这样一个问题:人脸检测器在FDDB上所达到的精度能否真实反映其在实际应用场景中的表现?FDDB中测试图像上的人脸包含了从表情到姿态、从光照到遮挡等各个方面的变化,因而是一个相对通用的数据集,但是在实际应用中,不同场景下人脸往往呈现出比较鲜明的特点,例如在视频监控场景下,由于摄像头架设位置较高和分辨率有限,同时在存储和传输过程中会引入噪声,因此图像上的人脸往往具有较大的俯仰角,且清晰度较低,在这种情况下,原来在FDDB上表现出色的检测器就未必能够达到令人满意的精度。在FDDB中,有大约10%的人脸其大小在40*40以下,而对于人脸识别等一些任务来说,太小的人脸并不适合,因此如果一个检测器因为在小脸上表现不好而导致其在FDDB上表现平平,而在较大的人脸上和表现更好的一些检测器没有太大差别,那么将其应用在人脸识别任务中是完全没有问题的,甚至还可能因为模型简单带来速度上的优势。总而言之,当面对具体的应用场景时,一方面,我们还需要具体问题具体分析,不能盲目地根据检测器在FDDB或者其它人脸检测数据集上精度来下结论;另一方面,我们需要基于当前的人脸检测器去适配实际所需要处理的数据,以使检测器能够在特定的场景下达到更好的精度。     除了FDDB之外,比较常用的人脸检测评测集还有AFW,以及最近几年公开的MALF、IJB-A和Wider Face。AFW包含的图像数比较少,总共只有205张测试图像,标注了468张人脸,不过由于其覆盖了众多的人脸变化模式,具有一定的挑战性,因此也比较常用。另外三个评测集在图像规模上都相对较大,其中MALF和Wider Face没有发布人脸标注和评测程序,需要提交检测结果给发布方进行评测,这在一定程度上防止了由于评测方式不一致而导致比较不公平和对测试集进行过拟合的情况;这两个数据集还按照不同的属性(如分辨率、姿态、难易程度等)将测试集分成了多个子集,评测时会同时在全集和子集上进行测试,这能够更加全面地反映检测器在不同场景下的能力。IJB-A中不仅包含静态人脸图像,还有一部分是从视频中提取的视频帧。在上面提到的所有评测集中,只有Wider Face提供了专门的训练集和验证集,其它评测集合都只包含测试集,这其实也给不同方法的比较带来了一个问题:我们难以判断导致检测器在精度上存在差异的原因到底是训练数据还是算法和模型本身,也不知道这两方面的因素谁起的作用更大。Wider Face应该是难度最大的一个评测集,所标注的人脸在姿态、遮挡情况等方面的跨度非常大,并且分辨率在50*50以下的人脸占到了50%(训练集和校验集中达到了80%以上),不过在部分应用场景下(如人脸识别),过于关注小尺寸的人脸并没有必要。    虽然基于深度网络的检测器目前能够达到很高的检测精度,并且其通用性非常强,但其所付出的计算代价也非常高,因此这类检测器突破的关键在于深度网络的简化和加速。除此之外,如果单单考虑人脸检测,这个分类问题相对来说要简单一些,也存在一种可能性:直接学习一个小型的网络就能足够好地完成这个任务。对于采用非深度学习方法的检测器,其基础的检测精度相比会低不少,但是速度上会有明显的优势,因此其关键在于针对特定应用场景下的问题进行合理的改进和适配,以获得更好的检测精度。     为了提供更加便利的人机交互接口,创造有效的视觉理解手段,让机器变得有温度,会观察,能感受,广大的科研工作者们在人脸检测和通用目标检测任务上还在继续探索。终有一天,当我们和机器四目相对时,彼此能够会心一笑:科学让生活更美好! 后记     本文从人脸检测任务本身开始,介绍了人脸检测的一般流程,然后分别介绍了三类不同的人脸检测方法:以VJ人脸检测器为代表的传统方法,基于深度网络的现代方法,以及将传统的人脸检测技术和深度网络相结合的方法。然而,在人脸检测几十年的研究历程中,还有很多其它的方法不能归到这三类中来,其中比较重要的包括基于部件模型的方法和基于范本的方法,虽然本文没有对这两类方法进行介绍,但是它们在人脸检测这一问题上仍然具有重要的地位和意义,感兴趣的读者可以进一步去阅读相关论文进行了解。该文章属于“深度学习大讲堂原创”,不允许转载,如需要转载,请联系我们。   长文干货!走近人脸检测:从VJ到深度学习(上)(下)_第1张图片 长文干货!走近人脸检测:从VJ到深度学习(上)(下)_第2张图片 作者简介邬书哲,中科院计算所智能信息处理重点实验室VIPL课题组博士生,研究方向:目标检测,尤其关注基于深度学习的目标检测方法。 如果您也关注人工智能,请别忘了关注我们哦~
请长按识别右图中的二维码! 长文干货!走近人脸检测:从VJ到深度学习(上)(下)_第3张图片 





长文干货!走近人脸检测:从?VJ?到深度学习(上)

人工智能学家 2016-04-13 17:00:26 阅读(172) 评论(0)
声明:本文由入驻搜狐公众平台的作者撰写,除搜狐官方账号外,观点仅代表作者本人,不代表搜狐立场。 举报

  人工智能学家

作者:邬书哲

中科院计算所智能信息处理重点实验室VIPL课题组博士生

研究方向:目标检测,尤其关注基于深度学习的目标检测方法。

  本文分上下两篇,上篇主要介绍人脸检测的基本流程,以及传统的VJ人脸检测器及其改进,下篇介绍基于深度网络的检测器,以及对目前人脸检测技术发展的思考与讨论。为了节省篇幅,文中略去了对具体参考文献等的引用,读者可以通过相关的关键词去搜索对应的论文。为了让本文更适合非计算机视觉和机器学习背景的读者,文中对所涉及到的专业术语尽量以通俗的语言和用举例的方式来进行解释,同时力求严谨,以体现实事求是和一丝不苟的科学研究精神。不过疏忽和遗漏在所难免,有不当的地方还请各位读者多多包涵,并联系笔者进行修正。愿君阅读愉快!

  这是一个看脸的世界!自拍,我们要艺术美颜;出门,我么要靓丽美妆。上班,我们要刷脸签到;回家,我们要看脸相亲。 当手机把你的脸变得美若天仙,当考勤机认出你的脸对你表示欢迎,你知道是什么魔力让冷冰冰的机器也变得温情脉脉,让呆呆的设备也变得善解人意吗?今天就让我们走近它们的内心,了解这些故事背后的一项关键技术:人脸检测

  看人先看脸,走在大街上,我们可以毫不费劲地看到所有人的脸:棱角分明的国字脸,娇小可人的瓜子脸,擦肩而过路人甲的脸,迎面走来明星乙的脸,戴着口罩被遮住的脸,斜向上45度仰角自拍的脸。可是,对于我们的计算机和各种终端设备而言,从眼前的画面中把人脸给找出来,并不是一件容易的事情,原因就在于,一千个读者就有一千个哈姆雷特,在你的眼里,人脸是这样的:

  长文干货!走近人脸检测:从VJ到深度学习(上)(下)_第4张图片

  而在机器的眼里,人脸是这样的:

  长文干货!走近人脸检测:从VJ到深度学习(上)(下)_第5张图片

  你没看错,图像存储在机器中不过就是一个由0和1组成的二进制串!更确切地说,机器看到的是图像上每一个点的颜色值,因此对于机器来说,一张图像就是一个由数排成的阵列。试想一下,如果我把每个点的颜色值都念给你听,你能告诉我对应的这张图像上有没有人脸和人脸在哪里吗?很显然,这并不是一个容易解决的问题。

  如果手机没法在自拍照中找到我们脸,那它就像一个失明的化妆师,没法展现出我们最好的一面;如果考勤机没法通过摄像头看到我们的脸,那我们的笑就只是自作多情,它也根本不可能识别出我们到底是谁。人脸检测架起了机器和我们之间沟通的桥梁,使得它能够知道我们的身份(人脸识别),读懂我们的表情(表情识别),和我们一起欢笑(人脸动画),与我们一起互动(人机交互)。

  人脸检测的开始和基本流程

  具体来说,人脸检测的任务就是判断给定的图像上是否存在人脸,如果人脸存在,就给出全部人脸所处的位置及其大小。由于人脸检测在实际应用中的重要意义,早在上世纪70年代就已经有人开始研究,然而受当时落后的技术条件和有限的需求所影响,直到上世纪90年代,人脸检测技术才开始加快向前发展的脚步,在新世纪到来前的最后十年间,涌现出了大量关于人脸检测的研究工作,这时期设计的很多人脸检测器已经有了现代人脸检测技术的影子,例如可变形模板的设计(将人脸按照五官和轮廓划分成多个相互连接的局部块)、神经网络的引入(作为判断输入是否为人脸的分类模型)等。这些早期的工作主要关注于检测正面的人脸,基于简单的底层特征如物体边缘、图像灰度值等来对图像进行分析,结合关于人脸的先验知识来设计模型和算法(如五官、肤色),并开始引入一些当时已有的的模式识别方法。

  虽然早期关于人脸检测的研究工作离实际应用的要求还有很远,但其中进行检测的流程已经和现代的人脸检测方法没有本质区别。给定一张输入图像,要完成人脸检测这个任务,我们通常分成三步来进行:

  1.选择图像上的某个(矩形)区域作为一个观察窗口

  2.在选定的窗口中提取一些特征对其包含的图像区域进行描述;

  3.根据特征描述来判断这个窗口是不是正好框住了一张人脸。

  检测人脸的过程就是不断地执行上面三步,直到遍历所有需要观察的窗口。如果所有的窗口都被判断为不包含人脸,那么就认为所给的图像上不存在人脸,否则就根据判断为包含人脸的窗口来给出人脸所在的位置及其大小。

  那么,如何来选择我们要观察的窗口呢?所谓眼见为实,要判断图像上的某个位置是不是一张人脸,必须要观察了这个位置之后才知道,因此,选择的窗口应该覆盖图像上的所有位置。显然,最直接的方式就是让观察的窗口在图像上从左至右、从上往下一步一步地滑动,从图像的左上角滑动到右下角——这就是所谓的滑动窗口范式,你可以将它想象成是福尔摩斯(检测器)在拿着放大镜(观察窗口)仔细观察案发现场(输入图像)每一个角落(滑动)的过程。

  长文干货!走近人脸检测:从VJ到深度学习(上)(下)_第6张图片

  别看这种用窗口在图像上进行扫描的方式非常简单粗暴,它的确是一种有效而可靠的窗口选择方法,以至于直到今天,滑动窗口范式仍然被很多人脸检测方法所采用,而非滑动窗口式的检测方法本质上仍然没有摆脱对图像进行密集扫描的过程。

  对于观察窗口,还有一个重要的问题就是:窗口应该多大?我们认为一个窗口是一个人脸窗口当且仅当其恰好框住了一张人脸,即窗口的大小和人脸的大小是一致的,窗口基本贴合人脸的外轮廓。

  长文干货!走近人脸检测:从VJ到深度学习(上)(下)_第7张图片

  那么问题来了,即使是同一张图像上,人脸的大小不仅不固定,而且可以是任意的,这样怎么才能让观察窗口适应不同大小的人脸呢?一种做法当然是采用多种不同大小的窗口,分别去扫描图像,但是这种做法并不高效。换一个角度来看,其实也可以将图像缩放到不同的大小,然后用相同大小的窗口去扫描——这就是所谓的构造图像金字塔的方式。图像金字塔这一名字非常生动形象,将缩放成不同大小的图像按照从大到小的顺序依次往上堆叠,正好就组成了一个金字塔的形状。

  长文干货!走近人脸检测:从VJ到深度学习(上)(下)_第8张图片

  通过构建图像金字塔,同时允许窗口和人脸的贴合程度在小范围内变动,我们就能够检测到不同位置、不同大小的人脸了。另外需要一提的是,对于人脸而言,我们通常只用正方形的观察窗口,因此就不需要考虑窗口的长宽比问题了。

  选好了窗口,我们开始对窗口中的图像区域进行观察,目的是收集证据——真相只有一个,我们要依靠证据来挖掘真相!在处理图像的过程中,这个收集证据的环节我们称之为特征提取,特征就是我们对图像内容的描述。由于机器看到的只是一堆数值,能够处理的也只有数值,因此对于图像所提取的特征具体表示出来就是一个向量,称之为特征向量,其每一维是一个数值,这个数值是根据输入(图像区域)经由某些计算(观察)得到的,例如进行求和、相减、比较大小等。总而言之,特征提取过程就是从原始的输入数据(图像区域颜色值排列组成的矩阵)变换到对应的特征向量的过程,特征向量就是我们后续用来分析和寻找真相的证据。

  特征提取之后,就到了决断的时刻:判别当前的窗口是否恰好包含一张人脸。我们将所有的窗口划分为两类,一类是恰好包含人脸的窗口,称之为人脸窗口,剩下的都归为第二类,称之为非人脸窗口,而最终判别的过程就是一个对当前观察窗口进行分类的过程。因为我们的证据是由数值组成的特征向量,所以我们是通过可计算的数学模型来寻找真相的,用来处理分类问题的数学模型我们通常称之为分类器,分类器以特征向量作为输入,通过一系列数学计算,以类别作为输出——每个类别会对应到一个数值编码,称之为这个类别对应的标签如将人脸窗口这一类编码为1,而非人脸窗口这一类编码为-1;分类器就是一个将特征向量变换到类别标签的函数。

  考虑一个最简单的分类器:将特征向量每一维上的数值相加,如果得到的和超过某个数值,就输出人脸窗口的类别标签1,否则输出非人脸窗口的类别标签-1。记特征向量为

  ,分类器为函数f(x),那么有:

  长文干货!走近人脸检测:从VJ到深度学习(上)(下)_第9张图片

  这里的t就是前面所说的“某个数值”,其决定了分类器在给定特征向量下的输出结果,我们称其为分类器的参数。不同形式和类型的分类器会有不同的参数,一个分类器可以有一个或者多个参数,参数或者其取值不同则对应到不同的分类器。选定了一个分类器之后,紧接着的一个问题就是:参数该怎么设置?具体到我们正在考虑的情况,就是:t的值该如何选取?

  要做出选择,就要有一个目标,在分类问题中,目标当然就是尽可能正确地进行分类,即分类的准确率尽可能高。然而,尽管我们对目标非常明确,我们也仍然没法给出一个最优的参数取值,因为我们并不使用机器所采用的二进制语言系统,我们并不懂什么才是对机器最好的。于是我们只有一种选择:把我们的目标告诉机器,举一些例子向其进行解释,然后让机器自己去学习这个参数,最后我们给机器设计一场考试,测试其是否满足了我们的要求。我们从一些图像上选出一部分人脸和非人脸窗口的样例,用对应的类别标签对其进行标注,然后将这些样例划分成两个集合,一个集合作为分类器学习所使用的训练集,另一个集合作为最终考查分类器能力的测试集,同时我们设定一个目标:希望分类的准确率能够在80%以上。

  学习过程开始时,我们先给分类器的参数设定一个初始值,然后让分类器通过训练集中带有“答案”(类别标签)的样例,不断去调整自己参数的取值,以缩小其实际的分类准确率和目标准确率之间的差距。当分类器已经达到了预先设定的目标或者其它停止学习的条件——期末考试的时间是不会因为你没有学好而推迟的,或者分类器觉得自己已经没有办法再调整了,学习过程就停止了,这之后我们可以考查分类器在测试集上的准确率,以此作为我们评判分类器的依据。这一过程中,分类器调整自己参数的方式和分类器的类型、设定的目标等都有关,由于这部分内容超出了本文所讨论的范畴,也并不影响读者对人脸检测方法的理解,因此不再展开进行讲述。

  在确定了选择窗口的策略,设计好了提取特征的方式,并学习了一个针对人脸和非人脸窗口的分类器之后,我们就获得了构建一个人脸检测系统所需要的全部关键要素——还有一些小的环节相比之下没有那么重要,这里暂且略去。

  由于采用滑动窗口的方式需要在不同大小的图像上的每一个位置进行人脸和非人脸窗口的判别,而对于一张大小仅为480*320的输入图像,窗口总数就已经高达数十万,面对如此庞大的输入规模,如果对单个窗口进行特征提取和分类的速度不够快,就很容易使得整个检测过程产生巨大的时间开销,也确实就因为如此,早期所设计的人脸检测器处理速度都非常慢,一张图像甚至需要耗费数秒才能处理完成——视频的播放速度通常为每秒25帧图像,这给人脸检测投入现实应用带

  来了严重的障碍。

  人脸检测技术的突破:VJ人脸检测器及其发展

  人脸检测技术的突破发生在2001年,两位杰出的科研工作者Paul Viola和Michael Jones设计了出了一个快速而准确的人脸检测器:在获得相同甚至更好准确度的同时,速度提升了几十上百倍——在当时的硬件条件下达到了每秒处理15张图像的速度,已经接近实时速度25fps(即25帧每秒)。这不仅是人脸检测技术发展的一个里程碑,也标志着计算机视觉领域的研究成果开始具备投入实际应用的能力。为了纪念这一工作,人们将这个人脸检测器用两位科研工作者的名字命名,称之为Viola-Jones人脸检测器,或者简称为VJ人脸检测器。

  VJ人脸检测之所以器能够获得成功,极大地提高人脸检测速度,其中有三个关键要素:特征的快速计算方法——积分图,有效的分类器学习方法——AdaBoost,以及高效的分类策略——级联结构的设计。VJ人脸检测器采用Haar特征来描述每个窗口,所谓Haar特征,其实就是在窗口的某个位置取一个矩形的小块,然后将这个矩形小块划分为黑色和白色两部分,并分别对两部分所覆盖的像素点(图像上的每个点称为一个像素)的灰度值求和,最后用白色部分像素点灰度值的和减去黑色部分像素点灰度值的和,得到一个Haar特征的值。

  长文干货!走近人脸检测:从VJ到深度学习(上)(下)_第10张图片

  Haar特征反映了局部区域之间的相对明暗关系,能够为人脸和非人脸的区分提供有效的信息,例如眼睛区域比周围的皮肤区域要暗,通过Haar特征就可以将这一特点表示出来。但是由于提取Haar特征时每次都需要计算局部区域内多个像素点灰度值之和,因此在速度上其并不快,为此VJ人脸检测器引入了积分图来加速Haar特征的提取。

  积分图是一张和输入图像一样大的图,但其每个点上不再是存放这个点的灰度值,而是存放从图像左上角到该点所确定的矩形区域内全部点的灰度值之和。

  长文干货!走近人脸检测:从VJ到深度学习(上)(下)_第11张图片

  积分图所带来的好处是两方面的,一方面它使得每次计算局部区域像素点的灰度值之和仅需要做4次加减法,与局部区域的大小无关;另一方面它避免了在相同像素点上重复求和,只在最开始计算一次——相邻的窗口有很大的重叠部分,对应的Haar特征也会重叠,如果每次都重新计算像素点的灰度值之和,则重叠部分的计算是重复的。积分图极大地加速了Haar特征的提取,向快速的检测器迈出了第一步。

  除了特征提取,分类过程的速度对于检测的速度也至关重要。分类的速度取决于分类器的复杂程度,也即从特征向量变换到类别标签的计算过程的复杂程度。复杂的分类器往往具有更强的分类能力,能够获得更好的分类准确度,但是分类时的计算代价比较高,而简单的分类器虽然计算代价小,但是分类准确度也较低。那么有没有兼顾计算代价和分类准确度两方面的办法呢?当然有,这就是AdaBoost方法。希望计算代价小,所以只用简单的分类器,但是又希望分类准确度高,于是把多个简单的分类器组合起来——聚弱为强,将多个弱分类器组合成一个强分类器,这就是AdaBoost方法的核心理念。通过AdaBoost方法来学习分类器,达到了以更小的计算代价换取同样的分类准确度的目的。

  造成人脸检测速度慢的根本原因还在于输入规模过大,动辄需要处理几十上百万的窗口,如果这样的输入规模是不可避免的,那么有没有可能在处理的过程中尽快降低输入规模呢?如果能够通过粗略地观察快速排除掉大部分窗口,只剩下少部分窗口需要进行仔细的判别,则总体的时间开销也会极大地降低。从这样的想法出发,VJ人脸检测器采用了一种级联结构来达到逐步降低输入规模的目的。

  长文干货!走近人脸检测:从VJ到深度学习(上)(下)_第12张图片

  具体说来,VJ人脸检测器将多个分类器级联在一起,从前往后,分类器的复杂程度和计算代价逐渐增大,对于给定的一个窗口,先由排在最前面也最简单的分类器对其进行分类,如果这个窗口被分为非人脸窗口,那么就不再送到后面的分类器进行分类,直接排除,否则就送到下一级分类器继续进行判别,直到其被排除,或者被所有的分类器都分为人脸窗口。这样设计的好处是显而易见的,每经过一级分类器,下一级分类器所需要判别的窗口就会减少,使得只需要付出非常少的计算代价就能够排除大部分非人脸窗口。从另一个角度来看,这实际上也是根据一个窗口分类的难度动态地调整了分类器的复杂程度,这显然比所有的窗口都用一样的分类器要更加高效。

  VJ人脸检测器通过积分图、AdaBoost方法和级联结构取得的巨大成功对后续的人脸检测技术研究产生了深远的影响,大量的科研工作者开始基于VJ人脸检测器进行改进,这些改进也分别覆盖了VJ人脸检测器的三个关键要素。

  特征的改进和变迁

  虽然Haar特征已经能够刻画人脸的一些特点,但是相比于人脸复杂的变化模式,VJ人脸检测器所采用的5种Haar特征还是过于简单。光考虑姿态上的变化,人脸可能是斜着的(平面内旋转),也可能是仰着的或者侧着的(平面外旋转),同一个Haar特征在不同姿态的人脸上差异可能非常大,而同时又可能和非人脸区域上的特征更相近,这就很容易在分类的时候引起误判。于是人们开始对Haar特征进行扩展,使得其能够刻画更加丰富的变化模式:

  1. 环形的黑白区域划分模式,而不仅仅是上下或者左右型;

  2. 旋转的Haar的特征,即将原来提取Haar特征的局部小块顺时针或逆时针旋转45度;

  3. 分离的Haar特征,即允许一个Haar特征由多个互相分离的黑白区域来计算,而不要求黑白区域必须处于一个矩形小块中;

  4. 对角型Haar特征;

  5. 组合Haar特征,即对多个不同的Haar特征进行组合和二值编码;

  6. 局部组合二值特征,即在局部对特定的Haar特征按照一定的结构进行组合和二值编码;

  7. 带权多通道Haar特征,即一个Haar特征不再只包含黑白两种块,而允许有多种不同形状和不同颜色的块,其中不同的颜色对应着不同的权值,表示像素点上求和之后所占的比重——原来只有1和-1两种,多通道指的是在像素点上求和不仅仅是在灰度这一个通道上计算,而是同时在其它通道上计算(如RGB三个颜色通道;事实上,基于原图计算而来和原图同样大小的任何一张图都可以是图像的一个通道)。

  这些扩展极大地增强了Haar特征的表达能力,使得人脸窗口和非人脸窗口之间具有更好的区分性,从而提高了分类的准确度。

  长文干货!走近人脸检测:从VJ到深度学习(上)(下)_第13张图片

  除了直接对Haar特征进行改进,人们也同时在设计和尝试其它特征。Haar特征本质上是局部区域像素值的一种线性组合,其相对应的更一般的形式则是不指定线性组合的系数,允许系数为任意实数,这被称之为线性特征——这里的组合系数可以基于训练样例来进行学习,类似于学习分类器参数的过程。稀疏粒度特征也是一种基于线性组合来构造的特征,与线性特征所不同的是,稀疏粒度特征是将不同尺度(将100*100的图像放大到200*200,它和原本大小就为200*200的图像是处于不同的尺度上)、位置和大小的局部区域进行组合,而线性特征只是组合同一个局部区域内的像素值。

  LBP特征是一种二值编码特征,其直接基于像素灰度值进行计算,特点是在编码时考虑的是两个值的相对大小,并且按照一定的空间结构来进行编码,局部组合二值特征就是在LBP特征的启发下设计的;从计算上来看,提取LBP特征比提取Haar特征要快,但是Haar特征对于人脸和非人脸窗口的区分能力更胜一筹。简化的SURF特征是一种和Haar特征相类似的特征,但是其计算的是局部区域中像素点的梯度和,并在求和的过程中考虑了梯度方向(所谓梯度,最简单的一种情形就是指同一行上两个不同位置像素值的差比上它们水平坐标的差);SURF特征比Haar特征更为复杂,因此计算代价更高,但是由于其表达能力更强,因此能够以更少数目的特征来达到相同的区分度,在一定程度上弥补了其在速度上的不足。HOG特征也是一种基于梯度的特征,其对一个局部区域内不同方向的梯度进行统计,计算梯度直方图来表示这个区域。积分通道特征和多通道的Haar特征有些类似,但是其使用的通道更加多样化,将通道的概念推广为由原图像变换而来并且空间结构和原图像对应的任何图像。聚合通道特征则在积分通道特征的基础上进一步加入了对每个通道进行下采样的操作,实现局部区域信息的聚合。

  在过去十几年的探索过程中,涌现出的特征不胜枚举,这里只选取了部分比较有代表性和反映了人们探索思路的特征进行举例。这里所有列举的特征都有一个共同的特点:都由科研工作者根据自己的经验手工设计,这些特征的设计反映了人们对问题的理解和思考。虽然随着不断的改进,设计出的特征已经日臻完善,但直到现在,人们在特征上的探索还远没有结束。

  分类器及其学习方法的改进

  分类器能力的强弱直接决定了分类准确度的高低,而分类的计算代价是影响检测速度的一个关键因素,因此,人们探索的另一个方向就是对分类器及其学习方法的改进。

  采用AdaBoost方法由弱分类器构建强分类器,这是一个顺序执行的过程,换言之,一旦一个弱分类器被选中,其就必定会成为强分类器的组成部分,不允许反悔,这其实是假设增加弱分类器一定会使得强分类器的分类准确度更高,但是,这个假设并不总是成立。事实上,每次对弱分类器的选择只是依照当时的情况决定,而随着新的弱分类器被增加进来,从整体上来看,之前的选择未必最优。基于这样的想法,出现了允许回溯的FloatBoost方法。FloatBoost方法在选择新的弱分类器的同时,也会重新考查原有的弱分类器,如果去掉某个弱分类器之后强分类器的分类准确度得到了提升,那说明这个弱分类器带来了负面影响,应该被剔除。

  VJ人脸检测器中,相级联的多个分类器在学习的过程中并不会产生直接的联系,其关联仅体现在训练样例上:后一级分类器的训练样例一定要先通过前一级分类器。不同分类器在学习时的独立性会带来两方面的坏处:一是在每个分类器都是从头开始学习,不能借鉴之前已经学习好的分类器的经验;二是每个分类器在分类时都只能依靠自己,不能利用其它分类器已经获得的信息。为此,出现了两种改进的方案:链式Boosting方法和嵌套式Boosting方法。两种方案都在学习新一级的分类器时,都考虑之前已经学好的分类器,区别在于链式Boosting方法直接将前面各级分类器的输出进行累加,作为基础得分,新分类器的输出则作为附加得分,换言之,前面各级分类器实际上是新分类器的一个“前缀”,所有的分类器通过这种方式链在了一起;嵌套式Boosting方法则直接将前一级分类器的输出作为新分类器第一个弱分类器的特征,形成一种嵌套的关系,其特点是只有相邻的分类器才会互相影响。还有一种和嵌套式Boosting方法相类似的方案:特征继承,即从特征而不是分类器的角度来关联不同的分类器,具体而言,新的分类器在学习时会先继承前一级分类器的所有特征,基于这些特征学习弱分类器,再此基础上再考虑增加新的弱分类器,这一方案的特点在于其只引入了分类器学习时的相互影响,而在分类时分类器之间仍然是相互独立的。

  相关的任务之间往往会相互产生促进作用,相辅相成,而和人脸检测密切相关的一个任务就是特征点定位:预测脸部关键点的位置,这些关键点可以是双眼中心、鼻尖、嘴角等。基于这样一种想法,在2014年出现了Joint Cascade,即把检测人脸所需要的分类器和预测特征点位置的回归器交替级联,同时进行人脸检测和特征点定位两个任务。用特征点定位辅助人脸检测的关键在于形状索引特征的引入,即特征不再是在整个窗口中提取,而是在以各个特征点为中心的局部区域进行提取,这样的好处就在于提高了特征的语义一致性。不同的人脸其对应的特征点位置是不同的,反过来看,也就是说相同的位置实际上对应于脸部的不同区域,那么在相同区域提取的特征实际上表示的是不同的语义,简单地说,就是在拿鼻子去和嘴巴匹配。采用形状索引特征可以很好地避免这个问题,从而增大人脸和非人脸窗口之间的区分性。对于一个给定的窗口,我们并不知道特征点的位置,因此采用一个“平均位置”作为初始位置,即基于标注有特征点坐标的人脸样例集,计算出的每个点坐标的平均值;在平均位置的基础上,我们提取特征预测各个特征点真实的位置,不过一次预测往往是不准确的,就好像跑步的时候我们没法直接从起点跳到终点一样,所以需要不断基于当前确定的特征点位置来预测新的位置,逐步向其真实的位置靠近。这个过程很自然地形成了一种级联结构,从而能够和人脸检测器耦合在一起,形成一种不同模型交替级联的形式。

  针对分类器学习过程中的每一个环节,人们都进行了细致而充分的探索,除了上面提到的几个方向,在分类器分类阈值的学习、提升分类器学习的速度等问题上,也出现了很多出色的研究工作。大部分在分类器及其学习方法上进行改进的工作关注的还是Boosting方法(AdaBoost方法是Boosting方法的一个杰出代表)和相对简单的分类器形式,如果能够引入具有更强分类能力的分类器,相信能给检测器带来进一步的性能提升,这一点在后文会有所涉及。

  级联结构的演化

  分类器的组织结构也是人们关心的一个重要问题,尤其是在面临多姿态人脸检测任务的时候。人脸的姿态是指人脸在三维空间中绕三个坐标轴旋转的角度,而多姿态人脸检测就是要将带旋转的人脸给检测出来,不管是斜着的(绕x轴旋转)、仰着的(绕y轴旋转)还是侧着的(绕z轴旋转)。不同姿态的人脸在表观特征上存在很大的差异,这给检测器带来了非常大的挑战,为了解决这一问题,通常采用分治的策略,即分别针对不同姿态的人脸单独训练分类器,然后组合起来构建成多姿态人脸检测器。

  最简单的多姿态人脸检测器就是将针对不同姿态人脸的分类器采用并列式的结构进行组织,其中并列的每一个分类器仍然采用原来的级联结构(我们称这种分类器为级联分类器);在检测人脸的过程中,一个窗口如果被其中一个级联分类器分为人脸窗口,则认为其确实是一个人脸窗口,而只有当每一个级联分类器都将其判别为非人脸窗口时,才将其排除掉。这种并列式的组织架构存在两方面的缺陷:一是造成了检测时间的成倍增长,因为绝大部分窗口是非人脸窗口,这些窗口需要经过每一个级联分类器的排除;二是容易造成整体分类准确度的降低,因为整个检测器分错的窗口包含的是所有级联分类器分错的窗口。

  有人设计了一种金字塔式的级联结构,金字塔的每一层对应于对人脸姿态(旋转角度)的一个划分,从顶层到底层划分越来越细,级联的每个分类器只负责区分非人脸和某个角度范围内的人脸。对于一个待分类的窗口,从最顶层的分类器开始对其进行分类,如果其被分为人脸窗口,则送入到下一层的第一个分类器继续进行分类,如果其被分为非人脸窗口,则送入到同一层的下一个分类器继续进行分类,当在某一层上所有的分类器都将其分为非人脸窗口时,就确认其为非人脸窗口,将其排除。金字塔式的级联结构也可以看成是一种特殊的并列式结构,只不过每个级联分类器相互之间有共享的部分,这样最直接的好处就在于减少了计算量,共享的部分只需要计算一次,同时在底层又保留了分治策略所带来的好处——子问题比原问题更加容易,因此更容易学习到分类准确度更高的分类器。

  长文干货!走近人脸检测:从VJ到深度学习(上)(下)_第14张图片

  还有一种比较典型的结构是树形的级联结构,从形状上来看其和金字塔式的级联结构是一样的,也是从上往下分类器的数目逐层增多,区别就在于树形的级联结构中没有同一层分类器之间的横向连接,只有相邻层分类器之间的纵向连接,即一个窗口在同一层上不会由多个分类器进行分类,而会直接被送往下一层或者被排除。树形级联结构通过引入分支跳转机制,进一步减少了对一个窗口进行分类所需要的计算量,不过同时也带来了新的问题,分支跳转通常根据姿态估计(估计旋转角度的范围)的结果来进行,而如果姿态估计出现错误,就会出现某个姿态的人脸窗口被送给另一个姿态人脸对应的分类器进行分类的情况,容易导致错误的分类。为了缓解这一问题,出现了允许多个分支同时跳转的设计,从而降低了由于跳转错误而引起分类错误的风险。

  分治策略是处理多姿态人脸检测任务最基本的策略,但要同时兼顾速度和分类准确度并不是一件容易的事情,分类能力的增强不可避免地会带来计算代价的增大,如何用更小的计算代价来换取更高的分类准确度,这仍然是一个需要去思考和探索的问题。

  人脸检测器的比拼

  在不断对人脸检测器进行改进的过程中,有一个问题是不容忽视的:如何科学地比较两个人脸检测器的优劣?简单地说,出一套考题让所有的检测器进行一场考试,谁得分高谁就更好。对于人脸检测器而言,所谓考题(测试集)就是一个图像集合,通常其中每张图像上都包含至少一张人脸,并且这些人脸的位置和大小都已经标注好。关于得分,需要考虑检测器两方面的表现,一是检测率,也即对人脸的召回率,检测出来的人脸占总人脸的比例——测试集中一共标注了100张人脸,检测器检测出其中70张人脸,则检测率为70%;二是误检(也称为虚警)数目,即检测器检测出来的人脸中出现错误(实际上不是人脸)的数目——检测器一共检测出80张人脸,然而其中有10个错误,只有70个是真正的人脸,那么误检数目就是10。在这两个指标上,我们所希望的总是检测率尽可能高,而误检数目尽可能少,但这两个目标之间一般是存在冲突的;在极端的情况下,如果一张脸也没有检测出来,那么误检数目为0,但是检测率也为0,而如果把所有的窗口都判别为人脸窗口,那么检测率为100%,而误检数目也达到了最大。在比较两个检测器的时候,我们通常固定一个指标,然后对比另一个指标,要么看相同误检数目时谁的检测率高,要么看相同检测率时谁的误检少。

  对于每一个检测出的人脸,检测器都会给出这个检测结果的得分(或者说信度),那么如果人为地引入一个阈值来对检测结果进行筛选(只保留得分大于阈值得检测结果),那么随着这个阈值的变化,最终得检测结果也会不同,因而其对应得检测率和误检数目通常也会不同。通过变换阈值,我们就能够得到多组检测率和误检数目的值,由此我们可以在平面直角坐标系中画出一条曲线来:以x坐标表示误检数目,以y坐标表示检测率,这样画出来的曲线称之为ROC曲线(不同地方中文译法不一,如接收机曲线、接收者操作特征曲线等,这里直接采用英文简写)。ROC曲线提供了一种非常直观的比较不同人脸检测器的方式,得到了广泛的使用。

  评测人脸检测器时还有一个重要的问题:怎么根据对人脸的标注和检测结果来判断某张人脸是否被检测到了?一般来说,检测器给出的检测框(即人脸窗口)不会和标注的人脸边框完全一致,而且对人脸的标注也不一定是矩形,例如还可能是椭圆形;因此当给定了一个检测框和一个标注框时,我们还需要一个指标来界定检测框是否和标注框相匹配,这个指标就是交并比:两者交集(重叠部分)所覆盖的面积占两者并集所覆盖面积的比例,一般情况下,当检测框和标注框的交并比大于0.5时,我们认为这个检测框是一个正确检测的人脸。

  在早期的人脸检测工作中,一般采用MIT-CMU人脸检测数据集作为人脸检测器的测试集,来比较不同的检测器。这个测试集只包含几百张带有人脸的图像,并且人脸主要是清晰且不带遮挡的正面人脸,因而是一个相对简单的测试集,现在几乎已经不再使用。在2010年,美国麻省大学的一个实验室推出了一个新的人脸检测评测数据集:FDDB,这个集合共包含2845张带有人脸的互联网新闻图像,一共标注了5171张人脸,其中的人脸在姿态、表情、光照、清晰度、分辨率、遮挡程度等各个方面都存在非常大的多样性,贴近真实的应用场景,因而是一个非常具有挑战性的测试集。FDDB的推出激发人们在人脸检测任务上的研究热情,极大地促进了人脸检测技术的发展,在此后的几年间,新的人脸检测方法不断涌现,检测器在FDDB上的表现稳步提高。从100个误检时的检测率来看,从最初VJ人脸检测器的30%,发展到现在已经超过了90%——这意味着检测器每检测出50张人脸才会产生一个误检,这其中的进步是非常惊人的,而检测器之间的比拼还在继续。

  长文干货!走近人脸检测:从VJ到深度学习(上)(下)_第15张图片

  长文干货!走近人脸检测:从VJ到深度学习(上)(下)_第16张图片

  作者简介

  邬书哲,中科院计算所智能信息处理重点实验室VIPL课题组博士生,研究方向:目标检测,尤其关注基于深度学习的目标检测方法

  人工智能学家 Aitists

人工智能学家是权威的前沿科技媒体和研究机构,2016年2月成立人工智能与互联网进化实验室(AIE Lab),重点研究互联网,人工智能,脑科学,虚拟现实,机器人,移动互联网等领域的未来发展趋势和重大科学问题。

  长按上方二维码关注微信号 Aitists

  投稿邮箱:[email protected]

你可能感兴趣的:(OpenCV)