論文為:Finn C, Abbeel P, Levine S, et al. Model-agnostic meta-learning for fast adaptation of deep networks[C]. international conference on machine learning, 2017: 1126-1135.
代碼地址(tensorflow版本):https://github.com/cbfinn/maml
復(fù)現(xiàn)這個詞,有兩點(diǎn)不太好,但我暫時想不到更簡練的詞了。
1.代碼不是自己寫的,只是按照原論文的參數(shù)訓(xùn)練模型和測試,以理解和驗證論文;
2.由于個人硬件資源的限制,并沒有完全按照原論文的參數(shù),個別參數(shù)按照自己的理解與硬件資源適配,做了部分調(diào)整。
下面,就把我的經(jīng)歷做下整理。
一、元學(xué)習(xí)與少次學(xué)習(xí)
開始看元學(xué)習(xí)的出發(fā)點(diǎn)是面臨一個(實體關(guān)系抽取任務(wù))數(shù)據(jù)量較少可能訓(xùn)練模型和測試結(jié)果會不太好,的這樣一個問題,然后看了清華大學(xué)高天宇同學(xué)的分享,https://www.bilibili.com/video/BV1GJ411W79k
發(fā)現(xiàn)他們解決這一問題(他們是以數(shù)據(jù)長尾現(xiàn)象的角度切入的),利用少次學(xué)習(xí)的方法,而其中的一類方法就是元學(xué)習(xí)的方法,并且元學(xué)習(xí)方法在近兩年特別火,所以就入手看了。
知道這兩個概念,并且拿到論文之后,就開始在網(wǎng)上搜,發(fā)現(xiàn)這兩個概念往往被大家混為一談,因為可能涉獵未深,有時候雖然覺得博客上說的不對,但自己也想不到一個合理的解釋,同時沒點(diǎn)積淀,論文也是難啃的,能接受論文里面的說法,但是沒有完全被大腦接受。因此,就在各種說法中浮浮沉沉,后來看到臺灣大學(xué)李宏毅老師的課程,https://www.bilibili.com/video/BV1J4411a7Bz?from=search&seid=8751855545990768949
才簡單理解了,下面這段話是我匯報“元學(xué)習(xí)入門”時自己總結(jié)的(看完上面視頻才能大致理解這段話)。
少次學(xué)習(xí),顧名思義,就是給定少量數(shù)據(jù)進(jìn)行訓(xùn)練的任務(wù),或者訓(xùn)練數(shù)據(jù)很少這樣場景下的學(xué)習(xí)任務(wù)。
一個大的觀點(diǎn)是說少次學(xué)習(xí)是元學(xué)習(xí)在監(jiān)督學(xué)習(xí)領(lǐng)域的應(yīng)用,另一個是說元學(xué)習(xí)和少次學(xué)習(xí)是兩個不同的東西,元學(xué)習(xí)更像是一種學(xué)習(xí)架構(gòu),少次學(xué)習(xí)是一種具體的學(xué)習(xí)任務(wù)。
而從概念本身來看,元學(xué)習(xí)的訓(xùn)練需要一系列的task,如果我們把其中一個task當(dāng)作普通的機(jī)器學(xué)習(xí)任務(wù)那樣,喂給大量的數(shù)據(jù),讓它很多次地通過迭代計算,這樣的方式去訓(xùn)練,有的算法需要耗費(fèi)幾天的時間,而元學(xué)習(xí)這種多任務(wù)的思路,將會變得無法訓(xùn)練,
因此,我門通常以少次學(xué)習(xí)任務(wù)來作為元學(xué)習(xí)訓(xùn)練的一個個任務(wù),這也是為什么元學(xué)習(xí)方法被大量應(yīng)用于少次學(xué)習(xí)任務(wù)中。
二、初跑代碼
從readme來看,我最后創(chuàng)建的python虛擬環(huán)境為python3.6.7+tensorflow1.15.2。

從元學(xué)習(xí)的論文出發(fā),它實現(xiàn)了三類任務(wù):回歸、分類和強(qiáng)化學(xué)習(xí)。第一個任務(wù)用的數(shù)據(jù)集比較簡單,正弦曲線的擬合可以幫助理解元學(xué)習(xí)算法的過程;第二個任務(wù)用的數(shù)據(jù)集雖然是圖像,但是任務(wù)類型可以和要做的事情相匹配,所以需要跑下數(shù)據(jù),理解分類任務(wù)的實現(xiàn)過程;第三個任務(wù)目前暫時看來還關(guān)系不大,就先沒跑實驗。
疫情期間,在家只有筆記本,操作系統(tǒng)是windows10,cpu是Intel(R) Core(TM) i7-8550U CPU @1.80GHz 1.99GHz
基于以上內(nèi)容,就開始跑代碼,按照代碼主目錄下的main.py中給出的命令,訓(xùn)練了正弦曲線的回歸模型,這個的訓(xùn)練時間可能就半個小時這樣的量級(因為這是一開始稀里糊涂跑的,忘了具體跑了多長時間了,就是比起后來跑圖像數(shù)據(jù)集花的時間少得多得多),但是跑完之后,發(fā)現(xiàn)我根本不懂輸出內(nèi)容是啥意思,這真是。。(意料之中吧),所以我接下來就進(jìn)行了 三 的內(nèi)容。
三、基于tensorflow-gpu跑maml的回歸任務(wù)
為了便于理解這個元學(xué)習(xí)模型,我還是決定先把這個回歸任務(wù)理解了,所以就找到了這個代碼:https://github.com/mari-linhares/tensorflow-maml/blob/master/maml.ipynb
不太妙的是,這個代碼的運(yùn)行環(huán)境是tensorflow-gpu==2.0.0-alpha0,因此我就開始了搭建可以使用gpu的環(huán)境的歷程,這個也是稍微花了點(diǎn)時間的,我的顯卡是NVIDIA GeForce 940MX。


GPU驅(qū)動版本(桌面右鍵->NVIDIA 控制面板)

1.看你的顯卡是否支持cuda(CUDA is a parallel computing platform and programming model invented by NVIDIA)
https://developer.nvidia.com/cuda-gpus
2.查看tensorflow-gpu、cuda和cudnn(CUDA for Deep Neural Networks)的對應(yīng)關(guān)系
https://tensorflow.google.cn/install/source_windows

3.安裝visual stdudio2015(因為一點(diǎn)混亂,我沒有按照上面查出來的安裝2017版,但是2015也成功跑起來了)
4.安裝cuda
安裝指南:https://docs.nvidia.com/cuda/cuda-installation-guide-microsoft-windows/#axzz4Vh7B32MZ
下載地址:https://developer.nvidia.com/cuda-downloads?target_os=Windows&target_arch=x86_64&target_version=10
安裝位置如下圖:

查看環(huán)境變量(安裝完成之后自動添加上去的,位于頂部)

5.查看cuda信息

6.安裝cudnn(CUDA for Deep Neural Networks,這個需要登錄)
https://developer.nvidia.com/cudnn
下載下來之后,解壓是個cuda的目錄,改為cudnn即可,放置位置如圖:

配置環(huán)境變量,同樣讓其位于頂部

7.pip安裝tensorflow-gpu==2.0.0-alpha0,并且嘗試import,會出現(xiàn)_pywrap_tensorflow_internal cannot find dll這樣的錯誤
7.1使用vs developer command prompt中的dumpbin.exe查看依賴的dll
dumpbin /dependents E:\desktop\mamlregression\Lib\site-packages\tensorflow\python\_pywrap_tensorflow_internal.pyd7.2用where查找這些dll是否都可以找到,把沒在環(huán)境變量的dll的路徑加上,沒有的下載。主要是這三個dll根本沒有,cublas64_100.dll,cusolver64_100.dll,cudart64_100.dll
7.3下載dll,放到cuda的bin目錄下
下載地址來源:https://medium.com/@iitbguha/tensorflow-with-gpu-installation-made-easy-659f88c0309b
這個博客里的link,是個谷歌云盤

放置好之后如下圖:

7.4檢查
import tensorflow as tf
四、元學(xué)習(xí)概念
剛才說由于元學(xué)習(xí)訓(xùn)練過程的特殊性,所以元學(xué)習(xí)使用的數(shù)據(jù)往往是少次學(xué)習(xí)數(shù)據(jù),因此后面描述遵循幾個少次學(xué)習(xí)中的定義。
元學(xué)習(xí),就是通過訓(xùn)練任務(wù)訓(xùn)練得到一個最好的初始化值。
按照少次學(xué)習(xí)的說法,這個訓(xùn)練任務(wù)中包含支持集和測試集兩種數(shù)據(jù),同時,少次學(xué)習(xí)中慣用一個設(shè)定:Nway-Kshot,從分類角度來說,Nway指的是N中類別,Kshot指的是每個類別的樣本數(shù)。如果說,要處理的問題是5分類,那么N=5,K的值由你真實的數(shù)據(jù)集來確定,也就是實際可以獲取到的每類樣本的樣本數(shù)。這里假設(shè)每類可以獲取到6個樣本。那么某一類別中的6個樣本,就可以分為兩部分,一部分做支持集,一部分做測試集。再次假設(shè),支持集中有5個樣本,測試集有1個樣本,那么按照少次學(xué)習(xí)任務(wù)的設(shè)定,這里的假設(shè)任務(wù)就可以下定義為5way5shot任務(wù)。
按照上面的假設(shè),結(jié)合李宏毅老師課程的介紹(如下圖),元學(xué)習(xí)的過程就是指,將這5個分類的5個樣本輸入一個基礎(chǔ)網(wǎng)絡(luò),經(jīng)過梯度下降的計算過程,更新模型中的參數(shù),直到得到最好的參數(shù)(這個更新次數(shù),原論文中只更新一次,原因有二:1是我們面對的數(shù)據(jù)不多,如果更新次數(shù)過多會導(dǎo)致過擬合;2我們要做到高效,即只通過一次更新就能很快地找到最好的參數(shù),而到了我們的測試數(shù)據(jù)上我們可以迭代更新不止一次,直到拿到最好的參數(shù))。再將測試數(shù)據(jù)輸入這個最好的參數(shù)對應(yīng)的模型,得到loss,再進(jìn)行計算梯度,此時進(jìn)行那個基礎(chǔ)網(wǎng)絡(luò)參數(shù)的更新。

此時,我們找到一個在這5個分類上最好的模型(參數(shù),因為參數(shù)確定,模型確定),但是我們最終的目的是做到任意數(shù)據(jù)的5分類問題都能得到很好的解決。因此類比機(jī)器學(xué)習(xí)的訓(xùn)練過程,我們需要大量的這種5分類的任務(wù),從這些大量5分類任務(wù)中學(xué)會學(xué)習(xí),而不僅僅是會學(xué)習(xí)(能做好一個特定的5分類任務(wù)),這也是元學(xué)習(xí)的核心之處。
有了大量的不同類別的5分類任務(wù),用同樣的方法,都得到一個最好的模型(參數(shù))。我們按照輸入模型的任務(wù)順序,任務(wù)1拿到的最好參數(shù)更新基礎(chǔ)網(wǎng)絡(luò),接下來,任務(wù)2也拿到了自己的最好的參數(shù),在任務(wù)1的更新的基礎(chǔ)上再次更新,如此重復(fù)下去,直到所有任務(wù)進(jìn)行完,就得到最終的參數(shù)作為初始化參數(shù)。(這些任務(wù)也可以作為一個任務(wù)batch,按照batch來更新參數(shù),只是這里假設(shè)是一個任務(wù)一個任務(wù)來更新,好像是叫做online梯度下降,而那個batch級的更新叫一定程度上的offline梯度下降,這個offline的程度取決于一次更新參數(shù)所能看到的任務(wù)數(shù)量。這段話有點(diǎn)碎,但是不影響括號外面的理解。)
下面這張圖是李宏毅老師課程上的參數(shù)更新過程。
