深度學習網絡訓練技巧

(改了點)

 

轉載請註明:煉丹實驗室
新開了一個專欄,爲什麼叫煉丹實驗室呢,因爲以後會在這個專欄裏分享一些關於深度學習相關的實戰心得,而深度學習很多人稱它爲玄學,猶如煉丹一般。不過即使是煉丹也是可以摸索出一些經驗規律的,希望和各位煉丹術士一起多多交流。

訓練技巧對深度學習來說是非常重要的,作爲一門實驗性質很強的科學,同樣的網絡結構使用不同的訓練方法訓練,結果可能會有很大的差異。這裏我總結了近一年來的煉丹心得,分享給大家,也歡迎大家補充指正。

參數初始化。

下面幾種方式,隨便選一個,結果基本都差不多。但是一定要做。否則可能會減慢收斂速度,影響收斂結果,甚至造成Nan等一系列問題。
n_in爲網絡的輸入大小,n_out爲網絡的輸出大小,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初始法,適用於普通激活函數(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初始法,適用於普通激活函數 (tanh,sigmoid):stdev = np.sqrt(n)
    • He初始化,適用於ReLU:stdev = np.sqrt(2/n)
  • svd初始化:對RNN有比較好的效果。參考論文:https://arxiv.org/abs/1312.6120

數據預處理方式

  • zero-center ,這個挺常用的.
    X -= np.mean(X, axis = 0) # zero-center
    X /= np.std(X, axis = 0) # normalize
  • PCA whitening,這個用的比較少.

訓練技巧

 

5、學習率:

6、驗證集的使用:

使用驗證集,可以知道什麼時候開始降低學習率和什麼時候停止訓練;

7、weight初始化:

①  如果你不想繁瑣的話,直接用0.02*randn(num_params)來初始化,當然別的值也可以去嘗試;

②  如果上面那個建議不太好使,那麼就依次初始化每一個weight矩陣用init_scale / sqrt(layer_width) * randninit_scale可以被設置爲0.1或者1

③  初始化參數對結果的影響至關重要,要引起重視;

④  在深度網絡中,隨機初始化權重,使用SGD的話一般處理的都不好,這是因爲初始化的權重太小了。這種情況下對於淺層網絡有效,但是當足夠深的時候就不行,因爲weight更新的時候,是靠很多weight相乘的,越乘越小,類似梯度消失的意思。

8、RNN&&LSTM(這方面沒有深入瞭解,借用別人的意思):

如果訓練RNN或者LSTM,務必保證gradientnorm被約束在15或者5(前提還是要先歸一化gradient),這一點在RNNLSTM中很重要;

9、梯度檢查:

檢查下梯度,如果是你自己計算的梯度;如果使用LSTM來解決長時依賴的問題,記得初始化bias的時候要大一點;

10、數據增廣:

儘可能想辦法多的擴增訓練數據,如果使用的是圖像數據,不妨對圖像做一點扭轉,剪切,分割等操作來擴充數據訓練集合;

11、評價結果:

評價最終結果的時候,多做幾次,然後平均一下他們的結果。

補充:

1、參數設置技巧  

無論是多核CPU還是GPU加速,內存管理仍然以字節爲基本單元做硬件優化,因此將參數設定爲2的指數倍,如64,128,512,1024等,將有效提高矩陣分片、張量計算等操作的硬件處理效率;

2、正則優化  

除了在神經網絡單元上添加傳統的L1/L2正則項外,Dropout更經常在深度神經網絡應用來避免模型的過擬合。初始默認的0.5的丟棄率是保守的選擇,如果模型不是很複雜,設置爲0.2就可以;

4、其他方法 

除了上述訓練調優的方法外,還有其他一些常用方法,包括:使用mini-batch learning方法、遷移訓練學習、打亂訓練集順序、對比訓練誤差和測試誤差調節迭代次數、日誌可視化觀察等等。

  • Minibatch:這個有時候還要根據你的硬件設備而定,一般建議用128,8這組,但是128,1也很好,只是效率會非常慢,注意的是:千萬不要用過大的數值,否則很容易過擬合;
  • 要做梯度歸一化,即算出來的梯度除以minibatch size
  • clip c(梯度裁剪): 限制最大梯度,其實是value = sqrt(w1^2+w2^2….),如果value超過了閾值,就算一個衰減繫系數,讓value的值等於閾值: 5,10,15
  • dropout對小數據防止過擬合有很好的效果,值一般設爲0.5,小數據上dropout+sgd在我的大部分實驗中,效果提升都非常明顯.因此可能的話,建議一定要嘗試一下。 dropout的位置比較有講究, 對於RNN,建議放到輸入->RNN與RNN->輸出的位置.關於RNN如何用dropout,可以參考這篇論文:http://arxiv.org/abs/1409.2329
  • adam,adadelta等,在小數據上,我這裏實驗的效果不如sgd, sgd收斂速度會慢一些,但是最終收斂後的結果,一般都比較好。如果使用sgd的話,可以選擇從1.0或者0.1的學習率開始,隔一段時間,在驗證集上檢查一下,如果cost沒有下降,就對學習率減半或者除於0.5.然後繼續,學習率會一直變得很小,到最後就可以停止訓練了, 我看過很多論文都這麼搞,我自己實驗的結果也很好。但是如果對於的大數據,何凱明老師也說過,要把學習率調到很小,他說0.00001都不爲過(如果記得不錯,應該是這麼說的); 很多人用的一個設計學習率的原則就是監測一個比率(每次更新梯度的norm除以當前weightnorm),如果這個比率在10e-3附近,且小於這個值,學習會很慢,如果大於這個值,那麼學習很不穩定,由此會帶來學習失敗。
  • adam和sgd,可以組合使用,也可以先用ada系列快速訓練到瓶頸處,最後快收斂的時候,更換成sgd繼續訓練,慢慢搜索,效果可能比只使用adam會好一些。據說adadelta一般在分類問題上效果比較好,adam在生成問題上效果比較好。adam 是自適應學習率算法,對學習率初始值敏感性不強,但初始學習率設爲0.0003是個比較合適的值。因爲優化問題到底是什麼取決於模型+數據。對於不同的優化問題可能不同的求解器的結果都不一樣。adam 的主要作用是自適應梯度值。如果數據集巨大,每個類裏都有很大的in-class diversity的話可能會對同一個label 得到較大的loss,這時候adam會有優勢。如果模型和數據都不是特別大,SGD+moment會有更好的效果。哈哈,調參沒有萬金油。
  • 除了gate之類的地方,需要把輸出限制成0-1之外,儘量不要用sigmoid,可以用tanh或者relu之類的激活函數.1. sigmoid函數在-4到4的區間裏,纔有較大的梯度。之外的區間,梯度接近0,很容易造成梯度消失問題。2. 輸入0均值,sigmoid函數的輸出不是0均值的。層數較淺的時候,比如過兩三個全連接層的話,從我個人經驗來看,使用relu效果是最差的,sigmoid不太穩定,不知道爲啥時好時壞。tanh和leakyRelu效果差不多,但tanh前期收斂快一點。
  • rnn的dim和embdding size,一般從128上下開始調整. batch size,一般從128左右開始調整.batch size合適最重要,並不是越大越好.
  • word2vec初始化,在小數據上,不僅可以有效提高收斂速度,也可以可以提高結果.
  • 儘量對數據做shuffle
  • LSTM 的forget gate的bias,用1.0或者更大的值做初始化,可以取得更好的結果,來自這篇論文:http://jmlr.org/proceedings/papers/v37/jozefowicz15.pdf, 我這裏實驗設成1.0,可以提高收斂速度.實際使用中,不同的任務,可能需要嘗試不同的值.
  • Batch Normalization據說可以提升效果,不過我沒有嘗試過,建議作爲最後提升模型的手段,參考論文:Accelerating Deep Network Training by Reducing Internal Covariate Shift
  • 如果你的模型包含全連接層(MLP),並且輸入和輸出大小一樣,可以考慮將MLP替換成Highway Network,我嘗試對結果有一點提升,建議作爲最後提升模型的手段,原理很簡單,就是給輸出加了一個gate來控制信息的流動,詳細介紹請參考論文: http://arxiv.org/abs/1505.00387
  • 來自@張馨宇的技巧:一輪加正則,一輪不加正則,反覆進行。

Ensemble

Ensemble是論文刷結果的終極核武器,深度學習中一般有以下幾種方式

  • 同樣的參數,不同的初始化方式
  • 不同的參數,通過cross-validation,選取最好的幾組
  • 同樣的參數,模型訓練的不同階段,即不同迭代次數的模型。

  • 不同的模型,進行線性融合. 例如RNN和傳統模型.

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章