Date: 2020/07/19
Coder: CW
Foreword:
本文是該系列的最后一篇,解析的源碼內(nèi)容包括如何將模型輸出轉(zhuǎn)化為預(yù)測結(jié)果以及評估驗證過程,在該系列前面的文章中解析模型實現(xiàn)的源碼時,只涉及到DETR模型中backbone與Transformer的部分,但是DETR自身也是一個nn.Module,本文會先對這部分的實現(xiàn)進行解析,然后講解如何對DETR的輸出進行后處理生成預(yù)測結(jié)果。
原計劃對評估驗證部分的源碼也進行解析,但是發(fā)現(xiàn)其中內(nèi)容主要是調(diào)用coco api來實現(xiàn),因此就不對這部分內(nèi)容作解析了,感興趣的朋友們可參考源碼:?coco_eval.py。
Outline
I. DETR 模型
II. PostProcess 生成預(yù)測結(jié)果
DETR 模型
num_classes不包含背景,aux_loss代表是否要對Transformer中Decoder的每層輸出都計算loss。

class_embed生成分類的預(yù)測結(jié)果,最后一維對應(yīng)物體類別數(shù)量,并且加上背景這一類;bbox_embed生成回歸的預(yù)測結(jié)果,MLP就是多層感知機的縮寫,顧名思義,由多層nn.Linear()組成,根據(jù)下圖的參數(shù)所示,這里有3層線性層,中間每層的維度被映射到hidden_dim,最后一層維度映射為4,代表bbox的中心點橫、縱坐標(biāo)和寬、高。
input_proj是將CNN提取的特征維度映射到Transformer隱層的維度,轉(zhuǎn)化為序列;query_embed用于在Transformer中對初始化query以及對其編碼生成嵌入。

順便瞄下MLP的實現(xiàn)。注意在最后一層生成bbox的時不需要ReLU激活。

接下來是DETR的前向過程。輸入是一個NestedTensor類的對象,這個類的實現(xiàn)在該系列的第三篇文章?源碼解析目標(biāo)檢測的跨界之星DETR(三)、Backbone與位置編碼 中有講到。

前向過程可分解為兩部分,第一部分如下所示,先利用CNN提取特征,然后將特征圖映射為序列形式,最后輸入Transformer進行編、解碼得到輸出結(jié)果。

第二部分就是對輸出的維度進行轉(zhuǎn)化,與分類和回歸任務(wù)所要求的相對應(yīng)。

PostProcess 生成預(yù)測結(jié)果
上一部分DETR的輸出并不是最終預(yù)測結(jié)果的形式,還需要進行簡單的后處理。但是這里的后處理并不是NMS哦!DETR預(yù)測的是集合,并且在訓(xùn)練過程中經(jīng)過匈牙利算法與GT一對一匹配學(xué)習(xí),因此不存在重復(fù)框的情況。
如doc string所述,這個后處理指的是將DETR的輸出轉(zhuǎn)換為coco api對應(yīng)的格式。

以下需要關(guān)注的點有兩個,一個是由于coco api中的評估不包含背景類,于是這里在生成預(yù)測結(jié)果時直接排除了背景類;另一個是模型在回歸部分的輸出是歸一化的值,需要根據(jù)圖像尺寸來還原。

那么這里問題就來了,在測試的時候,預(yù)測結(jié)果就有num_queries(默認100)個,而圖片中實際的物體數(shù)量通常并沒有那么多,這時候該如何處理呢?
如傳統(tǒng)套路一致,我們可以對預(yù)測分數(shù)設(shè)置一個閥值,只有預(yù)測的置信度大于閥值的query objects,我們將其輸出顯示(畫出bbox),官方show給我們的notebook如下:

@結(jié)語
至此,DE?TR: End-to-End Object Detection with Transformers 源碼解析系列完結(jié)撒花~!

本人能力有限,如系列文章中出現(xiàn)不當(dāng)之處,還請各位指定,謝謝!
該系列其余平篇幅匯總?cè)缦拢?/p>
源碼解析目標(biāo)檢測的跨界之星DETR(一)、概述與模型推斷
源碼解析目標(biāo)檢測的跨界之星DETR(二)、模型訓(xùn)練過程與數(shù)據(jù)處理
源碼解析目標(biāo)檢測的跨界之星DETR(三)、Backbone與位置編碼