一、train loss 收斂慢,把learning_rate調高
二、train loss不下降:
1、觀察數據中是否有異常樣本或異常label導致數據讀取異常
2、調小初始化權重,以便使softmax輸入的feature盡可能變小
3、降低學習率,這樣就能減小權重參數的波動范圍,從而減小權重變大的可能性。這條也是網上出現較多的方法。
4、調大batch_size
5、如果有BN(batch normalization)層,finetune時最好不要凍結BN的參數,否則數據分布不一致時很容易使輸出值變的很大。
6、神經網絡不夠深。
7、訓練的epoch不夠。
https://blog.csdn.net/u010159842/article/details/83614791
train loss 不斷下降,test loss不斷下降,說明網絡仍在學習;
train loss 不斷下降,test loss趨於不變,說明網絡過擬合;
train loss 趨於不變,test loss不斷下降,說明數據集100%有問題;
train loss 趨於不變,test loss趨於不變,說明學習遇到瓶頸,需要減小學習率或批量數目;
train loss 不斷上升,test loss不斷上升,說明網絡結構設計不當,訓練超參數設置不當,數據集經過清洗等問題。
二,
這個比較長,比較完整 Loss和神經網絡訓練
https://blog.csdn.net/u011534057/article/details/51452564
有1.梯度檢驗2.訓練前檢查,3.訓練中監控4.首層可視化5.模型融合和優化等等等
三,https://www.zhihu.com/question/38937343
四,https://blog.csdn.net/u010911921/article/details/71079367
原文地址:http://blog.csdn.net/u010911921/article/details/71079367
這段在使用caffe的時候遇到了兩個問題都是在訓練的過程中loss基本保持常數值,特此記錄一下。
1.loss等於87.33不變
loss等於87.33這個問題是在對Inception-V3網絡不管是fine-tuning還是train的時候遇到的,無論網絡迭代多少次,網絡的loss一直保持恆定。
查閱相關資料以后發現是由於loss的最大值由FLT_MIN計算得到,FLT_MIN是其對應的自然對數正好是-87.3356,這也就對應上了loss保持87.3356了。
這說明softmax在計算的過程中得到了概率值出現了零,由於softmax是用指數函數計算的,指數函數的值都是大於0的,所以應該是計算過程中出現了float溢出的異常,也就是出現了inf,nan等異常值導致softmax輸出為0.
當softmax之前的feature值過大時,由於softmax先求指數,會超出float的數據范圍,成為inf。inf與其他任何數值的和都是inf,softmax在做除法時任何正常范圍的數值除以inf都會變成0.然后求loss就出現了87.3356的情況。
解決辦法
由於softmax輸入的feature由兩部分計算得到:一部分是輸入數據,另一部分是各層的權值等組成
減小初始化權重,以使得softmax的輸入feature處於一個比較小的范圍
降低學習率,這樣可以減小權重的波動范圍
如果有BN(batch normalization)層,finetune時最好不要凍結BN的參數,否則數據分布不一致時很容易使輸出值變得很大(注意將batch_norm_param中的use_global_stats設置為false )。
觀察數據中是否有異常樣本或異常label導致數據讀取異常
本文遇到的情況采用降低學習率的方法,learning rate設置為0.01或者原來loss的或者。
2.loss保持0.69左右
采用VGG-16在做一個二分類問題,所以計算loss時等價與下面的公式:
當p=0.5時,loss正好為0.693147,也就是訓練過程中,無論如何調節網絡都不收斂。最初的網絡配置文件卷積層的參數如下所示:
從VGG-16訓練好的模型進行fine-tuning也不發生改變,當在網絡中加入初始化參數和decay_mult以后再次訓練網絡開始收斂。
但是具體是什么原因造成的,暫時還沒有找到,難道是初始化參數的問題還是?
參考資料
http://blog.csdn.net/jkfdqjjy/article/details/52268565?locationNum=14
https://groups.google.com/forum/#!topic/caffe-users/KEgrRlwXz9c
https://www.zhihu.com/question/68603783
loss一直不下降的原因有很多,可以從頭到尾濾一遍: 1)數據的輸入是否正常,data和label是否一致。 2)網絡架構的選擇,一般是越深越好,也分數據集。 並且用不用在大數據集上pre-train的參數也很重要的 3)loss 對不對。
具體到語音,很多是把audio轉成頻譜圖送給CNN訓練。
NIPS16 有個soundNet(torch的code),語音分類的performance很高,我覺得可以用來初始化你的model 參數, 可以參考下。
還有我見的3D-CNN 多用於視頻,做audio 用3D 的工作比較少,倒是見過是用1維卷積做audio的
---------------------
三、trian/dev loss和acc的結果都很正常,但inference時的結果不行。即二分類sigmoid之后測試集結果很多都是0或1.
神經元飽和:在訓練過程中sigmoid激活函數易梯度消失,檢查一下梯度是否等於0.
加了BN,緩解了這個問題
四、一些小總結:
loss訓練下降緩慢,收斂慢問題:
train loss 在epoch到200\300次才收斂,小數據量時收斂更快,train loss可能在0.6幾收斂,acc 也上升緩慢,
test loss 前期step幾乎沒變。
原因及修改:
1、因為learning rate采用的是指數下降,可能learning rate下降太快,修改成1000步才下降0.96,優化器采用的是GD,現在改成Adam。
2、數據量太大時,每次train batch都算一次全量的test loss會導致訓練速度慢,初始顯得train loss收斂慢,所以采取每100個batch才算一次test loss。
3、同時還增大了keep_prob。
如果出現資源耗盡的報錯(OOM),原因有:
1、確定是train_step OOM 還是test_step OOM。
2、如果是train_step,則batch_size調小試試。減少模型復雜度(減小卷積核數量還有全連接層神經元個數也可以試試)
3、如果是test_step OOM ,將test的數據集數量減少,因為test session.run的時候是全量跑的,不是batch跑的。
4、去查看一下顯存占比:nvidia-smi -l
-----------------------------------------------------------------------------+
| NVIDIA-SMI 418.40.04 Driver Version: 418.40.04 CUDA Version: 10.1 |
|-------------------------------+----------------------+----------------------+
| GPU Name Persistence-M| Bus-Id Disp.A | Volatile Uncorr. ECC |
| Fan Temp Perf Pwr:Usage/Cap| Memory-Usage | GPU-Util Compute M. |
|===============================+======================+======================|
| 0 Tesla P40 Off | 00000000:02:00.0 Off | 0 |
| N/A 49C P0 115W / 250W | 11129MiB / 22919MiB | 87% Default |
+-------------------------------+----------------------+----------------------+
| 1 Tesla P40 Off | 00000000:03:00.0 Off | 0 |
| N/A 23C P8 10W / 250W | 0MiB / 22919MiB | 0% Default |
+-------------------------------+----------------------+----------------------+
| 2 Tesla P40 Off | 00000000:83:00.0 Off | 0 |
| N/A 25C P8 9W / 250W | 0MiB / 22919MiB | 0% Default |
+-------------------------------+----------------------+----------------------+
| 3 Tesla P40 Off | 00000000:84:00.0 Off | 0 |
| N/A 22C P8 10W / 250W | 0MiB / 22919MiB | 0% Default |
+-------------------------------+----------------------+----------------------+
+-----------------------------------------------------------------------------+
| Processes: GPU Memory |
| GPU PID Type Process name Usage |
|=============================================================================|
注意Memory-Usage:每次同一交互式訓練是,如果直接interrupt kernel的話,再重跑train,顯存是不釋放的,需要restart整個代碼才會釋放,解決方法:不用notebook來跑,存成py腳本來跑。
在代碼中加入:
os.environ["CUDA_VISIBLE_DEVICES"] = "0" config = tf.ConfigProto() config.gpu_options.per_process_gpu_memory_fraction = 0.5 #指定GPU分配不超過0.5,如果超過則執行以下步驟 config.gpu_options.allow_growth=True # allocate when needed sess = tf.Session(config = config)
第一次train loss就等於0。
https://blog.csdn.net/qq_34661230/article/details/88313252
最后一層的輸出函數用錯了,我用的是tf.nn.softmax_cross_entropy_with_logits來計算cost。 我們知道softmax一般是用來做multiclass classifier的,也就是輸出的類別要大於兩個。對於一個binary classifier而言,很明顯我們要用sigmoid函數也就是tf.nn.sigmoid_cross_entropy_with_logits來計算cost,於是問題解決。
為什么?
那么為什么在binary classifier中使用了softmax之后cost就一直是0呢?可以看一下softmax的公式。
第一次train auc就等於100%,檢查計算auc的公式正不正確。
五、深度學習網絡調參
https://zhuanlan.zhihu.com/p/24720954?utm_source=zhihu&utm_medium=social
好的實驗環境是成功的一半
由於深度學習實驗超參眾多,代碼風格良好的實驗環境,可以讓你的人工或者自動調參更加省力,有以下幾點可能需要注意:
- 將各個參數的設置部分集中在一起。如果參數的設置分布在代碼的各個地方,那么修改的過程想必會非常痛苦。
- 可以輸出模型的損失函數值以及訓練集和驗證集上的准確率。
- 可以考慮設計一個子程序,可以根據給定的參數,啟動訓練並監控和周期性保存評估結果。再由一個主程序,分配參數以及並行啟動一系列子程序。
畫圖
畫圖是一個很好的習慣,一般是訓練數據遍歷一輪以后,就輸出一下訓練集和驗證集准確率。同時畫到一張圖上。這樣訓練一段時間以后,如果模型一直沒有收斂,那么就可以停止訓練,嘗試其他參數了,以節省時間。
如果訓練到最后,訓練集,測試集准確率都很低,那么說明模型有可能欠擬合。那么后續調節參數方向,就是增強模型的擬合能力。例如增加網絡層數,增加節點數,減少dropout值,減少L2正則值等等。
如果訓練集准確率較高,測試集准確率比較低,那么模型有可能過擬合,這個時候就需要向提高模型泛化能力的方向,調節參數。
從粗到細分階段調參
實踐中,一般先進行初步范圍搜索,然后根據好結果出現的地方,再縮小范圍進行更精細的搜索。
- 建議先參考相關論文,以論文中給出的參數作為初始參數。至少論文中的參數,是個不差的結果。
- 如果找不到參考,那么只能自己嘗試了。可以先從比較重要,對實驗結果影響比較大的參數開始,同時固定其他參數,得到一個差不多的結果以后,在這個結果的基礎上,再調其他參數。例如學習率一般就比正則值,dropout值重要的話,學習率設置的不合適,不僅結果可能變差,模型甚至會無法收斂。
- 如果實在找不到一組參數,可以讓模型收斂。那么就需要檢查,是不是其他地方出了問題,例如模型實現,數據等等。可以參考我寫的深度學習網絡調試技巧
提高速度
調參只是為了尋找合適的參數,而不是產出最終模型。一般在小數據集上合適的參數,在大數據集上效果也不會太差。因此可以嘗試對數據進行精簡,以提高速度,在有限的時間內可以嘗試更多參數。
- 對訓練數據進行采樣。例如原來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庫,可以上手即用:
- jaberg/hyperopt, 比較簡單。
- fmfn/BayesianOptimization, 比較復雜,支持並行調參。
總結
- 合理性檢查,確定模型,數據和其他地方沒有問題。
- 訓練時跟蹤損失函數值,訓練集和驗證集准確率。
- 使用Random Search來搜索最優超參數,分階段從粗(較大超參數范圍訓練較少周期)到細(較小超參數范圍訓練較長周期)進行搜索。
參考資料
這里列了一些參數資料,大家有時間,可以進一步閱讀。
Practical recommendations for gradient-based training of deep architectures by Yoshua Bengio (2012)
Efficient BackProp, by Yann LeCun, Léon Bottou, Genevieve Orr and Klaus-Robert Müller
Neural Networks: Tricks of the Trade, edited by Grégoire Montavon, Geneviève Orr, and Klaus-Robert Müller.