自從Transformer出來以后,Transformer便開始在NLP領域一統江湖。而Transformer在CV領域反響平平,一度認為不適合CV領域,直到最近計算機視覺領域出來幾篇Transformer文章,性能直逼CNN的SOTA,給予了計算機視覺領域新的想象空間。
本文不拘泥於Transformer原理和細節實現(知乎有很多優質的Transformer解析文章,感興趣的可以看看),着重於Transformer對計算機視覺領域的革新。
首先簡略回顧一下Transformer,然后介紹最近幾篇計算機視覺領域的Transformer文章,其中ViT用於圖像分類,DETR和Deformable DETR用於目標檢測。從這幾篇可以看出,Transformer在計算機視覺領域的范式已經初具雛形,可以大致概括為:Embedding -> Transformer -> Head
一些有趣的點寫在最后~~
Transformer
Transformer詳解
下面以機器翻譯為例子,簡略介紹Transformer結構。
1. Encoder-Decoder
Transformer結構可以表示為Encoder和Decoder兩個部分

Encoder和Decoder主要由Self-Attention和Feed-Forward Network兩個組件構成,Self-Attention由Scaled Dot-Product Attention和Multi-Head Attention兩個組件構成。
Scaled Dot-Product Attention公式:
Multi-Head Attention公式:
Feed-Forward Network公式:
2. Positional Encoding

如圖所示,由於機器翻譯任務跟輸入單詞的順序有關,Transformer在編碼輸入單詞的嵌入向量時引入了positional encoding,這樣Transformer就能夠區分出輸入單詞的位置了。
引入positional encoding的公式為:
是位置,
是維數,
是輸入單詞的嵌入向量維度。
3. Self-Attention
3.1 Scaled Dot-Product Attention

在Scaled Dot-Product Attention中,每個輸入單詞的嵌入向量分別通過3個矩陣,
和 來分別得到Query向量(
),Key向量(
)和Value向量(
)。

如圖所示,Scaled Dot-Product Attention的計算過程可以分成7個步驟:
- 每個輸入單詞轉化成嵌入向量。
- 根據嵌入向量得到
,
,
三個向量。
- 通過向量計算 : 。
- 對
,
進行歸一化,即除以
。
- 通過
激活函數計算
。
- 點乘Value值
,得到每個輸入向量的評分
。
- 所有輸入向量的評分
之和為
:
。
上述步驟的矩陣形式可以表示成:

與Scaled Dot-Product Attention公式一致。
3.2 Multi-Head Attention

如圖所示,Multi-Head Attention相當於h個不同Scaled Dot-Product Attention的集成,以h=8為例子,Multi-Head Attention步驟如下:
- 將數據
分別輸入到8個不同的Scaled Dot-Product Attention中,得到8個加權后的特征矩陣
。
- 將8個
按列拼成一個大的特征矩陣。
- 特征矩陣經過一層全連接得到輸出
。
Scaled Dot-Product Attention和Multi-Head Attention都加入了short-cut機制。
ViT
ViT將Transformer巧妙的應用於圖像分類任務,更少計算量下性能跟SOTA相當。

Vision Transformer(ViT)將輸入圖片拆分成16x16個patches,每個patch做一次線性變換降維同時嵌入位置信息,然后送入Transformer,避免了像素級attention的運算。類似BERT[class]標記位的設置,ViT在Transformer輸入序列前增加了一個額外可學習的[class]標記位,並且該位置的Transformer Encoder輸出作為圖像特征。
其中為原圖像分辨率,
為每個圖像patch的分辨率。
為Transformer輸入序列的長度。
ViT舍棄了CNN的歸納偏好問題,更加有利於在超大規模數據上學習知識,即大規模訓練優歸納偏好,在眾多圖像分類任務上直逼SOTA。
DETR
DETR使用set loss function作為監督信號來進行端到端訓練,然后同時預測所有目標,其中set loss function使用bipartite matching算法將pred目標和gt目標匹配起來。直接將目標檢測任務看成set prediction問題,使訓練過程變的簡潔,並且避免了anchor、NMS等復雜處理。
DETR主要有兩個部分:architecture和set prediction loss。
1. Architecture

DETR先用CNN將輸入圖像embedding成一個二維表征,然后將二維表征轉換成一維表征並結合positional encoding一起送入encoder,decoder將少量固定數量的已學習的object queries(可以理解為positional embeddings)和encoder的輸出作為輸入。最后將decoder得到的每個output embdding傳遞到一個共享的前饋網絡(FFN),該網絡可以預測一個檢測結果(包括類和邊框)或着“沒有目標”的類。
1.1 Transformer

1.1.1 Encoder
將Backbone輸出的feature map轉換成一維表征,得到 特征圖,然后結合positional encoding作為Encoder的輸入。每個Encoder都由Multi-Head Self-Attention和FFN組成。
和Transformer Encoder不同的是,因為Encoder具有位置不變性,DETR將positional encoding添加到每一個Multi-Head Self-Attention中,來保證目標檢測的位置敏感性。
1.1.2 Decoder
因為Decoder也具有位置不變性,Decoder的個object query(可以理解為學習不同object的positional embedding)必須是不同,以便產生不同的結果,並且同時把它們添加到每一個Multi-Head Attention中。
個object queries通過Decoder轉換成一個output embedding,然后output embedding通過FFN獨立解碼出
個預測結果,包含box和class。對輸入embedding同時使用Self-Attention和Encoder-Decoder Attention,模型可以利用目標的相互關系來進行全局推理。
和Transformer Decoder不同的是,DETR的每個Decoder並行輸出個對象,Transformer Decoder使用的是自回歸模型,串行輸出
個對象,每次只能預測一個輸出序列的一個元素。
1.1.3 FFN
FFN由3層perceptron和一層linear projection組成。FFN預測出box的歸一化中心坐標、長、寬和class。
DETR預測的是固定數量的個box的集合,並且
通常比實際目標數要大的多,所以使用一個額外的空類來表示預測得到的box不存在目標。
2. Set prediction loss
DETR模型訓練的主要困難是如何根據gt衡量預測結果(類別、位置、數量)。DETR提出的loss函數可以產生pred和gt的最優雙邊匹配(確定pred和gt的一對一關系),然后優化loss。
將 表示為gt的集合, 表示為
個預測結果的集合。假設
大於圖片目標數,
可以認為是用空類(無目標)填充的大小為
的集合。搜索兩個集合
個元素
的不同排列順序,使得loss盡可能的小的排列順序即為二分圖最大匹配(Bipartite Matching),公式如下:
其中表示pred和gt關於
元素
的匹配loss。其中二分圖匹配通過匈牙利算法(Hungarian algorithm)得到。
匹配loss同時考慮了pred class和pred box的准確性。每個gt的元素可以看成
,
表示class label(可能是空類)
表示gt box,將元素
二分圖匹配指定的pred class表示為
,pred box表示為
。
第一步先找到一對一匹配的pred和gt,第二步再計算hungarian loss。
hungarian loss公式如下:
其中 結合了L1 loss和generalized IoU loss,公式如下:
ViT和DETR兩篇文章的實驗和可視化分析很有啟發性,感興趣的可以仔細看看~~
Deformable DETR
從DETR看,還不足以趕上CNN,因為訓練時間太久了,Deformable DETR的出現,讓我對Transformer有了新的期待。
Deformable DETR將DETR中的attention替換成Deformable Attention,使DETR范式的檢測器更加高效,收斂速度加快10倍。

Deformable DETR提出的Deformable Attention可以可以緩解DETR的收斂速度慢和復雜度高的問題。同時結合了deformable convolution的稀疏空間采樣能力和transformer的關系建模能力。Deformable Attention可以考慮小的采樣位置集作為一個pre-filter突出所有feature map的關鍵特征,並且可以自然地擴展到融合多尺度特征,並且Multi-scale Deformable Attention本身就可以在多尺度特征圖之間進行交換信息,不需要FPN操作。
1. Deformable Attention Module
給定一個query元素(如輸出句子中的目標詞)和一組key元素(如輸入句子的源詞),Multi-Head Attention能夠根據query-key pairs的相關性自適應的聚合key的信息。為了讓模型關注來自不同表示子空間和不同位置的信息,對multi-head的信息進行加權聚合。其中表示query元素(特征表示為
),
表示key元素(特征表示為
),
是特征維度,
和
分別為
和
的集合。
那么Transformer 的 Multi-Head Attention公式表示為:
其中指定attention head,
和
是可學習參數,注意力權重
並且歸一化
,其中
是可學習參數。為了能夠分辨不同空間位置,
和
通常會引入positional embedding。
對於DETR中的Transformer Encoder,query和key元素都是feature map中的像素。
DETR 的 Multi-Head Attention 公式表示為:
其中。
DETR主要有兩個問題:需要更多的訓練時間來收斂,對小目標的檢測性能相對較差。本質上是因為Transfomer的Multi-Head Attention會對輸入圖片的所有空間位置進行計算。而Deformable DETR的Deformable Attention只關注參考點周圍的一小部分關鍵采樣點,為每個query分配少量固定數量的key,可以緩解收斂性和輸入分辨率受限制的問題。
給定一個輸入feature map ,表示為query元素(特征表示為),二維參考點表示為
,Deformable DETR 的 Deformable Attention公式表示為:
其中指定attention head,
指定采樣的key,
表示采樣key的總數(
)。
,
分別表示第
個采樣點在第
個attention head的采樣偏移量和注意力權重。注意力權重
在[0,1]的范圍內,歸一化
。
表示為無約束范圍的二維實數。因為
為分數,需要采用雙線性插值方法計算
。
2. Multi-scale Deformable Attention Module
Deformable Attention可以很自然地擴展到多尺度的feature maps。表示為輸入的多尺度feature maps,
。
表示為每個query元素
的參考點
的歸一化坐標。Deformable DETR 的Multi-scale Deformable Attention公式表示為:
其中指定attention head,
指定輸入特征層,
指定采樣的key,
表示采樣key的總數(
)。
,
分別表示第
個采樣點在第
特征層的第
個attention head的采樣偏移量和注意力權重。注意力權重
在[0,1]的范圍內,歸一化
。
3. Deformable Transformer Encoder
將DETR中所有的attention替換成multi-scale deformable attention。encoder的輸入和輸出都是具有相同分辨率的多尺度feature maps。Encoder從ResNet的中抽取多尺度feature maps
, (
由
進行3×3 stride 2卷積得到)。
在Encoder中使用multi-scale deformable attention,輸出是和輸入具有相同分辨率的多尺度feature maps。query和key都來自多尺度feature maps的像素。對於每個query像素,參考點是它本身。為了判斷query像素源自哪個特征層,除了positional embedding外,還添加了一個scale-level embedding,不同於positional embedding的固定編碼, scale-level embedding隨機初始化並且通過訓練得到。
4. Deformable Transformer Decoder
Decoder中有cross-attention和self-attention兩種注意力。這兩種注意力的query元素都是object queries。在cross-attention中,object queries從feature maps中提取特征,而key元素是encoder輸出的feature maps。在self-attention中,object queries之間相互作用,key元素也是object queries。因為Deformable Attention是用於key元素的feature maps特征提取的,所以decoder部分,deformable attention只替換cross-attention。
因為multi-scale deformable attention提取參考點周圍的圖像特征,讓檢測頭預測box相對參考點的偏移量,進一步降低了優化難度。
復雜度分析
假設query和key的數量分別為、
(
),維度為
,key采樣點數為
,圖像的feature map大小為
,卷積核尺寸為
。
Convolution復雜度
- 為了保證輸入和輸出在第一個維度都相同,故需要對輸入進行padding操作,因為這里kernel size為
(實際kernel的形狀為
)。
- 大小為
的卷積核一次運算復雜度為
,一共做了
次,故復雜度為
。
- 為了保證第三個維度相等,故需要
個卷積核,所以卷積操作的時間復雜度為
。
Self-Attention復雜度
的計算復雜度為
。
- 相似度計算
:
與
運算,得到
矩陣,復雜度為
。
計算:對每行做
,復雜度為
,則n行的復雜度為
。
- 加權和:
與
運算,得到
矩陣,復雜度為
。
- 故最后self-attention的時間復雜度為
。
Transformer
Self-Attention的復雜度為。
ViT
Self-Attention的復雜度為。
DETR
Self-Attention的復雜度為。
Deformable DETR
Self-Attention的復雜度為。
分析細節看原論文
幾個問題
如何理解? 為什么不使用相同的
和
?
1. 從點乘的物理意義上講,兩個向量的點乘表示兩個向量的相似度。
2. 的物理意義是一樣的,都表示同一個句子中不同token組成的矩陣。矩陣中的每一行,是表示一個token的word embedding向量。假設一個句子“Hello, how are you?”長度是6,embedding維度是300,那么
都是(6,300)的矩陣。
所以和
的點乘可以理解為計算一個句子中每個token相對於句子中其他token的相似度,這個相似度可以理解為attetnion score,關注度得分。雖然有了attention score矩陣,但是這個矩陣是經過各種計算后得到的,已經很難表示原來的句子了,而
還代表着原來的句子,所以可以將attention score矩陣與
相乘,得到的是一個加權后的結果。
經過上面的解釋,我們知道和
的點乘是為了得到一個attention score 矩陣,用來對
進行提煉。
和
使用不同的
,
來計算,可以理解為是在不同空間上的投影。正因為有了這種不同空間的投影,增加了表達能力,這樣計算得到的attention score矩陣的泛化能力更高。這里解釋下我理解的泛化能力,因為
和
使用了不同的
,
來計算,得到的也是兩個完全不同的矩陣,所以表達能力更強。但是如果不用
,直接拿
和
點乘的話,attention score 矩陣是一個對稱矩陣,所以泛化能力很差,這個矩陣對
進行提煉,效果會變差。
如何Position Embedding更好?
目前還是一個開放問題,知乎上有一些優質的討論,詳細分析可以看鏈接文章
ViT為什么要增加一個[CLS]標志位? 為什么將[CLS]標志位對應的向量作為整個序列的語義表示?
和BERT相類似,ViT在序列前添加一個可學習的[CLS]標志位。以BERT為例,BERT在第一句前添加一個[CLS]標志位,最后一層該標志位對應的向量可以作為整句話的語義表示,從而用於下游的分類任務等。
將[CLS]標志位對應的向量作為整個文本的語義表示,是因為與文本中已有的其它詞相比,這個無明顯語義信息的符號會更“公平”地融合文本中各個詞的語義信息,從而更好的表示整句話的語義。
歸納偏好是什么?
歸納偏置在機器學習中是一種很微妙的概念:在機器學習中,很多學習算法經常會對學習的問題做一些假設,這些假設就稱為歸納偏好(Inductive Bias)。歸納偏置可以理解為,從現實生活中觀察到的現象中歸納出一定的規則(heuristics),然后對模型做一定的約束,從而可以起到“模型選擇”的作用,即從假設空間中選擇出更符合現實規則的模型。可以把歸納偏好理解為貝葉斯學習中的“先驗”。
在深度學習中,也使用了歸納偏好。在CNN中,假設特征具有局部性(Locality)的特點,即把相鄰的一些特征融合到一起,會更容易得到“解”;在RNN中,假設每一時刻的計算依賴於歷史計算結果;還有attention機制,也是從人的直覺、生活經驗歸納得到的規則。
而Transformer可以避免CNN的局部性歸納偏好問題。舉一個DETR中的例子。

訓練集中沒有超過13只長頸鹿的圖像,DETR實驗中創建了一個合成的圖像來驗證DETR的泛化能力,DERT可以完全找到合成的全部24只長頸鹿。這證實了DETR避免了CNN的歸納偏好問題。
二分圖匹配? 匈牙利算法?
給定一個二分圖G,在G的一個子圖M中,M的邊集{E}中的任意兩條邊都不依附於同一個頂點,則稱M是一個匹配。求二分圖最大匹配可以用匈牙利算法。
詳細分析可以看鏈接文章
https://liam.page/2016/04/03/Hungarian-algorithm-in-the-maximum-matching-problem-of-bigraph/
ZihaoZhao:帶你入門多目標跟蹤(三)匈牙利算法&KM算法
BETR的positional embedding、object queries和slot三者之間有何關系?

DETR可視化decoder預測得到的20個slot。可以觀察到每個slot學習到了特定區域的尺度大小。Object queries從這個角度看,其實有點像Faster-RCNN等目標檢測器的anchor,結合encoder的positional embedding信息讓每個slot往學習到的特定區域去尋找目標。
Transformer相比於CNN的優缺點?
優點:
Transformer關注全局信息,能建模更加長距離的依賴關系,而CNN關注局部信息,全局信息的捕捉能力弱。
Transformer避免了CNN中存在的歸納偏好問題。
缺點:
Transformer復雜度比CNN高,但是ViT和Deformable DETR給出了一些解決方法來降低Transformer的復雜度。
Deformable detr中值得注意的幾個地方:
DeformableTransformer
中在不使用two_stage的條件下提供的reference_points
是由nn.Embedding
經過線性變化得到的,值得注意的是這個·reference_points·直接參與了loss的計算,也就是說這個分支上對self.reference_points
層進行了訓練。DeformableTransformer
中使用two_stage的條件下在每個位置上都生成了proposal,然后選擇topk個proposal作為query的reference_point,但是可以發現這里的topk 進行了detach,並不會傳遞從decoder傳來的梯度誤差。DeformableTransformer
中使用two_stage的條件會在encoder的輸出層的每個位置提供一個anchor,對於多尺度而言,提供了不同尺度的anchor。這里有個注意的是此時的query數量非常大,這會導致兩個問題:第一,正負樣本會很不均衡;第二,使用matcher分配gt給proposal會導致分配較慢,且密集proposal上進行一一配對會導致訓練不穩定,較難收斂。DeformableTransformerDecoder
在 不用return_intermediate時的輸出需要進行unsqueeze,否則在detector中調用時會有維度問題。- 在
deformable_detr
中DeformableDETR
的定義中, 在使用refine技術時,class_embed、bbox_embed是不共享參數的, 而不使用refine技術時,每層的class_embed, bbox_embed是參數共享的,使用nn.ModuleList
主要是為了forward中推理代碼的統一。
總結
Transformer給圖像分類和目標檢測方向帶來了巨大革新,分割、跟蹤、視頻等方向也不遠了吧
NLP和CV的關系變的越來越有趣了,雖然爭議很大,但是試想一下,NLP和CV兩個領域能用一種范式來表達,該有多可怕,未來圖像和文字是不是可以隨心所欲的轉來轉去?可感知可推理的強人工智能是不是不遠了?(想想就好)
向着NLP和CV的統一前進
Reference
[1]Attention Is All You Need
[2]An Image is Worth 16*16 Words: Transformers for Image Recognition at Scale
[3]End-to-End Object Detection with Transformers
[4]Deformable DETR: Deformable Transformers for End-to-End Object Detection