[調參]CV煉丹技巧/經驗


轉自:https://www.zhihu.com/question/25097993

我和@楊軍類似, 也是半路出家. 現在的工作內容主要就是使用CNN做CV任務. 干調參這種活也有兩年時間了. 我的回答可能更多的還是側重工業應用, 技術上只限制在CNN這塊.

先說下我的觀點, 調參就是trial-and-error. 沒有其他捷徑可以走. 唯一的區別是有些人盲目的嘗試, 有些人思考后再嘗試. 快速嘗試, 快速糾錯這是調參的關鍵.

 

看了楊軍的回答. 對於這個回答, 下面的評論里面

@紀秋佳

說的很對. 這個回答主要內容更多的是側重理解網絡. 而非訓練網絡.

我要再強調下, 楊軍的回答更多的涉及是理解網絡而非訓練網絡. 是的, 沒錯. 你看完回答中的所有內容, 對不起, 你還是不知道怎么實際訓練一個網絡, 尤其是復雜任務下的網絡(因為簡單任務根本不需要, 直接上來效果就會很好, 除非你要刷簡單任務的排行榜).

  • 首先說下可視化:

我個人的理解, 對於可視化, 更多的還是幫助人類以自己熟悉的方式來觀察網絡. 因為, 你是不可能邊觀察網絡, 還邊調參的. 你只是訓練完成后(或者准確率到達一個階段后), 才能可視化. 在這之前, 網絡沒有學習到良好的參數, 你可視化了也沒意義, 網絡達到不錯的准確率了, 你看看其實也就聽個響. 同樣, 你的網絡訓練的一塌糊塗, 你可視化也沒什么意義, 唯一能夠看到的就是中間結果亂七八糟, 或者全黑全白, 這時候你直接看最后准確率就可以知道這網絡沒救了.

  • 關於權重的可視化[Visualize Layer Weights](現在是否強求smooth其實意義不大, 這個后面說.):

同樣, 你看到一個不滿足平滑結果的圖像, 你知道, 這網絡訓練的不好, 但是為什么呢? 是數據不好? 沒有預處理? 網絡結構問題? Learning Rate太大或者太小? 或者就是差了一個LRN層(之前我就遇到, 加個LRN就能出smooth的weights, 當然這其實和預處理有關)?

Smooth是需要看一下的, 心里有個數. 但是具體調參怎么調是沒轍的. 第一, 你不可能告訴網絡, 這層你得學個邊界檢測的功能出來. 第二, 不同任務下會有不同的weights(雖然底層的特征有很大的通用性), 你覺得你憑什么來指導一個看圖片比你快得多的機器?

再說現在是否需要強求smooth. 現在的趨勢是鼓勵使用小filter, 3x3大小, 多加層次(這樣, 非線性更好點). 換句話說, 3x3的圖片, 總共才9個像素, 你怎么判斷smooth與否呢? 當然如果你使用大的filter, 一般5x5往上, 運氣不差的話, 你是可以看到smooth的結果的.

咱們再說另外一個極端, 一個網絡,運行的完美(滿足應用要求就算完美), 打開一看, 這weights不smooth啊. 你告訴我, 你打算怎么辦? 沒錯, 具有不平滑的權重的網絡同樣可以獲得很好的結果(這種情況我都習以為常了).

  • 那么可視化網絡就不重要了?

非常重要, 但是不在訓練這塊, 而是幫助理解網絡的原理這塊. 理解網絡原理后, 你才能在設計結構的時候心里有感覺(只是有感覺而已), 網絡出了問題, 或者在某些情況下不滿意, 有更好的直覺去調整.(沒錯, 只是直覺, 雖然有些情況下的調整從網絡原理來看邏輯上應該可以工作, 但是人家就是不工作, 你能咬機器去么?)

 

  • 那么怎樣訓練一個不錯的網絡呢?

這是一個很好的鏈接, 說明了如何從零開始不斷的trial-and-error(其實這里面沒遇到什么error):
Using convolutional neural nets to detect facial keypoints tutorial

 

========================================================
我自己的經驗, 有下面這些:

基本原則:
快速試錯

一些大的注意事項:
1. 剛開始, 先上小規模數據, 模型往大了放, 只要不爆顯存, 能用256個filter你就別用128個. 直接奔着過擬合去. 沒錯, 就是訓練過擬合網絡, 連測試集驗證集這些都可以不用.

為什么?
+ 你要驗證自己的訓練腳本的流程對不對. 這一步小數據量, 生成速度快, 但是所有的腳本都是和未來大規模訓練一致的(除了少跑點循環)
+ 如果小數據量下, 你這么粗暴的大網絡奔着過擬合去都沒效果. 那么, 你要開始反思自己了, 模型的輸入輸出是不是有問題? 要不要檢查自己的代碼(永遠不要懷疑工具庫, 除非你動過代碼)? 模型解決的問題定義是不是有問題? 你對應用場景的理解是不是有錯? 不要懷疑NN的能力, 不要懷疑NN的能力, 不要懷疑NN的能力. 就我們調參狗能遇到的問題, NN沒法擬合的, 這概率是有多小?
+ 你可以不這么做, 但是等你數據准備了兩天, 結果發現有問題要重新生成的時候, 你這周時間就醬油了.

2. Loss設計要合理.

+ 一般來說分類就是Softmax, 回歸就是L2的loss. 但是要注意loss的錯誤范圍(主要是回歸), 你預測一個label是10000的值, 模型輸出0, 你算算這loss多大, 這還是單變量的情況下. 一般結果都是nan. 所以不僅僅輸入要做normalization, 輸出也要這么弄.
+ 多任務情況下, 各loss想法限制在一個量級上, 或者最終限制在一個量級上, 初期可以着重一個任務的loss

3. 觀察loss勝於觀察准確率

准確率雖然是評測指標, 但是訓練過程中還是要注意loss的. 你會發現有些情況下, 准確率是突變的, 原來一直是0, 可能保持上千迭代, 然后突然變1. 要是因為這個你提前中斷訓練了, 只有老天替你惋惜了. 而loss是不會有這么詭異的情況發生的, 畢竟優化目標是loss.
給NN一點時間, 要根據任務留給NN的學習一定空間. 不能說前面一段時間沒起色就不管了. 有些情況下就是前面一段時間看不出起色, 然后開始穩定學習.

4. 確認分類網絡學習充分

分類網絡就是學習類別之間的界限. 你會發現, 網絡就是慢慢的從類別模糊到類別清晰的. 怎么發現? 看Softmax輸出的概率的分布. 如果是二分類, 你會發現, 剛開始的網絡預測都是在0.5上下, 很模糊. 隨着學習過程, 網絡預測會慢慢的移動到0,1這種極值附近. 所以, 如果你的網絡預測分布靠中間, 再學習學習.

5. Learning Rate設置合理
+ 太大: loss爆炸, 或者nan
+ 太小: 半天loss沒反映(但是, LR需要降低的情況也是這樣, 這里可視化網絡中間結果, 不是weights, 有效果, 倆者可視化結果是不一樣的, 太小的話中間結果有點水波紋或者噪點的樣子, 因為filter學習太慢的原因, 試過就會知道很明顯)
+ 需要進一步降低了: loss在當前LR下一路降了下來, 但是半天不再降了.
+ 如果有個復雜點的任務, 剛開始, 是需要人肉盯着調LR的. 后面熟悉這個任務網絡學習的特性后, 可以扔一邊跑去了.
+ 如果上面的Loss設計那塊你沒法合理, 初始情況下容易爆, 先上一個小LR保證不爆, 等loss降下來了, 再慢慢升LR, 之后當然還會慢慢再降LR, 雖然這很蛋疼.
+ LR在可以工作的最大值下往小收一收, 免得ReLU把神經元弄死了. 當然, 我是個心急的人, 總愛設個大點的.

6 對比訓練集和驗證集的loss
判斷過擬合, 訓練是否足夠, 是否需要early stop的依據, 這都是中規中矩的原則, 不多說了.

7 清楚receptive field的大小
CV的任務, context window是很重要的. 所以你對自己模型的receptive field的大小要心中有數. 這個對效果的影響還是很顯著的. 特別是用FCN, 大目標需要很大的receptive field. 不像有fully connection的網絡, 好歹有個fc兜底, 全局信息都有.



簡短的注意事項:

  1. 預處理: -mean/std zero-center就夠了, PCA, 白化什么的都用不上. 我個人觀點, 反正CNN能學習encoder, PCA用不用其實關系不大, 大不了網絡里面自己學習出來一個.
  2. shuffle, shuffle, shuffle.
  3. 網絡原理的理解最重要, CNN的conv這塊, 你得明白sobel算子的邊界檢測.
  4. Dropout, Dropout, Dropout(不僅僅可以防止過擬合, 其實這相當於做人力成本最低的Ensemble, 當然, 訓練起來會比沒有Dropout的要慢一點, 同時網絡參數你最好相應加一點, 對, 這會再慢一點).
  5. CNN更加適合訓練回答是否的問題, 如果任務比較復雜, 考慮先用分類任務訓練一個模型再finetune.
  6. 無腦用ReLU(CV領域).
  7. 無腦用3x3.
  8. 無腦用xavier.
  9. LRN一類的, 其實可以不用. 不行可以再拿來試試看.
  10. filter數量2^n.
  11. 多尺度的圖片輸入(或者網絡內部利用多尺度下的結果)有很好的提升效果.
  12. 第一層的filter, 數量不要太少. 否則根本學不出來(底層特征很重要).
  13. sgd adam 這些選擇上, 看你個人選擇. 一般對網絡不是決定性的. 反正我無腦用sgd + momentum.
  14. batch normalization我一直沒用, 雖然我知道這個很好, 我不用僅僅是因為我懶. 所以要鼓勵使用batch normalization.
  15. 不要完全相信論文里面的東西. 結構什么的覺得可能有效果, 可以拿去試試.
  16. 你有95%概率不會使用超過40層的模型.
  17. shortcut的聯接是有作用的.
  18. 暴力調參最可取, 畢竟, 自己的生命最重要. 你調完這個模型說不定過兩天這模型就扔掉了.
  19. 機器, 機器, 機器.
  20. Google的inception論文, 結構要好好看看.
  21. 一些傳統的方法, 要稍微了解了解. 我自己的程序就用過1x14的手寫filter, 寫過之后你看看inception里面的1x7, 7x1 就會會心一笑..


來源:https://www.zhihu.com/question/25097993/answer/161393876

趁着模型正在跑,我來強答一發。

 

我只對卷積網絡有一點點了解,所以接下來談的都是和卷積網絡相關的內容。

調參請在驗證集上!調參請在驗證集上!調參請在驗證集上!

首先我們假設我們手上有一個正確的,沒有bug,可以訓練的模型,以及預先設立的誤差目標。那么分三種情況:

1、模型表現非常好,在訓練集和驗證集上都滿足我們的目標。那不用調了。

2、模型在訓練集上的誤差很小,且各種(softmax 等等) loss 能減小到一個很小的值(對於我自己而言小於0.01),但是驗證集的 loss 相對較大(對我的問題而言,一般會在0.3~0.6)。那就是過擬合了。

3、在訓練集和驗證集上的loss都比較大,都大於0.3,那可能就是欠擬合了。

 

——————————————————————————————————————————

模型的訓練是在擬合訓練集的規律,模型的使用卻是將規律作用於測試集。那么我們假設訓練集和測試集所包含的規律是大方向相同的,小細節存在差異的。

 

如果一個模型在訓練集上一直一直訓練下去,那么它會很好的擬合訓練集所有的大方向規律和小細節規律,過擬合就是必然的了。因為訓練的目標是將訓練集 loss 降到 0。理想的訓練過程如圖:


 


 

我們假設模型在驗證集的表現由兩部分組成:1、對訓練集規律的掌握(主要指標 trainset loss),2、學習結果對訓練集的適應程度(主要指標 validation set loss)。如上圖所示,調參的本質就是要找到那個best model 平衡點。

——————————————————————————————————————————

 

出現上述情況該調什么?調試hyperparameters 的先后順序是什么?

1、優先調 learning rate!優先調 learning rate!優先調 learning rate!

學習速率會很大程度上影響模型的表現。同樣的模型采用不同的learning rate 可能會表現迥異。所以憑感覺建好一個模型后如果對表現不滿意應該優先調學習速率。我前段時間在知乎上看一個哥們說學習速率可以有解析解,希望他早日成功拯救我脫離調學習速率的苦海。模型具有理論容量和有效容量兩種能力指標,理論容量是由卷積核數量,模型深度等決定的。但是有效容量會受學習速率影響。

2、加 Dropout, 加 BN, 加Data Argument

一般而言,在設計模型之初我們都信奉大力出奇跡。模型盡量深,卷積核盡量多,強行讓模型擬合訓練集。這時容易遇到的問題就是過擬合。解決過擬合的第一要素是模型的正則化,最有效方法是加大訓練數據集。如果有錢任性,那請多標記數據。如果沒錢要認命(比如我),那就給訓練數據加增強,什么圖像裁剪,對稱變換,旋轉平移,都可以讓模型在驗證集上的表現更好。此外,增加常用的正則化也可以提升模型的表現。

3、調模型的層數和卷積核數量

走到這一步的時候都是迫不得已了。這兩個參數都是對模型理論容量具有巨大影響的參數,一旦調整了之后所有東西都要重新調。增大模型的層數和卷積核的數量都會提升模型的容量。不同的是,增大模型層數(讓模型變高)可以讓模型獲得更好的非線性,模型容量指數增加,缺點是加大層數會讓模型更難訓練,面臨梯度消失的風險,引入死單元。增加卷積核(讓模型變胖)可以在不引入訓練困難的情況下讓模型更好的擬合訓練集,也就是降低 training loss,但是會更容易過擬合。

 

總之,理想情況下表現優越的模型一般長的高高瘦瘦(深,每層卷積核不多),但是為了便於我們訓練,有時候不得不讓他更矮壯一些。模型的調參除了學習速率和正則化這些比較耗時的工作外,還需要一些靈感,來確定模型的身材。

 

來源:https://www.zhihu.com/question/25097993/answer/37525469

感覺除了層數和每層隱節點的個數,也沒啥好調的。其它參數,近兩年論文基本都用同樣的參數設定:迭代幾十到幾百epoch。sgd,mini batch size從幾十到幾百皆可。步長0.1,可手動收縮,weight decay取0.005,momentum取0.9。dropout加relu。weight用高斯分布初始化,bias全初始化為0。最后記得輸入特征和預測目標都做好歸一化。做完這些你的神經網絡就應該跑出基本靠譜的結果,否則反省一下自己的人品。

 

轉自:https://mp.weixin.qq.com/s?__biz=MzU0NTAyNTQ1OQ==&mid=2247484020&idx=3&sn=6882d32290f44d15cb353ea92849356b&chksm=fb727ea8cc05f7be022025b20d6e8e71170eb5eb1ce383d526aabe8b92a759fd426e9cd114b3#rd

今天給大家講講DNN(深度神經網絡)在訓練過程中遇到的一些問題,然后我們應該怎么去注意它,並學會怎么去訓練它。

 

1、數據集的准備:

必須要保證大量、高質量且帶有准確標簽的數據,沒有該條件的數據,訓練學習很困難的(但是最近我看了以為作者寫的一篇文章,說明不一定需要大量數據集,也可以訓練的很好,有空和大家來分享其思想---很厲害的想法);

2、數據預處理:

這個不多說,就是0均值和1方差化,其實還有很多方法;

3、Minibatch:

這個有時候還要根據你的硬件設備而定,一般建議用128,8這組,但是128,1也很好,只是效率會非常慢,注意的是:千萬不要用過大的數值,否則很容易過擬合;

4、梯度歸一化:

其實就是計算出來梯度之后,要除以Minibatch的數量,這個可以通過閱讀源碼得知(我之前有寫過SGD);

5、學習率:

①  一般都會有默認的學習率,但是剛開始還是用一般的去學習,然后逐漸的減小它;

②  一個建議值是0.1,適用於很多NN的問題,一般傾向於小一點;但是如果對於的大數據,何凱明老師也說過,要把學習率調到很小,他說0.00001都不為過(如果記得不錯,應該是這么說的);

③  一個對於調度學習率的建議:如果在驗證集上性能不再增加就讓學習率除以2或者5,然后繼續,學習率會一直變得很小,到最后就可以停止訓練了;

④  很多人用的一個設計學習率的原則就是監測一個比率(每次更新梯度的norm除以當前weightnorm),如果這個比率在10e-3附近,且小於這個值,學習會很慢,如果大於這個值,那么學習很不穩定,由此會帶來學習失敗。

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、dropout:(先空着,下次我要單獨詳細講解Dropout)

12、評價結果:

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

 

補充:


1、選擇優化算法  

傳統的隨機梯度下降算法雖然適用很廣,但並不高效,最近出現很多更靈活的優化算法,例如Adagrad、RMSProp等,可在迭代優化的過程中自適應的調節學習速率等超參數,效果更佳;

2、參數設置技巧  

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

3、正則優化  

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

4、其他方法 

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

 

 

轉載請注明:煉丹實驗室

之前曾經寫過一篇文章,講了一些深度學習訓練的技巧,其中包含了部分調參心得:深度學習訓練心得。不過由於一般深度學習實驗,相比普通機器學習任務,時間較長,因此調參技巧就顯得尤為重要。同時個人實踐中,又有一些新的調參心得,因此這里單獨寫一篇文章,談一下自己對深度學習調參的理解,大家如果有其他技巧,也歡迎多多交流。

好的實驗環境是成功的一半

由於深度學習實驗超參眾多,代碼風格良好的實驗環境,可以讓你的人工或者自動調參更加省力,有以下幾點可能需要注意:

  • 將各個參數的設置部分集中在一起。如果參數的設置分布在代碼的各個地方,那么修改的過程想必會非常痛苦。
  • 可以輸出模型的損失函數值以及訓練集和驗證集上的准確率。
  • 可以考慮設計一個子程序,可以根據給定的參數,啟動訓練並監控和周期性保存評估結果。再由一個主程序,分配參數以及並行啟動一系列子程序。

畫圖

畫圖是一個很好的習慣,一般是訓練數據遍歷一輪以后,就輸出一下訓練集和驗證集准確率。同時畫到一張圖上。這樣訓練一段時間以后,如果模型一直沒有收斂,那么就可以停止訓練,嘗試其他參數了,以節省時間。 
如果訓練到最后,訓練集,測試集准確率都很低,那么說明模型有可能欠擬合。那么后續調節參數方向,就是增強模型的擬合能力。例如增加網絡層數,增加節點數,減少dropout值,減少L2正則值等等。 
如果訓練集准確率較高,測試集准確率比較低,那么模型有可能過擬合,這個時候就需要向提高模型泛化能力的方向,調節參數。

從粗到細分階段調參

實踐中,一般先進行初步范圍搜索,然后根據好結果出現的地方,再縮小范圍進行更精細的搜索。

  1. 建議先參考相關論文,以論文中給出的參數作為初始參數。至少論文中的參數,是個不差的結果。
  2. 如果找不到參考,那么只能自己嘗試了。可以先從比較重要,對實驗結果影響比較大的參數開始,同時固定其他參數,得到一個差不多的結果以后,在這個結果的基礎上,再調其他參數。例如學習率一般就比正則值,dropout值重要的話,學習率設置的不合適,不僅結果可能變差,模型甚至會無法收斂。
  3. 如果實在找不到一組參數,可以讓模型收斂。那么就需要檢查,是不是其他地方出了問題,例如模型實現,數據等等。可以參考我寫的深度學習網絡調試技巧

提高速度

調參只是為了尋找合適的參數,而不是產出最終模型。一般在小數據集上合適的參數,在大數據集上效果也不會太差。因此可以嘗試對數據進行精簡,以提高速度,在有限的時間內可以嘗試更多參數。

  • 對訓練數據進行采樣。例如原來100W條數據,先采樣成1W,進行實驗看看。
  • 減少訓練類別。例如手寫數字識別任務,原來是10個類別,那么我們可以先在2個類別上訓練,看看結果如何。

超參數范圍

建議優先在對數尺度上進行超參數搜索。比較典型的是學習率和正則化項,我們可以從諸如0.001 0.01 0.1 1 10,以10為階數進行嘗試。因為他們對訓練的影響是相乘的效果。不過有些參數,還是建議在原始尺度上進行搜索,例如dropout值: 0.3 0.5 0.7)。

經驗參數

這里給出一些參數的經驗值,避免大家調參的時候,毫無頭緒。

  • learning rate: 1 0.1 0.01 0.001, 一般從1開始嘗試。很少見learning rate大於10的。學習率一般要隨着訓練進行衰減。衰減系數一般是0.5。 衰減時機,可以是驗證集准確率不再上升時,或固定訓練多少個周期以后。 
    不過更建議使用自適應梯度的辦法,例如adam,adadelta,rmsprop等,這些一般使用相關論文提供的默認值即可,可以避免再費勁調節學習率。對RNN來說,有個經驗,如果RNN要處理的序列比較長,或者RNN層數比較多,那么learning rate一般小一些比較好,否則有可能出現結果不收斂,甚至Nan等問題。
  • 網絡層數: 先從1層開始。
  • 每層結點數: 16 32 128,超過1000的情況比較少見。超過1W的從來沒有見過。
  • batch size: 128上下開始。batch size值增加,的確能提高訓練速度。但是有可能收斂結果變差。如果顯存大小允許,可以考慮從一個比較大的值開始嘗試。因為batch size太大,一般不會對結果有太大的影響,而batch size太小的話,結果有可能很差。
  • clip c(梯度裁剪): 限制最大梯度,其實是value = sqrt(w1^2+w2^2….),如果value超過了閾值,就算一個衰減系系數,讓value的值等於閾值: 5,10,15
  • dropout: 0.5
  • L2正則:1.0,超過10的很少見。
  • 詞向量embedding大小:128,256
  • 正負樣本比例: 這個是非常忽視,但是在很多分類問題上,又非常重要的參數。很多人往往習慣使用訓練數據中默認的正負類別比例,當訓練數據非常不平衡的時候,模型很有可能會偏向數目較大的類別,從而影響最終訓練結果。除了嘗試訓練數據默認的正負類別比例之外,建議對數目較小的樣本做過采樣,例如進行復制。提高他們的比例,看看效果如何,這個對多分類問題同樣適用。 
    在使用mini-batch方法進行訓練的時候,盡量讓一個batch內,各類別的比例平衡,這個在圖像識別等多分類任務上非常重要。

自動調參

人工一直盯着實驗,畢竟太累。自動調參當前也有不少研究。下面介紹幾種比較實用的辦法:

  • Gird Search. 這個是最常見的。具體說,就是每種參數確定好幾個要嘗試的值,然后像一個網格一樣,把所有參數值的組合遍歷一下。優點是實現簡單暴力,如果能全部遍歷的話,結果比較可靠。缺點是太費時間了,特別像神經網絡,一般嘗試不了太多的參數組合。
  • Random Search。Bengio在Random Search for Hyper-Parameter Optimization中指出,Random Search比Gird Search更有效。實際操作的時候,一般也是先用Gird Search的方法,得到所有候選參數,然后每次從中隨機選擇進行訓練。
  • Bayesian Optimization. 貝葉斯優化,考慮到了不同參數對應的實驗結果值,因此更節省時間。和網絡搜索相比簡直就是老牛和跑車的區別。具體原理可以參考這個論文: Practical Bayesian Optimization of Machine Learning Algorithms ,這里同時推薦兩個實現了貝葉斯調參的Python庫,可以上手即用:

總結

  • 合理性檢查,確定模型,數據和其他地方沒有問題。
  • 訓練時跟蹤損失函數值,訓練集和驗證集准確率。
  • 使用Random Search來搜索最優超參數,分階段從粗(較大超參數范圍訓練較少周期)到細(較小超參數范圍訓練較長周期)進行搜索。

 

神經網絡的代碼,比一般的代碼要難調試不少,和編譯錯誤以及運行時程序崩潰相比,神經網絡比較棘手的地方,往往在於程序運行正常,但是結果無法收斂,這個檢查起來可要麻煩多了。下面是根據我平時調試神經網絡的經驗,總結的一些比較通用的調試技巧,后續會再寫一篇文章,專門介紹一下theano如何進行調試,希望能對大家調試神經網絡有所幫助。

遇到Nan怎么辦?

Nan問題,我相信大部分人都遇到過,一般可能是下面幾個原因造成的:

  1. 除0問題。這里實際上有兩種可能,一種是被除數的值是無窮大,即Nan,另一種就是除數的值是0。之前產生的Nan或者0,有可能會被傳遞下去,造成后面都是Nan。請先檢查一下神經網絡中有可能會有除法的地方,例如softmax層,再認真的檢查一下數據。我有一次幫別人調試代碼,甚至還遇到過,訓練數據文件中,有些值就是Nan。。。這樣讀進來以后,開始訓練,只要遇到Nan的數據,后面也就Nan了。可以嘗試加一些日志,把神經網絡的中間結果輸出出來,看看哪一步開始出現Nan。后面會介紹Theano的處理辦法。
  2. 梯度過大,造成更新后的值為Nan。特別是RNN,在序列比較長的時候,很容易出現梯度爆炸的問題。一般有以下幾個解決辦法。
    1. 對梯度做clip(梯度裁剪),限制最大梯度,其實是value = sqrt(w1^2+w2^2….),如果value超過了閾值,就算一個衰減系系數,讓value的值等於閾值: 5,10,15。
    2. 減少學習率。初始學習率過大,也有可能造成這個問題。需要注意的是,即使使用adam之類的自適應學習率算法進行訓練,也有可能遇到學習率過大問題,而這類算法,一般也有一個學習率的超參,可以把這個參數改的小一些。
  3. 初始參數值過大,也有可能出現Nan問題。輸入和輸出的值,最好也做一下歸一化。具體方法可以參考我之前的一篇文章:深度學習個人煉丹心得 - 煉丹實驗室 - 知乎專欄

     

神經網絡學不出東西怎么辦?

可能我們並沒有遇到,或者解決了Nan等問題,網絡一直在正常的訓練,但是cost降不下來,預測的時候,結果不正常。

  1. 請打印出訓練集的cost值和測試集上cost值的變化趨勢,正常情況應該是訓練集的cost值不斷下降,最后趨於平緩,或者小范圍震盪,測試集的cost值先下降,然后開始震盪或者慢慢上升。如果訓練集cost值不下降,有可能是代碼有bug,有可能是數據有問題(本身有問題,數據處理有問題等等),有可能是超參(網絡大小,層數,學習率等)設置的不合理。 
    請人工構造10條數據,用神經網絡反復訓練,看看cost是否下降,如果還不下降,那么可能網絡的代碼有bug,需要認真檢查了。如果cost值下降,在這10條數據上做預測,看看結果是不是符合預期。那么很大可能網絡本身是正常的。那么可以試着檢查一下超參和數據是不是有問題。
  2. 如果神經網絡代碼,全部是自己實現的,那么強烈建議做梯度檢查。確保梯度計算沒有錯誤。
  3. 先從最簡單的網絡開始實驗,不要僅僅看cost值,還要看一看神經網絡的預測輸出是什么樣子,確保能跑出預期結果。例如做語言模型實驗的時候,先用一層RNN,如果一層RNN正常,再嘗試LSTM,再進一步嘗試多層LSTM。
  4. 如果可能的話,可以輸入一條指定數據,然后自己計算出每一步正確的輸出結果,再檢查一下神經網絡每一步的結果,是不是一樣的。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM