記錄模型訓(xùn)練時loss值的變化情況
記錄訓(xùn)練過程中的每一步的loss變化
if verbose and step % verbose == 0: sys.stdout.write('\r{} / {} : loss = {}'.format( step, total_steps, np.mean(total_loss))) sys.stdout.flush() if verbose: sys.stdout.write('\r') sys.stdout.flush()
一般我們在訓(xùn)練神經(jīng)網(wǎng)絡(luò)模型的時候,都是每隔多少步,輸出打印一下loss或者每一步打印一下loss,今天發(fā)現(xiàn)了另一種記錄loss變化的方法,就是用
sys.stdout.write('\r{} / {} : loss = {}')
如圖上的代碼,可以記錄每一個在每個epoch中記錄用一行輸出就可以記錄每個step的loss值變化,
\r就是輸出不會換行,因此如果你想同一樣輸出多次,在需要輸出的字符串對象里面加上"\r",就可以回到行首了。
sys.stdout.flush() #一秒輸出了一個數(shù)字
具體的實現(xiàn)就是下面的圖:
這樣在每個epoch中也可以觀察loss變化,但是只需要打印一行,而不是每一行都輸出。
補充知識:訓(xùn)練模型中損失(loss)異常分析
前言
訓(xùn)練模型過程中隨時都要注意目標函數(shù)值(loss)的大小變化。一個正常的模型loss應(yīng)該隨訓(xùn)練輪數(shù)(epoch)的增加而緩慢下降,然后趨于穩(wěn)定。雖然在模型訓(xùn)練的初始階段,loss有可能會出現(xiàn)大幅度震蕩變化,但是只要數(shù)據(jù)量充分,模型正確,訓(xùn)練的輪數(shù)足夠長,模型最終會達到收斂狀態(tài),接近最優(yōu)值或者找到了某個局部最優(yōu)值。在模型實際訓(xùn)練過程中,可能會得到一些異常loss值,如loss等于nan;loss值忽大忽小,不收斂等。
下面根據(jù)自己使用Pythorh訓(xùn)練模型的經(jīng)驗,分析出一些具體原因和給出對應(yīng)的解決辦法。
一、輸入數(shù)據(jù)
1. 數(shù)據(jù)的預(yù)處理
輸入到模型的數(shù)據(jù)一般都是經(jīng)過了預(yù)處理的,如用pandas先進行數(shù)據(jù)處理,尤其要注意空值,缺失值,異常值。
缺失值:數(shù)值類型(NaN),對象類型(None, NaN),時間類型(NaT)
空值:""
異常值:不再正常區(qū)間范圍的值
例如對缺失值可以進行判斷df.isnull()或者df.isna();丟棄df.dropna();填充df.fillna()等操作。
輸入到模型中的數(shù)據(jù)一般而言都是數(shù)值類型的值,一定要保證不能出現(xiàn)NaN, numpy中的nan是一種特殊的float,該值數(shù)值運算的結(jié)果是不正常的,所以可能會導(dǎo)致loss值等于nan??梢杂胣umpy.any(numpy.isnan(x))檢查一下input和target。
2. 數(shù)據(jù)的讀寫
例如使用Pandas讀取.csv類型的數(shù)據(jù)得到的DataFrame會添加默認的index,再寫回到磁盤會多一列。如果用其他讀取方式再讀入,可能會導(dǎo)致數(shù)據(jù)有問題,讀取到NaN。
import pandas as pd Output = pd.read_csv('./data/diabetes/Output.csv') trainOutput, testOutput = Output[:6000], Output[6000:] trainOutput.to_csv('./data/diabetes/trainOutput.csv') testOutput.to_csv('./data/diabetes/testOutput.csv')
3. 數(shù)據(jù)的格式
Pythorch中的 torch.utils.data.Dataset 類是一個表示數(shù)據(jù)集的抽象類。自己數(shù)據(jù)集的類應(yīng)該繼承自 Dataset 并且重寫__len__方法和__getitem__方法:
__len__ : len(dataset) 返回數(shù)據(jù)集的大小
__getitem__ :用以支持索引操作, dataset[idx]能夠返回第idx個樣本數(shù)據(jù)
然后使用torch.utils.data.DataLoader 這個迭代器(iterator)來遍歷所有的特征。具體可以參見這里
在構(gòu)造自己Dataset類時,需要注意返回的數(shù)據(jù)格式和類型,一般不會出現(xiàn)NaN的情況但是可能會導(dǎo)致數(shù)據(jù)float, int, long這幾種類型的不兼容,注意轉(zhuǎn)換。
二、學(xué)習(xí)率
基于梯度下降的優(yōu)化方法,當(dāng)學(xué)習(xí)率太高時會導(dǎo)致loss值不收斂,太低則下降緩慢。需要對學(xué)習(xí)率等超參數(shù)進行調(diào)參如使用網(wǎng)格搜索,隨機搜索等。
三、除零錯
對于回歸問題,可能出現(xiàn)了除0 的計算,加一個很小的余項可能可以解決。類似于計算概率時進行的平滑修正,下面的代碼片段中l(wèi)oss使用交叉混合熵(CossEntropy),計算3分類問題的AUC值,為了避免概率計算出現(xiàn)NaN而采取了相應(yīng)的平滑處理。
from sklearn.metrics import roc_auc_score model_ft, y_true, losslists = test_model(model_ft, criterion, optimizer) n_class = 3 y_one_hot = np.eye(n_class)[y_true.reshape(-1)] # solve divide zero errot eps = 0.0000001 y_scores = losslists / (losslists.sum(axis=1, keepdims=True)+eps) #print(y_scores) #print(np.isnan(y_scores)) """ metrics.roc_auc_score(y_one_hot, y_pred) """ print("auc: ") roc_auc_score(y_one_hot, y_scores)
四、loss函數(shù)
loss函數(shù)代碼編寫不正確或者已經(jīng)編寫好的loss函數(shù)API使用不清楚
五、某些易錯代碼
Pytorch在進行自動微分的時候,默認梯度是會累加的,所以需要在每個epoch的每個batch中對梯度清零,否則可能會導(dǎo)致loss值不收斂。不要忘記添加如下代碼
optimizer.zero_grad()
以上這篇記錄模型訓(xùn)練時loss值的變化情況就是小編分享給大家的全部內(nèi)容了,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
python中將txt文件轉(zhuǎn)換為csv文件的三種方法舉例
對于大數(shù)據(jù)的處理基本都是以CSV文件為基礎(chǔ)進行的,那么在進行深度學(xué)習(xí)的處理之前,需要先統(tǒng)一數(shù)據(jù)文件的格式,下面這篇文章主要給大家介紹了關(guān)于python中將txt文件轉(zhuǎn)換為csv文件的三種方法,需要的朋友可以參考下2024-06-06python實現(xiàn)域名系統(tǒng)(DNS)正向查詢的方法
這篇文章主要介紹了python實現(xiàn)域名系統(tǒng)(DNS)正向查詢的方法,結(jié)合實例形式分析了Python使用socket模塊下getaddrinfo方法進行域名查詢的具體技巧,需要的朋友可以參考下2016-04-04