VIT掌握了嗎?沒有就進(jìn)來看看學(xué)長的學(xué)習(xí)筆記吧!文末附資料包
來源:投稿 作者:橡皮
編輯:學(xué)姐
小聲逼逼
在過去的兩年里,Vision Transformer(ViT)
是計(jì)算機(jī)視覺(cv)領(lǐng)域最有影響力的工作之一。「它推翻了2012年在Alex net中提出的CNN在CV領(lǐng)域的統(tǒng)治地位: 當(dāng)能夠獲得足夠多的預(yù)訓(xùn)練數(shù)據(jù)時(shí),將ViT應(yīng)用到CV的效果非常好?!?/strong> 最重要的是,ViT的提出正式打破了CV和NLP之間的壁壘,同時(shí)還給CV和多模態(tài)的研究工作挖了一個(gè)大坑。
再叨叨兩句
其實(shí)很早之前在群里就聽小伙伴們聊過vision transformer
,但是因?yàn)楫?dāng)時(shí)自己所做的工作用到ViT的屬實(shí)是很少,所以對于主動去了解這個(gè)東西就有些嗤之以鼻。
真正開始學(xué),或者說認(rèn)真開始看原paper
結(jié)合code
去理解vision transformer
是由于我在AIR的暑研項(xiàng)目中,mentor
提出了個(gè)有意思的想法是「基于DETR (detection transformer)
思路構(gòu)造多類別異常檢測模型?!?/strong>
這就使我不得不加班加點(diǎn)的去從頭了解vision transformer
的結(jié)構(gòu)以及其中的self-attention以及cross-attention
機(jī)制。借此機(jī)會也想跟大家分享一下關(guān)于我的學(xué)習(xí)心得。
心路歷程 QVQ
對我個(gè)人而言,學(xué)習(xí)一個(gè)新技術(shù)或者去follow一項(xiàng)新的工作,我的學(xué)習(xí)路線通常是:
讀原paper??知乎一下大家有關(guān)這篇工作的討論??重讀技術(shù)路線??對照代碼去再次理解技術(shù)路線以及著重關(guān)注損失函數(shù)。(以下參考了沐神講vit視頻下的筆記進(jìn)行回憶)
首先是閱讀原paper
通過標(biāo)題和摘要可以獲得一些信息:an image is worth 16*16 words
,即每一張輸入transformer的圖片都會被打散為若干個(gè)16*16的小方格(patches),這樣就可以利用nlp里面典型的transformer結(jié)構(gòu)去做大規(guī)模的圖像識別。
值得一提的是在ViT之前,我們都知道transformer在nlp領(lǐng)域是基本操作,但是這么好的idea卻在cv領(lǐng)域應(yīng)用十分有限。
原文作者谷歌團(tuán)隊(duì)著手解決了這個(gè)問題:「attention+CNN或attention替換CNN components,但是保持CNN的整體結(jié)構(gòu)」。 對于保持結(jié)構(gòu),是指的ResNet50
有4個(gè)stage(R2/R3/R4/R5)
,每個(gè)stage
不變,直接使用attention
取代每一個(gè)stage
里面的每一個(gè)block
。作者實(shí)驗(yàn)證明attention
并不需要非得和CNN
一起使用,跟transformer
一起用時(shí),在大規(guī)模數(shù)據(jù)集上預(yù)訓(xùn)練并在中小數(shù)據(jù)集做fine-tuning
后照樣能夠取得sota
效果。
接下來我跳過related work
直接來看到了模型結(jié)構(gòu),不得不說看了主圖基本上就明白很多了。 ViT這篇文章盡可能使用原始transformer,「旨在于享受架構(gòu)的高效實(shí)現(xiàn)?!?/strong>

輸入一張圖,將它打成3*3的patches
,然后再將其分別flattened
從3*3變?yōu)?*9,經(jīng)過一個(gè)Linear Projection
后,將每個(gè)patches
轉(zhuǎn)變成了patch embedding
。由于encoder
中需要做self-attention
,即所有元素兩兩之間計(jì)算自注意力,這與順序無關(guān)。
但是由于每個(gè)patch
是來自于圖片是有序的,所以作者在patch embedding
前面加了position embedding
,這樣patch embedding + position embedding[CLS]=token
(包含了圖片的patch信息和每個(gè)patch在原圖的位置信息)??梢钥吹剑鋵?shí)真正輸入進(jìn)transformer
的就是tokens
,這與nlp
中的工作是異曲同工的。
另外,文章主圖做的分類任務(wù),雖然每個(gè)token
都會有輸出,但是最終還是只拿[CLS]
來做分類!這是因?yàn)?code>transformer encoder中的self-attention
機(jī)制使得所有tokens
都在做兩兩的信息交互,那么[CLS]
同樣也會跟著所有的patches
一起做交互,所以[CLS]
也是可以學(xué)到有用信息的拿來做最終的分類的。繼續(xù)看上面,「最終分類任務(wù)就是把[CLS]
單拎出來到通用的MLP head
中得到類別判斷,這樣就可以使用cross-entropy
來進(jìn)行訓(xùn)練了~」
根據(jù)代碼重新過一遍前向過程
雖然ViT的整體思路在主圖上的展示不能夠再清晰,但是畢竟最終要拿來改代碼做自己的任務(wù)嘛,根據(jù)代碼重新過一遍前向過程是有必要的:圖片$x:2242243(RGB三通道)->N個(gè)patches:\frac{224^2}{16^2}=196->每個(gè)patch的維度16*16*3=768$->經(jīng)過linear projection(E)
后:768(patch維度)D(embedding_dim)768->圖片$ xE=196*798 $至此2D圖片轉(zhuǎn)換為1D序列tokens!另外別忘了position embedding
的存在,所以輸入encoder
的序列長度是197*768~
到這里其實(shí)閱讀原文和代碼就結(jié)束了,方法思路和代碼的具體實(shí)現(xiàn)已經(jīng)get到了。 我并沒有看Related work以及實(shí)驗(yàn)部分的效果是因?yàn)楝F(xiàn)在ViT已經(jīng)是經(jīng)過各種大佬魔改之后被公認(rèn)為還不錯了。
VIT的坑
誠然ViT這篇文章中也提及到了一些transformer固有的缺陷,比如data-hungry,相比CNN缺少歸納偏置,序列長維度高以及計(jì)算復(fù)雜度高等。 但正因?yàn)橛羞@一系列待解決的問題,留給后面研究的可能性也就越大。所以我認(rèn)為ViT原文的可讀性依然非常的大,它講解了最基本的原理和insight,但是真正希望把vit應(yīng)用到自己的工作(其他領(lǐng)域)當(dāng)中去,還是要看一些經(jīng)典的ViT拓展工作來獲取獨(dú)到的思路,如DETR等等~
關(guān)注【學(xué)姐帶你玩AI】公眾號
后臺回復(fù)“VIT”
免費(fèi)領(lǐng)取VIT論文原文PDF資料&代碼數(shù)據(jù)集
