點擊上方“小白學視覺”,選擇加"星標"或“置頂”
重磅干貨,第一時間送達

你有哪些deep learning(rnn、cnn)調(diào)參的經(jīng)驗?
作者:hzwer
鏈接:
https://www.zhihu.com/question/41631631/answer/859040970
來源:知乎
總結一下在曠視實習兩年來的煉丹經(jīng)驗,我主要做了一些 RL,圖像質(zhì)量,圖像分類,GAN 相關的任務,日常大概占用 5 - 10 張卡。有的同學在打比賽的時候,從頭到尾只維護若干份代碼,每次載入前一次的訓練參數(shù),改一下代碼再煉,俗稱老丹。這樣會有幾個問題:某次引入一個 bug,過了很久才發(fā)現(xiàn),然后不知道影響范圍;得到一個好模型,但是不知道它是怎么來的;忘了自己的 baseline,不知道改動是正面還是負面。要盡可能確保每一個模型有可復現(xiàn)性,實踐上建議代碼不應該在訓練后再改動,訓練新的模型時,把舊的代碼復制一遍。得到的實驗結果要開個文檔記下來以便日后總結,避免遺忘。我經(jīng)常通過閱讀自己和別人的記錄來得到靈感。實驗一致性上也要多做努力,理想狀態(tài)是有合理的基準來測模型的性能,同一個代碼不應該由于超參的微小改動而有顯著結果差異。出現(xiàn)這種情況可能是數(shù)據(jù)太少或基準設置不當。『資源利用』
對于新入行的同學,不要試圖在玩具級別的數(shù)據(jù)集或任務上做靠譜的研究,比如 MNIST。不是每一個實驗都要出一個好模型,實驗是為了驗證結論的。如果每個實驗都要 8 張卡跑兩個星期,人力物力都耗不起。盡力把實驗控制在單卡一天以內(nèi),理想狀態(tài)是半天得一次結論。理論上來說,水多加面面多加水(加數(shù)據(jù)加計算量)的做法無限漲點。建議先設一個目標,比如說就是在一天的訓練時間下做對比實驗。我的實踐經(jīng)驗是,首先用小圖小模型,比如 128 x 128 輸入的 ResNet18;用 cProfile 來找性能瓶頸,比如我發(fā)現(xiàn)某個模型,訓練的時候有一大半時間耗費在等數(shù)據(jù),數(shù)據(jù)處理中一大半時間在調(diào)用 numpy 的 round 函數(shù),前期把精力集中在提高做實驗的效率上。『模型不 work』
先把錦上添花的東西去掉,比如數(shù)據(jù)增廣,玄學學習率和超參,魔幻損失函數(shù),異形模型。如果世界上有一個非要加旋轉增廣和 1.96e-4 學習率 42 batchsize,配上四種混合損失函數(shù)才能訓練好的模型,它應該存在于靈能文明??梢韵仍煲恍┍M量玩具的模型,驗證代碼正確性。『需要進一步改進』
先確認影響模型性能的組件。感性認識就是,數(shù)據(jù)是否需要增加或增廣。模型是大了還是小了,再根據(jù)速度和精度期望開始尋找合適的模型。能用全卷積的任務,少用全連接層,參數(shù)量小?;灸P蜕?ResNet, Unet 結構還是主流。當你的模型有 Batch Normalization,初始化通常不需要操心,激活函數(shù)默認 Relu 即可(某引用數(shù)萬的大佬說的)。一般順序是 Conv - BN - Relu。如果沒有 BN(很多任務上,BN降低訓練難度,但是可能影響最終性能 ),試著要做一些數(shù)據(jù)歸一化。雖然有至少十種激活函數(shù),但在 Relu 外只推薦試一下 Swish。優(yōu)化器只推薦 Momentum 和 Adam。在這些方面做嘗試意義不大,如果性能提升反倒可能說明模型不成熟。不推薦做人肉模型設計,比如把某層卷積改大一點,或者微調(diào)一下通道數(shù)。除非有特別 insight,不要自己亂設計新組件。超參上,learning rate 最重要,推薦了解 cosine learning rate 和 cyclic learning rate,其次是 batchsize 和 weight decay。當你的模型還不錯的時候,可以試著做數(shù)據(jù)增廣和改損失函數(shù)錦上添花了。Bag of Tricks for Image Classification with Convolutional Neural Networks,trick 合集 1。Must Know Tips/Tricks in Deep Neural Networks,trick 合集 2。33條神經(jīng)網(wǎng)絡訓練秘技,trick 合集 3。Batch Normalization,雖然玄學,但是養(yǎng)活了很多煉丹師。Searching for Activation Functions,swish 激活函數(shù)。作者:Towser
鏈接:
https://www.zhihu.com/question/41631631/answer/862075836
來源:知乎
1、一上來就自己動手寫模型。建議首先用成熟的開源項目及其默認配置(例如 Gluon 對經(jīng)典模型的各種復現(xiàn)、各個著名模型作者自己放出來的代碼倉庫)在自己的數(shù)據(jù)集上跑一遍,在等程序運行結束的時間里仔細研究一下代碼里的各種細節(jié),最后再自己寫或者改代碼。2、訓 RNN 不加 gradient clipping,導致訓練一段時間以后 loss 突然變成 Nan。3、tying input & output embedding(就是詞向量層和輸出 softmax 前的矩陣共享參數(shù),在語言模型或機器翻譯中常用)時學習率需要設置得非常小,不然容易 Nan。4、在數(shù)據(jù)集很大的情況下,一上來就跑全量數(shù)據(jù)。建議先用 1/100、1/10 的數(shù)據(jù)跑一跑,對模型性能和訓練時間有個底,外推一下全量數(shù)據(jù)到底需要跑多久。在沒有足夠的信心前不做大規(guī)模實驗。5、只喜歡漂亮的模型結構,瞧不起調(diào)參數(shù)的論文/實驗報告,看論文時經(jīng)常不看超參數(shù)設置等細節(jié)。舉個例子,現(xiàn)在還有相當多的人不知道 BERT 的激活函數(shù)是 GELU 而不是 transformer 原論文中的 ReLU。在自己沒有太多資源實驗的情況下,實驗報告類文章簡直是業(yè)界良心好不好!Regularizing and Optimizing LSTM Language Models(LSTM 的訓練技巧)Massive Exploration of Neural Machine Translation Architectures(NMT 里各個超參的影響)Training Tips for the Transformer Model(訓練 Transformer 時會發(fā)生的各種現(xiàn)象)RoBERTa: A Robustly Optimized BERT Pretraining Approach(BERT 預訓練技巧,雖然跟大部分人沒啥關系)Training ImageNet in 1 Hour(大批量訓練技巧)Bag of Tricks for Image Classification with Convolutional Neural Networks(各種訓練技巧集大成)EfficientNet: Rethinking Model Scaling for Convolutional Neural Networks(當前對參數(shù)利用最有效的 CNN)有時受 batch size、sequence length 各種因素的影響,loss 很大(比如說好幾萬),對于這種數(shù)字人是沒有數(shù)感的,建議首先計算一下 per token loss(如果是多任務,可以每個任務單獨算;類似地,某些 CV 任務可以計算 per pixel loss),心里有點感覺。脫離損失函數(shù)的形式談學習率沒有意義(例如單是對 batch size 求和或者取平均這個差異就會使梯度差成百上千倍)。在確定初始學習率的時候,從一個很小的值(例如 1e-7)開始,然后每一步指數(shù)增大學習率(例如擴大1.05 倍)進行訓練。訓練幾百步應該能觀察到損失函數(shù)隨訓練步數(shù)呈對勾形,選擇損失下降最快那一段的學習率即可。7、Adam 可以解決一堆奇奇怪怪的問題(有時 loss 降不下去,換 Adam 瞬間就好了),也可以帶來一堆奇奇怪怪的問題(比如單詞詞頻差異很大,當前 batch 沒有的單詞的詞向量也被更新;再比如Adam和L2正則結合產(chǎn)生的復雜效果)。用的時候要膽大心細,萬一遇到問題找各種魔改 Adam(比如 MaskedAdam, AdamW 啥的)搶救。8、subword 總是會很穩(wěn)定地漲點,只管用就對了。這一條放在最后,是因為很多人不把它當一回事兒??赡苁怯X得這一條不需要寫代碼所以不重要?我見過太多人因為這條浪費時間了,所以專門強調(diào)一下。有些指標是有滯后性的,需要等訓練一段時間才開始動。很多人訓練幾步看沒什么效果就把程序停掉開始 debug 了,但其實代碼毫無問題。如此反復好幾天甚至一兩周都在原地踏步,其實需要做的僅僅是讓程序自個兒安安靜靜地跑上幾個小時或者一天……作者:蕭瑟
鏈接:
https://www.zhihu.com/question/41631631/answer/94816420
來源:知乎
訓練技巧對深度學習來說是非常重要的,作為一門實驗性質(zhì)很強的科學,同樣的網(wǎng)絡結構使用不同的訓練方法訓練,結果可能會有很大的差異。這里我總結了近一年來的煉丹心得,分享給大家,也歡迎大家補充指正。
參數(shù)初始化。
下面幾種方式,隨便選一個,結果基本都差不多。但是一定要做。否則可能會減慢收斂速度,影響收斂結果,甚至造成Nan等一系列問題。
下面的n_in為網(wǎng)絡的輸入大小,n_out為網(wǎng)絡的輸出大小,n為n_in或(n_in+n_out)*0.5
Xavier初始法論文:
http://jmlr.org/proceedings/papers/v9/glorot10a/glorot10a.pdf
He初始化論文:https://arxiv.org/abs/1502.01852
- uniform均勻分布初始化:
w = np.random.uniform(low=-scale, high=scale, size=[n_in,n_out]) - Xavier初始法,適用于普通激活函數(shù)(tanh,sigmoid):scale = np.sqrt(3/n)
- He初始化,適用于ReLU:scale = np.sqrt(6/n)
- normal高斯分布初始化:
w = np.random.randn(n_in,n_out) * stdev # stdev為高斯分布的標準差,均值設為0 - Xavier初始法,適用于普通激活函數(shù) (tanh,sigmoid):stdev = np.sqrt(n)
- He初始化,適用于ReLU:stdev = np.sqrt(2/n)
- svd初始化:對RNN有比較好的效果。參考論文:https://arxiv.org/abs/1312.6120
數(shù)據(jù)預處理方式
- zero-center ,這個挺常用的.
X -= np.mean(X, axis = 0) # zero-center
X /= np.std(X, axis = 0) # normalize
訓練技巧
- 要做梯度歸一化,即算出來的梯度除以minibatch size
- clip c(梯度裁剪): 限制最大梯度,其實是value = sqrt(w1^2+w2^2….),如果value超過了閾值,就算一個衰減系系數(shù),讓value的值等于閾值: 5,10,15
- dropout對小數(shù)據(jù)防止過擬合有很好的效果,值一般設為0.5,小數(shù)據(jù)上dropout+sgd在我的大部分實驗中,效果提升都非常明顯.因此可能的話,建議一定要嘗試一下。 dropout的位置比較有講究, 對于RNN,建議放到輸入->RNN與RNN->輸出的位置.關于RNN如何用dropout,可以參考這篇論文:http://arxiv.org/abs/1409.2329
- adam,adadelta等,在小數(shù)據(jù)上,我這里實驗的效果不如sgd, sgd收斂速度會慢一些,但是最終收斂后的結果,一般都比較好。如果使用sgd的話,可以選擇從1.0或者0.1的學習率開始,隔一段時間,在驗證集上檢查一下,如果cost沒有下降,就對學習率減半. 我看過很多論文都這么搞,我自己實驗的結果也很好. 當然,也可以先用ada系列先跑,最后快收斂的時候,更換成sgd繼續(xù)訓練.同樣也會有提升.據(jù)說adadelta一般在分類問題上效果比較好,adam在生成問題上效果比較好。
- 除了gate之類的地方,需要把輸出限制成0-1之外,盡量不要用sigmoid,可以用tanh或者relu之類的激活函數(shù).1. sigmoid函數(shù)在-4到4的區(qū)間里,才有較大的梯度。之外的區(qū)間,梯度接近0,很容易造成梯度消失問題。2. 輸入0均值,sigmoid函數(shù)的輸出不是0均值的。
- rnn的dim和embdding size,一般從128上下開始調(diào)整. batch size,一般從128左右開始調(diào)整.batch size合適最重要,并不是越大越好.
- word2vec初始化,在小數(shù)據(jù)上,不僅可以有效提高收斂速度,也可以可以提高結果.
- LSTM 的forget gate的bias,用1.0或者更大的值做初始化,可以取得更好的結果,來自這篇論文:http://jmlr.org/proceedings/papers/v37/jozefowicz15.pdf, 我這里實驗設成1.0,可以提高收斂速度.實際使用中,不同的任務,可能需要嘗試不同的值.
- Batch Normalization據(jù)說可以提升效果,不過我沒有嘗試過,建議作為最后提升模型的手段,參考論文:Accelerating Deep Network Training by Reducing Internal Covariate Shift
- 如果你的模型包含全連接層(MLP),并且輸入和輸出大小一樣,可以考慮將MLP替換成Highway Network,我嘗試對結果有一點提升,建議作為最后提升模型的手段,原理很簡單,就是給輸出加了一個gate來控制信息的流動,詳細介紹請參考論文: http://arxiv.org/abs/1505.00387
- 來自@張馨宇的技巧:一輪加正則,一輪不加正則,反復進行。
Ensemble
Ensemble是論文刷結果的終極核武器,深度學習中一般有以下幾種方式
- 不同的參數(shù),通過cross-validation,選取最好的幾組
- 同樣的參數(shù),模型訓練的不同階段,即不同迭代次數(shù)的模型。
- 不同的模型,進行線性融合. 例如RNN和傳統(tǒng)模型.
作者:京東白條
鏈接:
https://www.zhihu.com/question/41631631/answer/776852832
來源:知乎
相信很多剛開始接觸深度學習朋友,會感覺深度學習調(diào)參就像玄學一般,有時候參數(shù)調(diào)的好,模型會快速收斂,參數(shù)沒調(diào)好,可能迭代幾次loss值就直接變成Nan了。記得剛開始研究深度學習時,做過兩個小例子。一個是用tensorflow構建了一個十分簡單的只有一個輸入層和一個softmax輸出層的Mnist手寫識別網(wǎng)絡,第一次我對權重矩陣W和偏置b采用的是正態(tài)分布初始化,一共迭代了20個epoch,當?shù)甑谝粋€epoch時,預測的準確度只有10%左右(和隨機猜一樣,Mnist是一個十分類問題),當?shù)甓畟€epoch,精度也僅僅達到了60%的樣子。然后我僅僅是將權重矩陣W初始化方法改成了全為0的初始化,其他的參數(shù)均保持不變,結果在訓練完第一個epoch后預測精度就達到了85%以上,最終20個epoch后精度達到92%。另一個例子是回歸問題的預測,當時采用的SGD優(yōu)化器,一開始學習率設定的0.1,模型可以正常訓練,只是訓練速度有些慢,我試著將學習率調(diào)整到0.3,希望可以加速訓練速度,結果沒迭代幾輪loss就變成Nan了。于是從那時起我就深刻的感受到參數(shù)調(diào)節(jié)在深度學習模型訓練中的重要意義。其實上述問題產(chǎn)生的原因也很好理解,對于參數(shù)初始化,因為我們學習的本來就是權重W與偏置b,如果初始化足夠好,直接就初始化到最優(yōu)解,那都不用進行訓練了。良好的初始化,可以讓參數(shù)更接近最優(yōu)解,這可以大大提高收斂速度,也可以防止落入局部極小。對于學習率,學習率如果取太大,會使模型訓練非常震蕩,可以想象我們最小化一個二次拋物線,選取一個很大的學習率,那么迭代點會一直在拋物線的兩邊震蕩,收斂不到最小值,甚至還有螺旋上升迭代點的可能。下面對深度學習調(diào)參技巧談些心得,雖說不能讓你通過以下閱讀成為一個調(diào)參高手,但最起碼可以提供一些調(diào)參的思路。常用的激活函數(shù)有relu、leaky-relu、sigmoid、tanh等。對于輸出層,多分類任務選用softmax輸出,二分類任務選用sigmoid輸出,回歸任務選用線性輸出。而對于中間隱層,則優(yōu)先選擇relu激活函數(shù)(relu激活函數(shù)可以有效的解決sigmoid和tanh出現(xiàn)的梯度彌散問題,多次實驗表明它會比其他激活函數(shù)以更快的速度收斂)。另外,構建序列神經(jīng)網(wǎng)絡(RNN)時要優(yōu)先選用tanh激活函數(shù)。一般學習率從0.1或0.01開始嘗試。學習率設置太大會導致訓練十分不穩(wěn)定,甚至出現(xiàn)Nan,設置太小會導致?lián)p失下降太慢。學習率一般要隨著訓練進行衰減。衰減系數(shù)設0.1,0.3,0.5均可,衰減時機,可以是驗證集準確率不再上升時,或固定訓練多少個周期以后自動進行衰減。一般常用的防止過擬合方法有使用L1正則項、L2正則項、dropout、提前終止、數(shù)據(jù)集擴充等。如果模型在訓練集上表現(xiàn)比較好但在測試集上表現(xiàn)欠佳可以選擇增大L1或L2正則的懲罰力度(L2正則經(jīng)驗上首選1.0,超過10很少見),或增大dropout的隨機失活概率(經(jīng)驗首選0.5);或者當隨著訓練的持續(xù)在測試集上不增反降時,使用提前終止訓練的方法。當然最有效的還是增大訓練集的規(guī)模,實在難以獲得新數(shù)據(jù)也可以使用數(shù)據(jù)集增強的方法,比如CV任務可以對數(shù)據(jù)集進行裁剪、翻轉、平移等方法進行數(shù)據(jù)集增強,這種方法往往都會提高最后模型的測試精度。如果數(shù)據(jù)是稀疏的,就用自適應方法,即 Adagrad, Adadelta, RMSprop, Adam。整體來講,Adam 是最好的選擇。SGD 雖然能達到極小值,但是比其它算法用的時間長,而且可能會被困在鞍點。如果需要更快的收斂,或者是訓練更深更復雜的神經(jīng)網(wǎng)絡,需要用一種自適應的算法。如果你希望訓練一個更深更復雜的網(wǎng)絡,那么殘差塊絕對是一個重要的組件,它可以讓你的網(wǎng)絡訓練的更深。BN層具有加速訓練速度,有效防止梯度消失與梯度爆炸,具有防止過擬合的效果,所以構建網(wǎng)絡時最好要加上這個組件。(1)Grid Search:網(wǎng)格搜索,在所有候選的參數(shù)選擇中,通過循環(huán)遍歷,嘗試每一種可能性,表現(xiàn)最好的參數(shù)就是最終的結果。其原理就像是在數(shù)組里找最大值。缺點是太費時間了,特別像神經(jīng)網(wǎng)絡,一般嘗試不了太多的參數(shù)組合。(2)Random Search:經(jīng)驗上,Random Search比Gird Search更有效。實際操作的時候,一般也是先用Gird Search的方法,得到所有候選參數(shù),然后每次從中隨機選擇進行訓練。另外Random Search往往會和由粗到細的調(diào)參策略結合使用,即在效果比較好的參數(shù)附近進行更加精細的搜索。(3)Bayesian Optimization:貝葉斯優(yōu)化,考慮到了不同參數(shù)對應的 ? ?實驗結果值,因此更節(jié)省時間,貝葉斯調(diào)參比Grid Search迭代次數(shù)少, ?速度快;而且其針對非凸問題依然穩(wěn)健。7.參數(shù)隨機初始化與數(shù)據(jù)預處理:參數(shù)初始化很重要,它決定了模型的訓練速度與是否可以躲開局部極小。relu激活函數(shù)初始化推薦使用He normal,tanh初始化推薦使用Glorot normal,其中Glorot normal也稱作Xavier normal初始化;數(shù)據(jù)預處理方法一般也就采用數(shù)據(jù)歸一化即可。https://www.zhihu.com/question/41631631/answer/92408405
來源:知乎最近在看 Karpathy 的 cs231n, 還沒看完, 不過過程中總結了一下他提到的一些技巧:- 通常情況下, 更新參數(shù)的方法默認用 Adam 效果就很好
- 如果可以載入全部數(shù)據(jù) (full batch updates), 可以使用 L-BFGS
- 訓練多個模型, 在測試時將結果平均起來, 大約可以得到 2% 提升.
- 訓練單個模型時, 平均不同時期的 checkpoints 的結果, 也可以有提升.
- 測試時可以將測試的參數(shù)和訓練的參數(shù)組合起來:
while True: data_batch = ... loss = network.forward(data_batch) dx = network.backward() x += - learning_rate * dx x_test = 0.995 * x_test + 0.005 * x # use for test set
下載1:OpenCV-Contrib擴展模塊中文版教程
在「小白學視覺」公眾號后臺回復:擴展模塊中文教程,即可下載全網(wǎng)第一份OpenCV擴展模塊教程中文版,涵蓋擴展模塊安裝、SFM算法、立體視覺、目標跟蹤、生物視覺、超分辨率處理等二十多章內(nèi)容。下載2:Python視覺實戰(zhàn)項目52講在「小白學視覺」公眾號后臺回復:Python視覺實戰(zhàn)項目,即可下載包括圖像分割、口罩檢測、車道線檢測、車輛計數(shù)、添加眼線、車牌識別、字符識別、情緒檢測、文本內(nèi)容提取、面部識別等31個視覺實戰(zhàn)項目,助力快速學校計算機視覺。在「小白學視覺」公眾號后臺回復:OpenCV實戰(zhàn)項目20講,即可下載含有20個基于OpenCV實現(xiàn)20個實戰(zhàn)項目,實現(xiàn)OpenCV學習進階。交流群
歡迎加入公眾號讀者群一起和同行交流,目前有SLAM、三維視覺、傳感器、自動駕駛、計算攝影、檢測、分割、識別、醫(yī)學影像、GAN、算法競賽等微信群(以后會逐漸細分),請掃描下面微信號加群,備注:”昵稱+學校/公司+研究方向“,例如:”張三?+?上海交大?+?視覺SLAM“。請按照格式備注,否則不予通過。添加成功后會根據(jù)研究方向邀請進入相關微信群。請勿在群內(nèi)發(fā)送廣告,否則會請出群,謝謝理解~