本系列已授權極市平臺,未經允許不得二次轉載,如有需要請私信作者,文章持續更新。

本文目錄

1 MoCo v2

1。1 MoCo v2 的 Motivation

1。2 MoCo 相對於 End-to-end 方法的改進

1。3 MoCo v2實驗

2 MoCo v3

2。1 MoCo v3 原理分析

2。2 MoCo v3 自監督訓練 ViT 的不穩定性

2。3 提升訓練穩定性的方法:凍結第1層 (patch embedding層) 引數

2。4 MoCo v3 實驗

Self-Supervised Learning

,又稱為自監督學習,我們知道一般機器學習分為有監督學習,無監督學習和強化學習。 而 Self-Supervised Learning 是無監督學習裡面的一種,主要是希望能夠學習到一種

通用的特徵表達

用於

下游任務 (Downstream Tasks)

。 其主要的方式就是透過自己監督自己。作為代表作的 kaiming 的 MoCo 引發一波熱議, Yann Lecun也在 AAAI 上講 Self-Supervised Learning 是未來的大勢所趨。所以在這個系列中,我會系統地解讀 Self-Supervised Learning 的經典工作。

1 MoCo v2

論文名稱:Improved Baselines with Momentum Contrastive Learning

論文地址:

1.1 MoCo v2 的 Motivation

上篇文章我們介紹了 MoCo 這個系列的第一版 MoCo v1,連結如下所示。

MoCo v1的方法其實可以總結為2點

(a)

[1 原始的端到端自監督學習方法]

裡面,Encoder

f_\textrm{q}

和 Encoder

f_\textrm{k}

的引數每個step 都更新,這個問題在前面也有提到,因為Encoder

f_\textrm{k}

輸入的是一個 Batch 的 negative samples (N-1個),所以輸入的數量不能太大,即dictionary不能太大,即 Batch size不能太大。

現在的 Momentum Encoder

f_\textrm{Mk}

的更新是透過動量的方法更新的,不涉及反向傳播,所以

f_\textrm{Mk}

輸入的負樣本 (negative samples) 的數量可以很多,具體就是 Queue 的大小可以比較大,可以比mini-batch大,屬於超引數。佇列是逐步更新的在每次迭代時,當前mini-batch的樣本入列,而佇列中最老的mini-batch樣本出列,那當然是負樣本的數量越多越好了。這就是 Dictionary as a queue 的含義,即透過動量更新的形式,使得可以包含更多的負樣本。而且 Momentum Encoder

f_\textrm{Mk}

的更新極其緩慢 (因為

m=0.999

很接近於1),所以Momentum Encoder

f_\textrm{Mk}

的更新相當於是看了很多的 Batch,也就是很多負樣本。

(b)

[2 採用一個較大的memory bank儲存較大的字典]

方法裡面,所有樣本的 representation 都存在 memory bank 裡面,根據上文的描述會帶來最新的 query 取樣得到的 key 可能是好多個step之前的編碼器編碼得到的 key,因此喪失了一致性的問題。但是MoCo的每個step都會更新Momentum Encoder,雖然更新緩慢,但是每個step都會透過4式更新一下Momentum Encoder,這樣 Encoder

f_\textrm{q}

和 Momentum Encoder

f_\textrm{Mk}

每個step 都有更新,就解決了一致性的問題。

SimCLR的兩個提點的方法

今天介紹MoCo 系列的後續工作:MoCo v2 和 v3。MoCo v2 是在 SimCLR 發表以後相繼出來的,它是一篇很短的文章, 只有2頁。在MoCo v2 中,作者們整合

SimCLR 中的兩個主要提升方法

到 MoCo 中,並且驗證了SimCLR演算法的有效性。

SimCLR的兩個提點的方法就是:

使用強大的資料增強策略,具體就是額外使用了 Gaussian Deblur 的策略和使用巨大的 Batch size,讓自監督學習模型在訓練時的每一步見到足夠多的負樣本 (negative samples),這樣有助於自監督學習模型學到更好的 visual representations。

使用預測頭 Projection head。在 SimCLR 中,Encoder 得到的2個 visual representation再透過Prediction head (

g(.)

)進一步提特徵,預測頭是一個 2 層的MLP,將 visual representation 這個 2048 維的向量

h_i,h_j

進一步對映到 128 維隱空間中,得到新的representation

z_i,z_j

。利用

z_i,z_j

去求loss 完成訓練,訓練完畢後扔掉預測頭,保留 Encoder 用於獲取 visual representation。

關於 SimCLR 的詳細解讀歡迎參考下面的連結:

SimCLR 的方法其實是晚於 MoCo v1 的。時間線如下:

MoCo v1 於 2019。11 釋出於arXiv,中了CVPR 2020;

SimCLR v1 於 2020。02 釋出於arXiv,中了ICML 2020;

MoCo v2 於 2020。03 釋出於arXiv,是一個技術報告,只有2頁。

SimCLR v2 於 2020。06 釋出於arXiv,中了NIPS 2020;

在 SimCLR v1 釋出以後,MoCo的作者團隊就迅速地將 SimCLR的兩個提點的方法移植到了 MoCo 上面,想看下效能的變化,也就是MoCo v2。結果顯示,MoCo v2的結果取得了進一步的提升並超過了 SimCLR v1,證明MoCo系列方法的地位。因為 MoCo v2 文章只是移植了 SimCLR v1 的技巧而沒有大的創新,所以作者就寫成了一個只有2頁的技術報告。

1.2 MoCo 相對於 End-to-end 方法的改進

MoCo v2 的亮點是不需要強大的 Google TPU 加持,僅僅使用 8-GPU 就能超越 SimCLR v1的效能。End-to-end 的方法和 MoCo v1的方法在本專欄的上一篇文章

Self-Supervised Learning 超詳細解讀 (四):MoCo系列 (1)

裡面已經有詳細的介紹,這裡再簡單概述下二者的不同,如下圖1,2,3所示。

Self-Supervised Learning 超詳細解讀 (五):MoCo系列解讀 (2)

圖1:早期的End-to-end的方法

Self-Supervised Learning 超詳細解讀 (五):MoCo系列解讀 (2)

圖2:MoCo v1/2 方法,圖中n為Batch size

Self-Supervised Learning 超詳細解讀 (五):MoCo系列解讀 (2)

圖3:早期的End-to-end的方法和MoCo方法的對比

End-to-end 的方法 (原始的端到端自監督學習方法):

一個Batch的資料假設有

N

個 image,這裡面有一個樣本 query

\color{purple}{q}

和它所對應的正樣本

\color{crimson}{k^{+}}

\color{purple}{q}

\color{crimson}{k^{+}}

來自同一張圖片的不同的 Data Augmentation,這個Batch剩下的資料就是負樣本 (negative samples),如下圖3所示。接著我們將這個 Batch 的資料同時輸入給2個

架構相同但引數不同

的 Encoder

f_\textrm{q}

和 Encoder

f_\textrm{k}

。然後對兩個 Encoder的輸出使用下式 1 所示的 Contrastive loss 損失函式使得query

\color{purple}{q}

和正樣本

\color{crimson}{k^{+}}

的相似程度儘量地高,使得query

\color{purple}{q}

和負樣本

\color{green}{k^{-}}

的相似程度儘量地低,透過這樣來訓練Encoder

f_\textrm{q}

和 Encoder

f_\textrm{k}

,這個過程就稱之為自監督預訓練。訓練完畢後得到的 Encoder 的輸出就是圖片的 visual representation。這種方法的缺點是:因為Encoder

f_\textrm{q}

和 Encoder

f_\textrm{k}

的引數都是透過反向傳播來更新的,所以 Batch size 的大小不能太大,否則 GPU 視訊記憶體就不夠了。所以,Batch size 的大小限制了負樣本的數量,也限制了自監督模型的效能。

Self-Supervised Learning 超詳細解讀 (五):MoCo系列解讀 (2)

圖4:End-to-end方法一個Batch的資料

\begin{equation} \small \mathcal{L}_{q, k^+, \{k^-\}} = -\log \frac{\exp(q{\cdot}k^+ / \tau)}{\exp(q{\cdot}k^+ / \tau) + {\displaystyle\sum_{k^-}}\exp(q{\cdot}k^-  / \tau)}. \label{eq:infonce} \end{equation} \tag{1}

MoCo 的方法:

一個Batch的資料假設有

N

個 image,這裡面有一個樣本 query

\color{purple}{q}

和它所對應的正樣本

\color{crimson}{k^{+}}

\color{purple}{q}

\color{crimson}{k^{+}}

來自同一張圖片的不同的 Data Augmentation,這個Batch剩下的資料就是負樣本 (negative samples)。 接著我們只把query

\color{purple}{q}

和正樣本

\color{crimson}{k^{+}}

輸入給2個

架構相同但引數不同

的 Encoder

f_\textrm{q}

和 Momentum Encoder

f_\textrm{Mk}

。所有的負樣本

\color{green}{k^{-}}

都會儲存在一個佇列 Queue 裡面。然後對兩個 Encoder的輸出使用上式 1 所示的 Contrastive loss 損失函式使得query

\color{purple}{q}

和正樣本

\color{crimson}{k^{+}}

的相似程度儘量地高,使得query

\color{purple}{q}

和負樣本

\color{green}{k^{-}}

的相似程度儘量地低。在任意一個 Epoch 的任意一個 step 裡面,我們只使用反向傳播來更新Encoder

f_\textrm{q}

的引數,然後透過2式的動量方法更新 Momentum Encoder

f_\textrm{Mk}

的引數。同時,佇列刪除掉尾部的一個 Batch 大小的負樣本,再在頭部進來一個 Batch 大小的負樣本,完成這個step的佇列的更新。這樣,

佇列的大小可以遠遠大於 Batch size 的大小了

,使得

負樣本的數量可以很多

,提升了自監督訓練的效果。而且,

佇列和

f_\textrm{Mk}

在每個 step 都會有更新

,沒有memory bank,也就

不會存在更新不及時導致的 #FormatImgID_56# 的更新和memory bank更新不一致

的問題。

\theta_\textrm{k}\leftarrow m\theta_\textrm{k}+(1-m)\theta_\textrm{q}\tag{2}

FAQ:MoCo方法裡面這個佇列 Queue 的內容是什麼,是如何生成的?

答:

是負樣本

\color{green}{k^{-}}

透過Momentum Encoder

f_\textrm{Mk}

f_\textrm{Mk}

採用2式的動量更新方法,而不是反向傳播) 之後輸出的值,它代表所有負樣本的 visual representation。佇列 Queue 的是 Batch size 的數倍大,且每個step都會進行一次 Dequeue 和 Enqueue 的操作更新佇列。

1.3 MoCo v2實驗

以上就是對 MoCo v1的概述,v2 將 SimCLR的兩個提點的方法 (

a 使用預測頭

b 使用強大的資料增強策略

) 移植到了 MoCo v1上面,實驗如下。

訓練集:

ImageNet 1。28 張訓練資料。

評價手段:

(1) Linear Evaluation

(在

Self-Supervised Learning 超詳細解讀 (二):SimCLR系列

文章中有介紹,Encoder (ResNet-50) 的引數固定不動,在Encoder後面加分類器,具體就是一個FC層+softmax啟用函式,使用全部的 ImageNet label 只訓練分類器的引數,而不訓練 Encoder 的引數)。看最後 Encoder+分類器的效能。

(2)

VOC 目標檢測

使用 Faster R-CNN 檢測器 (C4 backbone),在 VOC 07+12 trainval set 資料集進行 End-to-end 的 Fine-tune。在 VOC 07 test 資料集進行 Evaluation。

a 使用預測頭結果

預測頭 Projection head 分類任務的效能只存在於無監督的預訓練過程,在

Linear Evaluation和下游任務中都是被去掉的。

Linear Evaluation 結果如下圖5所示:

Self-Supervised Learning 超詳細解讀 (五):MoCo系列解讀 (2)

圖5:使用預測頭對比實驗Linear Evaluation 結果

圖中的

\tau

就是式1中的

\tau

。在使用預測頭且

\tau=0.07

時取得了最優的效能。

VOC 目標檢測如下圖6所示。在使用預測頭且預訓練的 Epoch 數為800時取得了最優的效能,AP各項指標也超越了有監督學習 supervised 的情況。

Self-Supervised Learning 超詳細解讀 (五):MoCo系列解讀 (2)

圖6:使用預測頭對比實驗VOC 目標檢測結果

b 使用強大的資料增強策略結果

如圖4所示,對資料增強策略,作者在 MoCo v1 的基礎上又添加了 blur augmentation,發現更強的色彩干擾作用有限。只新增 blur augmentation 就可以使得 ImageNet 分類任務的效能從60。6增長到63。4,再加上預測頭 Projection head 就可以使效能進一步漲到67。3。從圖 4 也可以看到:

VOC 目標檢測的效能和 ImageNet 分類任務的效能沒有直接的聯絡

與 SimCLR v1 的對比

如下圖7所示為 MoCo v2 與 SimCLR v1 效能的直接對比結果。預訓練的 Epochs 都取200。如果 Batch size 都取 256,MoCo v2在 ImageNet 有67。5的效能,超過了 SimCLR 的61。9的效能。即便 SimCLR 在更有利的條件下 (Batch size = 4096,Epochs=1000),其效能69。3也沒有超過 MoCo v2 的71。1的效能,證明了MoCo系列方法的地位。

Self-Supervised Learning 超詳細解讀 (五):MoCo系列解讀 (2)

圖7:與 SimCLR v1 的對比

小結

MoCo v2 把

SimCLR 中的兩個主要提升方法 (1 使用強大的資料增強策略,具體就是額外使用了 Gaussian Deblur 的策略 2 使用預測頭 Projection head)

到 MoCo 中,並且驗證了SimCLR演算法的有效性。最後的MoCo v2的結果更優於 SimCLR v1,證明 MoCo 系列自監督預訓練方法的高效性。

2 MoCo v3

論文名稱:An Empirical Study of Training Self-Supervised Vision Transformers

論文地址:

2.1 MoCo v3 原理分析

自監督學習模型一般可以分成 Generative 型別的或者 Contrastive 型別的。在 NLP 裡面的自監督學習模型 (比如本專欄第1篇文章介紹的BERT系列等等) 一般是屬於 Generative 型別的,通常把模型設計成 Masked Auto-encoder,即蓋住輸入的一部分 (Mask),讓模型預測輸出是什麼 (像做填空題),透過這樣的自監督方式預訓練模型,讓模型具有一個不錯的預訓練引數,且模型架構一般是個 Transformer。在 CV 裡面的自監督學習模型 (比如本專欄第2篇文章介紹的SimCLR系列等等) 一般是屬於 Contrastive 型別的,模型架構一般是個 Siamese Network (孿生神經網路),透過資料增強的方式創造正樣本,同時一個 Batch 裡面的其他資料為負樣本,透過使模型最大化樣本與正樣本之間的相似度,最小化與樣本與負樣本之間的相似度來對模型引數進行預訓練,且孿生網路架構一般是個 CNN。

這篇論文的重點是將目前無監督學習最常用的對比學習應用在 ViT 上。作者給出的結論是:

影響自監督ViT模型訓練的關鍵是:instability,即訓練的不穩定性。

而這種訓練的不穩定性所造成的結果

並不是訓練過程無法收斂 (convergence),而是效能的輕微下降 (下降1%-3%的精度)。

首先看 MoCo v3 的具體做法吧。它的損失函式和 v1 和 v2 版本是一模一樣的,都是 1 式:

\begin{equation} \small \mathcal{L}_{q, k^+, \{k^-\}} = -\log \frac{\exp(q{\cdot}k^+ / \tau)}{\exp(q{\cdot}k^+ / \tau) + {\displaystyle\sum_{k^-}}\exp(q{\cdot}k^-  / \tau)}. \label{eq:infonce} \end{equation} \tag{1}

那麼不一樣的是整個 Framework 有所差異,MoCo v3 的整體框架如下圖8所示,這個圖比論文裡的圖更詳細地刻畫了 MoCo v3 的訓練方法,讀者可以把圖8和上圖2做個對比,看看MoCo v3 的訓練方法和 MoCo v1/2 的訓練方法的差異。

Self-Supervised Learning 超詳細解讀 (五):MoCo系列解讀 (2)

圖8:MoCo v3方法,圖中n為Batch size

MoCo v3 的訓練方法和 MoCo v1/2 的訓練方法的差異是:

取消了 Memory Queue 的機制:

你會發現整套 Framework 裡面沒有 Memory Queue 了,那這意味著什麼呢?這就意味著 MoCo v3 所觀察的負樣本都來自一個 Batch 的圖片,也就是圖8裡面的

n

。換句話講,只有

當 Batch size 足夠大時,模型才能看到足夠的負樣本。

那麼 MoCo v3 具體是取了

4096

這樣一個巨大的 Batch size。

Encoder

f_\textrm{q}

除了 Backbone 和預測頭 Projection head 以外,還添加了個

Prediction head

,是遵循了 BYOL 這篇論文的方法。

對於同一張圖片的2個增強版本

\color{red}{x_1},\color{darkgreen}{x_2}

,分別透過

Encoder

f_\textrm{q}

Momentum

Encoder

f_\textrm{Mk}

得到

\color{red}{q_1},\color{darkgreen}{q_2}

\color{red}{k_1},\color{darkgreen}{k_2}

。讓

\color{red}{q_1},\color{darkgreen}{k_2}

透過 Contrastive loss (式 1) 進行最佳化

Encoder

f_\textrm{q}

的引數,讓

\color{darkgreen}{q_2},\color{red}{k_1}

透過 Contrastive loss (式 1) 進行最佳化

Encoder

f_\textrm{q}

的引數。

Momentum Encoder

f_\textrm{Mk}

透過式 2 進行動量更新。

\theta_\textrm{k}\leftarrow m\theta_\textrm{k}+(1-m)\theta_\textrm{q}\tag{2}

下面是虛擬碼,

f_\textrm{q}

f_\textrm{Mk}

在程式碼裡面分別表示為:

f_q

f_k。

1) 資料增強:

現在我們有一堆無標籤的資料,拿出一個 Batch,程式碼表示為

x

,也就是

N

張圖片,分別進行兩種不同的資料增強,得到

x_1

x_2

,則

x_1

N

張圖片,

x_2

也是

N

張圖片。

for

x

in

loader

# load a minibatch x with N samples

x1

x2

=

aug

x

),

aug

x

# augmentation

2) 分別透過 Encoder 和 Momentum Encoder:

x_1

分別透過 Encoder 和 Momentum Encoder 得到特徵

q_1

k_1

,維度是

N,C

,這裡特徵空間由一個長度為

C=128

的向量表示。

x_2

分別透過 Encoder 和 Momentum Encoder 得到特徵

q_2

k_2

,維度是

N,C

,這裡特徵空間由一個長度為

C=128

的向量表示。

q1

q2

=

f_q

x1

),

f_q

x2

# queries: [N, C] each

k1

k2

=

f_k

x1

),

f_k

x2

# keys: [N, C] each

3) 透過一個 Contrastive loss 最佳化 q_1 和 k_2,透過另一個 Contrastive loss 最佳化 q_2 和 k_1,並反向傳播更新 f_q 的引數:

loss

=

ctr

q1

k2

+

ctr

q2

k1

# symmetrized

loss

backward

()

update

f_q

# optimizer update: f_q

4) Contrastive loss 的定義:

對兩個維度是 (N,C) 的矩陣 (比如是q_1和k_2) 做矩陣相乘,得到維度是 (N,N) 的矩陣,其對角線元素代表的就是positive sample的相似度,就是讓對角線元素越大越好,所以目標是整個這個 (N,N) 的矩陣越接近單位陣越好,如下所示。

def

ctr

q

k

):

logits

=

mm

q

k

t

())

# [N, N] pairs

labels

=

range

N

# positives are in diagonal

loss

=

CrossEntropyLoss

logits

/

tau

labels

return

2

*

tau

*

loss

5) Momentum Encoder的引數使用動量更新:

f_k

=

m

*

f_k

+

1

-

m

*

f_q

# momentum update: f_k

全部的虛擬碼 (來自MoCo v3 的paper):

# f_q: encoder: backbone + pred mlp + proj mlp

# f_k: momentum encoder: backbone + pred mlp

# m: momentum coefficient

# tau: temperature

for

x

in

loader

# load a minibatch x with N samples

x1

x2

=

aug

x

),

aug

x

# augmentation

q1

q2

=

f_q

x1

),

f_q

x2

# queries: [N, C] each

k1

k2

=

f_k

x1

),

f_k

x2

# keys: [N, C] each

loss

=

ctr

q1

k2

+

ctr

q2

k1

# symmetrized

loss

backward

()

update

f_q

# optimizer update: f_q

f_k

=

m

*

f_k

+

1

-

m

*

f_q

# momentum update: f_k

# contrastive loss

def

ctr

q

k

):

logits

=

mm

q

k

t

())

# [N, N] pairs

labels

=

range

N

# positives are in diagonal

loss

=

CrossEntropyLoss

logits

/

tau

labels

return

2

*

tau

*

loss

以上就是 MoCo v3 的全部方法,都可以概括在圖8裡面。它的效能如何呢?假設 Encoder 依然取 ResNet-50,則 MoCo v2,MoCo v2+,MoCo v3 的對比如下圖9所示,主要的提點來自於

大的 Batch size (4096)

Prediction head 的使用

Self-Supervised Learning 超詳細解讀 (五):MoCo系列解讀 (2)

圖9:MoCo v2,MoCo v2+,MoCo v3 的對比 (Backbone: ResNet-50)

2.2 MoCo v3 自監督訓練 ViT 的不穩定性

上圖9的實驗結果證明了 MoCo v3 在

Encoder 依然取 ResNet-50

時的有效性。那麼當

Encoder 變成 Transformer

時的情況又如何呢?如本節一開始所述,作者給出的結論是:

影響自監督ViT模型訓練的關鍵是:instability,即訓練的不穩定性。

而這種訓練的不穩定性所造成的結果

並不是訓練過程無法收斂 (convergence),而是效能的輕微下降 (下降1%-3%的精度)。

Batch size 過大使得訓練不穩定

如下圖10所示是使用 MoCo v3 方法,Encoder 架構換成 ViT-B/16 ,Learning rate=1e-4,在 ImageNet 資料集上訓練 100 epochs 的結果。作者使用了4種不同的 Batch size:1024, 2048, 4096, 6144 的結果。可以看到當 bs=4096 時,曲線出現了 dip 現象 (稍稍落下又急速升起)。這種不穩定現象導致了精度出現下降。當 bs=6144 時,曲線的 dip 現象更大了,可能是因為跳出了當前的 local minimum。這種不穩定現象導致了精度出現了更多的下降。

Self-Supervised Learning 超詳細解讀 (五):MoCo系列解讀 (2)

圖10:Batch size過大使得訓練不穩定

Learning rate 過大使得訓練不穩定

如下圖11所示是使用 MoCo v3 方法,Encoder 架構換成 ViT-B/16 ,Batch size=4096,在 ImageNet 資料集上訓練 100 epochs 的結果。作者使用了4種不同的 Learning rate:0。5e-4, 1。0e-4, 1。5e-4 的結果。可以看到當Learning rate 較大時,曲線出現了 dip 現象 (稍稍落下又急速升起)。這種不穩定現象導致了精度出現下降。

Self-Supervised Learning 超詳細解讀 (五):MoCo系列解讀 (2)

圖11:Learning rate 過大使得訓練不穩定

LARS optimizer 的不穩定性

如下圖12所示是使用 MoCo v3 方法,Encoder 架構換成 ViT-B/16 ,Batch size=4096,在 ImageNet 資料集上訓練 100 epochs 的結果,不同的是使用了 LARS 最佳化器,分別使用了4種不同的 Learning rate:3e-4, 5e-4, 6e-4, 8e-4 的結果。結果發現當給定合適的學習率時,LARS的效能可以超過AdamW,但是當學習率稍微變大時,效能就會顯著下降。而且曲線自始至終都是平滑的,沒有 dip 現象。所以最終為了使得訓練對學習率更魯棒,作者還是採用 AdamW 作為最佳化器。因為若採用 LARS,則每換一個網路架構就要重新搜尋最合適的 Learning rate。

Self-Supervised Learning 超詳細解讀 (五):MoCo系列解讀 (2)

圖12:LARS optimizer 的不穩定性

2.3 提升訓練穩定性的方法:凍結第1層 (patch embedding層) 引數

上面圖10-12的實驗表明 Batch size 或者 learning rate 的細微變化都有可能導致 Self-Supervised ViT 的訓練不穩定。作者發現

導致訓練出現不穩定的這些 dip 跟梯度暴漲 (spike) 有關

,如下圖13所示,

第1層會先出現梯度暴漲的現象,結果幾十次迭代後,會傳到到最後1層

Self-Supervised Learning 超詳細解讀 (五):MoCo系列解讀 (2)

圖13:第1層會先出現梯度暴漲的現象,結果幾十次迭代後,會傳到到最後1層

所以說

問題就出在第1層出現了梯度暴漲啊

,一旦第1層梯度暴漲,這個現象就會在幾十次迭代之內傳遍整個網路。所以說想解決訓練出現不穩定的問題就不能讓第1層出現梯度暴漲!

所以作者解決的辦法是凍結第1層的引數 ,也就是patch embedding那層,隨機初始化後,不再更新這一層的引數,然後發現好使,如圖14所示。

patch embedding那層具體就是一個

k=p=16,s=p=16

的卷積操作,輸入 channel 數是3,輸出 channel 數是embed_dim=768/384/192。

patch embedding 程式碼:

self

proj

=

nn

Conv2d

in_chans

embed_dim

kernel_size

=

patch_size

stride

=

patch_size

如下圖14,15所示是使用 MoCo v3 or SimCLR, BYOL 方法,Encoder 架構換成 ViT-B/16 ,Batch size=4096,在 ImageNet 資料集上訓練 100 epochs 的結果,不同的是凍結了patch embedding那層的引數,使用了隨機引數初始化。

圖14和15表明不論是 MoCo v3 還是 SimCLR, BYOL 方法,凍結 patch embedding 那層的引數都能夠提升自監督 ViT 的訓練穩定性。除此之外, gradient-clip 也能夠幫助提升訓練穩定性,其極限情況就是凍結引數。

Self-Supervised Learning 超詳細解讀 (五):MoCo系列解讀 (2)

圖14:提升訓練穩定性的方法:凍結第1層 (patch embedding層) 的引數 (MoCo v3方法)

Self-Supervised Learning 超詳細解讀 (五):MoCo系列解讀 (2)

圖15:提升訓練穩定性的方法:凍結第1層 (patch embedding層) 的引數 (SimCLR, BYOL 方法)

2.4 MoCo v3 實驗

超引數細節

超引數

具體值

Optimizer

AdamW,bs=4096,epochs=100,搜尋lr和wd的最優解,warmup=40 epochs,cosine decay learning rate

Projection head

3層的 MLP,啟用函式ReLU, hidden dim=4096,output dim=256

Prediction head

2層的MLP,啟用函式ReLU, hidden dim=4096,output dim=256

loss

超引數tau=0。2

評價指標

Linear Evaluation (或者叫 Linear Classification,Linear Probing),在本專欄之前的文章介紹過,具體做法是:凍結Encoder的引數,在Encoder之後新增一個分類頭 (FC層+softmax),使用全部的標籤只訓練這個分類頭的引數,得到的測試集精度就是自監督模型的精度。

如下圖16所示是ViT-S/16 和 ViT-B/16 模型在4種自監督學習框架下的效能對比。為了確保對比的公平性,lr 和 wd 都經過了搜尋。結果顯示 MoCo v3 框架具有最優的效能。

Self-Supervised Learning 超詳細解讀 (五):MoCo系列解讀 (2)

圖16:ViT-S/16 and ViT-B/16在不同框架的效能對比

下圖17展示的是不同的自監督學習框架對 ViT 和 ResNet 模型的偏愛,可以看出 SimCLR 和 MoCo v3 這兩個自監督框架在 ViT 類的 Transformer 模型上的效果更好。

Self-Supervised Learning 超詳細解讀 (五):MoCo系列解讀 (2)

圖17:不同的自監督學習框架對 ViT 和 ResNet 模型的偏愛不同

對比實驗:

1) 位置編碼的具體形式

如下圖18所示,最好的位置編碼還是餘弦編碼 sin-cos。在無監督訓練過程去除位置編碼,效果下降了1個多點,說明 ViT 的學習能力很強,在沒有位置資訊的情況下就可以學習的很好;從另外一個角度來看,也說明 ViT 並沒有充分利用好位置資訊。

Self-Supervised Learning 超詳細解讀 (五):MoCo系列解讀 (2)

圖18:位置編碼的具體形式

2) class token 的必要性

如下圖19所示,使用 class token 的效能是76。5,而簡單地取消 class token,並換成 Global Average Pooling 會下降到69。7,這時候最後一層後面有個LN層。如果把它也去掉,效能會提升到76。3。說明 class token 並不是必要的,LN的選擇也很重要。

Self-Supervised Learning 超詳細解讀 (五):MoCo系列解讀 (2)

圖19:class token 的必要性

3) Prediction head 的必要性

如下圖20所示,去掉 Prediction head 會使效能稍微下降。

Self-Supervised Learning 超詳細解讀 (五):MoCo系列解讀 (2)

圖20:Prediction head 的必要性

4) momentum 超引數的影響

如下圖21所示,momentum 超引數取0。99是最優的。m=0就是 Momentum Encoder

f_\textrm{Mk}

的引數和 Encoder

f_\textrm{q}

的引數完全一致,那就是 SimCLR 的做法了。

Self-Supervised Learning 超詳細解讀 (五):MoCo系列解讀 (2)

圖21:momentum 超引數的影響

MoCo v3與其他模型的效能對比

Self-supervised Transformer 的效能對比可以有兩個方向,一個是跟 Supervised Transformer對比,另一個是跟 Self-supervised CNN對比。

第1個方向的對比如下圖22所示。雖然 MoCo v3-VIT-L 引數量 比 VIT-B 大了很多,但 VIT-B訓練的資料集比 ImageNet 大很多。

Self-Supervised Learning 超詳細解讀 (五):MoCo系列解讀 (2)

圖22:跟 Supervised Transformer對比

第2個方向的對比如下圖23所示。作者跟採用了 Big ResNet 的方法進行對比,以 VIT-L 為backbone的 MoCo v3 完勝。注意圖23這個表的每一列表示的是把 MoCo v3的方法用在每一列對應的模型上的效能 (比如第2列就是在 ViT-B 這種模型使用 MoCo v3)。第1行就代表直接使用這個模型,第2行代表把 ViT 模型裡面的 LN 全部換成 BN 的效果 (以ViT-BN 表示),第3行代表再把 ViT 模型的 patch 大小設定為7以獲得更長的sequence (以ViT-BN/7 表示),但是這會使計算量變為6倍。而且這裡沒有列出各個模型的引數量,可能存在不公平對比的情況。

Self-Supervised Learning 超詳細解讀 (五):MoCo系列解讀 (2)

圖23:跟 Self-supervised CNN對比

小結

MoCo v3 的改進如圖8所示,取消了 Memory Queue 的機制,添加了個

Prediction head

,且對於同一張圖片的2個增強版本

\color{red}{x_1},\color{darkgreen}{x_2}

,分別透過

Encoder

f_\textrm{q}

Momentum

Encoder

f_\textrm{Mk}

得到

\color{red}{q_1},\color{darkgreen}{q_2}

\color{red}{k_1},\color{darkgreen}{k_2}

。讓

\color{red}{q_1},\color{darkgreen}{k_2}

透過 Contrastive loss 進行最佳化

Encoder

f_\textrm{q}

的引數,讓

\color{darkgreen}{q_2},\color{red}{k_1}

透過 Contrastive loss 進行最佳化

Encoder

f_\textrm{q}

的引數。

在 Self-supervised 訓練 Transformer 的過程中發現了 instablity 的問題,透過凍住patch embedding的引數,以治標不治本的形式解決了這個問題,最終Self-supervised Transformer 可以 beat 掉 Supervised Transformer 和 Self-supervised CNN。