重点分析了Adaboost它的分类结构,以及如何使用Adaboost。这一节课讲解Adaboost分类器它训练的步骤以及训练好之后的XML文件的文件结构。所以这节课的核心是Adaboost分类器它的训练。如何来训练一个Adaboost分类器呢?
第一步,完成初始化数据的权值分布。正常情况下初始化的权值分布是需要一个计算公式来进行计算的。第一次进行初始化权值分布,所有的权值必须要相等,这是第一步的过程。
第二步,权值分布好之后,那么遍历判决阈值。把所有的阈值全部遍历一下,这样的话会计算出一系列的误差概率。这个最小的误差概率对应着一个权值t。
正常情况下我们使用Adaboost来进行训练的时候,一般使用的是opencv中已经编译好的exe文件。所以我们在Windows平台上或者是Mac平台上来进行训练的时候,那么我们直接可以使用它的可执行文件来进行训练,我们不需要自己来编写代码。
第四步我们要更新训练数据的权重分布。而香蕉它是一个错误的分类结果,这个时候它就会被加强。
要么是训练循环次数达到了我们的要求。比如说我们要求训练100次结束。另外一个我们的误差概率。因为每一次在进行训练的时候,它会有一个误差概率p。如果最小的误差概率p满足一定的情况,比如说满足小于0.01%,这个时候也可以终止。所以训练是否终止,它要查看一下当前的训练是否满足训练的终止条件。
G2(X)->G3(X)->G4(X)等等。
#adaboost 训练
# 1 初始化数据权值分布
# 苹果 苹果 苹果 香蕉
# 0.1 0.1 0.1 0.1
# 2 遍历阈值 p
# minP t
# 3 G1 (x)
# 4 权值分布 update
# 0.2 0.2 0.2 0.7
## 训练终止条件: 1 for count 2 p
准备两个opencv源代码中自带的XML文件。到opencv的官方网站下载opencv的源码,并找到这两个XML文件。
https://opencv.org/opencv-3-4-1.html
D:\opencv-3.4.1\opencv-3.4.1\data\haarcascades\haarcascade_frontalface_default.xml
通过key-value的形式标注每一个参数和当前参数对应的值。
-->
<opencv_storage>
<cascade type_id="opencv-cascade-classifier"><stageType>BOOST</stageType>
<featureType>HAAR</featureType>
<height>24</height>
<width>24</width>
<stageParams>
<maxWeakCount>211</maxWeakCount></stageParams>
<featureParams>
<maxCatCount>0</maxCatCount></featureParams>
<stageNum>25</stageNum>
BOOST表明它是一个BOOST分类器。紧接着特征的类型,我们使用的是HAAR模板。height和width是我们当前整个窗体的宽高,到底是一个24*24的。还有一个最大的弱分类器的个数,不能超过211个。以及当前的强分类器的个数,stageNum表明的是强分类器的个数。
<stages>
<_>
<maxWeakCount>9</maxWeakCount>
<stageThreshold>-5.0425500869750977e+00</stageThreshold>
<weakClassifiers>
<_>
<internalNodes>
0 -1 0 -3.1511999666690826e-02</internalNodes>
<leafValues>
2.0875380039215088e+00 -2.2172100543975830e+00</leafValues></_>
<_>
<internalNodes>
0 -1 1 1.2396000325679779e-02</internalNodes>
<leafValues>
-1.8633940219879150e+00 1.3272049427032471e+00</leafValues></_>
<_>
<internalNodes>
0 -1 2 2.1927999332547188e-02</internalNodes>
<leafValues>
-1.5105249881744385e+00 1.0625729560852051e+00</leafValues></_>
<_>
<internalNodes>
0 -1 3 5.7529998011887074e-03</internalNodes>
<leafValues>
-8.7463897466659546e-01 1.1760339736938477e+00</leafValues></_>
<_>
<internalNodes>
0 -1 4 1.5014000236988068e-02</internalNodes>
<leafValues>
-7.7945697307586670e-01 1.2608419656753540e+00</leafValues></_>
<_>
<internalNodes>
0 -1 5 9.9371001124382019e-02</internalNodes>
<leafValues>
5.5751299858093262e-01 -1.8743000030517578e+00</leafValues></_>
<_>
<internalNodes>
0 -1 6 2.7340000960975885e-03</internalNodes>
<leafValues>
-1.6911929845809937e+00 4.4009700417518616e-01</leafValues></_>
<_>
<internalNodes>
0 -1 7 -1.8859000876545906e-02</internalNodes>
<leafValues>
-1.4769539833068848e+00 4.4350099563598633e-01</leafValues></_>
<_>
<internalNodes>
0 -1 8 5.9739998541772366e-03</internalNodes>
<leafValues>
-8.5909199714660645e-01 8.5255599021911621e-01</leafValues></_></weakClassifiers></_>
<_>
<maxWeakCount>16</maxWeakCount>
<stageThreshold>-4.9842400550842285e+00</stageThreshold>
<weakClassifiers>
<_>
<internalNodes>
0 -1 9 -2.1110000088810921e-02</internalNodes>
<leafValues>
1.2435649633407593e+00 -1.5713009834289551e+00</leafValues></_>
<_>
<internalNodes>
0 -1 10 2.0355999469757080e-02</internalNodes>
<leafValues>
-1.6204780340194702e+00 1.1817760467529297e+00</leafValues></_>
<_>
<internalNodes>
0 -1 11 2.1308999508619308e-02</internalNodes>
<leafValues>
-1.9415930509567261e+00 7.0069098472595215e-01</leafValues></_>
<_>
<internalNodes>
0 -1 12 9.1660000383853912e-02</internalNodes>
<leafValues>
-5.5670100450515747e-01 1.7284419536590576e+00</leafValues></_>
<_>
<internalNodes>
0 -1 13 3.6288000643253326e-02</internalNodes>
<leafValues>
2.6763799786567688e-01 -2.1831810474395752e+00</leafValues></_>
<_>
<internalNodes>
0 -1 14 -1.9109999760985374e-02</internalNodes>
<leafValues>
-2.6730210781097412e+00 4.5670801401138306e-01</leafValues></_>
<_>
<internalNodes>
0 -1 15 8.2539999857544899e-03</internalNodes>
<leafValues>
-1.0852910280227661e+00 5.3564202785491943e-01</leafValues></_>
<_>
<internalNodes>
0 -1 16 1.8355000764131546e-02</internalNodes>
<leafValues>
-3.5200199484825134e-01 9.3339198827743530e-01</leafValues></_>
<_>
<internalNodes>
0 -1 17 -7.0569999516010284e-03</internalNodes>
<leafValues>
9.2782098054885864e-01 -6.6349899768829346e-01</leafValues></_>
<_>
<internalNodes>
0 -1 18 -9.8770000040531158e-03</internalNodes>
<leafValues>
1.1577470302581787e+00 -2.9774799942970276e-01</leafValues></_>
<_>
<internalNodes>
0 -1 19 1.5814000740647316e-02</internalNodes>
<leafValues>
-4.1960600018501282e-01 1.3576040267944336e+00</leafValues></_>
<_>
<internalNodes>
0 -1 20 -2.0700000226497650e-02</internalNodes>
<leafValues>
1.4590020179748535e+00 -1.9739399850368500e-01</leafValues></_>
<_>
<internalNodes>
0 -1 21 -1.3760800659656525e-01</internalNodes>
<leafValues>
1.1186759471893311e+00 -5.2915501594543457e-01</leafValues></_>
<_>
<internalNodes>
0 -1 22 1.4318999834358692e-02</internalNodes>
<leafValues>
-3.5127198696136475e-01 1.1440860033035278e+00</leafValues></_>
<_>
<internalNodes>
0 -1 23 1.0253000073134899e-02</internalNodes>
<leafValues>
-6.0850602388381958e-01 7.7098500728607178e-01</leafValues></_>
<_>
<internalNodes>
0 -1 24 9.1508001089096069e-02</internalNodes>
<leafValues>
3.8817799091339111e-01 -1.5122940540313721e+00</leafValues></_></weakClassifiers></_>
<_>
<maxWeakCount>27</maxWeakCount>
这个程序非常的长,大约有几万行。那么这整个过程描述的就是我们当前整个Adaboost分类器所有的一些参数。其中第一段表明的是stage0,stage0表明的是第一个强分类器。第一个强分类器它先列了第一个强分类器中弱分类器的个数以及它的阈值门限stageThreshold。这里还有一些各种判决,像leftValue和RightValue。这就是当阈值门限进行判决的时候,那么左边取什么值,右边取什么值。我们使用的时候并不会对这个XML文件进行解析,解析的步骤opencv已经帮我们做了,我们只需要简单的了解一下这个文件结构即可。
下一节课我们将通过已经训练好的Adaboost分类器的XML文件来进行一个人脸识别。