編者按:此前,論智曾寫過一篇Kaggle競(jìng)賽方案分享:如何分辨雜草和植物幼苗,介紹了當(dāng)時(shí)排名第五的開發(fā)者Kumar Shridhar的實(shí)戰(zhàn)思路。同樣是這個(gè)競(jìng)賽,自參賽起,fast.ai聯(lián)合創(chuàng)始人Jeremy Howard的名次卻經(jīng)歷連連暴跌,最后止步第105名。那么這位明星數(shù)據(jù)科學(xué)家究竟遭遇了何方狙擊?沒錯(cuò),就是他自己的學(xué)生,而這些新手最后也成功霸榜Kaggle。
當(dāng)我離開你時(shí),我只是求學(xué)者,但現(xiàn)在,我才是王者
隨著互聯(lián)網(wǎng)和知識(shí)傳播的深度結(jié)合,現(xiàn)在在線課程對(duì)許多人來(lái)說已經(jīng)不是新鮮事物,在深度學(xué)習(xí)領(lǐng)域,最受學(xué)生歡迎的MOOC課程平臺(tái)有三個(gè):Fast.ai、deeplearning.ai /Coursera和Udacity。其中,因?yàn)镴eremy Howard化繁為簡(jiǎn)、實(shí)戰(zhàn)為上的獨(dú)特授課風(fēng)格,F(xiàn)ast.ai給人的印象一直很“接地氣”,而植物幼苗分類賽的結(jié)果也證實(shí)了課程的教學(xué)效果。
那么這些新手在短短幾周內(nèi)就學(xué)會(huì)使用頂級(jí)算法的秘訣是什么?是什么讓他們能在競(jìng)賽中擊敗擁有大量GPU的資深深度學(xué)習(xí)專家?下文是你想知道的所有答案。
如果你已經(jīng)上手深度學(xué)習(xí),并希望快速了解Fast.ai課程中使用的強(qiáng)大技術(shù),請(qǐng)繼續(xù)閱讀。 如果你已經(jīng)完成Fast.ai課程,并希望回顧所學(xué)內(nèi)容,請(qǐng)繼續(xù)閱讀。 如果你正準(zhǔn)備入門深度學(xué)習(xí),并希望了解Fast.ai對(duì)初學(xué)者的幫助和這個(gè)行業(yè)的未來(lái)發(fā)展,請(qǐng)繼續(xù)閱讀。
首先,在正式開始前,我們都應(yīng)該知道,如果要有效學(xué)習(xí)Fast.ai的課程內(nèi)容,云GPU必不可少。這里我們先介紹一個(gè)好用的工具——FloydHub,對(duì)于初學(xué)者來(lái)說,這是訓(xùn)練深度學(xué)習(xí)模型最好的、也是最簡(jiǎn)單的方法。法國(guó)的Ecole 42非常喜愛這個(gè)工具,我們也可以借此為接觸更多有趣實(shí)現(xiàn)做準(zhǔn)備,如:
如何用100行神經(jīng)網(wǎng)絡(luò)代碼為黑白圖片著色
如何用深度學(xué)習(xí)做“前端”:基于設(shè)計(jì)模型圖片生成HTML和CSS代碼
下面,讓我們正式開始!
1. 使用Fast.ai庫(kù)
from fast.ai import *
Fast.ai庫(kù)不僅是讓新手快速構(gòu)建深度學(xué)習(xí)實(shí)現(xiàn)的工具包,它也是提供最佳實(shí)踐的一個(gè)強(qiáng)大而便捷的資源。每當(dāng)Fast.ai團(tuán)隊(duì)(包括AI研究人員和合作者網(wǎng)絡(luò))發(fā)現(xiàn)一篇特別有趣的論文,他們就會(huì)在各種數(shù)據(jù)集上測(cè)試,然后找出調(diào)整優(yōu)化方法。如果這些成果確實(shí)是有效的,它們會(huì)陸續(xù)出現(xiàn)在庫(kù)中,以便用戶快速接觸新技術(shù)。
這樣做的結(jié)果是Fast.ai庫(kù)現(xiàn)在已經(jīng)成為一個(gè)功能強(qiáng)大的工具箱,比如去年學(xué)界公認(rèn)的深度學(xué)習(xí)年度進(jìn)展:SGDR、循環(huán)學(xué)習(xí),現(xiàn)在所有Fast.ai用戶都可以快速訪問,并把它們用于自己的實(shí)現(xiàn)。
這個(gè)庫(kù)基于PyTorch構(gòu)建,使用流暢,用戶體驗(yàn)很好。
2. 使用多個(gè)學(xué)習(xí)率,而不是一個(gè)
使用不同的學(xué)習(xí)率意味著在訓(xùn)練期間,神經(jīng)網(wǎng)絡(luò)前幾層的變化比后幾層更多。在計(jì)算機(jī)視覺任務(wù)中,現(xiàn)在通行的一種做法是直接在現(xiàn)有架構(gòu)上構(gòu)建深度學(xué)習(xí)模型,實(shí)踐證明這樣做模型的性能更好。
而大多數(shù)架構(gòu),如Resnet、VGG、inception等都是在ImageNet上經(jīng)過預(yù)訓(xùn)練的,如果要使用它們,我們必須考量手頭數(shù)據(jù)集和ImageNet圖像的相似程度,并以此對(duì)權(quán)重做或多或少的調(diào)整。在修改權(quán)重時(shí),模型的最后幾層調(diào)整幅度更大,而用于檢測(cè)基礎(chǔ)特征的層(比如邊緣和輪廓)則只需極少調(diào)整。
下面是一些代碼示例,首先,我們從Fast.ai庫(kù)里獲得預(yù)訓(xùn)練模型:
from fastai.conv_learner import *
# 導(dǎo)入用于創(chuàng)建卷積學(xué)習(xí)對(duì)象的庫(kù) #選擇VVG16
# 將模型分配給resnet、vgg,甚至是你自己的自定義模型
PATH = './folder_containing_images'
data = ImageClassifierData.from_paths(PATH)
# 創(chuàng)建fast ai數(shù)據(jù)對(duì)象,這里我們用from_paths
# 其中PATH將每個(gè)圖像類分成不同的文件夾
learn = ConvLearner.pretrained(model, data, precompute=True)
# 創(chuàng)建一個(gè)學(xué)習(xí)對(duì)象,以便快速調(diào)用Fast.ai庫(kù)里的state of art算法
通過創(chuàng)建好的學(xué)習(xí)對(duì)象,我們可以凍結(jié)最后一層以前的所有層,單獨(dú)調(diào)整最后一層的參數(shù):
learn.freeze()
# 凍結(jié)最后一層之前的所有層,保持它們的參數(shù)不變
learning_rate = 0.1
learn.fit(learning_rate, epochs=3)
# 只訓(xùn)練最后一層幾個(gè)epoch
如果調(diào)參結(jié)果不錯(cuò),我們就可以在不同層使用不同的學(xué)習(xí)率,比如中間幾層參數(shù)變化幅度沒最后幾層那么大,所以它的學(xué)習(xí)率可以是后者的1/10。
learn.unfreeze()
# 將所有圖層的requires_grads設(shè)置為True,以便進(jìn)行更新
learning_rate = [0.001, 0.01, 0.1]
# first layer的學(xué)習(xí)率是0.001,middle layer的是0.01,final layer則是0.1.
learn.fit(learning_rate, epochs=3)
# 用不同學(xué)習(xí)率訓(xùn)練模型三個(gè)epoch
3. 如何找到合適的學(xué)習(xí)率
學(xué)習(xí)率是訓(xùn)練神經(jīng)網(wǎng)絡(luò)最重要的一個(gè)超參數(shù),但直到最近,許多人才發(fā)現(xiàn)以前設(shè)置學(xué)習(xí)率的方式非常不當(dāng)。去年,Leslie N. Smith在arXiv上提交了一個(gè)預(yù)印本:Cyclical Learning Rates for Training Neural Networks。他在文中提出一種確定學(xué)習(xí)率的新方法:循環(huán)學(xué)習(xí)率,即不使用固定值,而是用一個(gè)在合理閾值內(nèi)循環(huán)變化的數(shù)值,實(shí)驗(yàn)證明它可以減少迭代次數(shù),提高模型分類準(zhǔn)確率。文章一經(jīng)發(fā)布,F(xiàn)ast.ai就立馬推廣了這種方法。
對(duì)于這種方法,我們可以從一個(gè)較低的學(xué)習(xí)率開始訓(xùn)練神經(jīng)網(wǎng)絡(luò),然后隨著迭代進(jìn)行,逐漸對(duì)學(xué)習(xí)率做指數(shù)增加。以下是示例代碼:
learn.lr_find()
# 隨著學(xué)習(xí)率呈指數(shù)增長(zhǎng),訓(xùn)練學(xué)習(xí)對(duì)象
learn.sched.plot_lr()
# 繪制學(xué)習(xí)率和迭代的進(jìn)展圖
學(xué)習(xí)率隨迭代呈指數(shù)上升
同時(shí),記錄不同學(xué)習(xí)率時(shí)每個(gè)值的損失,并繪制相關(guān)圖像:
learn.sched.plot()
# 學(xué)習(xí)率和損失的關(guān)系圖
損失一直在減少,還沒有穩(wěn)定
在上圖情況下,我們可以確定的最佳學(xué)習(xí)率是0.01。
4. 余弦退火
隨著每個(gè)batch隨機(jī)梯度下降(SGD)的進(jìn)行,神經(jīng)網(wǎng)絡(luò)的損失會(huì)逐漸接近全局最小值,相應(yīng)的,學(xué)習(xí)率也應(yīng)該變得更小,防止算法超調(diào)。余弦退火是一種將學(xué)習(xí)率設(shè)置為隨模型迭代輪數(shù)不斷改變的方法,因?yàn)楦聦W(xué)習(xí)率用的是cos(),所以稱余弦。如下圖所示:
隨著x增加,cos(x)會(huì)不斷縮小
當(dāng)我們不斷增加x時(shí),cos(x)的變化是一個(gè)先緩慢后急劇再緩慢的過程,這種下降趨勢(shì)十分符合學(xué)習(xí)率,因此也可以提高模型性能。
learn.fit(0.1, 1)
# 在Fast.ai庫(kù)中調(diào)用learn.fit函數(shù)可以直接使用余弦退火
5. SGDR
在訓(xùn)練期間,梯度下降可能會(huì)陷入局部最小值而不是全局最小值。
梯度下降可能會(huì)陷入局部最小值
這時(shí),通過突然提高學(xué)習(xí)率,梯度下降可以“跳出”局部最小值,重新回歸尋找全局最小值的正軌。這種方法被稱為熱重啟隨機(jī)梯度下降(SGDR),它首次出現(xiàn)在德國(guó)弗萊堡大學(xué)的論文SGDR: Stochastic Grandient Descent with warm Restarted中,這也是ICLR 2017的重磅成果。
現(xiàn)在,SGDR已經(jīng)加入Fast.ai庫(kù),當(dāng)用戶調(diào)用learn.fit(learning_rate, epochs)時(shí),每個(gè)epoch的學(xué)習(xí)率會(huì)被重新設(shè)置成原始超參數(shù),然后在用余弦退火逐漸縮小。
每個(gè)epoch的學(xué)習(xí)率回歸原始值
每次學(xué)習(xí)率下降到最低點(diǎn),我們就稱之為一個(gè)循環(huán)。
cycle_len = 1
# 決定學(xué)習(xí)率降到最低要幾個(gè)epoch
# 在這種情況下,1個(gè)epoch
cycle_mult=2
# 在每個(gè)循環(huán)結(jié)束時(shí),將cycle_len值乘以2
learn.fit(0.1, 3, cycle_len=2, cycle_mult=2)
# 在這種情況下,將重啟3次
# 第一次的cycle_len為1,所以我們用1個(gè)epoch完成循環(huán)
# cycle_mult=2,所以下個(gè)循環(huán)是2個(gè)epoch
# 然后是4個(gè)epoch,以此類推
每個(gè)循環(huán)所需epoch是上個(gè)循環(huán)的兩倍
使用這種方法可以幫助開發(fā)者在圖像分類問題中占據(jù)先機(jī)。
6. 把激活函數(shù)想象成人
Softmax是一個(gè)專一的家伙,只喜歡挑選一個(gè)目標(biāo);Sigmoid只想知道你在-1和1之間的位置,如果超出了閾值,他才不管你的死活;Relu是一名稱職的夜店門衛(wèi),如果顏值為負(fù),你就別想過這道門。
以上述方式看待激活函數(shù)縱然有點(diǎn)蠢,但至少它區(qū)分了三種函數(shù)的不同,可以有效防止誤用。Jeremy Howard曾表示,他在許多學(xué)術(shù)論文中都看到過把Softmax用于多元分類,而文章、博客中的激活函數(shù)濫用更不鮮見。
7. 遷移學(xué)習(xí)對(duì)NLP任務(wù)非常有用
眾所周知,遷移學(xué)習(xí)在計(jì)算機(jī)視覺中的效果非常出色,而隨著研究人員的不斷探索,如今越來(lái)越多線索開始指向另一個(gè)現(xiàn)實(shí):自然語(yǔ)言處理(NLP)模型同樣能從遷移學(xué)習(xí)中收益頗多。
在fast.ai的第4課中,Jeremy Howard構(gòu)建了一個(gè)用于分類IMDB電影評(píng)論消極與否的模型,他把遷移學(xué)習(xí)思想引入模型,發(fā)現(xiàn)模型的準(zhǔn)確率遠(yuǎn)超Bradbury等人的最先進(jìn)成果,效果立竿見影。
他加入了一個(gè)預(yù)訓(xùn)練模型
而這個(gè)做法的成功秘訣是先訓(xùn)練一個(gè)模型,讓它對(duì)語(yǔ)言產(chǎn)生基礎(chǔ)理解,然后再把這個(gè)預(yù)訓(xùn)練模型作為模型的一部分用于情感分析。為了構(gòu)建這第一個(gè)模型,我們需要讓RNN學(xué)會(huì)預(yù)測(cè)文本序列中的下一個(gè)詞,也就是語(yǔ)言建模。一旦模型訓(xùn)練完畢,性能很好,第二個(gè)新模型就能利用它對(duì)每個(gè)次的編碼分析影評(píng)是積極的還是消極的。
雖然課程示例是個(gè)情感分析模型,但我們也可以把它用到其他NLP和計(jì)算機(jī)視覺任務(wù)中。
8. 用深度學(xué)習(xí)處理結(jié)構(gòu)化數(shù)據(jù)
在介紹機(jī)器學(xué)習(xí)和深度學(xué)習(xí)優(yōu)勢(shì)時(shí),我們一般會(huì)夸它們可以處理非結(jié)構(gòu)化數(shù)據(jù),認(rèn)為這是統(tǒng)計(jì)學(xué)無(wú)法做到的,但Fast.ai反其道而行之,他們用深度學(xué)習(xí)實(shí)現(xiàn)了在結(jié)構(gòu)化數(shù)據(jù)上快速生成出色結(jié)果,而無(wú)需借助特征工程和應(yīng)用領(lǐng)域的特定知識(shí)。
他們的庫(kù)充分利用了PyTorch的嵌入功能,允許將分類變量快速轉(zhuǎn)換為嵌入矩陣。當(dāng)然,課程中展示的技術(shù)相對(duì)較簡(jiǎn)單,只是將分類變量轉(zhuǎn)換為數(shù)字,然后為每個(gè)值分配嵌入向量:
為一周中的每一天嵌入4個(gè)值
與創(chuàng)建虛擬變量(one-hot編碼)的傳統(tǒng)方法相比,這樣做的好處是對(duì)于每一天,我們可以用4個(gè)值代替一個(gè)值,從而創(chuàng)建維度更高、更豐富的矩陣。
9. 競(jìng)賽致勝關(guān)鍵:擴(kuò)大圖像尺寸、Dropout和TTA
4月30日,在斯坦福大學(xué)舉辦的DAWNBench中,fast.ai團(tuán)隊(duì)一舉贏得Imagenet和CIFAR10分類競(jìng)賽,之后Jeremy Howard寫了一篇獲勝感言,他把競(jìng)賽結(jié)果歸功于fast.ai庫(kù)中的一些獨(dú)特工具。
兩年前Geoffrey Hinton提出的Dropout是其中之一。盡管論文發(fā)布之初,學(xué)界對(duì)這個(gè)概念十分追捧,但它在計(jì)算機(jī)視覺領(lǐng)域卻一直不受重視。幸好,現(xiàn)在有了PyTorch,如果我們用PyTorch實(shí)現(xiàn)Dropout,它會(huì)變得異常簡(jiǎn)單,而如果用了fast.ai庫(kù),整個(gè)過程就更簡(jiǎn)單了。
空格表示Dropout函數(shù)激活的區(qū)域
Dropout可以很好地防止模型過擬合,這對(duì)于在CIFAR10這樣的小型數(shù)據(jù)集上構(gòu)建分類器是非常重要的。在創(chuàng)建學(xué)習(xí)對(duì)象時(shí),fast.ai會(huì)自動(dòng)執(zhí)行Dropout,但它可以自定義修改:
learn = ConvLearner.pretrained(model, data, ps=0.5, precompute=True)
# 在測(cè)試集上創(chuàng)建0.5的Dropout(激活的一半)
# 驗(yàn)證集會(huì)自動(dòng)關(guān)閉此功能
除此之外,他們采用的另一種方法是先在較小的圖像上訓(xùn)練,然后擴(kuò)大圖像尺寸,在用相同的模型在上面訓(xùn)練。這樣做可以有效防止過擬合,同時(shí)提高模型性能。
# create a data object with images of sz * sz pixels
def get_data(sz):
tmfs = tfms_from_model(model, sz)
# tells what size images should be, additional transformations such
# image flips and zooms can easily be added here too
data = ImageClassifierData.from_paths(PATH, tfms=tfms)
# creates fastai data object of create size
return data
learn.set_data(get_data(299))
# changes the data in the learn object to be images of size 299
# without changing the model.
learn.fit(0.1, 3)
# train for a few epochs on larger versions of images, avoiding overfitting
最后一種方法則是測(cè)試時(shí)數(shù)據(jù)增強(qiáng)(TTA),也就是把測(cè)試集里的原始圖像做裁剪、縮放,轉(zhuǎn)換成一系列不同的圖像,然后用于圖像測(cè)試。這之后,我們計(jì)算不同版本的平均輸出,并將其作為圖像的最終分?jǐn)?shù),這可以通過調(diào)用learn.TTA()直接實(shí)現(xiàn):
preds, target = learn.TTA()
10. 創(chuàng)造力是關(guān)鍵
fast.ai團(tuán)隊(duì)不僅在DAWNBench競(jìng)賽中贏得了訓(xùn)練速度最快獎(jiǎng)(3小時(shí)),也把成本壓縮到25美元,堪稱奇跡。這里我們可以學(xué)到的經(jīng)驗(yàn)是,創(chuàng)建一個(gè)成功的深度學(xué)習(xí)模型并不意味著投入更多GPU,創(chuàng)造力、想法和創(chuàng)新可以為我們打開另一扇窗。
本文提到的大多數(shù)學(xué)術(shù)突破也是創(chuàng)造力的一個(gè)佐證,當(dāng)別人用千篇一律的做法解決問題時(shí),這些學(xué)者想到了不同的方法,而且這些創(chuàng)新確實(shí)有效。雖然硅谷的大公司擁有海量GPU,這是常人不敢奢望的,但我們要勇于發(fā)起挑戰(zhàn),創(chuàng)造出屬于自己的特殊的、新的東西。
有時(shí)候,現(xiàn)實(shí)的擠壓也是一種機(jī)遇,畢竟必要性是成功之母。
-
神經(jīng)網(wǎng)絡(luò)
+關(guān)注
關(guān)注
42文章
4765瀏覽量
100549 -
算法
+關(guān)注
關(guān)注
23文章
4601瀏覽量
92651 -
深度學(xué)習(xí)
+關(guān)注
關(guān)注
73文章
5493瀏覽量
120983
原文標(biāo)題:從fast.ai學(xué)到的十大技巧:如何在幾周內(nèi)上手頂級(jí)算法
文章出處:【微信號(hào):jqr_AI,微信公眾號(hào):論智】歡迎添加關(guān)注!文章轉(zhuǎn)載請(qǐng)注明出處。
發(fā)布評(píng)論請(qǐng)先 登錄
相關(guān)推薦
評(píng)論