整理的鏈接:https://www.zhihu.com/question/41631631
來源:知乎
著作權歸作者所有。商業轉載請聯系作者獲得授權,非商業轉載請注明出處。
來源:知乎
著作權歸作者所有。商業轉載請聯系作者獲得授權,非商業轉載請注明出處。
調了快1年的rnn, 深刻的感受到,深度學習是一門實驗科學,下面是一些煉丹心得. 后面會不斷補充. 有問題的地方,也請大家指正.
-
參數初始化,下面幾種方式,隨便選一個,結果基本都差不多.
- uniform
W = np.random.uniform(low=-scale, high=scale, size=shape) - glorot_uniform
scale = np.sqrt(6. / (shape[0] + shape[1]))
np.random.uniform(low=-scale, high=scale, size=shape) - 高斯初始化:
w = np.random.randn(n) / sqrt(n),n為參數數目
激活函數為relu的話,推薦
w = np.random.randn(n) * sqrt(2.0/n) - svd ,對RNN效果比較好,可以有效提高收斂速度.
-
數據預處理方式
- zero-center ,這個挺常用的.
X -= np.mean(X, axis = 0) # zero-center
X /= np.std(X, axis = 0) # normalize - PCA whitening,這個用的比較少.
- zero-center ,這個挺常用的.
-
訓練技巧
- 要做梯度歸一化,即算出來的梯度除以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的話,可以選擇從1.0或者0.1的學習率開始,隔一段時間,在驗證集上檢查一下,如果cost沒有下降,就對學習率減半. 我看過很多論文都這么搞,我自己實驗的結果也很好. 當然,也可以先用ada系列先跑,最后快收斂的時候,更換成sgd繼續訓練.同樣也會有提升.
- 除了gate之類的地方,需要把輸出限制成0-1之外,盡量不要用sigmoid,可以用tanh或者relu之類的激活函數.
- 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,可以提高收斂速度.實際使用中,不同的任務,可能需要嘗試不同的值.
-
Ensemble: 論文刷結果的終極核武器,深度學習中一般有以下幾種方式
- 同樣的參數,不同的初始化方式
- 不同的參數,通過cross-validation,選取最好的幾組
- 同樣的參數,模型訓練的不同階段
- 不同的模型,進行線性融合. 例如RNN和傳統模型.
補充一點,adam收斂雖快但是得到的解往往沒有sgd+momentum得到的解更好,如果不考慮時間成本的話還是用sgd吧。
再補充一個rnn trick,仍然是不考慮時間成本的情況下,batch size=1是一個很不錯的regularizer, 起碼在某些task上,這也有可能是很多人無法復現alex graves實驗結果的原因之一,因為他總是把batch size設成1。。。最近在看 Karpathy 的 cs231n, 還沒看完, 不過過程中總結了一下他提到的一些技巧:
關於參數:
- 通常情況下, 更新參數的方法默認用 Adam 效果就很好
- 如果可以載入全部數據 (full batch updates), 可以使用 L-BFGS
Model Ensembles:
- 訓練多個模型, 在測試時將結果平均起來, 大約可以得到 2% 提升.
- 訓練單個模型時, 平均不同時期的 checkpoints 的結果, 也可以有提升.
- 測試時可以將測試的參數和訓練的參數組合起來:
1.無論是cnn還是rnn,batch normalization都有用,不一定結果提高幾個點,收斂快多了
2.數據初始時normalize得好,有時候直接提高2個點,比如cifar10,轉到yuv下normalize再scn
3.loss不降了lr就除10
4. google的inception系列按它論文里說的永遠無法復現
本人做rnn的文本相關研究,一直使用adam,下降速度巨快,看別人論文也嘗試過adadelta和adagrad,但不知是姿勢不對還是別的原因效果很差,batch-size大小設置在50(訓練集大小為17w),dropout隨大流0.5,另外我發現l2取值對我的結果影響挺大的,之前一直跟着別人論文用0.001,我換成0.0001以后發現提升了1%