算法优化——如何将人脸检测的速度做到极致

零、检测与识别

  首先要区分两个概念“人脸检测/face detection”和“人脸识别/face recognition”。“人脸检测”是从图像中确定人脸的位置和大小,如下图所示;“人脸识别”是识别图像中的人脸是张三还是李四,是身份识别。

  人脸检测是一个非常经典的问题,很多人认为这是一个“已经解决”了的问题。人脸检测最经典的方法是Haar+AdaBoost。采用开源的Haar+AdaBoost实现(如OpenCV中的训练和检测程序),我们可以很容易的训练一个还算不错的人脸检测器。   但是,一旦将人脸检测技术投入实际应用,一系列问题便会冒出来。如(1)误检(把非人脸的物体当作人脸)较多,非人脸图像当作人脸送入后续算法,会引起一系列不良后果。(2)漏检问题,例如戴墨镜、大胡子、逆光条件、黑种人、倾斜姿态较大的脸无法检测到。(3)速度问题,虽很多人脸检测算法的速度已经很快,但在一个人脸分析(如人脸识别)系统中,人脸检测步骤的计算量往往超过50%。大部分检测算法采用窗口扫描的方式,窗口数目巨大,所以计算量居高不下。

  下面介绍一下设计Boosting人脸检测方法的一些技巧:

一、特征设计

  特征设计是重中之重,如果特征从原理上就是计算量大,后面无论如何优化,都很难降计算量。

  先说Haar特征,毫无疑问Haar特征用在人脸检测里具有里程碑式的意义。但现在看Haar特征,会发现它有一些明显的缺点。Haar特征是一种很弱的特征,这意味着需要很多特征组合在一起才能构成强分类器,对提升速度不利;如果正样本分布比较分散比较难区分时(例如正面侧面人脸全放进去),用这种弱特征分类会比较吃力。此外,在Haar特征的实现中,为了解决亮度归一化问题,需计算像素值的平方和(square sum),平方和需要64位整数来存储;还需要开方(sqrt)运算。64位整数运算和开方运算,对很多嵌入式系统来讲,都是高计算量操作。

HOG特征是一个描述能力特别强的特征,也可以用在人脸检测上。HOG特征需要计算梯度的方向和长度。计算方向需要ctan三角函数(可用查表法加速)以及开方操作。统计直方图时,为了效果好,需要soft voting加权投票。因此HOG是强描述特征,但特征提取的计算量较大。

LBP是一个好特征,描述能力强,特征提取仅需要逻辑运算和加法运算,值得推荐!LBP依然有吐槽点。如果你实现Multi-Block LBP,需要积分图来加速。积分图是很多算法的加速武器,但构建积分图时,很难用SIMD(单指令多数据)指令优化。

  前面三种特征的对比分析,是为了说明好的特征要表达能力强且计算简单。很多二值特征(Binary feature)符合这一特点。二值特征还可以天然地解决图像的亮度变化问题,不需要事先对图像进行亮度均衡化。(例如使用Haar+AdaBoost检测人脸前,先对图像做直方图均衡化再检测,效果会好很多。)

二、样本

  很多论文中会洋洋洒洒地介绍算法的先进性,但很少有论文分析样本对结果的影响。可能分析样本显得很工程化很low吧。而描述样本在高维特征空间的分布,应该是很多模式识别问题的核心问题。

  好,不谈理论谈经验。样本选择是一般人不提的重要事情。如果你用手机自拍照片训练人脸检测器,应用在视频监控中,一般效果不会太好;如果你对所有人脸样本进行人脸对齐,要求双目绝对水平,那么训练出的分类器速度会比较快,但不能处理人脸姿态变化。即人脸样本越单一,训练出的分类器的速度会越快,但正确检测率低;如果样本复杂,速度变慢但检测率升高。如何平衡样本的复杂性和检测速度,需要针对具体应用斟酌。

  此外负样本也很关键。如果你从几千张风景图里抠图作为负样本进行训练,那么基本上会overfitting,即训练时误检率很低,但实际应用时误检率比较高。要准确刻画非人脸图像,负样本的规模一定要大,负样本的内容一定要多样化!我们平时训练用的负样本图像大约有20GB,包含各种内容的图像。

三、分类器训练

  这个可说的不多,Boosting方法就那些,可以尝试各种Boosting方法和各种参数,找到合适的。

四、代码优化:

消灭重复计算

  通过分析工具,找出最影响速度的代码段,有针对性地优化。一般来说是判断窗口是否是人脸的代码最耗时,因为调用次数最多。代码里首先要消灭的是重复计算,如代码

int b1 = pixels[y*step + x] - pixels[y*step + x + 1];
int b2 = pixels[y*step + x + 2] - pixels[y*step + x + 3];

  可以写为

int offset = y *step + x;
int b1 =pixels[offset] - pixels[offset+1];
int b2 = pixels[offset+2] - pixels[offset+3];

展开循环

  如果循环次数是固定的,可以去掉for循环,直接展开。代码行数虽然多了,但是少了for循环的条件判断,可以加速,例如可加速10%-20%。另外可以在设计分类器的时候,就把这些因素考虑进去,由训练程序生成的强分类器包含固定数目的弱分类器,或者某种规律数目的弱分类器,这样有利于检测代码优化。

利用SIMD指令

  无论Intel CPU还是ARM CPU,都有SIMD(单指令多数据)指令。利用这些指令,可以一次算多个数据。例如两个BYTE向量相加,支持128位的SIMD指令可以一次算16个BYTE的加法,理论上可以加速16倍。我们常用的加速利器积分图,它的构建过程很难用SIMD加速。如果你有更好的策略,可以果断抛弃积分图。

多核并行运算

  OpenMP或者Intel TBB可以让我们充分利用CPU的多个内核进行并行运算,提升速度。但用了OpenMP或TBB,未必可以加速,或未必可以加速到期望的倍数。多核并行,任务的拆分的粒度应该尽可能粗,不同的任务尽可能不用同一块内存,也就是任务之间的相关度低一些有利于加速。

  举给例子:如果两个矩阵相加,按像素进行并行操作,加速效果会很糟糕;如果按行并行,效果会好很多,但不要按列并行!  

定点化

  有些低功耗嵌入式系统不支持硬件浮点运算,特征提取和分类器设计应尽可能避免浮点运算。不可避免的浮点数可以转为定点数,当然这会损失精度。我们曾经将float类型转为8位整数,而准确率无明显影响。

GPU优化

  GPU跟CPU不同,有自己独特的特点。GPU特别适合做无复杂逻辑但计算量大的事情。例如图像resize、图像滤波等。Boosting算法可以运行在GPU上,并获得加速,但GPU加速Boosting优势并没有你想象的明显。Boosting算法中逻辑分支较多,也就是有不定长的for循环,有if-else判断;并行的时候每个运算单元运算量并不相同,有些运行时间长,有些运行时间短。运行时间短的要等运行时间长的。我们做了很多努力,GPU版本(低端GTX750i显卡)速度大约可以做到CPU版本(i7多核并行)的6倍左右。跟OpenCV中用GPU加速Haar+Adaboost的倍数一致,而没有达到期望的几十倍加速。

五、未来展望

  到目前为止,Boosting方法在人脸检测中依然具有明显的速度优势。但基于深度学习的目标检测方法进展迅速,不容小视。深度学习的方法可以很容易地获得非常高的准确率,如在FDDB人脸检测评库上,传统方法能达到85%准确率就非常高了,但深度学习方法可以轻松超过90%,甚至超过95%。如果想兼顾速度和准确率,传统方法和深度学习的方法结合也许是一个思路,现在已经有一些这样的尝试了。此外,CNN专用硬件应可以弥补深度学习方法的劣势。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏人工智能头条

搞懂深度学习到底需要哪些数学知识

1032
来自专栏机器之心

LSTM、GRU与神经图灵机:详解深度学习最热门的循环神经网络

选自MachineLearningMastery 作者:Jason Brownlee 机器之心编译 参与:熊猫 循环神经网络是当前深度学习热潮中最重要和最核心的...

3629
来自专栏大数据挖掘DT机器学习

文本特征提取方法研究

一、课题背景概述 文本挖掘是一门交叉性学科,涉及数据挖掘、机器学习、模式识别、人工智能、统计学、计算机语言学、计算机网络技术、信息学等多个领域。文本挖掘就是从大...

66711
来自专栏量化投资与机器学习

【深度研究】Stacking 集成学习在多因子选股中的应用

2662
来自专栏大数据挖掘DT机器学习

Microsoft 神经网络分析算法(原理篇)

前言 本篇文章继续我们的微软挖掘系列算法总结,前几篇文章已经将相关的主要算法做了详细的介绍。在开始Microsoft 神经网络分析算法之前,本篇我们先将神经网络...

2916
来自专栏新智元

MIT 研究“看见”神经网络形成概念过程,神经网络不全是黑箱

【新智元导读】MIT 新研究为解开深度神经网络黑箱迈出重要一步:今年的CVPR上,研究者提交一份新的研究,全自动分析了 ResNet,VGG-16,GoogLe...

3055
来自专栏计算机视觉战队

Deep Learning(深度学习)神经网络为啥可以识别?

今天看到一些感兴趣的东西,现在总结了给大家分享一下,如果有错,希望大家指正批评,谢谢!那就开始进入正题。 先从简单的说起来吧! 一、基本变换:层 一般的神经...

2656
来自专栏AI研习社

不是你无法入门自然语言处理(NLP),而是你没找到正确的打开方式

〇、序 之前一段时间,在结合深度学习做 NLP 的时候一直有思考一些问题,其中有一个问题算是最核心一个:究竟深度网络是怎么做到让各种 NLP 任务解决地如何...

4046
来自专栏AI研习社

不是你无法入门自然语言处理(NLP),而是你没找到正确的打开方式

〇、序 之前一段时间,在结合深度学习做 NLP 的时候一直有思考一些问题,其中有一个问题算是最核心一个:究竟深度网络是怎么做到让各种 NLP 任务解决地如何...

4206
来自专栏机器之心

学界 | 用单张图片推理场景结构:UC Berkeley提出3D景深联合学习方法

选自BAIR Blog 作者:Shubham Tulsiani、Tinghui Zhou 机器之心经授权编译 参与:smith、蒋思源、李泽南 最近,UC Be...

2995

扫码关注云+社区