主要应用在人脸检测。haar特征 + adaboosting,人脸检测系统是一个级联的分类器系统,这里主要是讨论其中一个节点。

大体流程如果:

 

                

首先准备正负样本,在一个训练强分类器H时,使用booststraping策略来进行样本的提取:从整体样本集合中,抽样n1 < n个样本 针对抽样的集合训练分类器H1,,抽样的方法有很多,例不放回抽样等.当训练第二强分类器时,从样本整体集合D中,抽取 nn 个样本,其中合并进一半被 C1 分类错误的样本。得到样本集合 D2,训练弱分类器H2,抽取D样本集合中,H1 和 H2 分类不一致样本,组成D3,训练弱分类器H3

特征的选择:20 * 20 的图像

这里的尺度需要缩放,使得目标的大小具有更大适应性,根据给定的参数,特征的数量大概是67067(主要是为了能加速训练的过程,所以增加了一些限制)。在训练前对图像进行直方图均衡化(光照补偿)。

具体的haar特征提取参考:http://www.cnblogs.com/ello/archive/2012/04/28/2475419.html

系统使用haar特征的原因在于它的简单,计算复杂度低,可以达到实时性的目的。

Adaboost(Adaptive Boosting)算法 是一个将几个弱分类器结合起来,说白了就是几个臭皮匠顶个诸葛亮,不过不同于boostraping,它不是紧紧将几个弱分器的相加,而是需要样本权值来使得每次弱分类器的连续,涉及到权值的选择和更新,在抵抗噪声干扰使用的是权值修正 (Weight trimming)。如果分类正确了,权重降低,如果分类错了,则权重提高,初始的时候,权重都是一样的。通过多次迭代,可以想象得到,程序越往后执行,训练出的模型就越会在意那些容易分错(权重高)的点。当全部的程序执行完后,会得到M个模型在整个训练过程中其实就是一个贪婪算法,在每一次训练弱分类器的时候,都需要对所有的特征进行一个迭代,选择一个能是使得目标误差函数最小的特征作为弱分类器的特征(相当每个特征对应一个弱分类器),所以adaboosting算法也被认为是一个特征选择算法。算法之所以称为自适应,因为在每次迭代过程中会根据分类的结果来调整权值,这里也就是adaboost与boosting算法的最大差异。

adaboost/boosting 的差异:http://www.cnblogs.com/fartherfuture/p/3678668.html

adaboosting算法的流程如下:

整个过程完成之后,就得到一个强分类器。 之后通过样本选择策略来更新样本,再训练得到一个强分类器。。。。。

通过多个分类器结合起来得到一个级联分类器(强强联合)。

在Opencv2.4.8里有具体的函数或者应用程序来选择样本和训练级联分类器。

 

CreateSample 使用的是Opencv_createSample.exe 应用程序,具体参见文档:Opencv 之 HaarTraining算法剖析 作者周明才,讲的很好

下面是我根据文档的结果

Opencv_haartrainging d的参数中最值得注意的就是 -npos 和 -nneg ,参数-nstages 表示级联分类器的级数nstages, -minhitrate 表示最小命中率,默认是0.95

-npos 代表的是正样本的数目,是指在训练一个强分类器从.vec文件中抽样出来的数据样本,-nneg表示训练一个强分类器的负样本数目。

假设.vec文件的数目是CountVec,那么有这样一个不等式成立

CountVec >= (npos + (nstages - 1)*(1 -minhitrate) * npos ) + nneg 

为什么需要满足这个不等式呢?

主要原因在于每一个强分类器时样本的选择上,在 stage=0时,随机的从.vec文件中选择npos个正样本,由于存在虚警,在每一次训练一个强分类器之后,会把那些分类错误的从整个样本库中剔除掉,总的样本就剩下 CountVec = CountVec - (1 - minhitrate)* npos,在第二个强分类器的训练过程中就是从剩下的Countvec抽样,一直这样进行nstage次,所以就有CountVec >= (npos + (nstages - 1)*(1 -minhitrate) * npos ) + nneg 。

当在使用opencv_haartraining 训练的时候,出现如下的报错

Opencv Error:Assert failed (elements_read == 1) in icvGetHaarTraininDataFrom

那么基本可以认定Countvec的个数不足于一次强分类器的训练也就是这个时候 Countvec < npos.

在机器学习中经常会遇到正负样本的问题,花了一点时间查找资料,基本上弄明白了一点到底是怎么回事,记录在这里以便以后查看,也希望能够帮助到有疑惑的人,当然也希望理解的比较透彻的人看到之后对于理解的不对的地方能够予以指点。

首先我将这个问题分为分类问题与检测问题两个方面进行理解。在分类问题中,这个问题相对好理解一点,比如人脸识别中的例子,查到的资料中介绍的比较清楚的网址如下(http://stackoverflow.com/questions/25598335/collect-negative-samples-of-adaboost-algorithm-for-face-detection),其中的截图如下,正样本很好理解,就是人脸的图片,负样本的选取就与问题场景相关,具体而言,如果你要进行教室中学生的人脸识别,那么负样本就是教室的窗子、墙等等,也就是说,不能是与你要研究的问题毫不相关的乱七八糟的场景图片,这样的负样本并没有意义,还有一个比较好的网址是(http://www.doc.ic.ac.uk/~sgc/teaching/pre2012/v231/lecture10.html)

在检测的问题中,我理解着就不是那么简单了,因为检测问题需要做的事情是指出哪里有什么,也就是既要给出框,又要说明框中是什么,在这种情况下,我们所具备的数据就是一些人工标注的图片,这些图片上有框,并且会给出框中的物体类别,我们需要运用这些数据生成训练中的正负样本数据,参考了faster以及SSD两种检测框架中对于正负样本的选取准则,我的理解如下:

首先,检测问题中的正负样本并非人工标注的那些框框,而是程序中(网络)生成出来的框框,也就是faster rcnn中的anchor boxes以及SSD中在不同分辨率的feature map中的默认框,这些框中的一部分被选为正样本,一部分被选为负样本,另外一部分被当作背景或者不参与运算。不同的框架有不同的策略,大致都是根据IOU的值,选取个阈值范围进行判定,在训练的过程中还需要注意均衡正负样本之间的比例。

 

我理解着,在fast的框架中,也是需要多SS算法生成的框框与GT框进行IOU的判断,进而选取正负样本,总之,正负样本都是针对于程序生成的框框而言,而非GT数据。