mmdetection最小復刻版(七):anchor-base和anchor-free差異分析
AI編輯:深度眸
0 摘要
論文題目:Bridging the Gap Between Anchor-based and Anchor-free Detection via Adaptive Training Sample Selection
論文地址:https://arxiv.org/abs/1912.02424
ATSS簡單來說就是
(1) 對於anchor-free典型算法FCOS,希望消除回歸范圍regress_ranges和中心擴展比例參數center_sample_radius這兩個核心超參,使其在anchor-free領域變成真正的自適應算法
(2) 對於anchor-base經典算法retinanet,希望借鑒fcos的正負樣本分配策略思想來彌補和fcos的性能差異,同時也能夠自適應,無須設置正負樣本閾值
從此anchor-base和anchor-free都不需要調核心參數,豈不美滋滋!
不僅如此,本文還通過實驗回答了一個問題:anchor-base和anchor-free算法的核心差異是啥?是啥原因導致兩者性能差異?結論就是:正負樣本定義規則的不同導致性能差異。
本文通俗易懂,正如本文標題Bridging the Gap所示,為了清楚理解anchor-base和anchor-free特點,本文是非常值得分析的一篇目標檢測算法。
貼一下框架github地址:
https://github.com/hhaAndroid/mmdetection-mini
歡迎star
1 anchor-base和anchor-free本質差別
為了說明這個問題,作者結合retinanet和fcos算法並采用了非常公平的一系列對比實驗進行論證。
兩個算法其余參數都是相同的,除了表格中的。首先FCOS在開所有訓練trick時候mAP是37.8,為了公平比較retinanet設置anchor個數為1,anchor比例是正方形,可以發現當采用相同trick后,mAP是37.0,大概差了1個點,差距蠻大的。
排除上述trick因素后,現在兩個算法的區別是1.正負樣本定義;2.回歸分支中從point回歸還是從anchor回歸。其中從point回歸就是指的每個點預測距離4條邊的距離模式,而從anchor回歸是指的retinanet那種基於anchor回歸的模式。
結果如下表所示:
首先看行方向,可以發現不管是采用point還是box回歸模式,mAP都是非常接近的,說明回歸分支中從point回歸還是從anchor回歸對結果影響很小。再看列方向,可以發現差別就在於在定義正負樣本的時候采用的策略不一樣,一個是基於iou准則,一個是基於空間scale約束,而且很明顯可以看出,fcos的正負樣本定義策略比retinanet的max iou策略好的多。
到目前為止,我們可以知道:anchor-base和anchor-free的性能差異本質區別在於正負樣本定義不同。那么其不同具體在哪里?
對於1和2兩個輸出預測層,retinanet采用統一閾值iou,可以確定上圖藍色1位置是正樣本,而對於fcos來說,有2個藍色1,其表明fcos的定義方式會產生更多的正樣本區域,這種細微差距就會導致retinanet的性能比fcos低一些。關於fcos和retinanet的正負樣本定義規則請參考以前微信公眾號文章。
2 ATSS算法
前面我們已經知道了正負樣本定義對最終性能影響很大,很明顯fcos的正負樣本定義規則優於retinanet,但是我們在前文說過fcos的定義規則存在兩個超參:多尺度輸出回歸范圍regress_ranges用於限制每一層回歸的數值范圍;中心擴展因子center_sample_radius用於計算每個輸出層哪些位置屬於正樣本區域。這兩個超參在不同的數據集上面可能要重新調整,而且不一定好設置。而本文ATSS就希望消除這兩個超參,達到自適應的功能。
其定義規則也比較簡單,通俗易懂,流程為:
需要注意由於依然需要計算iou,故anchor設置不能少,只不過anchor僅僅用於計算正負樣本區域而已(對於fcos來說是這樣,但是對於retinanet來說,anchor設置必不可少),在計算loss時候可以是anchor-free中特征圖上點距離4條邊的距離或者是anchor-base中基於anchor的變換回歸,anchor默認設置為1。主要是理解思想:
-
計算每個gt bbox和多尺度輸出層的所有anchor的iou
-
計算每個gt bbox中心和多尺度輸出層的所有anchor中心的l2距離
-
對於任何一個輸出層,遍歷每個gt,找出topk(默認是9)個最小l2距離的anchor點。假設一共有l個輸出層,那么對於任何一個gt bbox,都會挑選出topk×l個候選位置
-
對於每個gt bbox,計算所有后續位置iou的均值和標准差,兩者相加得到該gt bbox的獨特閾值
-
對於每個gt bbox,選擇出候選位置中iou大於閾值的位置,該位置認為是正樣本,負責預測該gt bbox
-
如果topk參數設置過大,可能會導致某些正樣本位置不在gt bbox內部,故需要過濾掉這部分正樣本,設置為背景樣本
他是如何做到自適應的呢?原因是均值(所有層的候選樣本算出一個均值)代表了anchor對gt衡量的普遍合適度,其值越高,代表候選樣本質量普遍越高,iou也就越大,而標准差代表哪一層適合預測該gt bbox,標准差越大越能區分層和層之間的anchor質量差異。均值和標准差相加就能夠很好的反應出哪一層的哪些anchor適合作為正樣本。一個好的anchor設計,應該是滿足高均值、高標准差的設定。
如上圖所示,(a)的閾值計算出來是0.612,采用該閾值就可以得到level3上面的才是正樣本,是高均值高方差的。同樣的如果anchor設置和gt不太匹配,計算出來的閾值為0.219,依然可以選擇出最合適的正樣本區域,雖然其屬於低均值、低方差的。采用自適應策略依然可以得到相對好的正負樣本,至少可以保證每個GT一定有至少一個anchor負責對應。
從上表可以看出,ATSS美滋滋,而且ATSS就一個topk的超參,當然實驗表明參數設置不敏感(但是應該不能太小)。
3 正樣本區域可視化及其參數topk分析
使用方法非常簡單,在對應的train_cfg里面將debug標志設置為True即可,效果如下所示:
從0-4分別代表stride從小到大的預測層,分別負責從小到大物體的檢測。白色的gt bbox,紅色點是正樣本點,綠色是anchor size,對於fcos來說實際訓練時候是不需要的,這里僅僅是為了好看而已。看起來其自適應規則還是蠻不錯的,不僅正樣本數比較多,而且正樣本點都是在物體中心點附近。
在topk=9時候,隨機統計結果如下:
單張圖片中正樣本anchor個數 56
單張圖片中正樣本anchor個數 153
單張圖片中正樣本anchor個數 18
單張圖片中正樣本anchor個數 28
單張圖片中正樣本anchor個數 37
單張圖片中正樣本anchor個數 9
單張圖片中正樣本anchor個數 15
單張圖片中正樣本anchor個數 9
單張圖片中正樣本anchor個數 27
單張圖片中正樣本anchor個數 195
單張圖片中正樣本anchor個數 9
單張圖片中正樣本anchor個數 78
單張圖片中正樣本anchor個數 68
在topk=3時候,隨機統計結果如下:
單張圖片中正樣本anchor個數 6
單張圖片中正樣本anchor個數 90
單張圖片中正樣本anchor個數 12
單張圖片中正樣本anchor個數 3
單張圖片中正樣本anchor個數 22
單張圖片中正樣本anchor個數 8
單張圖片中正樣本anchor個數 13
單張圖片中正樣本anchor個數 9
單張圖片中正樣本anchor個數 6
單張圖片中正樣本anchor個數 21
單張圖片中正樣本anchor個數 53
單張圖片中正樣本anchor個數 35
相對正樣本數量會少很多。topk參數設置原則應該是在不要引入大量低質量回歸正樣本的前提下應該盡量提高該閾值。
4 代碼實現細節
4.1 訓練模式
前面說過atss自適應分配策略可以作用於anchor-base和anchor-free,在mmdet框架中復現的是retinanet模式,也就是說整個ATSS算法實現采用的是style='pytorch',retinanet訓練模式(注意fcos是caffe模式),此時anchor的設置就必不可少了(不僅要用於自適應計算正樣本,還需要用於變換預測),並且FPN層采用的是fcos中用的P5下采樣模式,而不是原始retinanet中的C5下采樣模式。
4.2 anchor設置
在retinanet算法中,為了在自適應統計正負樣本階段能夠計算iou,需要設置anchor,並且參與訓練,配置如下所示:
anchor_generator=dict(
type='AnchorGenerator',
ratios=[1.0],
octave_base_scale=8,
scales_per_octave=1,
strides=[8, 16, 32, 64, 128]),
意思是每個特征圖僅僅設置一個尺度的anchor,且anchor大小是strides * octave_base_scale,從上面的可視化分析圖中也可以看出。
4.3 centerness分支
該分支和fcos一樣,也是掛在bbox回歸分支,其余設置和fcos完全相同即分類分支是focal loss;回歸分支是giou loss;centerness分支是bce loss。
bbox回歸分支的target是anchor和gt bbox的變換值,如下所示:
bbox_coder=dict(
type='DeltaXYWHBBoxCoder',
target_means=[.0, .0, .0, .0],
target_stds=[0.1, 0.1, 0.2, 0.2]),
如果是fcos模式,那么bbox回歸分支的target應該是特征圖上面點距離4條邊的距離。
再次貼一下框架github地址:
https://github.com/hhaAndroid/mmdetection-mini
歡迎star
推薦閱讀