---
# System prepended metadata

title: Vision Transformer (ViT)
tags: [論文筆記]

---

論文: [An Image is Worth 16x16 Words: Transformers for Image Recognition at Scale](https://arxiv.org/abs/2010.11929)

## Transformer: From NLP to CV
Transformer 成功應用在 NLP 領域最大的變革在於使用自注意力機制，能夠過探索全局的向量相關性去得出很好的推論結果，再搭配 Positoin embedding 去為結果排序；然而，若 Transformer 在文字或句子這種有強烈前後相關性的結構終能取得成功，理論上，在影像這種局部特性顯著的資料中應該也能有不錯的表現，而這就是 Vision Transformer 想要傳達的訊息。

在 Transformer 推出後，有許多將 CNN 和 Self-attention 搭配在一起的混合式模型出現:
* 有些是直接將 CNN 中的某些層直接改為 Self-attention
* 有些是利用 CNN 當作 Feature extractor，輸出的 Feature map 再餵進 Transformer

然而，其實單用 Transformer 架構，==在較大的資料集上做預訓練並直接遷移到下游任務上，就可以獲得和 CNN 匹配或甚至更好的結果:==

<div class="text-center">
    <img src="https://hackmd.io/_uploads/BJ3pknz30.png" style="width: 600px; object-fit: cover;">
</div>

&nbsp;
在本篇論文中是拿 ViT 做分類任務，直接先上模型架構圖:

<div class="text-center">
    <img src="https://hackmd.io/_uploads/SkGve3zn0.png" style="width: 600px; object-fit: cover;">
</div>

&nbsp;
* 如同論文標題 AN IMAGE IS WORTH 16X16 WORDS: TRANSFORMERS FOR IMAGE RECOGNITION AT SCALE 所述，==直接將影像分割為多個 16X16 的影像 Patch==
* 每個影像 Patch 視作 NLP 應用中的一個詞，直接餵入 Transformer 即可
* 每個影像 Patch 也會加入 Position embedding，讓模型學習 Patch 應出現在整張影像中何處
* ==最前方額外加入一組向量（位置為 0），稱作 Class token（Class embedding）==
* 推論不會把所有輸出過 FC layer（論文中皆稱 MLP）後做預測，而是僅僅拿上述 Class embedding 來做預測，原因是經過 Self-attention 後，Class embedding 應能學習到影像中的交互關係，所以拿它來做推論即可

<div class="text-center">
    <img src="https://hackmd.io/_uploads/HyE5UhMnA.png" style="width: 800px; object-fit: cover;">
</div>

&nbsp;
若將上面敘述的以數學表示出來:

<div class="text-center">
    <img src="https://hackmd.io/_uploads/BJogwhfhR.png" style="width: 800px; object-fit: cover;">
</div>

&nbsp;
其中，搭配模型架構講解，步驟切為二大塊: Patch embedding 和 Transformer encoder:

* Embedding
    * $z_0 = [x_{class}; x^1_pE;x^2_pE;...  ;x^N_pE] + E_{pos}$
    * $x^N_pE$ 為每一個圖塊
    * $E_{pos}$ 為共享、可學習的 1D 權重，與所有的 Patch embedding 做相加（Sum）而非拼接（Concatenate）
    * $x_{class} = z^0_0$ 為 Extra learnable class embedding（又稱為 Class token），放在序列最前端，在和序列中所有的 Patch（Token）做矩陣運算，獲得與所有 Patch 的相關性資訊
* Transformer encoder
    * 包含兩個重要模組：多頭注意力（MSA）、全連接層（MLP）
    * 做 Layernorm 的位置和原版 Transformer 略有不同
    * 殘差連接（Residual connection）
    * MLP: Two layers with a GELU
    * $LN(z^0_L)$ 來自於最後一層的類別向量 $z^0_L$，是匯聚所有資訊的類別編碼，再經過 Layernorm 得到預測輸出

:::info
論文中 ViT 設計為了和原本 Transformer 論文盡可能保持一致，因此同樣用 Class token 去做分類輸出；實際上 Transformer encoder 的最後的一排輸出也可以像 CNN 一樣，做 GAP（Global average pooling）去拉平 Feature map 做全局的權重分配:

<div class="text-center">
    <img src="https://hackmd.io/_uploads/B1kFOJV2A.png" style="width: 800px; object-fit: cover;">
</div>

論文中也有將測試表現放上來，假設做 GAP 的話，在 Learning rate 的部分如果直接和 Class token 相同的話，模型表現會不佳，因此如何調整參數也是很重要的:

<div class="text-center">
    <img src="https://hackmd.io/_uploads/SyKPY1EhA.png" style="width: 800px; object-fit: cover;">
</div>
:::

論文中影像輸入為 224X224、搭配 16X16 的 Patch size，ViT 吃進的序列長度為 14X14=196；但使用一個預訓練好的 ViT 去做下游任務，其實是不太好去調整影像輸入尺寸的，例如使用更高解析度的影像（例如: 320X320），若保持 16X16 的 Patch size，序列長度就會變為 20X20=400，==那麼原先學習好的位置編碼就會失效==（原本是 1~196，現在變成 1~400），論文中直接用插植來作解決，算是一個臨時的解決方案（長度由 196 變為 400，插植越多越失真）:

<div class="text-center">
    <img src="https://hackmd.io/_uploads/HkD3pJ42A.png" style="width: 800px; object-fit: cover;">
</div>

&nbsp;
最後，本篇論文也對應 Transformer 提出三種結構變體:

<div class="text-center">
    <img src="https://hackmd.io/_uploads/BJUBiTz20.png" style="width: 550px; object-fit: cover;">
    <img src="https://hackmd.io/_uploads/ByQCopznR.png" style="width: 800px; object-fit: cover;">
</div>

## Transformer v.s. CNN
從幾個面向來討論目前 SOTA 的 CNN 模型和 ViT:
* Benchmark 表現 & 訓練成本
* 性能受數據集大小影響
* 模型架構效能 & 計算成本
* 不同的 Position embedding 設計方式
* Attention distance 如何對應至 CNN 的感受野（Receptive field）

---

1. Benchmark 表現 & 訓練成本

    直接比較分類準確率其實相差不遠，但如果從訓練效率上來看又是另一回事；舉例來說，在相同硬體條件下，ViT-H/14 的訓練時間大幅小於 BiT-L，準確率表現還更好。
    
    <div class="text-center">
        <img src="https://hackmd.io/_uploads/BkQP2aMhC.png" style="width: 800px; object-fit: cover;">
        <img src="https://hackmd.io/_uploads/Hyx633TMnC.png" style="width: 800px; object-fit: cover;">
    </div>
    
2. 性能受數據集大小影響
    
    * 下圖左橫軸為資料集大小，往右表示資料集愈大，可觀察到 Transformer 在量體小的資料集做預訓練，其表現會不如 CNN，而隨著資料集逐漸增大 Transformer 表現會超越 CNN
    * 下圖右可得知隨著資料量不斷上升，CNN 較快達到性能飽和，而 Transformer 則較慢
    
    <div class="text-center">
        <img src="https://hackmd.io/_uploads/HJmRk0z2C.png" style="width: 800px; object-fit: cover;">
    </div>

3. 模型架構效能 & 計算成本
    
    ==混合架構（CNN+Transformer）在較小的模型尺寸下，效能優於純 CNN 或純 Transformer，當模型尺寸較大時效能則愈來愈接近。==
    
    <div class="text-center">
        <img src="https://hackmd.io/_uploads/By0GfRf30.png" style="width: 800px; object-fit: cover;">
    </div>

4. Position embedding

    <div class="text-center">
        <img src="https://hackmd.io/_uploads/S1yRv0GhC.png" style="width: 800px; object-fit: cover;">
    </div>

    作者有嘗試不同種位置編碼對於學習效果影響:
    * 不加入位置編碼
    * 1D 位置編碼（本篇論文，將影像每列拉平按順序編碼）
    * 2D 位置編碼（行列編碼分開）
    * 相對位置編碼（依照相對距離作編碼）
    
    <div class="text-center">
        <img src="https://hackmd.io/_uploads/S1Bs_0M2R.png" style="width: 800px; object-fit: cover;">
    </div>
    
    除了不加入位置編碼外，其實如何設計它差異不大，==一般的 1D 位置編碼就有學習到位置的相對關係，每個圖像塊會和緊鄰的部分相關性最高==，因此學出的 Position embedding 會和同行、同列的相關性最高，並且依照距離遠近逐漸遞減:
    
    <div class="text-center">
        <img src="https://hackmd.io/_uploads/Hky6hRz20.png" style="width: 800px; object-fit: cover;">
        <img src="https://hackmd.io/_uploads/Sy0JiCGnR.png" style="width: 800px; object-fit: cover;">
        <img src="https://hackmd.io/_uploads/rk8QykXhR.png" style="width: 800px; object-fit: cover;">
    </div>

5. Attention distance
    
    首先，自注意力距離代表的就是自注意力分數（Attention score），如下圖所示，隨著橫軸愈大表示模型愈深層、縱軸則是各自注意力的平均距離，可以觀察出
    
    * 在淺層時，平均距離分散，有些關注短距離（局部）、有些關注長距離（全局）
    * 在深層時，平均距離逐漸收斂且都很大，代表大部分皆關注長距離

    ==這代表 Local feature 主要是由模型淺層，可以說在此多提供像素級別（Pixel level）的特徵；而隨著往深層走，模型多提供 Global feature，也就是語意化（Semantic level）高階特徵，這點和 CNN 非常相似。此外，這也對應到了 CNN 的感受野，隨著模型加深，單一元素輸出的感受野是愈來愈大的。==
    
    <div class="text-center">
        <img src="https://hackmd.io/_uploads/B1WQlyXn0.png" style="width: 800px; object-fit: cover;">
    </div>
    
    因此，我們可以這樣來看，CNN 是一步步經由許多的 Local feature 組合去合成高階語意特徵，而 ViT 是透過 Self-attention 一次看整張影像去計算、同時關注局部和全局，最終結論卻和 CNN 相仿、殊途同歸。

## Inductive bias
從字詞意義出發，Inductive 為歸納，用來尋找共同點形成通用規則；Bias 為偏差，是對於模型架構的設計偏好。因此，將二個字組在一起表示: ==由人類知識歸納出的規則（Heuristics），對模型做一定程度的前提假設==。

若從機率角度出發:
* Inductive bias 可以稱作是先驗知識（Prior knowledge），例如在 Bayesian statistics 中，通常會有一個先驗分佈（Prior distribution），代表了對某事發生的初始信念
* 當新資料進來時，根據這些資料更新我們的信念而形成後驗分佈（Posterior distribution），Inductive bias 就像先驗分佈，幫助模型在面對新資料時，能夠更有效地進行學習和預測

有許多例子都是歸納偏差的例子，
1. 統計模型中，ANOVA 變異數分析常常會做出某些假設，例如資料服從常態分佈，這些假設實際上就是一種歸納偏差
2. ==CNN 的歸納偏差主要是 Locality（區域性）和 Spatial invariance（空間不變性）==
    * Locality: 空間相近的像素關聯性相對遠距離的像素來的高
    * Spatial invariance: 代表 Kernel 權重共享，學習到的特徵在整張圖像中皆通用，不管特徵出現在圖像中何處，都可以透過掃過去的 Kernel 捕捉到
3. RNN 的歸納偏差主要是 Sequentiality（順序性）和 Time invariance（時間不變性）
    * Sequentiality: 假設文字序列前後文之間有關聯性
    * Time invariance: 同 CNN，RNN 也是利用 Kernel 權重共享

其中，再更詳細討論 CNN 計算機制，卷積操作會為整個計算加上空間約束:
* ==由於權重共享，從卷積層中提取的特徵具有平移不變性（Translation invariance），對特徵的全局位置不敏感，而對於特徵（紋理）是否存在較為敏感；另外，它的旋轉不變性（Rotation invariance）和縮放不變性（Scale invariance）則主要是透過 Pooling 層得到==
* ==從卷積層中提取的特徵是局部敏感的，每一個操作都只考慮到圖像的局部區域==

但也由於卷積操作這樣的歸納偏差，讓它在提取視覺特徵方面相當出色，卻缺乏對於圖像的全局理解，需要透過 FC layer 這樣的操作補足全局間的依賴關係；反之，ViT 對於圖像的特定歸納偏差（或稱前提假設）就很小，==ViT 使用的 Self-attention 運算可視為計算圖塊全局相關性後，由模型自行決定 Kernel 尺寸的過程。==

最後，==透過為模型引入合理假設和限制，能夠防止模型過度學習資料中的雜訊而 Overfitting、提升泛化能力==，例如: 下圖的六個離散點可以用很多不同曲線去做擬合，但加入了正規化的 Inductive bias 後就能獲得更具通用性的模型（曲線）去描述它:

<div class="text-center">
    <img src="https://hackmd.io/_uploads/BJoTgSEn0.png" style="width: 400 px; object-fit: cover;">
</div>

## Reference
* [ViT论文逐段精读【论文精读】](https://www.youtube.com/watch?v=FRFt3x0bO94&t=3122s)
* [[Transformer_CV] Vision Transformer(ViT)重點筆記](https://hackmd.io/@YungHuiHsu/ByDHdxBS5)
* [如何理解Inductive bias？](https://www.zhihu.com/question/264264203)