『論文筆記』MoCo:Momentum Contrast for Unsupervised Visual Representation Learning


我認為MoCo這篇最創新的地方,就是解決了一個非常重要但以前又沒有思路的工程問題,就是怎么節省內存節省時間搞到大量的negative sample。之前的memory bank雖然機智,但是必須存下來整個數據集,空間開銷O(N),所以處理不了Instagram級別的數據,這個問題困擾我很久而且我沒找到有效策略,我試過跟MoCo一樣用一個queue,也是存過去m個batch的sample,這個其實很容易想到,但我發現效果不好,問題就是我只有一個encoder,我沒有像他一樣在不斷update這個encoder的同時保存一個它的歷史smooth的版本。這點說透了后聽起來就沒那么復雜, 但在他們發現這點之前這個辦法並不顯然, kaiming在這些地方總是尤為厲害, 哎真的學不來。 (又跟同學學習了一下, 這個相似trick在Q-learning里面就很多被用到, 大家update Q-function的時候就是用類似的momentum去做的,看來是我學得太少)。

作者:田永龍
鏈接:https://www.zhihu.com/question/355779873/answer/895625711
來源:知乎
著作權歸作者所有。商業轉載請聯系作者獲得授權,非商業轉載請注明出處。



對比是在正負例之間進行的,那負例越多,這個任務就越難,於是一個優化方向就是增加負例。

純粹的增大batch size是不行的,總會受到GPU內存限制。一個可行的辦法就是增加memory bank,把之前編碼好的樣本存儲起來,計算loss的時候一起作為負例:

 

但這樣有個問題是存儲好的編碼都是之前的編碼器計算的,而xq的編碼器一直在更新,會有兩側不一致的情況,影響目標優化。一個可行方法之一就是用最新的左側encoder更新編碼再放入memory bank,但這依然避免不了memory bank中表示不一致的情況,實驗效果很差。還有研究用動量去更新樣本表示,但這樣必須存儲所有樣本,消耗過多內存。

所以何凱明在2019年底推出了MoCo(Momentum Contrast)模型,延續memory bank的思想,使用動量的方式更新encoder參數,解決新舊候選樣本編碼不一致的問題:

 

 

x_q:代表某一圖片(定義為P_q)的圖像增強操作(旋轉、平移、剪切等)后的一個矩陣;

x_k:代表多張圖片(定義為P_K, 其中P_K包含P_q)的圖像增強操作后的多個矩陣的矩陣集;

encoder,momentum encoder:分別代表兩個編碼網絡,這兩個網絡的結構相同,參數不同;

q:x_q經過encoder網絡編碼后的一個向量;

k:x_k經過momentum encoder網絡編碼后的多個向量;

contrastive loss(即L_q):

 

 

其中:

k_+是指x_k矩陣集中的那個來自對P_q圖片的一次增強操作后形成的矩陣,經過momentum encoder網絡編碼后,形成的一個向量;

k_i是指x_k矩陣集中的每一個矩陣,經過momentum encoder網絡編碼后,形成的一個向量;這樣的向量一共有K+1個(包含k_+),其中只有k_+是來自P_q圖片,其它均來自“非”P_q圖片;

T是一個常數;訓練過程:

最小化L_q,通過后反饋僅調整更新encoder網絡參數;而momentum encoder網絡參數通過如下公式(momentum update)直接更新:

 


其中θ_k是指momentum encoder網絡參數,θ_q是指encoder網絡參數,m是一個介於0.0~ 1.0的動量系數。

這樣每次入隊的新編碼都是上一步更新后的編碼器輸出,以很低的速度慢慢迭代,與舊編碼盡量保持一致。實驗發現,m=0.999時比m=0.9好上很多。最終在ImageNet的實驗效果也遠超前人,成為當時的SOTA:

訓練過程如下:

1 初始化

准備一批圖片Ps(如共1000000張圖片,編號0~1000000)。

創建encoder和momentum encoder兩個模型,這兩個模型的網絡結構是一樣的,初始參數也是一樣的(訓練開始后兩者參數將不再一樣)。

從Ps中選擇前n張(如n=5000)進行數據增強操作得5000個矩陣,並將這些矩陣輸入到momentum encoder生成5000個d維(如d=128)向量;定義這5000個128維的向量集合為Queue(Queue將是動態更新的)。

2 訓練單元

2.1 從Ps中提取1張(第5001張)新圖片pi;

2.2 對pi進行一次數據增強得矩陣x_q_i,其shape=[1, 224, 224, 3];對pi再進行一次數據增強得矩陣集x_k_i,其shape=[1, 224, 224,3];其中x_q_i和x_k_i兩者並不相同,但是都是pi的一次增強。

2.3 將x_q_i輸入到encoder網絡得矩陣q_i,其shape=[1, 128];將x_k_i輸入到momentum encoder網絡得矩陣k_i,其shape=[1, 128]。

2.4 從Queue中取出所有向量(共k個)k_is,其shape=[k, 128]。

2.5 定義q_i為q,其shape=[1,128];將k_i和k_is合並定義為Ks,其shape=[k+1, 128]。

2.6 更新網絡參數

由如下公式計算loss(其中k+是k_i,其它ki均來自k_is):

 


最小化該loss函數,由后反饋僅更新encoder網絡參數;而momentum encoder網絡參數由如下公式更新(其中θ_k,θ_q分別是momentum encoder網絡和encoder網絡參數):

 

2.7 更新Queue

刪除Queue的第一個元素,並在其最后添加元素k_i;操作后Queue的size不變。

2.8 實際訓練是批量進行的,即Ps中同時取出N(如n=256)張新圖片,同時進行上述處理,Queue的更新的最小單元也是256個。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM