論文閱讀:End-to-End Object Detection with Transformers(DETR)
DETR 是 Detection Transformer的縮寫, 是Facebook 提出的主要用於目標檢測領域的新模型,
Facebook AI 的研究者把 Transformer 用到了目標檢測任務中,還取得了媲美 Faster R-CNN 的效果。該研究推出的 Transformer 視覺版本——Detection Transformer(DETR),可用於目標檢測和全景分割。與之前的目標檢測相比,DETR 的架構有了根本上的改變,也是第一個將 Transformer 成功整合為檢測 pipeline 中心構建塊的目標檢測框架。基於 Transformer 的端到端目標檢測,沒有 NMS 后處理步驟、真正的沒有 anchor,且對標超越 Faster R-CNN, 這里大膽推測一下基於 Transformer 結構的目標檢測模型和語義分割會越來越多。
論文下載:https://arxiv.org/abs/2005.12872
代碼地址:https://github.com/facebookresearch/detr
簡介
DETR,即DEtection TRansformer,將目標檢測任務轉化成序列預測任務,使用transformer編碼器-解碼器結構和雙邊匹配的方法,由輸入圖像直接預測得到預測結果序列,整個過程就是使用CNN提取特征后編碼解碼得到預測輸出。基於Transformers的端到端目標檢測,沒有NMS后處理步驟、真正的沒有anchor,DETR達到了與Faster RCNN基線相當的准確性和運行時間性能。
主要貢獻:
- 使用標准的前向網絡(代碼中使用的Resnet網絡)特征的處理和結果 加上Transformer 結構,再配合 postion encoding以及 object queries 不需要 anchor 直接得到了 box 坐標和類別。
- 使用了bipartite matching loss (匈牙利排序算法),為每一個預測框唯一地分配一個gt框, 將GT和模型預測直接對應,不需要NMS直接做的Set prediction
- 在transformer中使用了parallel decoding
- 直接開啟了 transformer 在圖像分類和目標檢測領域的全新領域
然而它也有兩個明顯的缺點:
- 難以檢測小物體
- 由於使用了transformer,訓練時間很長
模型整體結構
論文中模型結構
DETR 使用常規的 CNN 主干來學習輸入圖像的 2D 表示。模型將其展平並傳遞到 transformer 編碼器之前進行位置編碼補充。然后,transformer 解碼器將少量固定數量的位置嵌入作為輸入,稱為目標查詢,並另外參與編碼器的輸出。將解碼器的每個輸出嵌入傳遞到預測檢測(類和邊界框)或無目標類的共享前饋網絡(FFN)。
主干網絡
- backbone(CNN-Resnet)
- transformer
- positional(位置信息)
- encoder
- decoder
- predicttion head
backbone
首先將圖片(3,H,W)
輸入到由CNN網絡構成的backbone,得到特征圖 feature map, shape=(C,H/32,W/32) 論文中 C=2048
然后將該feature map輸入到一個1∗1卷積,輸出(embed_dim,H/32,W/32),論文中embed_dim=256。由於transformer的encoder希望的輸入是一個序列,因此將feature map的reshape成(embed_dim,H/32,W/32),還需要 特征和位置編碼 結合起來,為了體現圖像在x和y維度上的信息,作者的代碼里分別計算了兩個維度的Positional Encoding 然后Cat到一起。然后,將CNN骨干網的輸出轉換為一維特征圖,並將其作為輸入傳遞到Transformer編碼器。該編碼器的輸出是N個固定長度的嵌入(向量),其中N是模型假設的圖像中的對象數。
Transformer
先用 1 × 1 卷積將輸入降至較小的維度d, d=256,得到新特征圖 ,再將新的特征圖 空間維度折疊成1維,轉換為 (d,WH) 的序列化輸入。DETR包含多個encoder,每個encoder都為標准結構,包含mullti-head self-attention模塊和前向網絡FFN。由於transformer是排序不變的,為每個attention層補充一個固定的位置encoding輸入。
decoder也是transformer的標准結構,使用multi-head self-attention模塊和encoder-decoder注意力機制輸出 N 個大小為 d,d=256 的embedding,唯一不同的是DETR並行地decode N個目標,不需要自回歸的機制,此外 decoder將 N 個object queries轉換為 N 個輸出embedding,然后獨立地解碼成box坐標和class標簽,得到 N 個最終的預測結構
FFNs
這里有兩個FFNs, 分類采用了一層的感知機,而預測采用帶ReLU激活的3層感知機以及線性映射層來解碼得到最終的預測結果,
FFN預測 N個 歸一化的中心坐標、高度、寬度以及softmax后的類別得分,由於 N一般大於目標個數,所以使用特殊的類別 ∅ 來標記無預測目標,類似於背景類。需要注意,最后用於輸出的FFN與encoder和decoder里的FFN是不一樣的.
檢測和損失函數
DETR的一個loss計算是一個主要的創新點
分類輸出的通道為num_classes+1,類別從0開始,背景類別為num_classes。
基於CNN的方法會計算每個anchor的預測結果,然后利用預測結果和ground truth box之間計算iou,挑選iou大於一定閾值的那些anchors作為正樣本,來回歸它們的class和box deltas。類似的,DETR也會計算每個object query的prediction,但DETR會直接計算box的四個角的歸一化值,而不再基於box deltas。為了移除anchor,作者將預測框和gt框直接進行匹配。首先,作者設置了一個N,遠大於圖片的GT框數量,代表預測框的數量(也就是代碼中的num_query)。然后將這N個預測框與gt框一對一進行匹配,
如何和gt bbox計算loss?這就需要用到經典的雙邊匹配算法了,也就是常說的匈牙利算法,該算法廣泛應用於最優分配問題,在bottom-up人體姿態估計算法中進行分組操作時候也經常使用。detr中利用匈牙利算法先進行最優一對一匹配得到匹配索引,然后對bx100個結果進行重排就和gt bbox對應上了(對gt bbox進行重排也可以,沒啥區別),就可以算loss了。
匈牙利算法是一個標准優化算法,具體是組合優化算法,在scipy.optimize.linear_sum_assignmen函數中有實現,一行代碼就可以得到最優匹配,網上解讀也非常多,這里就不寫細節了,該函數核心是需要輸入A集合和B集合兩兩元素之間的連接權重,基於該重要性進行內部最優匹配,連接權重大的優先匹配。
優化對象是 ,其是長度為N的list,
,
表示無序gt bbox集合的哪個元素和輸出預測集合中的第i個匹配。其實簡單來說就是找到最優匹配,因為在最佳匹配情況下l_match和最小即loss最小。
前面說過匈牙利算法核心是需要提供輸入A集合和B集合兩兩元素之間的連接權重,這里就是要輸入N個輸出集合和M個gt bbox之間的關聯程度,如下所示
模型效果
參考文獻:
https://www.cnblogs.com/Glucklichste/p/14057005.html
https://www.cnblogs.com/SpicyWonton/p/15310929.html
https://blog.csdn.net/zjuPeco/article/details/107209584?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522163296639116780264098848%2522%252C%2522scm%2522%253A%252220140713.130102334..%2522%257D&request_id=163296639116780264098848&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~top_click~default-2-107209584.first_rank_v2_pc_rank_v29&utm_term=DETR&spm=1018.2226.3001.4187