ViT
AN IMAGE IS WORTH 16X16 WORDS:
TRANSFORMERS FOR IMAGE RECOGNITION AT SCALE
https://arxiv.org/pdf/2010.11929.pdf
這篇工作Vision Transformer基于NLP領(lǐng)域中大放異彩的Transformer模型來(lái)處理視覺(jué)領(lǐng)域的任務(wù)。作者將二維的圖像數(shù)據(jù)用一個(gè)簡(jiǎn)單的方式轉(zhuǎn)換為和Transformer中處理的句子序列差不多的形式, 然后使用 Transformer編碼器來(lái)提取特征。

Multi-head self-Attention 多頭注意力機(jī)制
Transformer的論文叫Attention is all you need, 現(xiàn)在在深度學(xué)習(xí)領(lǐng)域中提到Attention可能大家都會(huì)想到Transformer的self-Attention自注意力,其實(shí)注意力機(jī)制剛開(kāi)始是應(yīng)用于循環(huán)神經(jīng)網(wǎng)絡(luò)中的,self-Attention可以看成是一個(gè)更通用的版本。Attention本來(lái)是在Encoder-Decoder框架中關(guān)乎中間的隱藏狀態(tài)的這么一個(gè)函數(shù)。 而self-Attention無(wú)所謂隱藏狀態(tài),只關(guān)注輸入序列中向量之間的依賴關(guān)系。Transformer給出了一個(gè)非常簡(jiǎn)潔的公式 。

看到softmax就知道是在求概率,V代表的是數(shù)值,QK代表一個(gè)查字典的操作。但是這樣還是很抽象,要理解的話得把矩陣拆成向量才行。這里推薦一篇可視化Transformer的博客。https://jalammar.github.io/illustrated-transformer/

我的理解就是把原向量進(jìn)行三次編碼,然后在計(jì)算attention結(jié)果的時(shí)候,一個(gè)編碼只和自己有關(guān),代表該token的特征,另外兩個(gè)用來(lái)和序列中其他向量的編碼進(jìn)行匹配,得到當(dāng)前向量與其他向量之間的關(guān)聯(lián)程度。
卷積在視覺(jué)中占主流的原因很重要的原因是局部感受野,另外卷積的形式一坨一坨的很契合對(duì)圖片數(shù)據(jù)的處理。但是,卷積的感受野是受限的,要多層抽象才能得到一個(gè)比較大的感受野。而自注意力我覺(jué)得可以理解為在輸入的全局中有選擇的進(jìn)行權(quán)重。這個(gè)過(guò)程進(jìn)行多次,就是多頭自注意力機(jī)制。
把圖片當(dāng)作單詞處理
最終的編碼就長(zhǎng)成這個(gè)樣子:

對(duì)應(yīng):

圖片轉(zhuǎn)化為序列數(shù)據(jù)
E
將圖片拆分為多個(gè)patch,每個(gè)壓扁的通過(guò)線性變換E, 得到一個(gè)固定長(zhǎng)度的特征向量,參考NLP中的習(xí)慣稱為token。這個(gè)token的長(zhǎng)度D文中使用了768,1024,1280對(duì)應(yīng)三個(gè)尺寸的模型ViT-Base,Large以及Huge。
class token
另外每個(gè)序列的開(kāi)頭還會(huì)加上一個(gè)class token,最終用來(lái)分類的是class token 對(duì)應(yīng)的特征向量。這個(gè)token的參數(shù)是可學(xué)習(xí)的,會(huì)和序列中所有其他patch所生成的token一樣,正常進(jìn)行查詢匹配的注意力操作,我的理解是它起到了一個(gè)類似總結(jié)的作用。代碼中可以看到,最終通過(guò)MLP的要么是只取class token的結(jié)果,或者也可以使用對(duì)所有token在每個(gè)位置取平均值的方法。但是論文好像沒(méi)有解釋取平均值會(huì)怎么樣,有了解的同學(xué)歡迎補(bǔ)充。
#https://github.com/lucidrains/vit-pytorch/blob/4f3dbd003f004569a916f964caaaf7b9a0a28017/vit_pytorch/vit.py
def forward(self, img):
x = self.to_patch_embedding(img)
b, n, _ = x.shape
cls_tokens = repeat(self.cls_token, '() n d -> b n d', b = b)
x = torch.cat((cls_tokens, x), dim=1)
x += self.pos_embedding[:, :(n + 1)]
x = self.dropout(x)
x = self.transformer(x)
x = x.mean(dim = 1) if self.pool == 'mean' else x[:, 0] # (只使用 class token)
x = self.to_latent(x)
return self.mlp_head(x)
- 位置編碼
雖然注意力可以捕捉到token和token之間的依賴關(guān)系,但是token的位置信息卻無(wú)處可尋。也就是說(shuō),無(wú)論這些patch如何排序,得到的結(jié)果都是一樣的。NLP領(lǐng)域中有非常多的解決方案,ViT使用的是可學(xué)習(xí)的位置編碼,和class token 與 patch的線性變換相加得到最終編碼。也許也可以用拼接,不過(guò)原Transformer中沒(méi)有提到,另外Transformer中使用的是固定的編碼。 總之,就是無(wú)論哪個(gè)序列,讓序列中同一位置的token附帶上一模一樣的信息就可以了。ViT附錄D3中有不同位置編碼方式的對(duì)比實(shí)驗(yàn)結(jié)果,如果沒(méi)有考慮位置信息,那么結(jié)果很差,而使用不同位置編碼的結(jié)果其實(shí)差距不大。
不同編碼的對(duì)比試驗(yàn),編碼方法可以去參看原文
既然已經(jīng)通過(guò)上面的處理把圖片的輸入轉(zhuǎn)化為T(mén)ranformer處理單詞序列的形式了,那么接下來(lái)直接通過(guò)多頭注意力機(jī)制多次處理,最終得到的結(jié)果是和圖片中每個(gè)patch都相關(guān)的特征。就相當(dāng)于替代卷積層完成了特征提取得到 z_l。

實(shí)驗(yàn)
不用卷積運(yùn)算,訓(xùn)練需要的計(jì)算資源要少很多。
ViT 如果用大量數(shù)據(jù)集進(jìn)行預(yù)訓(xùn)練,那么效果會(huì)很好。
ViT 模型更大對(duì)比同量級(jí)state-of-the-art表現(xiàn)更好。

swinTransformer
https://arxiv.org/pdf/2103.14030.pdf




position bias in self-attention head
不同于ViT中在輸入序列中加上一個(gè)絕對(duì)的位置編碼,swinTransformer使用的是相對(duì)位置偏置,加在attention內(nèi)部的查詢操作里。論文做了實(shí)驗(yàn),如果同時(shí)使用兩種方法,表現(xiàn)會(huì)反而下降。

