Andrej Karpathy 是深度學(xué)習(xí)計(jì)算機(jī)視覺(jué)領(lǐng)域斗幼、與領(lǐng)域的研究員。博士期間師從李飛飛。在讀博期間,兩次在谷歌實(shí)習(xí),研究在 Youtube 視頻上的大規(guī)模特征學(xué)習(xí)誓沸,2015 年在 DeepMind 實(shí)習(xí)趁仙,研究深度強(qiáng)化學(xué)習(xí)干奢。畢業(yè)后宋光,Karpathy 成為 OpenAI 的研究科學(xué)家黑低,后于 2017 年 6 月加入特斯拉擔(dān)任人工智能與視覺(jué)總監(jiān)菩暗。
今日他發(fā)布的這篇博客能為深度學(xué)習(xí)研究者們提供極為明晰的洞見(jiàn)掏熬,在 Twitter 上也引發(fā)了極大的關(guān)注。
1. 誰(shuí)說(shuō)神經(jīng)網(wǎng)絡(luò)訓(xùn)練簡(jiǎn)單了履恩?
很多人認(rèn)為開(kāi)始訓(xùn)練神經(jīng)網(wǎng)絡(luò)是很容易的咐刨,大量庫(kù)和框架號(hào)稱(chēng)可以用 30 行代碼段解決你的數(shù)據(jù)問(wèn)題联予,這就給大家留下了(錯(cuò)誤的)印象:訓(xùn)練神經(jīng)網(wǎng)絡(luò)這件事是非常簡(jiǎn)單的子刮,不同模塊即插即用就能搭個(gè)深度模型。
簡(jiǎn)單的建模過(guò)程通常如下所示:
>>> your_data = # plug your awesome dataset here
>>> model = SuperCrossValidator(SuperDuper.fit, your_data, ResNet50, SGDOptimizer)# conquer world here
這些庫(kù)和示例令我們想起了熟悉標(biāo)準(zhǔn)軟件及模塊挺峡,標(biāo)準(zhǔn)軟件中通晨拢可以獲取簡(jiǎn)潔的 API 和抽象。
例如 Request 庫(kù)的使用展示如下:
>>> r = requests.get('https://api.github.com/user', auth=('user', 'pass'))
>>> r.status_code200
酷橱赠!這些庫(kù)和框架的開(kāi)發(fā)者背負(fù)起理解用戶(hù) Query 字符串尤仍、url、GET/POST 請(qǐng)求狭姨、HTTP 連接等的大量需求宰啦,將復(fù)雜度隱藏在幾行代碼后面。這就是我們熟悉與期待的送挑。
然而绑莺,神經(jīng)網(wǎng)絡(luò)不一樣,它們并不是現(xiàn)成的技術(shù)惕耕。我在 2016 年撰寫(xiě)的一篇博客中試圖說(shuō)明這一點(diǎn)纺裁,在那篇文章中我認(rèn)為反向傳播是「leaky abstraction」,然而現(xiàn)在的情況似乎更加糟糕了司澎。
Backprop + SGD 不是魔法欺缘,無(wú)法讓你的網(wǎng)絡(luò)運(yùn)行;批歸一化也無(wú)法奇跡般地使網(wǎng)絡(luò)更快收斂挤安;RNN 也不能神奇地讓你直接處理文本谚殊。不要因?yàn)槟憧梢詫⒆约旱膯?wèn)題表示為強(qiáng)化學(xué)習(xí),就認(rèn)為你應(yīng)該這么做蛤铜。如果你堅(jiān)持在不理解技術(shù)原理的情況下去使用它嫩絮,那么你很可能失敗。
2. 背著我不 work 的神經(jīng)網(wǎng)絡(luò)
當(dāng)你破壞代碼或者錯(cuò)誤配置代碼時(shí)围肥,你通常會(huì)得到某種異常剿干。你在原本應(yīng)該插入字符串的地方插入了整數(shù);導(dǎo)入出錯(cuò)穆刻;該關(guān)鍵字不存在……此外置尔,為了方便 debug,你還很可能為某個(gè)功能創(chuàng)建單元測(cè)試氢伟。
這還只是開(kāi)始榜轿。訓(xùn)練神經(jīng)網(wǎng)絡(luò)時(shí)幽歼,有可能所有代碼的句法都正確,但整個(gè)訓(xùn)練就是不對(duì)谬盐〉樗剑可能問(wèn)題出現(xiàn)在邏輯性(而不是句法),且很難通過(guò)單元測(cè)試找出來(lái)设褐。
例如颠蕴,你嘗試截?fù)p失度而不是梯度,這會(huì)導(dǎo)致訓(xùn)練期間的異常值被忽視助析,但語(yǔ)法或維度等檢測(cè)都不會(huì)出現(xiàn)錯(cuò)誤。又或者椅您,你弄錯(cuò)了正則化強(qiáng)度外冀、學(xué)習(xí)率、衰減率掀泳、模型大小等的設(shè)置雪隧,那么幸運(yùn)的話網(wǎng)絡(luò)會(huì)報(bào)錯(cuò),然而大部分時(shí)候它會(huì)繼續(xù)訓(xùn)練员舵,并默默地變?cè)恪?/p>
因此脑沿,「快速激烈」的神經(jīng)網(wǎng)絡(luò)訓(xùn)練方式?jīng)]有用,只會(huì)導(dǎo)致困難÷砥В現(xiàn)在庄拇,這些經(jīng)驗(yàn)性困難是使神經(jīng)網(wǎng)絡(luò)正常運(yùn)行的攔路虎,你需要更加周密詳盡地調(diào)試網(wǎng)絡(luò)才能減少困難韭邓,需要大量可視化來(lái)了解每一件事措近。
在我的經(jīng)驗(yàn)中,深度學(xué)習(xí)成功的重要因素是耐心和注重細(xì)節(jié)女淑。
如何解決
基于以上兩點(diǎn)事實(shí)瞭郑,我開(kāi)發(fā)了一套將神經(jīng)網(wǎng)絡(luò)應(yīng)用于新問(wèn)題的特定流程。該流程嚴(yán)肅地執(zhí)行了上述兩項(xiàng)原則:耐心和注重細(xì)節(jié)鸭你。
具體來(lái)說(shuō)屈张,它按照從簡(jiǎn)單到復(fù)雜的方式來(lái)構(gòu)建,我們?cè)诿恳徊蕉紝?duì)即將發(fā)生的事作出準(zhǔn)確的假設(shè)袱巨,然后用實(shí)驗(yàn)來(lái)驗(yàn)證假設(shè)或者調(diào)查直到發(fā)現(xiàn)問(wèn)題阁谆。我們?cè)噲D盡力阻止大量「未經(jīng)驗(yàn)證的」復(fù)雜性一次來(lái)襲,這有可能導(dǎo)致永遠(yuǎn)也找不到的 bug/錯(cuò)誤配置瓣窄。如果讓你像訓(xùn)練神經(jīng)網(wǎng)絡(luò)那樣寫(xiě)它的代碼笛厦,你會(huì)想使用非常小的學(xué)習(xí)率,然后猜測(cè)俺夕,再在每次迭代后評(píng)估整個(gè)測(cè)試集裳凸。
1. 梳理數(shù)據(jù)
訓(xùn)練神經(jīng)網(wǎng)絡(luò)的第一步是不要碰代碼贱鄙,先徹底檢查自己的數(shù)據(jù)。這一步非常關(guān)鍵姨谷。我喜歡用大量時(shí)間瀏覽數(shù)千個(gè)樣本逗宁,理解它們的分布,尋找其中的模式梦湘。幸運(yùn)的是瞎颗,人類(lèi)大腦很擅長(zhǎng)做這件事。有一次捌议,我發(fā)現(xiàn)數(shù)據(jù)中包含重復(fù)的樣本哼拔,還有一次我發(fā)現(xiàn)了損壞的圖像/標(biāo)簽。我會(huì)查找數(shù)據(jù)不均衡和偏差瓣颅。我通常還會(huì)注意自己的數(shù)據(jù)分類(lèi)過(guò)程倦逐,它會(huì)揭示我們最終探索的架構(gòu)。比如宫补,只需要局部特征就夠了還是需要全局語(yǔ)境檬姥?標(biāo)簽噪聲多大?
此外粉怕,由于神經(jīng)網(wǎng)絡(luò)是數(shù)據(jù)集的壓縮/編譯版本健民,你能夠查看網(wǎng)絡(luò)(錯(cuò)誤)預(yù)測(cè),理解預(yù)測(cè)從哪里來(lái)贫贝。如果網(wǎng)絡(luò)預(yù)測(cè)與你在數(shù)據(jù)中發(fā)現(xiàn)的不一致秉犹,那么一定是什么地方出問(wèn)題了。
在你對(duì)數(shù)據(jù)有了一些感知之后平酿,你可以寫(xiě)一些簡(jiǎn)單的代碼來(lái)搜索/過(guò)濾/排序標(biāo)簽類(lèi)型凤优、標(biāo)注規(guī)模、標(biāo)注數(shù)量等蜈彼,并沿任意軸可視化其分布和異常值筑辨。異常值通常能夠揭示數(shù)據(jù)質(zhì)量或預(yù)處理中的 bug。
2. 配置端到端訓(xùn)練/評(píng)估架構(gòu)幸逆、獲取基線結(jié)果
現(xiàn)在我們已經(jīng)理解了數(shù)據(jù)棍辕,那我們就可以開(kāi)始構(gòu)建高大上的多尺度 ASPP FPN ResNet 并訓(xùn)練強(qiáng)大的模型了嗎?當(dāng)然還不到時(shí)候还绘,這是一個(gè)充滿(mǎn)荊棘的道路楚昭。我們下一步需要構(gòu)建一個(gè)完整的訓(xùn)練、評(píng)估架構(gòu)拍顷,并通過(guò)一系列實(shí)驗(yàn)確定我們對(duì)準(zhǔn)確率的置信度抚太。
在這個(gè)階段,你們最好選擇一些不會(huì)出錯(cuò)的簡(jiǎn)單模型,例如線性分類(lèi)器或非常精簡(jiǎn)的 ConvNet 等尿贫。我們希望訓(xùn)練這些模型电媳,并可視化訓(xùn)練損失、模型預(yù)測(cè)和其它度量指標(biāo)(例如準(zhǔn)確率)庆亡。當(dāng)然在這個(gè)過(guò)程中匾乓,我們還需要基于一些明確假設(shè),從而執(zhí)行一系列對(duì)照實(shí)驗(yàn)(ablation experiments)又谋。
該階段的一些技巧與注意事項(xiàng):
固定隨機(jī) seed:始終使用固定的隨機(jī) seed 能保證很多屬性拼缝,例如在我們兩次運(yùn)行相同代碼時(shí)能得到相同的輸出。這能消除變化因子彰亥,從進(jìn)行合理的判斷婶恼。
簡(jiǎn)化:確保禁用不必要的技巧速缨。例如姜性,在這個(gè)階段肯定需要關(guān)閉數(shù)據(jù)增強(qiáng)赘风。數(shù)據(jù)增強(qiáng)可以在后期引入,并作為一種強(qiáng)大的正則化策略仁卷。不過(guò)在這個(gè)階段引入的話,它就有機(jī)會(huì)帶來(lái)一些愚蠢的 bug犬第。
使用多數(shù)據(jù)锦积、少次數(shù)的驗(yàn)證評(píng)估:當(dāng)我們?cè)诶L制測(cè)試損失時(shí),我們需要在整個(gè)比較大的測(cè)試集中執(zhí)行評(píng)估歉嗓。不要過(guò)幾個(gè)批量就繪制一次測(cè)試損失丰介,然后再依賴(lài) TensorBoard 的平滑處理。我們雖然追求的是準(zhǔn)確率鉴分,但也要防止犯這些低級(jí)錯(cuò)誤哮幢。
在初始化中驗(yàn)證損失:驗(yàn)證你的損失函數(shù)在初始化中有比較合理的損失值。例如志珍,如果你正確地初始化最終層橙垢,那么你應(yīng)該通過(guò)-log(1/n_classes) 度量初始化的 Softmax 值。L2 回歸和 Huber 損失函數(shù)等都有相同的默認(rèn)值伦糯。
優(yōu)秀的初始化:正確地初始化最終層柜某。例如,如果你正在對(duì)均值為 50 的一些數(shù)據(jù)做回歸處理敛纲,那么初始化的最終偏置項(xiàng)就應(yīng)該為 50喂击。如果你有一個(gè)非平衡數(shù)據(jù)集(兩類(lèi)樣本數(shù) 1:10),那么就需要在 logits 上設(shè)置偏置項(xiàng)淤翔,令模型在初始化時(shí)預(yù)測(cè)概率為 0.1翰绊。正確配置這些偏置項(xiàng)將加快收斂速度,因?yàn)榫W(wǎng)絡(luò)在前面幾次迭代中基本上只在學(xué)習(xí)偏置。
人類(lèi)基線結(jié)果:監(jiān)控?fù)p失值等其他度量指標(biāo)(例如準(zhǔn)確度)监嗜,這些指標(biāo)應(yīng)該是人類(lèi)能解釋并檢查的谐檀。盡可能評(píng)估你自己(人類(lèi))獲得的準(zhǔn)確率,并與構(gòu)建的模型做對(duì)比秤茅≈刹梗或者對(duì)測(cè)試數(shù)據(jù)進(jìn)行兩次標(biāo)注,其中一次為預(yù)測(cè)值框喳,另一次為標(biāo)注值课幕。
獨(dú)立于輸入的基線結(jié)果:訓(xùn)練一個(gè)獨(dú)立于輸入的基線模型,例如最簡(jiǎn)單的方法就是將所有輸入都設(shè)置為 0五垮。這樣的模型應(yīng)該比實(shí)際輸入數(shù)據(jù)表現(xiàn)更差乍惊,你的模型是否準(zhǔn)備好從任何輸入中抽取任何信息?
在批數(shù)據(jù)上過(guò)擬合:在單個(gè)批數(shù)據(jù)上使得過(guò)擬合(兩個(gè)或多個(gè)少樣本)放仗。為此润绎,我們需要增加模型擬合能力,并驗(yàn)證我們能達(dá)到的最低損失值(即 0)诞挨。我還想在同一張圖中顯示標(biāo)簽和預(yù)測(cè)值莉撇,并確保損失值一旦達(dá)到最小,它們就能完美地對(duì)齊了惶傻。
驗(yàn)證訓(xùn)練損失的下降:在這一階段棍郎,你可能希望在數(shù)據(jù)集上實(shí)現(xiàn)欠擬合,該階段的模型應(yīng)該是極簡(jiǎn)的银室。然后我們嘗試增加一點(diǎn)模型的擬合能力涂佃,再看看訓(xùn)練損失是否稍微下降了一些。
在輸入網(wǎng)絡(luò)前可視化:在運(yùn)行模型之前蜈敢,我們需要可視化數(shù)據(jù)辜荠。也就是說(shuō),我們需要可視化輸入到網(wǎng)絡(luò)的具體數(shù)據(jù)抓狭,即可視化原始張量的數(shù)據(jù)和標(biāo)簽伯病。這是唯一的「真實(shí)來(lái)源」,我有很多次都是因?yàn)檫@個(gè)過(guò)程而節(jié)省了大量時(shí)間辐宾,并揭示了數(shù)據(jù)預(yù)處理和數(shù)據(jù)增強(qiáng)過(guò)程中的問(wèn)題狱从。
可視化預(yù)測(cè)過(guò)程:我喜歡在訓(xùn)練過(guò)程中對(duì)一個(gè)固定的測(cè)試批數(shù)據(jù)進(jìn)行模型預(yù)測(cè)的可視化。這展示了預(yù)測(cè)值如何變化的過(guò)程叠纹,能為我們提供關(guān)于訓(xùn)練過(guò)程的優(yōu)秀直覺(jué)季研。很多時(shí)候,如果網(wǎng)絡(luò)以某種方式小幅度波動(dòng)誉察,那么模型最可能在嘗試擬合數(shù)據(jù)与涡,這也展示了一些不穩(wěn)定性。太低或太高的學(xué)習(xí)率也很容易注意到,因?yàn)槎秳?dòng)量比較大驼卖。
使用反向傳播繪制依賴(lài)性:你的深度學(xué)習(xí)代碼通常包括復(fù)雜的氨肌、矢量化的、Boardcast 操作酌畜。一個(gè)常見(jiàn)的 bug 是怎囚,人們會(huì)無(wú)意間使用 view 而不是 transpose/permute,從而混合了批量數(shù)據(jù)中的維度信息桥胞。然而恳守,你的網(wǎng)絡(luò)仍然可以正常訓(xùn)練,只不過(guò)它們學(xué)會(huì)忽略了其它樣本中的數(shù)據(jù)贩虾。一種 debug 的方法是將某些樣本 i 的損失設(shè)置為 1.0催烘,然后運(yùn)行反向傳播一直到輸入,并確保第 i 個(gè)樣本的梯度不為零缎罢。更一般的伊群,梯度為我們提供了網(wǎng)絡(luò)中的依賴(lài)性關(guān)系,它們?cè)?debug 中非常有用策精。
一般化特殊案例:這是一種更為通用的代碼技巧舰始,但是我經(jīng)常看到人們?cè)谑褂眠@些技巧時(shí)會(huì)新產(chǎn)生 Bug咽袜,尤其是在從頭構(gòu)建一般函數(shù)時(shí)蔽午。相反,我喜歡直接寫(xiě)非常具體的函數(shù)酬蹋,它只包含我現(xiàn)在需要做的事情。我會(huì)先讓這個(gè)函數(shù)能 work抽莱,然后再一般化好函數(shù)范抓,并確保能取得相同的結(jié)果。通常這個(gè)過(guò)程會(huì)體現(xiàn)在向量化代碼中食铐,我會(huì)先用循環(huán)編寫(xiě)某個(gè)過(guò)程匕垫,然后再一次一個(gè)循環(huán)地將它們轉(zhuǎn)化為向量化化代碼。
3. 過(guò)擬合
到了這個(gè)階段虐呻,我們應(yīng)該對(duì)數(shù)據(jù)集有所了解了象泵,而且有了完整的訓(xùn)練+評(píng)估流程。對(duì)于任何給定的模型斟叼,我們可以計(jì)算出我們信任的度量偶惠。而且還為獨(dú)立于輸入的基線準(zhǔn)備了性能,一些 dumb 基線的性能(最好超過(guò)這些)朗涩,我們?nèi)祟?lèi)的表現(xiàn)有大致的了解(并希望達(dá)到這一點(diǎn))『瞿酰現(xiàn)在,我們已經(jīng)為迭代一個(gè)好的模型做好了準(zhǔn)備。
我準(zhǔn)備用來(lái)尋找好模型的方法有兩個(gè)階段:首先獲得足夠大的模型兄一,這樣它能夠過(guò)擬合(即關(guān)注訓(xùn)練損失)厘线,然后對(duì)其進(jìn)行適當(dāng)?shù)恼齽t化(棄掉一些訓(xùn)練損失以改進(jìn)驗(yàn)證損失)。我喜歡這兩個(gè)階段的原因是出革,如果我們不能用任何模型實(shí)現(xiàn)較低的誤差率造壮,則可能再次表明一些問(wèn)題、bug 和配置錯(cuò)誤骂束。
該階段的一些技巧與注意事項(xiàng):
選擇模型:為了達(dá)到理想的訓(xùn)練損失耳璧,我們可能希望為數(shù)據(jù)選擇一個(gè)合適的架構(gòu)。當(dāng)我們?cè)谔暨x模型時(shí)栖雾,我的第一個(gè)建議即別好高騖遠(yuǎn)楞抡。我看到很多人都非常渴望一開(kāi)始就堆疊一些新的模塊析藕,或創(chuàng)造性地用于各種異質(zhì)架構(gòu)召廷,從而想一步到位做好。我建議可以找最相關(guān)的論文账胧,并直接利用它們的簡(jiǎn)單架構(gòu)竞慢,從而獲得良好性能。后面再基于這個(gè)架構(gòu)做修改和改進(jìn)治泥,并將我們的想法加進(jìn)去就行了筹煮。
Adam 是一般選擇:在配置基線模型地早期階段,我喜歡使用 Adam 算法(學(xué)習(xí)率為 3e-4)居夹。在我的經(jīng)驗(yàn)中败潦,Adam 對(duì)超參數(shù)的容忍度更高,不太好的學(xué)習(xí)率也能獲得一般的效果准脂。對(duì)于卷積網(wǎng)絡(luò)來(lái)說(shuō)劫扒,一般經(jīng)過(guò)仔細(xì)調(diào)整的 SGD 幾乎總會(huì)略?xún)?yōu)于 Adam,但最佳學(xué)習(xí)率的可能區(qū)域要窄得多狸膏。
一次復(fù)雜化一個(gè):如果你有多個(gè)特性插入分類(lèi)器沟饥,我建議你一個(gè)個(gè)插入,從而確保能獲得期待的性能提升湾戳。不要在最開(kāi)始時(shí)就一次性全加上贤旷,這樣你會(huì)弄不清楚性能提升到底是哪個(gè)特性帶來(lái)的。還有其它增加復(fù)雜性的方法砾脑,例如你可以先嘗試插入較小的圖像幼驶,然后再慢慢地加大。
別相信默認(rèn)的學(xué)習(xí)率衰減:如果你修改來(lái)自其它領(lǐng)域的代碼韧衣,你應(yīng)該小心使用學(xué)習(xí)率衰減方法县遣。對(duì)于不同問(wèn)題糜颠,你不僅希望使用不同的衰減策略,同時(shí)因?yàn)?Epoch 的數(shù)量不同萧求,衰減過(guò)程也會(huì)不一樣其兴。例如數(shù)據(jù)集的大小,會(huì)影響 Epoch 的數(shù)量夸政,而很多學(xué)習(xí)率衰減策略是直接與 Epoch 相關(guān)的元旬。在我自己的工作中,我經(jīng)常整個(gè)地關(guān)閉學(xué)習(xí)率衰減守问,即使用常數(shù)學(xué)習(xí)率匀归。
4. 正則化
理想情況下,我們現(xiàn)在至少有了一個(gè)擬合訓(xùn)練集的大模型『呐粒現(xiàn)在是時(shí)候?qū)λM(jìn)行正則化穆端,并通過(guò)放棄一些訓(xùn)練準(zhǔn)確率來(lái)提升驗(yàn)證準(zhǔn)確率了。技巧包括:
更多數(shù)據(jù):首先仿便,在當(dāng)前任何實(shí)際環(huán)境中正則化模型的最好方式是增加更多真實(shí)的訓(xùn)練數(shù)據(jù)体啰。在你能收集更多數(shù)據(jù)時(shí),花費(fèi)大量工程時(shí)間試圖從小數(shù)據(jù)集上取得更好結(jié)果是很常見(jiàn)的一個(gè)錯(cuò)誤嗽仪。我認(rèn)為增加更多數(shù)據(jù)是單調(diào)提升一個(gè)較好配置神經(jīng)網(wǎng)絡(luò)性能的唯一可靠方式荒勇。
數(shù)據(jù)增強(qiáng):比真實(shí)數(shù)據(jù)較次的方法是半假數(shù)據(jù),試驗(yàn)下更激進(jìn)的數(shù)據(jù)增強(qiáng)闻坚。
創(chuàng)造性增強(qiáng):如果半假數(shù)據(jù)也沒(méi)有沽翔,假數(shù)據(jù)也還可以。人們?cè)趯で髷U(kuò)展數(shù)據(jù)集的創(chuàng)造性方法窿凤。例如仅偎,域隨機(jī)化、使用模擬數(shù)據(jù)雳殊、把數(shù)據(jù)插入場(chǎng)景這樣機(jī)智的混合方法哨颂,甚至可以用 GAN。
預(yù)訓(xùn)練:即使你有足夠的數(shù)據(jù)相种,你也可以使用預(yù)訓(xùn)練網(wǎng)絡(luò),基本沒(méi)什么損失品姓。
堅(jiān)持監(jiān)督式學(xué)習(xí):不要對(duì)無(wú)監(jiān)督學(xué)習(xí)過(guò)于激動(dòng)寝并。據(jù)我所知,沒(méi)有什么無(wú)監(jiān)督學(xué)習(xí)方法在當(dāng)前計(jì)算機(jī)視覺(jué)任務(wù)上有很強(qiáng)的結(jié)果(盡管 NLP 領(lǐng)域現(xiàn)在有了 BERT 和其他類(lèi)似模型腹备,但這更多歸功于文本更成熟的本質(zhì)以及對(duì)噪聲比更好的信號(hào))衬潦。
更小的輸入維度:移除可能包含假信號(hào)的特征。如果你的數(shù)據(jù)集很小植酥,任何加入的假輸入只會(huì)增加過(guò)擬合的可能镀岛。類(lèi)似地弦牡,如果低級(jí)細(xì)節(jié)作用不大,試試輸入更小的圖像漂羊。
更小的模型:在許多情況下驾锰,你可以在網(wǎng)絡(luò)上使用域知識(shí)約束來(lái)降低模型大小。例如走越,在 ImageNet 主干網(wǎng)絡(luò)頂部使用全連接層一度很流行椭豫,但它們后來(lái)被簡(jiǎn)單的平均池化取代,消除了這一過(guò)程中大量的參數(shù)旨指。
減小批大猩退帧:由于 BN 基于批量大小來(lái)做歸一化,較小的批量大小具有更強(qiáng)的正則化效果谆构。這主要因?yàn)橐粋€(gè)批量的統(tǒng)計(jì)均值與標(biāo)準(zhǔn)差是實(shí)際均值和標(biāo)準(zhǔn)差的近似裸扶,所以縮放量和偏移量在小批量?jī)?nèi)波動(dòng)地更大。
drop:增加 dropout搬素。在卷積網(wǎng)絡(luò)上使用 dropout2d(空間 dropout)呵晨。保守謹(jǐn)慎的使用 dropout,因?yàn)樗鼘?duì) batch 歸一化好像不太友好蔗蹋。
權(quán)重衰減:增加權(quán)重衰減懲罰何荚。
早停(early stopping):基于你得到的驗(yàn)證損失停止訓(xùn)練,從而在即將過(guò)擬合之前獲取模型猪杭。
嘗試更大的模型:我過(guò)去多次發(fā)現(xiàn)更大模型最終都會(huì)很大程度的過(guò)擬合餐塘,但它們「早停」后的性能要比小模型好得多皂吮。
最后戒傻,為了更加確保網(wǎng)絡(luò)是個(gè)合理的分類(lèi)器,我喜歡可視化網(wǎng)絡(luò)第一層的權(quán)重蜂筹,確保自己獲得了有意義的邊緣需纳。如果第一層的濾波器看起來(lái)像噪聲,那需要去掉些東西艺挪。類(lèi)似地不翩,網(wǎng)絡(luò)內(nèi)的激活函數(shù)有時(shí)候也會(huì)揭示出一些問(wèn)題。
5. 精調(diào)
現(xiàn)在你應(yīng)該位于數(shù)據(jù)集一環(huán)麻裳,探索取得較低驗(yàn)證損失的架構(gòu)模型空間口蝠。這一步的一些技巧包括:
隨機(jī)網(wǎng)格搜索:在同時(shí)精調(diào)多個(gè)超參數(shù)時(shí),使用網(wǎng)格搜索聽(tīng)起來(lái)更誘惑津坑,能夠確保覆蓋到所有環(huán)境妙蔗。但記住,使用隨機(jī)搜索反而是最佳方式疆瑰。直觀上眉反,因?yàn)樯窠?jīng)網(wǎng)絡(luò)對(duì)一些參數(shù)更為敏感昙啄。在極限情況下,如果參數(shù) a 很重要寸五,改變 b 卻沒(méi)有影響梳凛,然后相比于多次在固定點(diǎn)采樣,你寧可徹底采樣 a播歼。
超參數(shù)優(yōu)化:如今社區(qū)內(nèi)有大量好的貝葉斯超參數(shù)優(yōu)化工具箱伶跷,我的一些朋友用過(guò)后覺(jué)得很成功。但我的個(gè)人經(jīng)驗(yàn)是秘狞,探索好的叭莫、寬的模型空間和超參數(shù)的最佳方法是找個(gè)實(shí)習(xí)生。開(kāi)玩笑而已烁试,哈哈哈雇初。
6. 最后的壓榨
一旦你找到最好的架構(gòu)類(lèi)型和超參數(shù),依然可以使用更多的技巧讓系統(tǒng)變得更好:
集成:模型集成是能將準(zhǔn)確率穩(wěn)定提升 2% 的一種好方式减响。如果你承擔(dān)不起測(cè)試階段的計(jì)算成本靖诗,試著使用《Distilling the Knowledge in a Neural Network》中的方法把你的模型蒸餾到一個(gè)網(wǎng)絡(luò)。
一直訓(xùn)練:我經(jīng)持荆看到一些人在驗(yàn)證損失趨平時(shí)會(huì)中斷模型訓(xùn)練刊橘,以我的經(jīng)驗(yàn)來(lái)看,網(wǎng)絡(luò)會(huì)長(zhǎng)時(shí)間保持非直觀的訓(xùn)練颂鸿。寒假時(shí)有一次我忘了關(guān)掉模型訓(xùn)練促绵,一月回來(lái)后發(fā)現(xiàn)它取得了 SOTA 結(jié)果。
結(jié)論
一旦你做到了這些嘴纺,你就具備了成功的所有要素:對(duì)神經(jīng)網(wǎng)絡(luò)败晴、數(shù)據(jù)集和問(wèn)題有了足夠深的了解,配置好了完整的訓(xùn)練/評(píng)估體系栽渴,取得高置信度的準(zhǔn)確率尖坤,逐漸探索更復(fù)雜的模型,提升每一步的表現(xiàn)∠胁粒現(xiàn)在萬(wàn)事俱備慢味,就可以去讀大量論文,嘗試大量實(shí)驗(yàn)并取得 SOTA 結(jié)果了墅冷。