概述
DETR使用了目前很火的transformer實現了目標檢測,同時也是一個真正意義上的anchor-free模型(不像FCOS,用錨點代替錨框)。DETR主要有以下兩個特點:
- 使用了bipartite matching loss,為每一個預測框唯一地分配一個gt框
- 在transformer中使用了parallel decoding
然而它也有兩個明顯的缺點:
- 難以檢測小物體
- 由於使用了transformer,訓練時間很長
模型結構
DETR的模型結構如圖1所示:
首先將圖片\((3, H, W)\)輸入到由CNN網絡構成的backbone,得到feature map\((C, \frac{H}{32}, \frac{W}{32})\),論文中\(C = 2048\),然后將該feature map輸入到一個\(1*1\)卷積,輸出\((embed\_dim, \frac{H}{32}, \frac{W}{32})\),論文中\(embed\_dim = 256\)。由於transformer的encoder希望的輸入是一個序列,因此將feature map的reshape成\((embed\_dim, \frac{H}{32}\frac{W}{32})\),最后由於transformer無法檢測位置信息,還需要將reshape之后的feature map與位置編碼加起來,輸入到encoder中。decoder的輸入稱為"object queries",這相當於是一個可以學習的位置編碼,作用相當於teacher forcing。decoder的結構和原始的transformer一樣,先是對"object queries"進行self attention,然后將輸出作為attention的query,encoder的輸出作為attention的key和value,得到attention的輸出。再將該輸出輸入到FFN中,得到decoder一個layer的輸出。最后再將decoder的輸出分別輸入到全連接和FFN中,分別預測類別和位置。考慮一個batch的輸出,最后輸出的shape為:\((num\_decoder\_layers, batch\_size, num\_query, 81)\)和\((num\_decoder\_layers, batch\_size, num\_query, 4)\),其中\(num\_query\)是每張圖片的預測框數量,大於圖中gt框的數量(該shape參考的是mmdetection的代碼,官方代碼可能不一樣)。
計算loss
DETR的一個loss計算是一個主要的創新點,為了移除anchor,作者將預測框和gt框直接進行匹配。首先,作者設置了一個N,遠大於圖片的gt框數量,代表預測框的數量(也就是代碼中的\(num\_query\)),然后將這N個預測框與gt框一對一進行匹配,由於是一對一匹配,而gt框的數量遠小於N,因此需要將gt框集合大小擴充到N,擴充的都是\(\emptyset\),表示背景。然后需要找到一個匹配,使得匹配的cost最小,cost計算方式如圖2所示:
式子左邊代表的是預測類別的cost,右邊代表的是預測偏移的cost。其中
是指示函數,表示只考慮預測框不是背景的情況。其中
代表的是第i個預測框預測類別為\(c_i\)的概率,\(\sigma\)表示的是一個匹配排列方式,我們的目的就是要找到一個使得cost的最小的匹配排列方式\(\hat{\sigma}\)。需要注意的是,式子左邊有一個負號,因為對於一個預測框最優的gt框是預測概率最大的,我們要使cost最小,就需要取相反數。式子右邊的\(L_{box}\)的公式如圖3所示:
\(L_{box}\)由兩部分組成,左半部分是IoU loss,右半部分是\(L_1\) loss。這是因為\(L_1\)loss對框的尺寸敏感,而IoU loss與尺寸無關,作者同時使用兩者就是為了平衡大物體與小物體對loss的影響程度。
上面的解釋可能不太清楚,下面結合代碼的實現流程,再簡要說明一下:
在mmdetection中,cost是用一個矩陣表示的,其維度為:\((num_query, num_gt)\),該cost是由三部分相加而成的,分別是:cls_cost,reg_cost和iou_cost,這三部分的維度也都是\((num_query,num_gt)\)。對於cls_cost,其表示分類的cost,其中\((i, j)\)位置的元素表示第\(i\)個預測框的類別是第\(j\)個gt框所屬類別的概率的相反數(為什么是相反數在上面解釋了);對於reg_cost,其表示\(L_1\) loss,其中\((i, j)\)位置的元素表示第\(i\)個預測框與第\(j\)個gt框的\(L_1\)距離,距離越小cost就越小;對於iou_cost,其表示IoU loss,其中\((i, j)\)位置的元素表示第\(i\)個預測框與第\(j\)個gt框的IoU大小的相反數。將這三個cost相加,就得到了最終的cost,然后使用匈牙利算法,就能找到每個預測框所對應cost最小的gt框,這就是匹配的全部過程。
將預測框與gt框進行匹配之后,就可以計算loss了,loss的公式如圖4所示:
其實這個公式和cost很相似,就只是給分類的loss加了一個log。對於預測為背景的預測框,分類損失的值會除以10,並且不參與\(L_{box}\)的計算。
最后再總結一下預測和計算loss的過程,首先輸入圖片,輸出預測。然后利用本次的預測值與gt框進行匹配,再利用匹配的結果計算loss,反向傳播更新參數。也就是說,每次迭代預測與gt框的匹配結果基本上都不一樣,這一點需要注意。
總結
DETR使用transformer作為目標檢測模型的head網絡,並在此基礎上直接將預測框與gt框進行匹配,是一個真正意義上的anchor-free模型。如果不使用transformer作為head網絡,直接像RetinaNet那樣用幾個簡單的卷積層作為head網絡,再使用預測框與gt框直接匹配,效果會如何呢?
