團4中心特征
这些所谓的特征不就是一堆堆带条纹的矩形么,到底是干什么用的?
我这样给出解释,将上而的任意一个矩形放到人脸区域上,然后,将白色区域的像素和减去黑色区域的像素和,得到的值我们暂且称之为人脸特征值,如果你把这个矩形放到一个非人脸区域,那么计算出的特征值应该和人脸特征值是不一样的,而且越不一样越好,所以这些方块的目的就是把人脸特征量化,以区分人脸和非人脸。
为了增加区分度,可以对多个矩形特征计算得到一个区分度更大的特征值,那么什么样的矩形特征怎么样的组合到一块可以更好的区分出人脸和非人脸呢,这就是AdaBoost算法要做的事了。
这里我们先放下积分图这个概念不管,为了让我们的思路连贯,我直接开始介绍AdaBoost算法。
2.2AdaBoost你给我如实道来!
本节旨在介绍AdaBoost在Haar分类器中的应用,所以只是描述了它在Haar分类器中的特性,而实际上AdaBoost是一种具有一般性的分类器提升算法,它使用的分类器并不局限某一特定算法。
上而说到利用AdaBoost算法可以帮助我们选择更好的矩阵特征组合,英实这里提到的矩阵特征组合就是我们之前提到的分类器,分类器将矩阵组合以二叉决策树的形式存储起来。
我现在脑子里浮现了很多问题,总结起来大概有这么些个:
•:
••弱分类器和强分类器是什么?
•:
••弱分类器是怎么得到的?
•:
••强分类器是怎么得到的?
•:
••二叉决策树是什么?
要回答这一系列问题,我得跟你罗嗦一会儿了,这得从AdaBoost的身世说起。
2.2.1AdaBoost的身世之谜
关于AdaBoost的身世,我把相关英文文献从上世纪80年代一直下到2001年,我发现我在短时间内没法读完,所以我只能尝试着从别人的总结中拼凑那些离散的片段,难免有
之前讲Haar分类器的前世今生也简单说过AdaBoost的身世,但是说的还不透。
我比较喜欢査算法的户口,所以新写了一章査了下去。
AdaBoost的老祖宗可以说是机器学习的一个模型,它的名字叫
PAC(ProbablyApproximatelyCorrect)o
PAC模型是计算学习理论中常用的模型,是Valiant牛在我还没岀生的1984年提出来的,他认为“学习"圧和析或模式不存在时仍能获取知识的一种“过程”,并给出
了一个从讣算角度来获得这种“过程"的方法,这种方法包括:
(1)适当信息收集机制的选择:
(2)学习的协定;
(3)对能在合理步骤内完成学习的概念的分类。
PAC学习的实质就是在样本训练的基础卜.,使算法的输出以槪率接近未知的目标概念°PAC学习模型是考虑样本复杂度(指学习器收敛到成功假设时至少所需的训练样本数)和讣算复杂度(指学习器收敛到成功假设时所需的汁算量)的一个基本框架,成功的学习被宦义为形式化的概率理论。
(来自论文《基于Adaboost的人脸检测方法及眼睛定位算法研究》)简单说来,PAC学习模型不要求你每次都正确,只要能在多项式个样本和多项式时间内得到满足需求的正确率,就算是一个成功的学习。
基于PAC学习模型的理论分析,Valiant牛提岀了Boosting算法,Boosting算法涉及到两个重要的概念就是弱学习和强学习,所谓的弱学习,就是指一个学习算法对一组槪念的识别率只比随机识别好一点,所谓强学习,就是指一个学习算法对一组概率的识别率很高。
现在我们知逍所谓的弱分类器和强分类器就是弱学习算法和强学习算法。
弱学习算法是比较容易获得的,获得过程需要数量巨大的假设集合,这个假设集合是基于某些简单规则的组合和对样本集的性能评估而生成的,而强学习算法是不容易获得的,然而,Kearns和Valiant两头牛提岀了弱学习和强学习等价的问题并证明了只要有足够的数据,弱学习算法就能通过集成的方式生成任意高精度的强学习方法。
这一证明使得Boosting有了可靠的理论基础,Boosting算法成为了一个提升分类器精确性的一般性方法。
1990年,Schapire牛提出了第一个多项式时间的算法,1年后Freund牛又提岀了一个效率更髙的Boosting算法。
然而,Boosting算法还是存在着几个主要的问题,英一Boosting算法需要预先知道弱学习算法学习正确率的下限即弱分类器的误差,其二Boosting算法可能导致后来的训练过分集中于少数特别难区分的样本,导致不稳左。
针对Boosting的若T•缺陷,Freund和Schapire牛于1996年前后提岀了一个实际可用的自适应Boosting算法AdaBoost,AdaBoost目前已发展岀了大槪四种形式的算法,
DiscreteAdaBoost(AdaBoost.M1)、RealAdaBoostxLogitBoostgentleAdaBoost,本文不做一一介绍。
至此,AdaBoost的身世之谜就这样揭开鸟。
同时弱分类器和强分类器是什么的问题也解释淸楚了。
剩下3个问题,我们先看一下,弱分类器是如何得到的。
2.2.2弱分类器的孵化
最初的弱分类器可能只是一个最基本的Haar-like特征,计算输入图像的Haar-like特征值,和最初的弱分类器的特征值比较,以此来判断输入图像是不是人脸,然而这个弱分类器太简陋了,可能并不比随机判断的效果好,对弱分类器的孵化就是训练弱分类器成为最优弱分类器,注意这里的最优不是指强分类器,只是一个误差相对稍低的弱分类器,训练弱分类器实际上是为分类器进行设置的过程。
至于如何设置分类器,设置什么,我们首先分别看下弱分类器的数学结构和代码结构。
◊•数学结构
pf(x)
其他
一个弱分类器h(x,f,p,0)由子窗口图像X,—个特征f,指示不等号方向的P和阈值8组成。
P的作用是控制不等式的方向,使得不等式都是〈号,形式方便。
◊•代码结构
1
/*
*CARTclassifier
3
*/
4
typedefstructCvCARTHaarClassifier
5
{
6
CV_INT_HAAR_CLASSIFIER_FIELDS()
7
intcount;
8
int*compidx;
9
CvTHaarFeature*feature;
10
CvFastHaarFeature*fastfeature;
11
float*threshold;
12
int*left;
13
int*right;
14
float*val;
15
}CvCARTHaarClassifier;
代码结构中的threshold即代表数学结构中的6阈值。
这个阈值究竟是干什么的?
我们先了解下CvCARTHaarClassifier这个结构,注意CART这个词,它是一种二叉决策树,它的提出者LeoBreiman等牛称其为“分类和回归树
(CART)”。
什么是决策树?
我如果细讲起来又得另起一章,我只简略介绍它。
“机器学习中,决策树是一个预测模型;他代表的是对象属性与对象值之间的一种映射关系。
树中每个筋点表示某个对象,而每个分叉路径则代表的某个可能的属性值,而每个叶结点则对应从根肖点到该叶肖点所经历的路径所表示的对象的值“决策树仅有单一输岀,若欲有复数输出,可以建立独立的决策树以处理不同输岀。
从数据产生决策树的机器学习技术叫做决策树学习,通俗说就是决策树。
”(来自《维基百科》)
决策树包含:
分类树,回归树,分类和回归树(CART),CHAID«
分类和回归的区别是,分类是当预计结果町能为两种类型(例如男女,输使用的回归是当局域结果可能为实数(例如剧价,患者住院时间等)使用的概念.
决策树用途很广可以分析因素对事件结果的影响(详见维基百科),同时也是很常用的分类方法,我举个最简单的决策树例子,假设我们使用三个Haar-like特征fl,f2,f3来判断输入数据是否为人脸,可以建立如下决策树:
具体操作过程如下:
1)对于每个特征f,计算所有训练样本的特征值,并将其排序。
扫描一颯排好序的特征值,对排好序的表中的每个元素,计算下而四个值:
全部人脸样本的权重的和tl:
全部非人脸样本的权重的和to:
在此元素之前的人脸样本的权重的和S1:
在此元素之前的非人脸样本的权重的和sO;
2)最终求得每个元素的分类误差函—…二
在表中寻找r值最小的元素,则该元素作为最优阈值。
有了该阈值.我们的第一个最优弱分类器就诞生了。
在这漫长的煎熬中,我们见证了一个弱分类器孵化成长的过程,并回答了如何得到弱分类器以及二叉决策树是什么。
最后的问题是强分类器是如何得到的。
2.2.3弱分类器的化蝶飞
首先看一下强分类器的代码结构:
1/食internalscageclassifier*/
2typedefstructCvSta今emaarClassifier
3(
4CV_INT_HAAR_CLASSIFIER_FIELDS()
5intcount;
6floatthreshold;
CvIntHaarClassifier**classifier;
8}CvStageHaarClassifier;
/*internalxCV_INT_HAAR_CLASSIFIER_FIELDS()
}CvIntHaarClassifier;
这里要提到的是CvIntHaarClassifier结构:
它就相当于一个接口类,当然是用C语言模拟的面向对象思想,利用CV_INT_HAAR_CLASSIFIER_FIELDS0这个宏让弱分类CvCARTHaarClassifier强分类器和CvStageHaarClassifier继承于CvIntHaarClass辻ier°
强分类器的诞生需要T轮的迭代,具体操作如下:
1•给世训练样本集S,共N个样本,其中X和丫分别对应于正样本和负样本;T为训练的最大循环次数:
2.初始化样本权重为1/N,即为训练样本的初始概率分布:
3•第一次迭代训练N个样本,得到第一个最优弱分类器,步骤见2.2.2节
4.提高上一轮中被误判的样本的权重;
5.将新的样本和上次本分错的样本放在一起进行新一轮的训练。
6.循环执行4-5步骤,T轮后得到T个最优弱分类器。
7.
组合T个最优弱分类器得到强分类器,组合方式如下:
其他
相当于让所有弱分类器投票,再对投票结果按照弱分类器的错误率加权求和,将投票加权求和的结果与平均投票结果比较得出最终的结果。
至此,我们看到英实我的题目起的漂亮却并不贴切,强分类器的脱颖而出更像是民主的投票制度,众人拾材火焰高,强分类器不是个人英雄主义的的产物,而是团结的力量。
但从宏观的局外的角度看,整个AdaBoost算法就是一个弱分类器从孵化到化蝶的过程。
小人物的奋斗永远是理想主义者们津津乐道的话题。
但暂时让我们放下AdaBoost继续探讨Haar分类器的其他特性吧。
2.3强分类器的强强联手
至今为止我们好像一直在讲分类器的训练,实际上Haar分类器是有两个体系的,训练的体系,和检测的体系。
训练的部分大致都提到了,还剩下最后一部分就是对筛选式级联分类器的训练。
我们看到了通过AdaBoost算法辛苦的训练出了强分类器,然而在现实的人脸检测中,只靠一个强分类器还是难以保证检测的正确率,这个时候,需要一个豪华的阵容,训练出多个强分类器将它们强强联手,最终形成正确率很高的级联分类器这就是我们最终的目标Haar分类器。
那么训练级联分类器的目的就是为了检测的时候,更加准确,这涉及到Haar分类器的另一个体系,检测体系,检测体系是以现实中的一幅大图片作为输入,然后对图片中进行多区域,多尺度的检测,所谓多区域,是要对图片划分多块,对每个块进行检测,由于训练的时候用的照片一般都是20*20左右的小图片,所以对于大的人脸,还需要进行多尺度的检测,多尺度检测机制一般有两种策略,一种是不改变搜索窗口的大小,而不断缩放图片,这种方法显然需要对每个缩放后的图片进行区域特征值的运算,效率不高,而另一种方法,是不断初始化搜索窗口size为训练时的图片大小,不断扩大搜索窗口,进行搜索,解决了第一种方法的弱势。
在区域放大的过程中会岀现同一个人脸被多次检测,这需要进行区域的合并,这里不作探讨。
无论哪一种搜索方法,都会为输入图片输出大虽的子窗口图像,这些子窗口图像经过筛选式级联分类器会不断地被每一个节点筛选,抛弃或通过。
它的结构如图所示。
被拒络的图像剩下的图像为人脸
我想你一左觉得很熟悉,这个结构不是很像一个简单的决策树么。
在代码中,它的结构如下:
1/*internaltreecascadeclassifiernode*/
2typedefstructCvTreeCascadeNode
3{
4CvStageHaarClassifier*stage;
5
structCvTreeCascadeNode*next;
6
structCvTreeCascadeNode*child;
7
structCvTreeCascadeNode*parent;
8
structCvTreeCascadeNode*next_same_level;
9
structCvTreeCascadeNode*childeval;
10intidx;
11intleaf;
12}CvTreeCascadeNode;
13/*internaltreecascadeclassifier*/
14typedefstructCvTreeCascaaeClassifier
15{
16CV_INT_HAAR_CLASSIFIER_FIELDS()
17CvTreeCascadeNode*root;/*rootofthetree*/
18CvTreeCascaaeNode*root^eval;/*rootnodeforthefiltering*/
19intnext_idx;
20}CvTreeCascadeClassifier;
级联强分类器的策略是,将若干个强分类器由简单到复杂排列,希望经过训练使每个强分类器都有较高检测率,而误识率可以放低,比如几乎99%的人脸可以通过,但50%的非人脸也可以通过,这样如果有20个强分类器级联,那么他们的总识别率为0.99*20=98%,错误接受率也仅为0.5^20匕0.0001%。
这样的效果就可以满足现实的需要了,但是如何使每个强分类器都具有较髙检测率呢,为什么单个的强分类器不可以同时具有较髙检测率和较高误识率呢?
下而我们讲讲级联分类器的训练。
(匸要参号J'论文《归Adaboost的人脸检测方法及眼睛定位算法研究》)
设K是一个级联检测器的层数,D是该级联分类器的检测率,F是该级联分类器的误识率,在是第i层强分类器的检测率,f:
是第i层强分类器的误识率。
如果要训练一个级联分类器达到给宦的F值和D值,只需要训练出每层的d值和f值,这样:
d'K二D,f"K=F
级联分类器的要点就是如何训练每层强分类器的d值和f值达到指泄要求。
AdaBoost训练岀来的强分类器一般具有较小的误识率,但检测率并不很高,一般情况下,髙检测率会导致高误识率,这是强分类阈值的划分导致的,要提髙强分类器的检测率既要降低阈值,要降低强分类器的误识率就要提高阈值,这是个矛盾的事情。
据参考论文的实验结果,增加分类器个数可以在提高强分类器检测率的同时降低误识率,所以级联分类器在训练时要考虑如下平衡,一是弱分类器的个数和计算时间的平衡,二是强分类器检测率和误识率之间的平衡。
具体训练方法如下,我用伪码的形式给出:
1)设左每层最小要达到的检测率d,最大误识率f,最终级联分类器的误识率Ft:
2)P二人脸训练样本,N=非人脸训练样本,Do=l.0,Fo=l.0:
3)i=0:
4)for:
Fi>Ft
•・++i;
••ni=0;Fi=Fi-i;
••for:
Fi>f*Fi-i
■・++□;
■•利用AdaBoost算法在P和N上训练具有m个弱分类器的强分类器;
■•衡量当前级联分类器的检测率Di和误识率Fi;
■•for:
di》•降低第i层的强分类器阈值;
沖衡量当前级联分类器的检测率Di和误识率Fi;
■咽二①;
■•利用当前的级联分类器检测非人脸图像,将误识的图像放入N;
2.4积分图是一个加速器
之所以放到最后讲积分图(Integralimage),不是因为它不重要,正相反,它是Haar分类器能够实时检测人脸的保证。
当我把Haar分类器的主脉络都介绍完后,苴实在这里引出积分图的概念恰到好处。
在前面的章节中,我们熟悉了Haar-like分类器的训练和检测过程,你会看到无论是训练还是检测,每遇到一个图片样本,每遇到一个子窗口图像,我们都而临着如何计算当前子图像特征值的问题,一个Haar-like特征在一个窗口中怎样排列能够更好的体现人脸