近期小編在做映像分類的實驗,無奈狀況連連。現將遇到的幾個大坑簡單記錄一下,以備日後之需。如果你也出現了問題(1)中GPU記憶體問題,請看完整篇文章。
1、記憶體報錯
如果你是GPU環境,那你要注意了,你的電腦上現在應該有兩個記憶體限制。
(1)GPU記憶體
GPU記憶體大家可以使用下面命令查看
nvidia-smi
如果你想動態觀測,那你可以使用下面命令:
nvidia-smi -l
如果程式在運行過程中提示如下錯誤,那就說明是你的GPU記憶體不夠了。
Check failed: error == cudaSuccess (2 vs. 0) out of memory
解決方案:
(1)batch_size太大了,一次性讀入的圖片太多了,所以就超出了顯存。因此需要將train.prototxt中的檔案train和test的batch_size調小一點。
(2)如果圖片的尺寸可以更改,可以通過設定crop_size來更改圖片的大小尺寸,從而解決錯誤。
上述兩種方法選一種即可,但過分的減少batch_size 亦可引發問題2 的出現,這事就要兩種方法相結合進行解決。
(2)電腦記憶體
當電腦記憶體不足時,這個錯誤比較好判斷,目前小編手裡沒有現有的錯誤,以後有了這個錯誤提示,再來補充。(一般大家看了都會知道是記憶體不足了)
問題2、caffe訓練時accuracy,loss值迭代到一定程度後無論學習率怎麼變化,兩者值都不變。accura = 0.18833, loss=87.3365
小編被這個問題折磨的尤為慘烈,暫且不論accuracy值的大小,畢竟網路都是需要調的,不可能直接上來accuracy的值就很高。單說loss值,這也太高了。訓練好的網路loss值一般要在0.01以下,這可倒好,沒有下降反而上升到了天際。
小編各種方法都實驗過了:
(1)學習率base_lr降低。從0.1到0.0000001我都試過了,頂多是迭代的次數不同而已,最終都會迴歸到一個問題上,那就是迭代到一定程度後兩者值都不變:accura = 0.18833, loss=87.3365。
(2)查看標籤是否正確,從0開始標記。小編一共就設計了兩類,0和1,就這還看了好幾遍。
(3)產生的lmdb資料包是否正確。產生資料包lmdb的程式看了一遍又一遍,生怕是自己產生的lmdb出現問題。
無奈小編都開始感覺是自己的映像庫中的髒資料太多,都打算重新弄資料庫。還好老天佑我,在我絕望之際給了我啟示:我看到了這篇博文(http://blog.csdn.net/ying86615791/article/details/60757573)
博文內容:
可以在solver裡面設定:
debug_info: true
看看各個層的data和diff是什麼值,一般這個時候那些值不是NAN(無效數字)就是INF(無窮大),
一般的解決辦法是:
1、檢查資料的標籤是否從0開始且連續
2、把學習率base_lr調低
3、資料問題
4、中介層沒有歸一化,導致經過幾層後,輸出的值已經很小了,這個時候再計算梯度就比較尷尬了,
這也是我遇到的問題,所以我再各個卷積層加入了BN層和SCALE層,不過FC層沒有必要加吧。
5、把base_lr調低,然後batchsize也調高
6、把data層的輸入圖片進行歸一化,就是從0-255歸一化到0-1,使用的參數是:
transform_param { scale: 0.00390625//像素歸一化,1/255 }
7、網路參數太多,網路太深,刪掉幾層看看,可能因為資料少,需要減少中介層的num_output
8、記得要shuffle資料,否則資料不夠隨機,幾個batch之間的資料差異很小,一旦連續幾個batch把loss調很小,然後就。。。 現在不造解釋,
上述博文內容中,第5和第8條引起我的注意:
5、把base_lr調低,然後batchsize也調高8、記得要shuffle資料,否則資料不夠隨機,幾個batch之間的資料差異很小,一旦連續幾個batch把loss調很小,然後就。。。 現在不造解釋,
雖然不太知道為什麼,但是這改變了我的一個想法,資料層中的batch_size其實與訓練過程是有關的。它的改變會引起accuracy或者loss的改變。
小編的batch_size 因為問題1的出現被小編嚴重調低,將batch_size設為了1 。為了調高batch_size,只能縮小映像,所以小編使用crop_size對映像進行裁剪,這時奇蹟發生了,小編的loss值再沒上來過。
所以,如果你的loss值一直loss=87.3365恒不變,你又找不到其他的原因,那你請試試提高你的batch_size.小編最後train部分的batch_size值增加到了20.