神经网络调参经验大汇总
作者:Andrej Karpathy,翻譯:杰少 @大野人007
今天看到一篇非常非常棒的調(diào)節(jié)NN的文章,作者是特斯拉高級(jí)總監(jiān)Andrej Karpathy,就翻譯過來和大家一起分享,難免翻譯有問題,有興趣的朋友可以去引文閱讀原文。
為了能更好地訓(xùn)練NN,karpathy為自己定制了一套具體的流程。在每次用NN處理一個(gè)新問題的時(shí)候,都會(huì)按照這套流程來,該流程的核心主要有兩步驟。
- 從簡(jiǎn)單到復(fù)雜,每一步我們都會(huì)對(duì)將要發(fā)生的事情做出具體的假設(shè),然后通過實(shí)驗(yàn)驗(yàn)證這些假設(shè),或者進(jìn)行研究,直到我們發(fā)現(xiàn)一些問題。我們努力防止的是一次引入大量“未經(jīng)驗(yàn)證”的復(fù)雜假設(shè),這必然會(huì)引入錯(cuò)誤/錯(cuò)誤配置,這將需要花費(fèi)很長(zhǎng)時(shí)間才能找到(如果有的話)。
- 編寫你的神經(jīng)網(wǎng)絡(luò)代碼并訓(xùn)練一個(gè),可以使用一個(gè)非常小的學(xué)習(xí)率和猜測(cè),然后在每次迭代后評(píng)估完整的測(cè)試集。
訓(xùn)練神經(jīng)網(wǎng)絡(luò)的第一步是不接觸任何神經(jīng)網(wǎng)絡(luò)代碼,而是從檢查數(shù)據(jù)開始。
這一步至關(guān)重要。我喜歡花大量的時(shí)間(以小時(shí)為單位)瀏覽數(shù)千個(gè)示例,了解它們的分布并尋找模式。幸運(yùn)的是,你的大腦在這方面很在行。有一次,我發(fā)現(xiàn)數(shù)據(jù)中包含重復(fù)的樣本。另一次我發(fā)現(xiàn)損壞的圖像/標(biāo)簽。我尋找數(shù)據(jù)不平衡和Bias。我通常還會(huì)注意我自己對(duì)數(shù)據(jù)進(jìn)行分類的過程,這暗示了我們將最終探索的體系結(jié)構(gòu)類型。例如,
- 非常局部的特征是否足夠?
- 或者我們是否需要全局上下文的信息?
- 有多少變化,它采取什么形式?
- 什么變化是虛假的,是否可以被預(yù)處理掉?
- 空間位置重要嗎?還是我們想把它平均化?
- 細(xì)節(jié)有多重要?我們能承受多大程度的減少圖像采樣?
- 標(biāo)簽存在多少噪音?
此外,神經(jīng)網(wǎng)絡(luò)實(shí)際上是數(shù)據(jù)集的壓縮/編譯版本,您將能夠查看網(wǎng)絡(luò)(mis)預(yù)測(cè)并了解它們可能來自何處。如果你的網(wǎng)絡(luò)給了你一些與你在數(shù)據(jù)中看到的不一致的預(yù)測(cè),那么就有問題了。
一旦你有了一個(gè)定性的感覺,寫一些簡(jiǎn)單的代碼來搜索/過濾/排序你能想到的任何東西(例如標(biāo)簽的類型、注釋的大小、注釋的數(shù)量等),并可視化它們的分布和任何軸上的異常值也是一個(gè)好主意。異常值幾乎總是會(huì)暴露出數(shù)據(jù)質(zhì)量或預(yù)處理中的一些缺陷。
在我們了解我們數(shù)據(jù)之后,下一步任務(wù)便是建立一個(gè)完整的**“訓(xùn)練+評(píng)估”**框架,并通過一系列實(shí)驗(yàn)獲得對(duì)其正確性。在這個(gè)階段,最好選擇一些比較擅長(zhǎng)的簡(jiǎn)單模型,例如線性分類器,或者較小的卷積網(wǎng)絡(luò)等。之后我們便可以進(jìn)行訓(xùn)練,可視化損失函數(shù),評(píng)估指標(biāo)(如準(zhǔn)確性)等,在進(jìn)行模型預(yù)測(cè),并在過程中使用明確的假設(shè)進(jìn)行消融實(shí)驗(yàn)。
這一步的核心技巧有:
- 數(shù)據(jù)擴(kuò)充是一種正則化策略,我們以后可能會(huì)采用這種策略,但剛開始就引入則經(jīng)常會(huì)犯一些愚蠢的錯(cuò)誤。
- 在評(píng)估中添加重要的數(shù)字。繪制測(cè)試損失圖時(shí),對(duì)整個(gè)(大型)測(cè)試集運(yùn)行評(píng)估。不要只繪制批次的測(cè)試損失圖,然后依靠在Tensorboard中平滑它們。我們追求正確,非常愿意為了保持理智而放棄時(shí)間。
- 驗(yàn)證損失@init。確保loss從正確的損失值開始。例如,如果正確初始化最后一層,則應(yīng)在初始化時(shí)在softmax上測(cè)量-log(1/n_class)。對(duì)于L2回歸、Huber損失等,可以導(dǎo)出相同的默認(rèn)值。
- init well。正確初始化最終層的權(quán)重。例如,如果您對(duì)一些平均值為50的值進(jìn)行回歸,則將最終偏差初始化為50。如果您有一個(gè)正:負(fù)比率為1:10的不平衡數(shù)據(jù)集,則在您的登logits上設(shè)置偏差,以便網(wǎng)絡(luò)在初始化時(shí)預(yù)測(cè)概率為0.1。正確設(shè)置這些參數(shù)將加快收斂速度并消除“hockey stick”損失曲線,在最初的幾次迭代中,您的網(wǎng)絡(luò)基本上只是在學(xué)習(xí)偏差。
- human基線。監(jiān)控除損失以外的人類可解釋和可檢查的指標(biāo)(例如準(zhǔn)確性)。盡可能評(píng)估自己(人類)的準(zhǔn)確性并與之進(jìn)行比較。或者,對(duì)測(cè)試數(shù)據(jù)進(jìn)行兩次注釋,對(duì)于每個(gè)示例,將一次注釋視為預(yù)測(cè),第二次注釋視為基本真理。
- 輸入相關(guān)的基線。訓(xùn)練輸入獨(dú)立的基線(例如,最簡(jiǎn)單的方法是將所有輸入設(shè)置為零)。這應(yīng)該比實(shí)際插入數(shù)據(jù)而不將其歸零的情況更糟糕。即:您的模型是否學(xué)習(xí)從輸入中提取任何信息?
- 過擬合一個(gè)batch。使用少數(shù)幾個(gè)樣本(例如,僅兩三個(gè)樣本)對(duì)單個(gè)批次進(jìn)行過擬合。為此,我們?cè)黾恿四P偷娜萘?#xff08;例如添加層或filters),并驗(yàn)證我們可以達(dá)到最低的可實(shí)現(xiàn)損耗(例如零)。我還喜歡在同一個(gè)圖中可視化標(biāo)簽和預(yù)測(cè),并確保一旦我們達(dá)到最小損失,它們最終會(huì)完美對(duì)齊。如果他們不這樣做,那么肯定在某個(gè)地方存在一個(gè)bug,我們無法繼續(xù)下一階段。
- 驗(yàn)證是否減少了訓(xùn)練loss,在這個(gè)階段,我們更加希望看到在數(shù)據(jù)集上欠擬合,因?yàn)槟阏谑褂靡粋€(gè)玩具模型。試著稍微增加它的容量。你的訓(xùn)練損失有沒有像應(yīng)該的那樣減少?
- 在net之前可視化,可視化數(shù)據(jù)的明確正確位置就在y_hat=model(x)(或sess.run in tf)之前。也就是說,您希望準(zhǔn)確地可視化進(jìn)入網(wǎng)絡(luò)的內(nèi)容,將數(shù)據(jù)和標(biāo)簽的原始張量解碼為可視化。這是唯一的“真理之源”。我無法計(jì)算這節(jié)省了我多少時(shí)間,并暴露了數(shù)據(jù)預(yù)處理和擴(kuò)充方面的問題。
- 可視化預(yù)測(cè)動(dòng)態(tài)。在訓(xùn)練過程中,我喜歡在固定的測(cè)試批次上可視化模型的預(yù)測(cè)。這些預(yù)測(cè)的“動(dòng)態(tài)”會(huì)讓你對(duì)訓(xùn)練的進(jìn)展有非常好的直覺。很多時(shí)候,如果網(wǎng)絡(luò)以某種方式擺動(dòng)過多,暴露出不穩(wěn)定性,人們可能會(huì)感覺到網(wǎng)絡(luò)在努力適應(yīng)數(shù)據(jù)。非常低或非常高的學(xué)習(xí)率在抖動(dòng)量上也很容易被注意到。
- 使用backprop來圖表來依賴關(guān)系。深度學(xué)習(xí)代碼通常會(huì)包含復(fù)雜的、矢量化的和廣播式的操作。我曾經(jīng)遇到過的一個(gè)相對(duì)常見的錯(cuò)誤是,人們錯(cuò)誤地理解了這一點(diǎn)(例如,他們?cè)谀程幨褂靡晥D而不是轉(zhuǎn)置/置換),無意中在批處理維度中混合了信息。這是一個(gè)令人沮喪的事實(shí),您的網(wǎng)絡(luò)通常仍能正常訓(xùn)練,因?yàn)樗鼘W(xué)會(huì)忽略其他樣本中的數(shù)據(jù)。調(diào)試此問題(以及其他相關(guān)問題)的一種方法是將損耗設(shè)置為微不足道的值,如樣本的所有輸出之和,運(yùn)行反向傳遞到輸入,并確保僅在第個(gè)輸入上獲得非零梯度。例如,可以使用相同的策略來確保時(shí)間t時(shí)的自回歸模型僅取決于。更一般地說,梯度為您提供了有關(guān)網(wǎng)絡(luò)中哪些依賴于哪些的信息,這對(duì)于調(diào)試非常有用。
- 泛化一個(gè)特例。這更像是一個(gè)通用的編碼技巧,從頭開始編寫一個(gè)相對(duì)通用的功能。我喜歡為我現(xiàn)在正在做的事情編寫一個(gè)非常具體的函數(shù),讓它工作起來。
在這一步,我們應(yīng)該對(duì)數(shù)據(jù)集有很好的理解,并且我們有完整的訓(xùn)練+評(píng)估流程。
對(duì)于任何給定的模型,我們都可以(重復(fù)地)計(jì)算出我們信任的度量。我們還擁有獨(dú)立于輸入的基線的表現(xiàn),一些愚蠢基線的性能(我們最好擊敗這些基線),我們對(duì)人類的表現(xiàn)有一個(gè)粗略的感覺(我們希望達(dá)到這一點(diǎn))。現(xiàn)在可以在一個(gè)好的模型上進(jìn)行迭代了。
我喜歡采用的尋找一個(gè)好模型的方法有兩個(gè)階段:
- 首先獲得一個(gè)足夠大的模型,使其能夠過擬合(即,關(guān)注訓(xùn)練損失),然后適當(dāng)?shù)卣{(diào)整它(放棄一些訓(xùn)練損失以改善驗(yàn)證損失)。
我喜歡這兩個(gè)階段的原因是,如果我們?cè)谌魏文P蜕隙紵o法達(dá)到低錯(cuò)誤率,那么這可能再次表明一些問題、bug或錯(cuò)誤配置。
這一步的一些建議:
理想情況下,我們現(xiàn)在所處的位置是,我們有一個(gè)至少擬合訓(xùn)練集的大模型。現(xiàn)在需要對(duì)其進(jìn)行正則化,并通過放棄一些訓(xùn)練精度來獲得更好的驗(yàn)證精度。這邊有一些技巧:
- 獲取更多數(shù)據(jù)。首先,到目前為止,在任何實(shí)際環(huán)境中正華化模型的最佳和首選方法是添加更多真實(shí)的訓(xùn)練數(shù)據(jù)。當(dāng)您可以收集更多數(shù)據(jù)時(shí),花費(fèi)大量的工程周期試圖從一個(gè)小數(shù)據(jù)集中榨取數(shù)據(jù),這是一個(gè)非常常見的錯(cuò)誤。據(jù)我所知,添加更多數(shù)據(jù)幾乎是單調(diào)地提高配置良好的神經(jīng)網(wǎng)絡(luò)幾乎無限期性能的唯一保證。另一種可能是集成(如果你能負(fù)擔(dān)得起的話),但在5個(gè)模型之后,這種繼承就最為流行了。
- 數(shù)據(jù)擴(kuò)充。與真實(shí)數(shù)據(jù)相比,下一個(gè)最好的方法是半假數(shù)據(jù)——嘗試更激進(jìn)的數(shù)據(jù)擴(kuò)充。
- 創(chuàng)造性的數(shù)據(jù)增加。如果有一半的假數(shù)據(jù)不起作用,假數(shù)據(jù)也可能起到作用。人們正在尋找擴(kuò)展數(shù)據(jù)集的創(chuàng)造性方法;例如,域隨機(jī)化、模擬的使用、巧妙的混合,例如將(可能模擬的)數(shù)據(jù)插入場(chǎng)景,甚至是GANs。
- 預(yù)訓(xùn)練:如果可以的話,即使你有足夠的數(shù)據(jù),使用預(yù)先訓(xùn)練好的網(wǎng)絡(luò)也不會(huì)有什么壞處。
- 堅(jiān)持監(jiān)督學(xué)習(xí)。不要對(duì)無監(jiān)督的預(yù)訓(xùn)練過度興奮。據(jù)我所知,與2008年的那篇博文所告訴你的不同,目前還沒有一個(gè)版本的NLP在現(xiàn)代計(jì)算機(jī)視覺方面取得了很好的效果(盡管這段時(shí)間來使用BERT處理NLP問題非常好,很可能是因?yàn)槲谋镜教厥庑再|(zhì),以及更高的信噪比)。
- 較小的輸入維度。刪除可能包含虛假信號(hào)的功能。如果您的數(shù)據(jù)集很小,任何添加的虛假輸入都只是另一個(gè)過擬合的機(jī)會(huì)。同樣,如果低級(jí)細(xì)節(jié)無關(guān)緊要,請(qǐng)嘗試輸入較小的圖像。
- 更小的模型size。在許多情況下,您可以使用網(wǎng)絡(luò)上的領(lǐng)域知識(shí)約束來減小其大小。例如,過去流行在ImageNet主干的頂部使用完全連接的層,但后來這些層被簡(jiǎn)單的平均池所取代,從而消除了過程中的大量參數(shù)。
- 減少batch大小。由于batch范數(shù)內(nèi)的標(biāo)準(zhǔn)化,較小的batch大小在某種程度上對(duì)應(yīng)于更強(qiáng)的正則化。這是因?yàn)閎atch經(jīng)驗(yàn)平均值/std是完整平均值/std的更近似版本,因此比例和偏移量會(huì)使批次更容易“擺動(dòng)”。
- 加上drop。將dropout2d(空間dropout)用于CONVnet。謹(jǐn)慎使用此選項(xiàng),因?yàn)檩z學(xué)似乎不能很好地處理批處理規(guī)范化。
- 權(quán)重衰減。增加weight衰減懲罰。
- 早停。根據(jù)驗(yàn)證損失停止訓(xùn)練,以便在模型即將過度擬合時(shí)捕捉模型。
- 試試大一點(diǎn)的模型。我最后一次提到這一點(diǎn),而且是在提前停止之后,但我發(fā)現(xiàn)在過去的幾次中,大型車型當(dāng)然最終會(huì)過度擬合,但它們的“提前停止”性能通常會(huì)比小型車型好得多。
最后,為了使您的網(wǎng)絡(luò)成為一個(gè)合理的分類器,我喜歡可視化網(wǎng)絡(luò)的第一層權(quán)重,并確保獲得有意義的好邊。如果您的第一層過濾器看起來像噪音,那么可能會(huì)有問題。類似地,網(wǎng)絡(luò)內(nèi)部的激活有時(shí)會(huì)顯示奇怪的工件并提示問題。
現(xiàn)在,您應(yīng)該“in the loop”使用數(shù)據(jù)集,為達(dá)到低驗(yàn)證損失的結(jié)構(gòu)需要探索更廣闊的模型空間。此步驟的一些提示和技巧:
- 隨機(jī)網(wǎng)格搜索。為了同時(shí)調(diào)整多個(gè)超參數(shù),使用網(wǎng)格搜索來確保覆蓋所有的設(shè)置聽起來很誘人,但請(qǐng)記住,最好使用隨機(jī)搜索。直覺上,這是因?yàn)樯窠?jīng)網(wǎng)絡(luò)通常比其他網(wǎng)絡(luò)對(duì)某些參數(shù)更敏感。在極限情況下,如果參數(shù)a很重要,但更改b沒有效果,那么您寧愿更全面地對(duì)a進(jìn)行采樣,而不是多次在幾個(gè)固定點(diǎn)進(jìn)行采樣。
- 超參數(shù)優(yōu)化。目前有大量fancy的貝葉斯超參數(shù)優(yōu)化工具箱,我的一些朋友也說出了他們的成功,但我個(gè)人的經(jīng)驗(yàn)是,探索模型和超參數(shù)的美好和廣闊空間的最先進(jìn)方法是使用實(shí)習(xí)生:)。只是開玩笑......
一旦您找到了最佳的結(jié)構(gòu)和超參數(shù),仍然可以使用更多的技巧從結(jié)果中榨出最后的汁液:
- 集成。模型集成是一種幾乎可以保證在任何情況下獲得2%準(zhǔn)確率的方法。如果您在測(cè)試時(shí)負(fù)擔(dān)不起計(jì)算,請(qǐng)考慮使用暗知識(shí)將您的集成提取到網(wǎng)絡(luò)中。
- 留著訓(xùn)練。我經(jīng)常看到人們?cè)噲D在驗(yàn)證損失趨于平穩(wěn)時(shí)停止模型培訓(xùn)。根據(jù)我的經(jīng)驗(yàn),網(wǎng)絡(luò)會(huì)持續(xù)很長(zhǎng)時(shí)間的訓(xùn)練。有一次,我在寒假期間不小心離開了,留著一個(gè)模特訓(xùn)練,當(dāng)我在一月份回來的時(shí)候,那是SOTA。
結(jié)論
一旦你來到這里,你將擁有成功的所有要素:你對(duì)技術(shù)、數(shù)據(jù)集和問題有著深刻的理解,你建立了整個(gè)訓(xùn)練/評(píng)估結(jié)構(gòu),對(duì)其準(zhǔn)確性有著高度的信心,你探索了越來越復(fù)雜的模型,通過預(yù)測(cè)每一步的方式獲得性能改進(jìn)。您現(xiàn)在已經(jīng)準(zhǔn)備好閱讀大量論文,嘗試大量實(shí)驗(yàn),并獲得SOTA結(jié)果。祝你好運(yùn)!
參考文獻(xiàn)
A Recipe for Training Neural Networks
總結(jié)
以上是生活随笔為你收集整理的神经网络调参经验大汇总的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 淘宝搜索中基于embedding的召回
- 下一篇: 推荐系统里,可以用蒸馏吗?