前言 本文介紹了在圖像預(yù)處理調(diào)參、模型訓(xùn)練調(diào)參等方面中的技巧,并提醒讀者要多注意數(shù)據(jù)的分布和呈現(xiàn)的狀態(tài)。
對(duì)卷積網(wǎng)絡(luò)來說,所學(xué)習(xí)的就是數(shù)據(jù)集的數(shù)據(jù)分布,你的卷積核參數(shù)最后形成的也是對(duì)數(shù)據(jù)集中特征分布的認(rèn)知。
寫這篇文章就是因?yàn)閡p主的邀請(qǐng),然后分享一下自己工作時(shí)候總結(jié)的一些經(jīng)驗(yàn)和技巧,不一定適用別的網(wǎng)絡(luò),有的還可能會(huì)有反作用,所以也就是給大家提供一個(gè)思路,歡迎拍磚吧,因?yàn)槎际枪緮?shù)據(jù),分享試驗(yàn)結(jié)果也比較麻煩,所以大家看個(gè)思路就好。
1、預(yù)處理技巧分享
圖像預(yù)處理部分調(diào)參的主要目的是對(duì)輸入數(shù)據(jù)進(jìn)行增強(qiáng),使得網(wǎng)絡(luò)模型在訓(xùn)練的過程中能更專注于目標(biāo)特征部分的學(xué)習(xí)。常用的方式是圖像的隨機(jī)旋轉(zhuǎn)、裁剪以及翻轉(zhuǎn)等方式,這些方式的預(yù)處理其本質(zhì)其實(shí)是為了讓你的數(shù)據(jù)集更豐富,讓網(wǎng)絡(luò)能夠?qū)W習(xí)到更多的分布情況,這個(gè)網(wǎng)上已經(jīng)有很多博客了,筆者就不贅述了;另一種調(diào)整的trick是在圖像上疊加信息,例如在輸入數(shù)據(jù)上增加高斯噪聲,椒鹽噪聲,從而提升網(wǎng)絡(luò)對(duì)有干擾和成像較差情況下的目標(biāo)檢測(cè)能力。本文將對(duì)圖像上疊加信息的調(diào)參技巧進(jìn)行一定的擴(kuò)展講解。
1、為什么在原始圖像上疊加信息會(huì)管用,不會(huì)破壞原有的圖像信息么?
在圖像上疊加信息分成兩類,一類是疊加噪聲,這種操作的目的是為了讓網(wǎng)絡(luò)能夠適應(yīng)圖像質(zhì)量不佳情況下的圖像檢測(cè)任務(wù),在板端實(shí)測(cè)的結(jié)果,這種疊加噪聲的方式也可以一定程度提高網(wǎng)絡(luò)對(duì)輸入圖像中待檢測(cè)目標(biāo)的仿射變換的適應(yīng)能力。筆者通過在輸入圖像上疊加一定量的高斯噪聲,在Hi3516CV500上完成基于yolov3-tiny的車牌檢測(cè)任務(wù)時(shí),提高了0.5%的精度。
另一類信息的疊加是對(duì)嘗試對(duì)圖像上某一特定特征進(jìn)行增強(qiáng),該增強(qiáng)的目的是突出該方面的圖像特征,使得網(wǎng)絡(luò)能夠首先注意到該種特征并更專注于此類特征的學(xué)習(xí),因?yàn)檫@種方式只是對(duì)圖像中的指定特征或位置有變動(dòng),并不會(huì)整體上對(duì)圖像的結(jié)構(gòu)有巨大的改變,所以并不會(huì)破壞圖像的信息可讀性。例如:利用canny算子對(duì)圖像中的邊緣特征進(jìn)行增強(qiáng)。
2、上面說的兩種調(diào)參技巧是怎么想出來的?
我們都知道,網(wǎng)絡(luò)學(xué)習(xí)的是數(shù)據(jù)中的參數(shù)分布,何凱明大神也在retinanet的論文里提到過,數(shù)據(jù)的不平衡是影響檢測(cè)網(wǎng)絡(luò)性能的主要因素,而focal loss的提出就是讓網(wǎng)絡(luò)在學(xué)習(xí)時(shí)更專注于漏檢和誤分的樣本。那么我們接著這個(gè)思路想,如何使得網(wǎng)絡(luò)更專注于目標(biāo)區(qū),從而獲得盡量多的價(jià)值更高的誤撿和漏檢樣本呢?花朵吸引蜜蜂靠的是自己的香味和更鮮艷的外表,所以我們也要讓目標(biāo)區(qū)域更“顯眼”,而平時(shí)在訓(xùn)練檢測(cè)網(wǎng)絡(luò)時(shí),發(fā)現(xiàn)對(duì)數(shù)據(jù)集進(jìn)行標(biāo)注時(shí),anchor base類算法,目標(biāo)標(biāo)注框比實(shí)際的物體緊縮框大大概幾個(gè)像素時(shí)得到的檢測(cè)結(jié)果統(tǒng)計(jì)精度和定位框的穩(wěn)定性都會(huì)好,那么我們是不是可以認(rèn)為,對(duì)anchor base的檢測(cè)網(wǎng)絡(luò)來說,目標(biāo)物體的邊緣也是很重要的,所以就想到了通過canny算子增強(qiáng)邊緣的方式來增強(qiáng)訓(xùn)練數(shù)據(jù)。
3、如何在實(shí)際的網(wǎng)絡(luò)訓(xùn)練中應(yīng)用以上的技巧?
實(shí)際使用過程如下:
1)通過對(duì)輸入數(shù)據(jù)的手動(dòng)查驗(yàn)或自動(dòng)化統(tǒng)計(jì),確定較好的canny閾值
2)利用閾值對(duì)訓(xùn)練樣本中10-20個(gè)batch的數(shù)據(jù)進(jìn)行canny邊緣增強(qiáng)。
3)增強(qiáng)方式為:原圖轉(zhuǎn)灰度提取到的canny邊緣所對(duì)應(yīng)的原圖像素位置進(jìn)行對(duì)比度增強(qiáng)或直接涂黑。加深程度可以由自定義的超參數(shù)alpha來指定。
4)用這10-20個(gè)batch的數(shù)據(jù)進(jìn)行幾個(gè)epoch的訓(xùn)練后再換成普通數(shù)據(jù)進(jìn)行訓(xùn)練。
2、模型訓(xùn)練參數(shù)調(diào)整
講了預(yù)訓(xùn)練時(shí)候的數(shù)據(jù)增強(qiáng),接下來是模型訓(xùn)練參數(shù)部分。其實(shí)這部分網(wǎng)上講的trick很多了,大家平時(shí)注意搜集一下或者github上找一找,就有很多人的練手的倉庫可以跟著學(xué)。我也就不多講了,因?yàn)槲乙膊桓艺f學(xué)全了。我講講我自己實(shí)際跑模型時(shí)候的一些想法。
1、BFEnet特征擦除網(wǎng)絡(luò)
這個(gè)網(wǎng)絡(luò)是reid方向的,先講這個(gè)是因?yàn),這個(gè)特征擦除和上面講到的噪聲本質(zhì)上有相似的地方,都是通過在訓(xùn)練時(shí)遮蔽一部分特征值,來讓網(wǎng)絡(luò)習(xí)慣一定量的噪聲干擾,從而增強(qiáng)性能。這個(gè)技巧可以用在應(yīng)對(duì)有遮擋的場(chǎng)景下的模型。
2、anchor的調(diào)整
在yolo的代碼里大家肯定都看了,作者是根據(jù)你給的數(shù)據(jù)集里面,標(biāo)定的目標(biāo)的長(zhǎng)和寬進(jìn)行k-means的聚類,然后確定在當(dāng)前這個(gè)數(shù)據(jù)集上的anchor的。我這里的經(jīng)驗(yàn)就是,我發(fā)現(xiàn)有人問過我為啥我只訓(xùn)練一類的檢測(cè),然后重新計(jì)算的anchor6個(gè)或者9個(gè)anchor尺寸差的都不大,但是在實(shí)際檢測(cè)的時(shí)候,卻檢測(cè)不到東西。我的結(jié)論是:對(duì)anchor的設(shè)計(jì)應(yīng)該是基于模型作者默認(rèn)的anchor進(jìn)行微調(diào)而不是完全的重新計(jì)算。
原因:大家都知道,yolov3來說,輸出是三個(gè)特征圖,分別對(duì)應(yīng)小目標(biāo),中目標(biāo)和大目標(biāo)。比如我們要檢測(cè)的目標(biāo)在圖像中占比我們?nèi)搜鄹杏X應(yīng)該是比較大的,然后我們統(tǒng)計(jì)的框也都是比較大的尺寸,但是在實(shí)際訓(xùn)練的時(shí)候,并不是說大目標(biāo)就一定由yolov3的最初設(shè)計(jì)的大目標(biāo)輸出層輸出的。很可能就是由中間目標(biāo)層輸出的,而因?yàn)閍nchor的設(shè)計(jì)過大,導(dǎo)致訓(xùn)練的網(wǎng)絡(luò)不收斂的有之,明明收斂了,卻檢測(cè)不到目標(biāo)的情況也有之。
解決辦法:在設(shè)計(jì)anchor的時(shí)候,首先統(tǒng)計(jì)目標(biāo)框的分布,然后進(jìn)行聚類,聚類后替換或修改原有的9個(gè)anchor中和你計(jì)算的anchor相近的幾個(gè)原有的anchor值。然后再訓(xùn)練,如果框還是不夠緊縮,再對(duì)某幾個(gè)框進(jìn)行精調(diào)就可以了,核心思路就是:anchor的分布也要滿足對(duì)全集的稀疏覆蓋而不僅僅是你的當(dāng)前數(shù)據(jù)集。
3、后處理的優(yōu)化
后處理的優(yōu)化部分嚴(yán)格來說不算是網(wǎng)絡(luò)訓(xùn)練的trick了,應(yīng)該是部署的trick,比如海思的NPU部署的時(shí)候,會(huì)限制比較大的pool核,所以最好訓(xùn)練的時(shí)候就把大的pooling切換為幾個(gè)小的連續(xù)pooling,實(shí)測(cè)雖然理念上兩者應(yīng)該是差不多的,但是實(shí)際上還是差了0.3%的精度。(指的是直接多層的pooling轉(zhuǎn)換到板子和訓(xùn)練時(shí)是一個(gè)大的pooling,到轉(zhuǎn)換時(shí)候再改結(jié)構(gòu)成幾個(gè)小的pooling)
還有一個(gè)就是nms部分,這部分也有同學(xué)問過我說因?yàn)槲业臄?shù)據(jù)集有遮擋,可能兩個(gè)離的比較近的,nms就把有遮擋的那個(gè)小目標(biāo)去掉了。這部分分享一個(gè)小技巧就是,你在算nms的時(shí)候,也關(guān)注一下兩個(gè)框的中心點(diǎn)距離,可以設(shè)置中心點(diǎn)距離超過多少的兩個(gè)框,不做nms。這樣就能避免nms的一部分武斷刪除檢測(cè)結(jié)果bbox。
4、大模型訓(xùn)練時(shí)的一個(gè)訓(xùn)練技巧
有一位同學(xué)問過我,就是為啥同樣的模型,用比較少的數(shù)據(jù)訓(xùn)練的時(shí)候很快到了97%的MAP,但是換300w的大數(shù)據(jù)集的訓(xùn)練以后,卡在93%上不去了。這里面有一個(gè)技巧叫warm up,也就是說在大數(shù)據(jù)下訓(xùn)練模型的時(shí)候,可以先從大數(shù)據(jù)集上取一部分?jǐn)?shù)據(jù)訓(xùn)練模型,然后以這個(gè)訓(xùn)練的模型為預(yù)訓(xùn)練模型,在大數(shù)據(jù)集上,增大batch_size再進(jìn)行訓(xùn)練,至少?zèng)]卡在93%這個(gè)問題上了。
5、學(xué)習(xí)率手動(dòng)修正策略
我們訓(xùn)練的時(shí)候,一般都會(huì)設(shè)置學(xué)習(xí)率的衰減,有很多的方式,按已迭代步長(zhǎng)的,按當(dāng)前損失值的,按訓(xùn)練集當(dāng)前損失值和測(cè)試集計(jì)算的損失值的gap差值做修正項(xiàng)的。我這里提到的技巧就是比如以步長(zhǎng)調(diào)整學(xué)習(xí)率為例,什么時(shí)候可以靠自動(dòng)化的修正學(xué)習(xí)率,什么時(shí)候要手動(dòng)調(diào)整一下。
我們?cè)谟?xùn)練模型的時(shí)候,一般都會(huì)關(guān)注損失函數(shù)變化曲線圖,在曲線圖中,數(shù)據(jù)集的稀疏程度能通過損失曲線的震蕩情況有一定的反映,如果有個(gè)別的跳點(diǎn),多為數(shù)據(jù)集中的壞數(shù)據(jù)(標(biāo)記錯(cuò)誤數(shù)據(jù)),當(dāng)我們的損失圖呈現(xiàn)為震蕩--階躍--在另一個(gè)損失值附近震蕩時(shí),就要注意了,此時(shí)多半是因?yàn)槟愕臄?shù)據(jù)集在做打亂的時(shí)候數(shù)據(jù)并沒有打的很散,可以在這個(gè)位置先停止訓(xùn)練并記錄當(dāng)前狀態(tài),再降低學(xué)習(xí)率,繼續(xù)訓(xùn)練,等訓(xùn)練數(shù)據(jù)再次開始恢復(fù)之前的震蕩位置時(shí),再恢復(fù)學(xué)習(xí)率訓(xùn)練。
這樣操作的原因是為了避免在參數(shù)中引入過大的噪聲,噪聲分兩種,一種就是錯(cuò)誤的數(shù)據(jù),比如背景啊,像目標(biāo)但是不是目標(biāo)的東西,還有就是多類別訓(xùn)練的時(shí)候,對(duì)每個(gè)類別來說,其余類別也算是噪聲的一種。所以采用要么把數(shù)據(jù)集弄好(這個(gè)很難,我也沒看過誰的文章里真的能說清把訓(xùn)練集弄好是啥樣的),要么加大batch,要么就訓(xùn)練時(shí)候注意。
3、總結(jié)
模型的調(diào)參訓(xùn)練技巧其實(shí)說白了就是怎么讓模型得到的是數(shù)據(jù)全集的稀疏分布,且和別的類別有比較好的區(qū)分,也就是類內(nèi)差小類間差則盡量大。以這個(gè)為核心,告訴模型應(yīng)該關(guān)注什么,少關(guān)注什么,既然是數(shù)據(jù)的科學(xué),多關(guān)注數(shù)據(jù)的分布和呈現(xiàn)的狀態(tài),祝大家在訓(xùn)練的時(shí)候都得到自己滿意的結(jié)果。