首页 > 代码库 > OpenCV中的Haar+Adaboost(六):minHitRate与maxFalseAlarm
OpenCV中的Haar+Adaboost(六):minHitRate与maxFalseAlarm
在之前的文章中,分别讲解了Haar特征,强弱分类器组合形式,以及GAB。那么在了解这些内容的基础上,本节开始正式讲解OpenCV Adaboost训练过程。需要再次说明的是,本系列文章讲解的是OpenCV中的opencv_traincascade.exe程序的实现方法,并不代表仅只有此一种实现方法。
-------------------------------------------
在了解训练过程之前,还需要分析一些和训练相关的原理。
(一)precision与recall
对于所有的监督学习(supervised learning),都需要一组正样本(positive samples)和负样本(negative samples)。以训练人脸检测器为例,人脸图片即正样本,所有的非人脸区域即为负样本。对于一组positive samples和negative samples,经过检测器后,会有以下4种情况:
positive sample会产生:
1. TP(true positive),即positive sample被检测器判定为目标
2. FN(false negative),即positive samples被检测器判断为非目标,相当于检测器“漏掉”了目标
negative sample会产生:
1. TN(true negative),即negative sample被检测器判定为非目标
2. FP(false positive),即negative sample被检测器判定为目标,相当于产生了“误检” or “虚警”
也就是说,在实际中不仅关心是否检测错误,更关心的是把“什么”检测成了“什么”,分类更加细致。借用知乎网友Charles Xiao的一张图:
图1
其中论文中常见的两个指标:
precision = tp / (tp + fp)
recall = tp / (tp + fn)
一般在实际应用中,希望precision和recall都很高。还是以人脸检测为例,不妨假设图中有10个人脸。
- 若检测器只发现了1个人脸,此时precision=1虽然很高,但是recall=0.1非常低
- 若检测器发现了50个人脸(假设包含了10个真人脸),此时recall=1很高,但是precision=10/50=0.2很低
所以只有precision和recall都比较高时,讨论检测器的参数才有意义。但是现实情况中鱼和熊掌不可兼得,很难做到precision和recall都很高,所以会绘制precision-recall曲线(简称PR曲线)评估检测器的意义。由于这不是本文的主要内容,不再介绍,等有机会我会补上一篇介绍。
(二)hitRate与falseAlarm
图2
而在Adaboost训练过程中,我们更关心的是minHitRate和maxFalseAlarmRate参数,如图2红框中。在OpenCV的boost.cpp中CvCascadeBoost::isErrDesired()函数,对每一个stage有如下定义:
float hitRate = ((float) numPosTrue) / ((float) numPos); float falseAlarm = ((float) numFalse) / ((float) numNeg);
换个表达方式:
hitRate = tp / (tp + fn) = recall
falseAlarm = fp / (tn + fp)
这里hitRate称为“命中率”,度量检测器对正样本的通过能力,显然越接近1越好;而falseAlarm称为“虚警率”,度量检测器对负样本的通过能力,显然越接近0越好。
图3
考虑到Haar+Adaboost的stage间“串联”形式(如图3,参考本系列文章三),stageNum个stage串联后,已知每一个stage的hitRate(i)和falseAlarm(i),整个检测器最终的hitRate和falseAlarmRate为:
hitRate = hitRate(1) x hitRate(2) x ..... x hitRate(stageNum) = ∏hitRate(i)
falseAlarmRate = falseAlarm(1) xfalseAlarm(2)x ...... x falseAlarm(stageNum) = ∏hitRate(i)
那么:
1.为了让检测器最终的hitRate接近1,每一个stage的hitRate(i)必须很大,即每一个stage的正样本通过率必须非常高。
2. 同理,为了让检测器最终的falseAlarmRate接近0,每一个stage的falseAlarm(i)必须很小,即每一个stage的负样本虚警率必须比较低。
从图2中可以看到默认minHitRate = 0.995,默认maxFalseAlarmRate = 0.5。假设stageNum = 20时,最终检测器有:
hitRate ≈ minHitRate ^ stageNum = 0.995 ^ 20 = 0.904610....
falseAlarmRate ≈ maxFalseAlarmRate ^ stageNum = 0.5 ^ 20 = 0.00000095...
然后换一组参数,当minHitRate = 0.9,maxFalseAlarmRate = 0.6时,每一个stage的hitRate从0.995变为0.9,最终的检测器hitRate竟然掉到了0.12,crazy!
hitRate ≈ 0.9 ^ 20 = 0.12157...
falseAlarmRate ≈ 0.6 ^ 20 = 0.000036...
由此看出每一个stage的minHitRate必须非常高(>=0.995)!而maxFalseAlarmRate则相对“温和”一些。
总结一下:
1. 由于串联的stage数量很多,minHitRate必须非常接近1,才能保证最终检测器有较好的recall;
2. falseAlarmRate相当于对检测器的precision作了约束;
3. 相对于maxFalseAlarmRate,minHitRate更加敏感。
-------------------------------------------------------------------------------
插入一段:前段时间在知乎翻到一个问题,结合上述内容恰好可以解释。
-------------------------------------------------------------------------------
本节介绍了一些和训练相关的基本的参数,下节以此为基础介绍OpenCV中分类器训练方法。
欢迎提出意见和建议!
OpenCV中的Haar+Adaboost(六):minHitRate与maxFalseAlarm