W 1 loss不收斂或不下降問題處理經驗

2022-06-17 14:42:13 字數 3452 閱讀 7344

訓練集loss不下降

驗證集loss不下降

測試集loss不下降

實踐總結

loss不下降,分多種情況:訓練集不下降,驗證集不下降,本文結合其它部落格,做個小的總結:

首先看看不同情況:train loss與test loss結果分析

train loss 不斷下降,test loss不斷下降,說明網路仍在學習;

train loss 不斷下降,test loss趨於不變,說明網路過擬合;

train loss 趨於不變,test loss不斷下降,說明資料集100%有問題;

train loss 趨於不變,test loss趨於不變,說明學習遇到瓶頸,需要減小學習率或批量數目;

train loss 不斷上公升,test loss不斷上公升,說明網路結構設計不當,訓練超引數設定不當,資料集經過清洗等問題。

使用簡單模型進行測試,比如機器學習的模型,較快能驗證。另外檢測資料集是否是亂序的。

通過參考別人已經設計好並實現和測試過的結構,以及特徵工程方案,進行改進和適應性修改,可以更快更好的完成目標任務。當模型結構不好或者規模太小、特徵工程存在問題時,其對於資料的擬合能力不足,是很多人在進行乙個新的研究或者工程應用時,遇到的第乙個大問題。建議使用小的資料集進行測試下。這個問題應該比較容易發現,並且應該第乙個排除掉。

調整bn,啟用等的順序,不過這個估計只能調優,不能起到太大作用。

初始化方式比較多樣化,可以參考我的其它文件:《【pytorch-2-5-2】深度學習權值初始化的方法》。不過很多網路,不使用初始化,也能進行訓練。

l1 l2和dropout是防止過擬合用的,建議是訓練初期,不啟用任何正則化手段。

若是非常複雜的問題,比如成千上萬的分類問題。若使用單層的神經網路,訓練起來肯定不好,loss也不會收斂。建議嘗試至少3層的網路。

在神經網路的啟用函式、損失函式方面的選取,也是需要根據任務型別,選取最合適的。

比如,卷積神經網路中,卷積層的輸出,一般使用relu作為啟用函式,因為可以有效避免梯度消失,並且線性函式在計算效能上面更加有優勢。而迴圈神經網路中的迴圈層一般為tanh,或者relu,全連線層也多用relu,只有在神經網路的輸出層,使用全連線層來分類的情況下,才會使用softmax這種啟用函式。

而損失函式,對於一些分類任務,通常使用交叉熵損失函式,回歸任務使用均方誤差,有自動對齊的任務使用ctc loss等。損失函式相當於模型擬合程度的乙個評價指標,這個指標的結果越小越好。乙個好的損失函式,可以在神經網路優化時,產生更好的模型引數。

神經網路的優化器選取一般選取adam,但是在有些情況下adam難以訓練,這時候需要使用如sgd之類的其他優化器。另外減小學習率,使用lr_scheduler逐步降低學習率;這部分建議看看我的另外兩篇:《adamoptimizer及各類優化器》《【pytorch-2-5-1】學習率調整-torch.optim.lr_scheduler》。

若出現上下震動不收斂時候,也有可能是batchsize太小導致的。所以建議增大batchsize試試。這樣可以增加訓練方向一致性。當然也可能因過大時,模型前期由於梯度的平均,導致收斂速度過慢。

這個能一定程度加快模型收斂,並起到正則化的作用。具體可見這篇:《【dl-0】》

資料歸一化/歸一化

def feature_normalize(data):

mu = np.mean(data,axis=0)

std = np.std(data,axis=0)

return (data - mu)/std

具體可見:

計算量不同,訓練時間不同,若是沒有gpu加速,估計訓練就更慢了。這種就是等一等了,或者換多gpu加速試試。

這裡的瓶頸一般包括:梯度消失、大量神經元失活、梯度**和瀰散、學習率過大或過小等。

梯度消失時,模型的loss難以下降,就像走在高原上,幾乎任何地方都是高海拔,可以通過梯度的檢驗來驗證模型當前所處的狀態。有時梯度的更新和反向傳播**存在bug時,也會有這樣的問題。

在使用relu啟用函式的時候,當每乙個神經元的輸入x為負時,會使得該神經元輸出恒為0,導致失活,由於此時梯度為0,無法恢復。有一種解決方案是使用leakyrelu,這時,y軸的左邊圖線會有乙個很小的正梯度,使得神經網路在一定時間後可以得到恢復。不過leakyrelu並不常用,因為部分神經元失活並不影響結果,相反,這種輸出為0還有很多積極的作用。因為relu方程輸入為負時,輸出值為0,利用此特性可以很好地忽略掉卷積核輸出負相關資訊,同時保留相關資訊。

調整到本階段,預設是訓練集上的loss可以下降,但驗證集上的loss已經不降。大部分是從處理過擬合的手段進行的。

正則化是用來解決模型過擬合問題的乙個很重要的手段,人為給定乙個正則係數lambda,進行權重衰減,將一些相關性不大的特徵項的引數衰減到幾乎為0,相當於去掉了這一項特徵,這跟降維類似,相當於減少了特徵維度。而去掉基本無關的維度,那麼就避免了模型對於這一維度特徵的過分擬合。還有在神經網路兩個層之間增加dropout和normal等,也起到了抑制過擬合的作用。

過擬合很重要的乙個原因也是模型的複雜度太高,除了正則化手段以外,適當減小模型的規模也是很重要的,盡量讓神經網路結構的假設空間與預期目標模型需要儲存的資訊量相匹配。降低資料的維度,類似起到dropout的效果。

由於批規範內部的標準化,較小的批大小在某種程度上對應較強的正則化。這是因為批處理的經驗平均值/std是完整平均值/std的更近似版本,所以規模和偏移量會使批處理更加"搖擺"。

停止基於驗證損失的訓練,在模型即將過度適應時抓住它。

大模型嘗試:我只是在早期停止後才提到這一點,但我發現在過去的幾次大的模型當然最終會過度適應,但它們的"早期停止"效能通常會比小的模型好得多。

深度學習就是在有大量資料的基礎上發展起來的。深度學習的三件套:資料、模型和硬體。增加資料量,能更好訓練模型。

這個是直接對現有的資料集做擴容,一定程度上可以再次提高驗證集上的準確率,比如對影象做旋轉,對聲音檔案進行加噪處理等。最終的效果雖然比不上同等情況下的資料量的增加帶來的效果增益,但是在現有條件下,算是擴增資料量的乙個有效的方案。

測試集一般為模型之前訓練時從未見過的新資料,或者目標應用場景下的真實資料。由於訓練集和驗證集的loss不下降時,應歸為前兩節的內容,所以這一節中,我們預設訓練集和驗證集的loss情況是正常的。如果測試集的loss很高,或者正確率很低,那麼一般是因為訓練資料的分布和場景與測試資料的分布和應用場景不一致。

比如,乙個語音識別模型,輸入的資料集都是女性的錄音音訊,那麼對於男性的聲音就不能很好的識別出來。這個也是博主之前做語音識別的時候遇到過的乙個真實案例,解決方案就是增加含有大量男性錄音音訊的資料集來訓練。

雜訊問題是實際應用場景下,頻繁遇到的問題。直接容易理解的案例就是,在語音識別中,標準語音資料集都是在安靜環境下採集的資料,但是在實際應用中,我們錄音時多多少少會有雜訊,那麼我們需要專門去處理雜訊,比如進行乙個降噪處理,或者在訓練資料中新增雜訊等。在影象的識別中,那麼就需要考慮中的遮擋、霧霾、旋轉、映象和大小遠近等問題。

在實際工作中,訓練4000+的分類模型中,1.5 、1.7 、1.9在實際訓練中改善比較明顯。

如何解決神經網路訓練時loss不下降的問題

造假資料1w條

coding utf 8 from faker import faker from custom.custom import myprovider import pandas as pd import pymysql class create data object def init self 選擇...

pytorch中的loss函式(3) L1Loss

1 l1loss原理 l1loss計算 值和真實值的mean absolute error mae,平均絕對值誤差 其中 若是mean 先計算 值x與真實值y這兩個tensor中的對應位置的兩個元素的差的絕對值,得到乙個新的同樣大小的tensor,然後求這個tensor中所有元素的均值 若是sum ...

nginx單機1W併發優化

高併發思路 socket層面分析 nginx 1.子程序允許開啟的連線 worker connections 2.http連線快速關閉 keep alivetime 0 http請求完之後,馬上斷開連線 系統 1.最大連線數 somaxconn 2.加快tcp連線的 recycle 3.空的tcp是...