一文梳理無(wú)監(jiān)督對(duì)比學(xué)習(xí)(MoCo/SimCLR/SwAV/BYOL/SimSiam)

極市導(dǎo)讀
?本文從對(duì)比學(xué)習(xí)的概念出發(fā),收集了五個(gè)2020年的關(guān)于對(duì)比學(xué)習(xí)的經(jīng)典研究,詳細(xì)介紹了每個(gè)工作的模型及思路過(guò)程,幫助大家快速掌握對(duì)比學(xué)習(xí)的原理和發(fā)展的脈絡(luò)。?>>12月10日(周四)極市直播|湯凱華:利用因果分析解決通用的長(zhǎng)尾分布問(wèn)題
對(duì)比學(xué)習(xí)的概念很早就有了,但真正成為熱門(mén)方向是在2020年的2月份,Hinton組的Ting Chen提出了SimCLR,用該框架訓(xùn)練出的表示以7%的提升刷爆了之前的SOTA,甚至接近有監(jiān)督模型的效果。在SimCLR推出后,各路大佬們又陸續(xù)提出了不少有意義的工作,本文將對(duì)2020年的一些對(duì)比學(xué)習(xí)經(jīng)典研究進(jìn)行總結(jié),方便大家快速掌握這個(gè)方向的原理和發(fā)展脈絡(luò)。
首先再簡(jiǎn)要說(shuō)下對(duì)比學(xué)習(xí)的基本原理,先從無(wú)監(jiān)督表示學(xué)習(xí)講起。表示學(xué)習(xí)的目標(biāo)是為輸入?
?學(xué)習(xí)一個(gè)表示?
?,最好的情況就是知道?
?就能知道?
?。這就引出了無(wú)監(jiān)督表示學(xué)習(xí)的第一種做法:生成式自監(jiān)督學(xué)習(xí)。比如還原句子中被mask的字,或者還原圖像中被mask的像素。但這種方式的前提需要假設(shè)被mask的元素是相互獨(dú)立的,不符合真實(shí)情況。另一方面,研究者們也質(zhì)疑如此細(xì)粒度的還原是否真正必要。
舉個(gè)例子,假如有人讓你憑空畫(huà)一張一美元,你可能只畫(huà)成這樣[1]:

而如果給你一張美元照著臨摹,可能還能畫(huà)好看點(diǎn),比如這樣:

所以說(shuō)我們記住的事物特征,不一定是像素級(jí)別的,而是更高維度的。更具體來(lái)說(shuō),比如用編碼去做分類(lèi)任務(wù),我們不需要知道每個(gè)數(shù)據(jù)的細(xì)節(jié),只要抓住每個(gè)類(lèi)別的主要特征,自然就能把他們分開(kāi)了:

不重構(gòu)數(shù)據(jù),那如何衡量表示?
?的好壞呢?這時(shí)也可以用互信息?
?,代表我們知道了?
?之后,
?的信息量減少了多少。如果對(duì)最大化互信息的目標(biāo)進(jìn)行推導(dǎo)[2],就會(huì)得到對(duì)比學(xué)習(xí)的loss(也稱(chēng)InfoNCE),其核心是通過(guò)計(jì)算樣本表示間的距離,拉近正樣本,拉遠(yuǎn)負(fù)樣本。也就是說(shuō),當(dāng)我們能夠區(qū)分該樣本的正負(fù)例時(shí),得到的表示就夠用了。
具體的做法是,輸入N個(gè)圖片,用不同的數(shù)據(jù)增強(qiáng)方法為每個(gè)圖片生成兩個(gè)view,分別對(duì)它們編碼得到y(tǒng)和y'。我們對(duì)上下兩批表示兩兩計(jì)算cosine,得到NxN的矩陣,每一行的對(duì)角線位置代表y和y'的相似度,其余代表y和N-1個(gè)負(fù)例的相似度。

對(duì)每一行做softmax分類(lèi),采用交叉熵?fù)p失作為loss,就得到對(duì)比學(xué)習(xí)的損失了:

其中
?是可調(diào)節(jié)的系數(shù)。
對(duì)比學(xué)習(xí)的原理很簡(jiǎn)單,比較粗暴的優(yōu)化方向就是增加view難度、增加更多負(fù)例、提升encoder表現(xiàn)等。下面就讓我們看看大佬們?cè)谶@一年里是如何花式優(yōu)化的。
MoCo(CVPR20)
既然對(duì)比是在正負(fù)例之間進(jìn)行的,那負(fù)例越多,這個(gè)任務(wù)就越難,于是一個(gè)優(yōu)化方向就是增加負(fù)例。
純粹的增大batch size是不行的,總會(huì)受到GPU內(nèi)存限制。一個(gè)可行的辦法就是增加memory bank,把之前編碼好的樣本存儲(chǔ)起來(lái),計(jì)算loss的時(shí)候一起作為負(fù)例:

但這樣有個(gè)問(wèn)題是存儲(chǔ)好的編碼都是之前的編碼器計(jì)算的,而
的編碼器一直在更新,會(huì)有兩側(cè)不一致的情況,影響目標(biāo)優(yōu)化。一個(gè)可行方法之一就是用最新的左側(cè)encoder更新編碼再放入memory bank,但這依然避免不了memory bank中表示不一致的情況,實(shí)驗(yàn)效果很差。還有研究用動(dòng)量去更新樣本表示,但這樣必須存儲(chǔ)所有樣本,消耗過(guò)多內(nèi)存。
所以何凱明大佬在2019年底推出了MoCo(Momentum Contrast)模型[3],延續(xù)memory bank的思想,使用動(dòng)量的方式更新encoder參數(shù),解決新舊候選樣本編碼不一致的問(wèn)題:
對(duì)于每個(gè)batch x:
隨機(jī)增強(qiáng)出?
、
?兩種view分別用?
、
?對(duì)輸入進(jìn)行編碼得到歸一化的 q 和 k,并去掉 k 的梯度更新將 q 和 k 一一對(duì)應(yīng)相乘得到正例的cosine(Nx1),再將 q 和隊(duì)列中存儲(chǔ)的K個(gè)負(fù)樣本相乘(NxK),拼接起來(lái)的到 Nx(1+K) 大小的矩陣,這時(shí)第一個(gè)元素就是正例,直接計(jì)算交叉熵?fù)p失,更新?
?的參數(shù)動(dòng)量更新?
?的參數(shù):
將 k 加入隊(duì)列,把隊(duì)首的舊編碼出隊(duì),負(fù)例最多時(shí)有65536個(gè)
這樣每次入隊(duì)的新編碼都是上一步更新后的編碼器輸出,以很低的速度慢慢迭代,與舊編碼盡量保持一致。實(shí)驗(yàn)發(fā)現(xiàn),m=0.999時(shí)比m=0.9好上很多。最終在ImageNet的實(shí)驗(yàn)效果也遠(yuǎn)超前人,成為當(dāng)時(shí)的SOTA:

SimCLR(ICML20)
SimCLR是Hinton組的Chen Ting在20年2月提出的工作,直接比MoCo高出了7個(gè)點(diǎn),并直逼監(jiān)督模型的結(jié)果:

框架結(jié)構(gòu)還是采用雙塔:

主要做了以下改動(dòng):
探究了不同的數(shù)據(jù)增強(qiáng)組合方式,選取了最優(yōu)的 在encoder之后增加了一個(gè)非線性映射
?。研究發(fā)現(xiàn)encoder編碼后的
會(huì)保留和數(shù)據(jù)增強(qiáng)變換相關(guān)的信息,而非線性層的作用就是去掉這些信息,讓表示回歸數(shù)據(jù)的本質(zhì)。注意非線性層只在無(wú)監(jiān)督訓(xùn)練時(shí)用,在遷移到其他任務(wù)時(shí)不使用計(jì)算loss時(shí)多加了負(fù)例。以前都是拿右側(cè)數(shù)據(jù)的N-1個(gè)作為負(fù)例,SimCLR將左側(cè)的N-1個(gè)也加入了進(jìn)來(lái),總計(jì)2(N-1)個(gè)負(fù)例。另外SImCLR不采用memory bank,而是用更大的batch size,最多的時(shí)候bsz為8192,有16382個(gè)負(fù)例
MoCo v2
SimCLR推出后一個(gè)月,何凱明和Chen Xinlei同學(xué)對(duì)MoCo進(jìn)行了一些小改動(dòng):
改進(jìn)了數(shù)據(jù)增強(qiáng)方法 訓(xùn)練時(shí)在encoder的表示上增加了相同的非線性層 為了對(duì)比,學(xué)習(xí)率采用SimCLR的cosine衰減

經(jīng)過(guò)改動(dòng)后,以更小的batch size就超過(guò)了SimCLR的表現(xiàn):

SimCLR v2(NIPS20)
在2020年中,Hinton組的Chen Ting同學(xué)又提出了SimCLR v2[4],主要做了以下改動(dòng):
采用更深但維度略小的encoder,從 ResNet-50 (4×) 改到了 ResNet-152 (3×+SK),在1%的監(jiān)督數(shù)據(jù)下提升了29個(gè)點(diǎn) 采用更深的3層MLP,并在遷移到下游任務(wù)時(shí)保留第一層(以前是完全舍棄),在1%的監(jiān)督數(shù)據(jù)下提升了14個(gè)點(diǎn) 參考了MoCo使用memory,但由于batch已經(jīng)足夠大了,只有1%左右的提升
最終模型比之前的SOTA好了不少:

SwAV(NIPS20)
對(duì)比學(xué)習(xí)需要很多負(fù)例進(jìn)行比較,既耗時(shí)又耗內(nèi)存,于是FAIR聯(lián)合Inria也推出了一個(gè)新的方法SwAV。作者提出了一個(gè)新的想法:對(duì)各類(lèi)樣本進(jìn)行聚類(lèi),然后去區(qū)分每類(lèi)的類(lèi)簇。模型結(jié)構(gòu)如下:

具體的做法是,先用K個(gè)點(diǎn)?
?表示聚類(lèi)中心(prototypes),給定一個(gè)batch的編碼?
,將其通過(guò)?
?映射到一組新的向量?
。這里假設(shè)向量都是d維的[5],那C的維度就是 dxK,Z的維度是 dxB,Q的維度則是KxB,每個(gè)元素?
?相當(dāng)于第k個(gè)聚類(lèi)中心與第b個(gè)樣本的相似度,理想情況下,樣本與自己的類(lèi)簇中心相似度為1,與其他的為0,
其實(shí)就是一個(gè)one-hot label。不過(guò)作者發(fā)現(xiàn)soft label效果會(huì)好一些。這樣每個(gè)樣本又獲得了一個(gè)新的表示(Codes)。
有了?
?和?
?之后,理論上同一張圖片不同view所產(chǎn)生的?
?和?
?也可以相互預(yù)測(cè),作者便定義了新的loss:

其中


BYOL
上文講的方法來(lái)回都逃不過(guò)“對(duì)比”這個(gè)范式,而DeepMind提出的BYOL則給了我們一個(gè)不同視角。
在表示學(xué)習(xí)中,我們現(xiàn)在采用的框架本質(zhì)是通過(guò)一個(gè)view的表示去預(yù)測(cè)相同圖像其他view,能預(yù)測(cè)對(duì)說(shuō)明抓住了圖像的本質(zhì)特征。但在做這樣的預(yù)測(cè)時(shí)會(huì)有坍縮(collapse)的風(fēng)險(xiǎn),意思是全都變成一個(gè)表示,那也可以做到預(yù)測(cè)自己。對(duì)比學(xué)習(xí)為了解決這個(gè)問(wèn)題,將表示預(yù)測(cè)問(wèn)題轉(zhuǎn)換為了正負(fù)例判別問(wèn)題,這樣就迫使模型的輸出是多樣的,避免坍縮。
于是BYOL的作者想:如何不用負(fù)例,也能學(xué)到好的表示呢?如果共用encoder,用MSE作為損失,縮小相同圖像不同view的距離,肯定會(huì)坍縮。而作者發(fā)現(xiàn)如果把其中一個(gè)encoder變成隨機(jī)初始化的固定下來(lái)(stop gradient),就能達(dá)到18.8%的準(zhǔn)確率。為了得到更好的encoder,作者參考動(dòng)量的方法對(duì)其中一個(gè)encoder做了改進(jìn):

這里我們按照論文,稱(chēng)上半部分為online(更新梯度),下半部分為target(不更新梯度)。BYOL的優(yōu)化目的是用online表示預(yù)測(cè)target表示,采用MSE作為損失函數(shù)。Online梯度回傳后,使用滑動(dòng)平均對(duì)targe的encoder和MLP參數(shù)進(jìn)行更新。在預(yù)測(cè)階段只使用
?。
雖然BYOL沒(méi)有顯示地使用對(duì)比學(xué)習(xí)loss,但一篇博主在實(shí)驗(yàn)[6]中發(fā)現(xiàn)BYOL依靠的還是“對(duì)比”。他們?cè)趶?fù)現(xiàn)BYOL的時(shí)候直接基于了MoCo的代碼,結(jié)果發(fā)現(xiàn)效果還沒(méi)有隨機(jī)的好,原來(lái)是因?yàn)镸LP中沒(méi)有加BN。如果深究BN的作用,就會(huì)發(fā)現(xiàn)它重新調(diào)整了輸出的分布,避免坍縮,同時(shí)BN也在隱式地進(jìn)行對(duì)比,去除batch內(nèi)樣本相同的部分,保留不同的特征。
同時(shí),在不依賴負(fù)樣本后,BYOL對(duì)于數(shù)據(jù)增強(qiáng)方法的選擇更加魯棒,下面是它的效果:

SimSiam
延續(xù)BYOL的思想,Chen Xinlei與何凱明大佬又對(duì)孿生網(wǎng)絡(luò)進(jìn)行了研究,發(fā)現(xiàn)stop-gradient是避免坍縮的關(guān)鍵,于是提出了SimSiam。
SimSiam的結(jié)構(gòu)非常簡(jiǎn)單:

左側(cè)的編碼器生成?
,經(jīng)過(guò)MLP后輸出?
右側(cè)的編碼器生成?

計(jì)算?
?與?
?的cosine相似度左右調(diào)換,再計(jì)算?
?與?
?的cosine相似度最大化3、4兩個(gè)步驟的和,且右側(cè)永遠(yuǎn)不傳播梯度
訓(xùn)練步驟雖然簡(jiǎn)潔,但為什么work卻有很多學(xué)問(wèn)。簡(jiǎn)單的解釋是,對(duì)于整體目標(biāo)的優(yōu)化可以看作一個(gè)EM過(guò)程,左右兩邊交替更新,所以在更新左側(cè)encoder時(shí)可以將右側(cè)看成常數(shù)。更多的細(xì)節(jié)可以參考Andy的詳解。
最終SimSiam的效果超過(guò)了眾多前輩,但仍比BYOL差3個(gè)點(diǎn):

同時(shí)他們提到,孿生網(wǎng)絡(luò)自帶建模不變性(invariance)的歸納偏置(inductive bias):
two observations of the same concept should produce the same outputs
這個(gè)發(fā)現(xiàn)可以幫我們理解為什么孿生網(wǎng)絡(luò)效果很好,表示學(xué)習(xí)就是要建模數(shù)據(jù)中的不變性。
其他細(xì)節(jié)
1. 數(shù)據(jù)增強(qiáng)方法

SimCLR中對(duì)數(shù)據(jù)增強(qiáng)方法進(jìn)行了研究,得到了兩個(gè)結(jié)論:
不同的數(shù)據(jù)增強(qiáng)方式組合起來(lái)會(huì)更好,單一增強(qiáng)的任務(wù)太簡(jiǎn)單 Crop和Color組合的方式最好,因?yàn)榇蠖鄶?shù)圖像中的顏色是比較一致的,即使裁剪也會(huì)容易辨認(rèn),如果去掉顏色會(huì)增加任務(wù)難度
2. BatchNorm導(dǎo)致的信息泄露
在分布式訓(xùn)練中,BN都是分別在各個(gè)設(shè)備上做的。而對(duì)比學(xué)習(xí)的正例對(duì)在一個(gè)機(jī)器上計(jì)算,會(huì)出現(xiàn)信息泄露。個(gè)人認(rèn)為,在BN去除batch內(nèi)共同特征時(shí),很可能被歸一化到相似的分布,降低任務(wù)難度。
MoCo的解決辦法是把一邊的樣本重新shuffle再并行,另一邊順序不變,這樣batch的統(tǒng)計(jì)量就不同了;SimCLR的解法是計(jì)算一個(gè)全局的BN值。
3. MLP
在SimCLR以后的工作中都使用了MLP,SimSiam也對(duì)它的作用進(jìn)行了探究:

可以看到不使用MLP基本沒(méi)效果可言。作者通過(guò)實(shí)驗(yàn)發(fā)現(xiàn):MLP可能承擔(dān)了估計(jì)整體期望的功能。這同SimCLR最初增加MLP時(shí)的發(fā)現(xiàn)是一致的,核心思想還是過(guò)濾表示中的無(wú)效特征,得到本質(zhì),服務(wù)于“對(duì)比”任務(wù)。
總結(jié)
對(duì)比學(xué)習(xí)在2020年異?;鸨?,CV領(lǐng)域的高質(zhì)量研究層出不窮,很多都超過(guò)了有監(jiān)督學(xué)習(xí)的表現(xiàn)。這次我們只介紹了無(wú)監(jiān)督對(duì)比學(xué)習(xí),實(shí)際上它在有監(jiān)督任務(wù)上也有應(yīng)用,同時(shí)NLP、Graph領(lǐng)域也都看得到它的身影。期待CV與NLP領(lǐng)域相互借鑒,碰撞出更好的工作。
參考資料
推薦閱讀
ReID任務(wù)大幅領(lǐng)先,港中文開(kāi)源自步對(duì)比學(xué)習(xí)框架,充分挖掘無(wú)監(jiān)督學(xué)習(xí)樣本|NeurIPS 2020
ICLR 2020 | 精度逼近有監(jiān)督,港中文提出無(wú)監(jiān)督學(xué)習(xí)框架:同步平均教學(xué)
圖像分類(lèi)最新技術(shù)綜述論文: 21種半監(jiān)督、自監(jiān)督和無(wú)監(jiān)督學(xué)習(xí)方法一較高低

