Haar特征Adaboost级联分类器训练经验——Practical Tips

最近在项目中使用opencv的人脸检测算法来检测灰机,效果还ok,就分类器训练过程中的一些小技巧做一个总结,其中有一部分是前人的经验,对这部分内容我发扬一下拿来主义,还有一些是自己的心得体会,希望对新手有一些帮助。至于算法原理网上很多,我不再赘述。检测效果主要还是看分类器训练得好不好,所以检测过程我也不说,网上也有很多源码解析得很好。训练是一个fine tuning的过程,经验显得尤为重要,我重点就此给一点tips。

Tip1:正样本和负样本数量和比例问题

理论上来说,负样本越多越好,负样本越多,虚警率就越低(见多识广嘛),这里的“多”不仅体现在数量上,更应该体现在模式多样性上。负样本过少,涵盖的背景变化情况就少,可能出现负样本全部不能通过当前分类器,即没有负样本被错分成正样本,从而陷入死循环(死循环出现在函数icvGetHaarTrainingData中)。通常正负样本绝对数量在10^3数量级,比例在1:2-1:5。有人奇怪了,既然负样本越多越好,为什么不1:10呢,因为如果这样正样本的统计特性将被忽略,造成正样本权重和很小,小到一定程度的时候可能很大一部分正样本都不参与训练了(在weightTrimRate=0.95时),那么假设没有正样本参与训练了,只有负样本参与后续训练,训练出来的分类器会是什么样子的呢?

Tip2:正样本处理函数cvCreateSamples

正样本图片可以只截取目标部分,也可以是包含目标的整个大图,只是都要用文本文件描述图片名称、目标数目、目标矩形坐标,这部分可以看http://docs.opencv.org/2.4/doc/user_guide/ug_traincascade.html,总之最后会归一化到指定尺度上计算haar特征。这个函数里设置目标数目是要生成的正样本数目。

Tips3: 负样本生成方式

负样本与正样本不同,负样本图片大小是大于或等于正样本大小的,负样本在负样本图片上采样获得,采样尺寸与正样本尺寸一样,为了获得更多负样本同时也抵抗背景尺度变化,负样本图片会缩放后再采样,如此一张大图比如1000*1000,正负样本尺寸20*20,假设采样不重叠,可以采样50*50个负样本,再把大图缩小到0.8倍(举个例子),成为800*800的,依旧不重叠采样,又可以采集40*40个负样本,以此类推,仅一张负样本大图就可以采集到很多负样本了。

Tips4: 每一级的正样本和负样本数目

训练函数cvCreateTreeCascadeClassifier有两个参数npos和nneg,指的是每一级的正样本数目和负样本数目,不要和训练的样本数一样。这里特别要注意,当设置minHitRate为0.95时如果正训练样本个数为10000个,那么其中的500个就很可能背叛别为负样本,第二次选择的时候必须多选择后面的500个,按照这种规律我们为后面的每级多增加npos*minHitRate个正样本,假设Vec文件中正样本总数是 TotalNum,那么应满足npos+(nstage-1)*(1-minHitRate)*npos<=TotalNum.以上式子也只是根据训练级数和准备的正样本总和设置一个参与训练的正样本个数,只能作为估算,小于计算出来的数可能没有问题,但是大于那个数肯定有问题,会出现fread都不到数据的错误,从而训练崩溃。

Tips5: 级数设置

级数与样本数量有关,还应顾及到最终的检出率和虚警率。通常在10-20级之间,样本数量少的(比如正样本1000一下),通常级数不用设定很高,往往不到最后一级训练就终止了,因为样本数少已经达到指标。说要顾及检出率和虚警率主要是跟函数cvCreateTreeCascadeClassifier中float minhitrate和float maxfalsealarm两个参数有关。这两个参数分别指每一级的最小命中和最大虚警,假设分别设置为0.995和0.5,分类器有20级,总的检出率就是0.995^20=0.9046,总的虚警率0.5^20趋近于0.级数越高虽然虚警率更低,但检出率也会牺牲,训练和检测时间都会加长,需要综合考虑。

Tips6:训练停了可以重启

有时候训练陷入死循环,或者电脑突然断电了,训练的难道就白费了吗?幸好,训练是可以重启的。比如当负样本不足时容易陷入死循环,这时我们可以让程序停下来,添加更多的负样本后再重新训练,电脑突然关机后也适用于此,只需要设置参数,分类器名称与之前一致就好,它会接着干完它的工作。

大概就是这些了,网上有几篇实用的博客:

http://www.computer-vision-software.com/blog/2009/11/faq-opencv-haartraining/ 这一篇一定要读,经验性的训练错误一般都列出来了

http://blog.csdn.net/xidianzhimeng/article/details/42147601 这一篇重点分析了几个重要的参数含义和设置方法,对我帮了大忙,非常值得一读

http://blog.csdn.net/lampqiu/article/details/40188763  这一篇很好地解释了负样本是如何采样的,同时从代码角度分析了为什么负样本不足时会产生死循环

http://www.cnblogs.com/louyihang-loves-baiyan/p/4769853.html  这一篇是主要函数参数的中文介绍,有一些实用tips

你可能感兴趣的:(机器学习)