本篇不講任何正負(fù)樣本定義的方法以及各種采樣的方法,只從實(shí)際訓(xùn)練角度結(jié)合量產(chǎn)經(jīng)驗(yàn)思考正負(fù)樣本背后的本質(zhì)問題。
1. 什么是正負(fù)樣本?
對(duì)于YOLO系列的結(jié)構(gòu),正負(fù)樣本就是feature map上的每一個(gè)grid cell(或者說(shuō)對(duì)應(yīng)的anchor)。
對(duì)于RCNN系列的結(jié)構(gòu),RPN階段定義的正負(fù)樣本其實(shí)和YOLO系列一樣,也是每一個(gè)grid cell。RCNN階段定義的正負(fù)樣本是RPN模塊輸出的一個(gè)個(gè)proposals,即感興趣區(qū)域(region of interesting,roi),最后會(huì)用RoIPooling或者RoIAlign對(duì)每一個(gè)proposal提取特征,變成區(qū)域特征,這和grid cell中的特征是不一樣的。
對(duì)于DETR系列,正負(fù)樣本就是Object Queries,與gt是嚴(yán)格的一對(duì)一匹配。而YOLO,RCNN是可以多對(duì)一的匹配。
通常情況下,檢測(cè)問題會(huì)涉及到3種不同性質(zhì)的樣本:
正樣本(positive)
對(duì)于positive,它存在的意義是讓模型具備判斷前景的能力,不僅要讓模型知道圖像上這個(gè)位置存在前景目標(biāo),還要把具體的位置用bbox框出來(lái),所以一旦判定某個(gè)grid cell或者proposal是正樣本,你就需要對(duì)其負(fù)責(zé)cls+bbox的訓(xùn)練。
忽略樣本(ignore)
ignore最大的用處就是可以處理模棱兩可的樣本,以及影響模型訓(xùn)練的樣本。所以對(duì)于ignore,對(duì)其不負(fù)責(zé)任何訓(xùn)練,或者對(duì)其負(fù)責(zé)bbox的訓(xùn)練,但是不負(fù)責(zé)cls的訓(xùn)練。
負(fù)樣本(negative)
對(duì)于negative,它存在的意義是讓模型具備區(qū)分背景的能力,不讓模型產(chǎn)生背景的誤檢,所以對(duì)于negative只負(fù)責(zé)cls的訓(xùn)練,不負(fù)責(zé)bbox的訓(xùn)練。
看到有同學(xué)問:能不能舉幾個(gè)實(shí)際ignore的例子理解一下。
那舉幾個(gè)例子:
1. 如果你發(fā)現(xiàn)遮擋達(dá)到80%以上的vehicle或者模糊的vehicle,如果當(dāng)正樣本訓(xùn)練的話,loss收斂不了,那么就可以把這些原本是正樣本的納入ignore中,不參與訓(xùn)練。如果你確實(shí)不想把遮擋80%以上的vehicle召回出來(lái),那么歸入負(fù)樣本。
2. 卡車上運(yùn)載著的多層passenger car,不想把這種passenger car召回,那么可以把這些原本是負(fù)樣本的納入ignore,因?yàn)檫@些負(fù)樣本顯然和正常的passenger car的正樣本特征存在一定矛盾。
3. 像bus這種,由于車身鏡像的作用,就把旁邊的vehicle照進(jìn)來(lái)。
2. 怎么定義哪些是正樣本/ignore/負(fù)樣本
常規(guī)使用的方法:
借助每個(gè)grid cell中人為設(shè)置的anchor,計(jì)算其與所有g(shù)t(ground truth)的iou,通過(guò)iou的信息來(lái)判定每個(gè)grid cell屬于positive/ignore/negative哪種。
以當(dāng)前gt為中心的一定范圍內(nèi),去判定每個(gè)grid cell屬于哪種樣本。
在具體的自動(dòng)駕駛量產(chǎn)項(xiàng)目中,往往會(huì)根據(jù)實(shí)際需求,比如對(duì)precision和recall的要求,在與gt匹配的邏輯中,會(huì)從類別、大小等角度去考慮,另外還會(huì)考慮特殊標(biāo)記的gt框(hard、dontcare)。
有以下幾個(gè)原則:
數(shù)量少的類別A,為其盡可能匹配適當(dāng)多一點(diǎn)的anchor,數(shù)量多的類別B,為其匹配少量且高質(zhì)量的anchor。這樣做目的是提高A的recall,提高B的precision,保證每個(gè)batch中,各類別間生成的正樣本數(shù)量趨于1:1
為小目標(biāo)匹配高質(zhì)量的anchor,忽略其周圍低質(zhì)量的anchor。這樣做是為了減少小目標(biāo)的誤檢,可能在一定程度上犧牲了召回。
對(duì)于中大目標(biāo),就要考慮具體那個(gè)類別的數(shù)量了,數(shù)量少的類別匹配多一點(diǎn),數(shù)量多就少匹配。
對(duì)于特殊標(biāo)記的gt框,如hard、dontcare, 如果一些負(fù)樣本和這些hard、dontcare強(qiáng)相關(guān),那么把這些負(fù)樣本變成ignore,避免讓樣本間產(chǎn)生歧義。
正負(fù)樣本的定義過(guò)程是一個(gè)迭代的過(guò)程,會(huì)根據(jù)模型的實(shí)際訓(xùn)練過(guò)程以及測(cè)試效果來(lái)動(dòng)態(tài)調(diào)整, 比如模型對(duì)某個(gè)類recall偏低,那么此時(shí)我們就要增加該類生成正樣本的數(shù)量了。
定義的過(guò)程就是將正負(fù)樣本嚴(yán)格區(qū)分開,為后續(xù)的采樣提供方便。 如下圖,將從正樣本過(guò)渡到負(fù)樣本的這些樣本歸入ignore。
注意:ignore樣本的區(qū)間不能太大,存在一個(gè)上限。如果太大,模型在推理階段會(huì)存在一定的隨機(jī)性。
3. 采樣哪些正負(fù)樣本參與訓(xùn)練
個(gè)人認(rèn)為:該部分是訓(xùn)練檢測(cè)模型最為核心的部分,直接決定模型最后的性能。理解正負(fù)樣本的訓(xùn)練,實(shí)質(zhì)是理解正負(fù)樣本的變化是如何影響precision和recall的。
我們先考慮3個(gè)基本問題,對(duì)于某個(gè)類別gt:
假設(shè)我們希望precision=1,不考慮recall,那么屬于該gt的并且參與訓(xùn)練的正負(fù)樣本理想情況會(huì)是什么樣的?
正樣本:數(shù)量適當(dāng),并且質(zhì)量要極高。(因?yàn)椴豢紤]recall,那正樣本的選取我只要選擇那些極高質(zhì)量的正樣本參與訓(xùn)練就可以了,推理的時(shí)候就可以保證,模型一定認(rèn)為是前景的才輸出)
負(fù)樣本:多樣性越豐富越好,數(shù)量越多越好(實(shí)際已經(jīng)滿足數(shù)量多的情況)。
2. 假設(shè)我們希望recall=1,不考慮precision呢?
正樣本:數(shù)量越多越好。(因?yàn)椴豢紤]precision,那我就把所有樣本當(dāng)正樣本訓(xùn)練就好了,推理的時(shí)候,不管是前景還是背景,通通都認(rèn)為是前景輸出,一定能保證recall=1)
負(fù)樣本:數(shù)量為0最好。
3. 現(xiàn)在我們希望precision=1, recall=1呢?
正樣本:數(shù)量越多越好,并且質(zhì)量越高越好。(因?yàn)榭紤]到recall=1,也就是要讓模型盡可能的把所有前景目標(biāo)都召回出來(lái),那么越多且質(zhì)量越高的正樣本就越好)
負(fù)樣本:多樣性越豐富越好,并且數(shù)量越多越好。
從以上3個(gè)問題分析得到,對(duì)于某個(gè)類別的gt,屬于該gt的正樣本中,數(shù)量和質(zhì)量是矛盾的。數(shù)量越多,那么質(zhì)量必然下降,recall會(huì)偏高,precision會(huì)偏低。反之,數(shù)量越少,質(zhì)量會(huì)高,但是recall會(huì)偏低,precision會(huì)偏高。對(duì)于負(fù)樣本來(lái)說(shuō),要求它數(shù)量越多,并且多樣性越豐富,這并不矛盾,實(shí)際是可以做到這點(diǎn)。
有人會(huì)問,不看mAP嗎?
mAP是綜合衡量了recall從0到1變化的過(guò)程中(實(shí)際recall達(dá)不到1),precision的變化曲線,mAP并不直觀,實(shí)際把mAP當(dāng)做其中一個(gè)衡量指標(biāo)而已。
所以,我們采樣的目標(biāo)就是:
正樣本:質(zhì)量高,數(shù)量適當(dāng)
負(fù)樣本:多樣性越豐富,數(shù)量適當(dāng)(或者說(shuō)是正樣本數(shù)量的n倍,n一般取值[3,10])
一般情況下,定義的那些正樣本都會(huì)采樣參與訓(xùn)練,負(fù)樣本就隨機(jī)采樣一些去訓(xùn)練。但在訓(xùn)練的過(guò)程中你需要考慮幾點(diǎn):
1. 定義的那些正樣本,模型真的都能搞定嗎?
在量產(chǎn)級(jí)的數(shù)據(jù)集中,往往會(huì)有百千萬(wàn)量級(jí)的目標(biāo),雖然在定義正樣本的時(shí)候考慮到了很多因素,但是面對(duì)百千萬(wàn)量級(jí)的目標(biāo),往往會(huì)存在一定比例的正樣本,模型壓根就學(xué)不會(huì),訓(xùn)練后期模型loss就在一個(gè)小區(qū)間里震蕩, 所以我們就要對(duì)這些樣本做進(jìn)一步處理,把其歸為ignore,減少他們對(duì)模型訓(xùn)練的影響。
對(duì)于FN(漏檢),我們就要根據(jù)具體的需求分析這些FN到底是否需要檢出,如果需要檢出,就需要調(diào)整定義這些FN的正樣本的匹配邏輯,讓其產(chǎn)生適合訓(xùn)練的正樣本。
2. 面對(duì)數(shù)量眾多的負(fù)樣本,怎么針對(duì)性的采樣(適應(yīng)自己的項(xiàng)目)。
其實(shí)在項(xiàng)目前期,負(fù)樣本的采樣可以選擇隨機(jī),但當(dāng)你進(jìn)行大量路采數(shù)據(jù)測(cè)試后,總結(jié)發(fā)現(xiàn)模型輸出的FP,比如,發(fā)現(xiàn)模型輸出大框背景的頻次偏高,那么這個(gè)時(shí)候我們就要改變隨機(jī)采樣負(fù)樣本的策略,就要針對(duì)性的增加小分辨率feature map上的負(fù)樣本的采樣。如果模型經(jīng)常把特定背景(樹尖,房屋)檢測(cè)為目標(biāo),那么我們需要1. 檢查gt的標(biāo)注質(zhì)量。2. 想辦法采樣到這類的負(fù)樣本參與訓(xùn)練。
3. 盡可能保證每個(gè)batch中,類別間采樣的正樣本比例接近1:1。
在量產(chǎn)級(jí)數(shù)據(jù)中,因?yàn)槭菍?shí)車采集,往往會(huì)出現(xiàn)類別不均衡現(xiàn)象,隨著數(shù)據(jù)量的不斷增加,這種不均衡會(huì)被嚴(yán)重放大,如果直接采樣全部正樣本采樣訓(xùn)練,模型很可能出現(xiàn)precision和recall偏向類別多的那個(gè)類,比如類A,這個(gè)時(shí)候就需要考慮適當(dāng)降低類A的采樣,同時(shí)考慮適當(dāng)增加類B類C的采樣訓(xùn)練,來(lái)達(dá)成類別間正樣本的比例接近1:1。
所以,正負(fù)樣本的采樣是根據(jù)當(dāng)前模型的檢測(cè)效果來(lái)動(dòng)態(tài)改變優(yōu)化的,但是不管怎么改變,對(duì)正負(fù)樣本的采樣不會(huì)偏離理想狀態(tài)的,只不過(guò)離理想狀態(tài)的距離由自己手頭的數(shù)據(jù)集標(biāo)注質(zhì)量決定。
當(dāng)然,如果你的數(shù)據(jù)集足夠干凈,定義的那些正負(fù)樣本也接近理想狀態(tài),那么就可以讓模型通過(guò)OHEM之類的方式,根據(jù)模型當(dāng)前狀態(tài)來(lái)自動(dòng)選取參與訓(xùn)練的正負(fù)樣本。
如有錯(cuò)誤,請(qǐng)指正。