簡單讀了一下新鮮出爐的代碼,也和 DETR 的實現做了一下對比。Backbone、 Matcher 和 positional encoding 的實現和 DETR是一樣的,主要的修改在 deformable_detr.py 和 deformable_transformer.py 中,所以基本沒有藏 trick 大家不用擔心 (復現起來應該也會輕鬆一些)。真正有效的應該主要在於 multi-scale deformable attention,畢竟 multi-scale / pyramid representation, deformable 和 attention 本身就是 CV 里最 work 的幾類 idea,單獨拎出其中一個都可以做好多篇 paper,何況這篇 paper 把這些東西都攢一塊了,還在 Table 2 里都驗證清楚了每個部分的 gain,可以說是很良心了有木有~

當然,由於 paper 的篇幅,paper 中有幾個小細節其實大家有空還可以再 study 一下。比如,DETR 中是直接回歸的 bounding box 絕對坐標,不依賴任何先驗,但是 Deformable DETR 引入了 reference,回歸的是基於 point 坐標的 offset,這個細節的處理應該也是會讓模型更好學的。還有就是 head 的部分調整了初始化策略,應該對訓練也有幫助。再加上 K=1 的情況本身就相當於在 head 里引入了 Deformable Convolution (paper 里也解釋了 Deformable Attention 退化為 Deformable Conv 的情況,所以 baseline 上來就比 DETR 高了很多也不足為奇(就是嚇到寶寶了)。

最後打個廣告,MMDetection 目前已經復現了 DETR,在150 epoch的情況下 bbox mAP 達到 40.1, 比 DETR 官方 report 的 performance 高了 0.5 (我們也還沒弄明白為啥就高了 0.5 個點…)所以歡迎感興趣的小夥伴參與進來一起搞明白。當然,我們在明年也會復現 Deformable DETR,有志同道合的小夥伴也可以一起參與復現吶


Deformable DETR 真的很驚艷,之前都覺得 DETR converge 慢是匈牙利匹配演算法的問題,結果 Deformable DETR 告訴我們,真正問題還是模型的表達能力。

這個 Deformable Attention module 在嚴格意義上講不能叫 Transformer 或者 self-attention,因為 Attention weight 不再基於 query 和 key 的 pairwise 對比,而是只依賴於 query,這種形式有點兒像 WeightNet 的思想,就是卷積核取決於輸入。

Transformer/Non-local/Self-Attention 引入到 CV 裡面是對 CNN 網路結構的一種補充,比如 relation network 可以讓不同的 ROI feature 聯繫起來。傳統 CNN 是空間連接相對固定的表達方式,比如卷積只對周圍固定的位置進行加權求和,雖然 pooling 可以整合不同位置的信息,但是 pooling 抹去了相對位置的信息,而且空間連接同樣固定。在 STN 把空間位置可微後,出現了 Deformable Convolution,讓空間連接更靈活了。Deformable DETR 更是指出 vision 中的 Transformer 就是在學這種空間連接,但是因為從 dense 連接中學到比較 sparse 的重要信息比較難(而且 softmax 的 gradient小),所以乾脆直接把這種連接定義成 sparse 的,也就是說 key 不是全部 feature,而是 query 周圍的一些點(learnable)。

感覺文章在告訴我們兩個大趨勢,1. 讓網路權重更靈活(隨著輸入變化),2. 讓空間連接更靈活(同樣依賴於輸入)。上面提到的很多文章中,都出現了一個名字 @Jifeng Dai,膜拜一下大神


Deformable DETR主要是將之前DETR直接使用特徵圖進行訓練變為注意力之後的特徵圖。將之前DETR花費時間學習到的Sparse Att map快速得到。

無意義內容分割線


可變性att部分:

可變形注意力Query部分是特徵圖線性投影后的結果,元是特徵圖直接預測offset(2*核元素數),權重(核元素數,後面過Softmax歸一化)。Key則是原始特徵圖。對於每個PIXEL預測周圍PIXEL特徵之和。相對可變形卷積可以認為是卷積Kernel的參數按位置變化了。

多尺度可變形att:

加入了多層尺度att,也就是考慮不同尺度,因為meshgrid歸一化了,坐標其實通用。

可變形TransformerEncoder部分:

用上述多尺度可變形att代替DETR transformer att部分(3尺度,不帶FPN,多尺度可變形att自帶融合多尺度加成)。加入可學習尺度嵌入和固定的位置嵌入。

可變形TransformerDecoder部分:

cross-att使用多尺度可變att,self-att保持。 預想參考點是目標中心,然後Decoder俺中心信息去預測box類別。

補充優化:迭代bbox結果優化和兩級預測。

預測部分是用了K為4 M為8。也就是單個尺度的採樣其實很少,也是為了省空間。往可解釋性上說,感覺上多層ATT其實是在某個目標周圍多次採樣(試探),然後確認是不是在目標中心,同時邊界大概在哪。多次試探後確認,高尺度決定個大概後,低尺度精細化?感覺這個Offset多次猜?

實現倒是簡單,這是一個M=1情況下的可變形Att的實現。如 @立夏之光 所說,K=1就是個Warp,如果要保證稀疏,所有目標區域都要往Reference Point集中?如果作者能給最後激活圖看看也許更好。

class DFMAtt(nn.Module):
def __init__(self, in_ch,out_ch, k):
super().__init__()
self.conv = nn.Conv2d(in_ch, out_ch, 1, 1, 0,bias=True)
self.k=k
self.out_ch=out_ch
offset_list=[]
for x in range(k):
conv = nn.Conv2d(in_ch, 2, 1, 1, 0,bias=True)
offset_list.append(conv)
self.offset_conv=nn.ModuleList(offset_list)
self.weight_conv= nn.Sequential(nn.Conv2d(in_ch, k, 1, 1, 0,bias=True),nn.Softmax(1))

def forward(self,input):
b, c, h, w = input.size()
proj_feat=self.conv(input)
offsets=[]
for x in range(self.k):
flow = self.offset_conv[x](input)
offsets.append(flow)
offsetweights= torch.repeat_interleave(self.weight_conv(input),self.out_ch,1)
feats=[]
for x in range(self.k):
flow=offsets[x]
flow = flow.permute(0, 2, 3, 1)
grid_y, grid_x = torch.meshgrid(torch.arange(0, h), torch.arange(0, w))
grid = torch.stack((grid_x, grid_y), 2).float()
grid.requires_grad = False
grid = grid.type_as(proj_feat)
vgrid = grid + flow
vgrid_x = 2.0 * vgrid[:, :, :, 0] / max(w - 1, 1) - 1.0
vgrid_y = 2.0 * vgrid[:, :, :, 1] / max(h - 1, 1) - 1.0
vgrid_scaled = torch.stack((vgrid_x, vgrid_y), dim=3)
feat = F.grid_sample(proj_feat, vgrid_scaled, mode=bilinear, padding_mode=zeros)
feats.append(feat)
feat=torch.cat(feats,1)*offsetweights
feat= sum(torch.split(feat,self.out_ch,1))
return feat


手碼搶答。

開啟了人人(並不)都可以玩得起 DETR 的時代,contribution 自然是相當大。如果 DETR 能引領一個大發展,那麼本文之於 DETR,應該相當於 ResNet 之於 AlexNet。

和 @余昌黔 大佬的 Representative Graph Neural Network 在思路上有很強的一致性。都是對全連接 Transformer 的計算量進行優化,為每個 query 採樣 K 個 key-value pair。考慮到 feature map 上的冗餘,採樣點能夠很好的概括關鍵信息。不過私以為最大的性能收益,來源於這一方法可以自然地引入多尺度特徵。

個人也有個疑問之處,Table 2的第三行已經可以吊打 DETR(Table 1第四五行)。這裡 K=1 時,方法退化為 @大大拉頭 Semantic flow 里的 warping 操作。跟據經驗,這個操作無法取得如此大的增益。希望作者們能來介紹下,實現還做了哪些改進吶。沒有 MS input 的情況下,是用了 DC5 嗎?

最近 CV 領域 transformer 相關文章頻出,很多人評論 NLP 對 CV 輸出。這點是不太贊同的。君不見 CV 領域 attention 文章頻出,甚至被視為划水(???)。NLP 里 Sparse Transformer, LinFormer 讚譽一片。但其實 CV 領域早就屢見不鮮。這裡可以參見我寫過的知乎文章和回答。Transformer 就是 Attention 的一種。捧 Transformer 損 Attention,是本領域最大的烏龍了


先引用一下之前關於DETR的分析吧

王Sr:如何看待End-to-End Object Detection with Transformers??

www.zhihu.com圖標

我們可以認為之前的單/多階段演算法、anchor based/free的方法都是local的方法,detr算是完全global的方法,而本文算是重新將detr拉回到了local的思路上,也藉此加快了收斂速度。

接下來再對本文做個拆解:

首先本文提出將原始detr的encoder部分換成deformable attention module,這個過程可以理解成是sparse transformer,當然也可以單純理解成是基於deformable+self attention的fpn的改進(當然這種操作似乎之前也見過,segmentation里的semantic flow,還有VID領域LSTS)

decoder部分iterative bbox refinement和two stage的思路看起來就很像是relationnet,本文沒有引用這篇還是有些奇怪

而經過了上面這兩點的修改,其實本文和detr的相似度就低了很多,甚至完全可以看做是之前純local的方式的改進,區別就在於query(之前的local的方法中anchor也可以理解成是一種query)和損失函數的設置。

從這個角度說,其實會引出一個更值得探討的問題: 檢測任務我們究竟需要怎樣的query?究竟多少query足夠很好的完成檢測任務?(detr中只有100個,而之前的方法動輒需要幾千個anchor)。這個問題如果可以得到很好的解決,目標檢測領域可能會迎來真正的革新。


推薦閱讀:
相关文章