1. 程式人生 > >訓練過程--對loss和acc的分析、處理

訓練過程--對loss和acc的分析、處理

  計算loss是會把所有loss層的loss相加。

從驗證集誤差是和測試集誤差的角度分析

  其實你這個問題就是個偽命題,如果我們刻意的去在訓練集上擬合模型,使其準確率達到很高的高度,或者說盡量在驗證集合上表現的好,都是相悖的。
  因為我們不能為了某一特定資料集來刻意擬合,因為模型預測資料是不一定就在這個訓練或者驗證集合的空間中。
  還有,如果這個model預測集合acc20% 訓練集合acc19% (即訓練集精度低於測試集精度),那麼這個模型肯定是不好的。
  還有一點需要注意,就是千萬不能為了擬合測試集合而去更改模型,測試集合應該每次都有不同。

那麼如何選取一個較為理想的medel?

  首先,要有一個期望的準確率,通過不同模型的實驗,找到最能接近的;
  然後,選定模型後進行引數調優;
  那麼我們要儘可能的提高model的準確率,同時提高其泛化的能力,不能單一看某一指標,此時可參考 準確率、召回率、虛警率、F1Score等指標綜合評判。或者採用多重驗證隨機劃分訓練、預測、驗證集合,多次隨機後找到最優引數。

  有時候訓練集合誤差很低,但是泛化能力極差,產生過擬合,
  有時候驗證集合誤差很低,但是可能驗證集合無法代表所有的樣本,有特殊性或者其他異常點較多。
  所以模型問題不能單一從你這兩點來評判。

一般而言,訓練集loss < 驗證集loss <測試集loss

  因為網路 [已見過] 所有訓練集samples,故最低。而網路用驗證集作為反饋來調節引數,相當於參考了驗證集samples中的資訊(間接 [已見過])。又因為網路沒有任何測試集的資訊,所以測試結果一般而言最差。
  不過這都不是絕對的,有不符合這個一般現象的task,而我們不可以說哪種情況更“好”。
  多數情況驗證集上錯誤率更低一點。因為是選擇在驗證集上準確率最高的模型來進行測試。考慮到資料的隨機性,在驗證集上準確率最高的模型在測試集上不一定是最高的,所以算出來的指標通常驗證集會比測試集上好一點。

  但是實際情況下都有可能,特別是資料量不太大的時候。樣本集合的資料也只是近似整體的分佈,肯定會有波動。

  一個好的網路,二者的差距應該是很低的。但一般情況下因為網路不可避免地存在一定程度上的過擬合,所以肯定是train_loss低於test_lost,但如果低太多,就得考慮是過擬合的問題還是因為樣本的特徵空間不統一的問題。

  一般訓練集不大時,最終訓練的網路及容易過擬合,也就是說train-loss一定會收斂,但是test-loss不會收斂;

  訓練時的loss會低於test的loss大概1~2個數量級,通常是10倍左右。


單獨觀察訓練集loss曲線

  1)如果你的 learning_rate_policy 是 step 或者其他變化型別的話, loss 曲線可以幫助你選擇一個比較合適的 stepsize;
  2)如果loss曲線表現出線性(下降緩慢)表明學習率太低;
  3)如果loss不再下降,表明學習率太高陷入區域性最小值;
  4)曲線的寬度和batch size有關,如果寬度太寬,說明相鄰batch間的變化太大,應該減小batch size。

可能導致不收斂的問題(如loss為87.3365,loss居高不下等)的解決方案

  1)在caffe中可以在solver裡面設定:debug_info: true,看看各個層的data和diff是什麼值,一般這個時候那些值不是NAN(無效數字)就是INF(無窮大);
  2)檢查資料標籤是否從0開始並且連續;
  3)把學習率base_lr調低;
  4)資料問題,lmdb生成有誤;
  5)中間層沒有歸一化,導致經過幾層後,輸出的值已經很小了,這個時候再計算梯度就比較尷尬了,可以嘗試在各個卷積層後加入BN層和SCALE層;
  5)把base_lr調低,然後batchsize也調高;
  6)把data層的輸入圖片進行歸一化,就是從0-255歸一化到0-1,使用的引數是:

 transform_param {  
    scale: 0.00390625//畫素歸一化,1/255
  } 

  7)網路引數太多,網路太深,刪掉幾層看看,可能因為資料少,需要減少中間層的num_output;
  8)記得要shuffle資料,否則資料不夠隨機,幾個batch之間的資料差異很小。

loss出現NAN

  1)觀察loss值的趨勢,如果迭代幾次以後一直在增大,最後變成nan,那就是發散了,需要考慮減小訓練速率,或者是調整其他引數。
  2)資料不能太少,如果太少的話很容易發散"
  3)Gradient Clipp
  處理gradient之後往後傳,一定程度上解決梯度爆炸問題。(但由於有了batch normalization,此方法用的不多)
  4)原因可能是訓練的時間不夠長。
  5)可以看一下訓練時,網路引數的L2或L1


聯合觀察loss曲線和acc

  1)單獨的 loss 曲線能提供的資訊很少的,一般會結合測試機上的 accuracy 曲線來判斷是否過擬合;
  2)關鍵是要看你在測試集上的acc如何;
  3)可以把accuracy和loss的曲線畫出來,方便設定stepsize,一般在accuracy和loss都趨於平緩的時候就可以減小lr了;
  4)看第一次test時(即iteration 0),loss和精度,如果太差,說明初始點的設定有問題
  5)使用caffe時,train時,看見的loss是訓練集的;accuracy才是測試集的
  6)所謂的過擬合是:loss下降,accuracy也下降