原因一:除0錯(cuò)誤
- 數(shù)據(jù)原因:由于路徑或臟數(shù)據(jù)等原因频敛,造成數(shù)據(jù)讀取出差
解決方法:判斷出現(xiàn)nan的數(shù)據(jù)的id,剔除馅扣,簡(jiǎn)單粗暴 - 代碼原因:數(shù)據(jù)本身就存在0值斟赚,代碼在執(zhí)行過程中將其置為分母
注意:很多代碼都存在隱式除0操作,因?yàn)楝F(xiàn)成的損失函數(shù)有不少采用了log函數(shù)岂嗓,如CrossEntropyLoss和log_softmax汁展。使用log函數(shù)的優(yōu)點(diǎn)可以拖到最底部鹊碍,后文會(huì)描述厌殉。
y = log(softmax(x))
y' = 1/softmax(x) ##出現(xiàn)除0操作,softmax的值域區(qū)間為[0,1]
解決方法: 令y= log(softmax(x)+EPS), 其中EPS可以取1e-12(極小值)
原因二:學(xué)習(xí)策略、超參設(shè)置不當(dāng)
- 學(xué)習(xí)速率過大侈咕,嘗試調(diào)小
- batch_size過大公罕,嘗試調(diào)小
- 嘗試使用batch normalization和instance normalization
為什么很多損失函數(shù)都以log函數(shù)為原型?
令X表示我們模型的輸出耀销,而我們希望的預(yù)測(cè)類別是c楼眷,
則有預(yù)測(cè)概率P=softmax(X)
其中Pc:輸出X屬于c類的概率
一般來說,我們希望輸出概率Pc越大越好熊尉,如何優(yōu)化罐柳?
最簡(jiǎn)單的做法就是令損失函數(shù)
loss_f = -Pc
這樣的做法在理解上十分直觀,當(dāng)我們優(yōu)化loss_f取得最小值時(shí)狰住,即Pc取得最大值
但我們還是需要使用log函數(shù)U偶!催植!
為方便講解肮蛹,我們暫時(shí)忽略損失函數(shù)前面的符號(hào),
令loss_f = Pc
loss_g = log(Pc)
- 等價(jià)性
loss_f與loss_g均為單調(diào)遞增函數(shù)创南,優(yōu)化loss_f與loss_g等價(jià) - 懲罰力度
loss_f是斜率為1的直線函數(shù)伦忠,具有梯度不變形,意味著不管Pc的值為0.9還是0.1稿辙,懲罰力度都是一樣的
而loss_g是曲線函數(shù)昆码,接近0的地方值接近”無窮大“,接近1的地方值接近0邻储,意味著當(dāng)Pc=0.9時(shí)懲罰力度更小赋咽,而Pc接近0的時(shí)候表示偏差太大,懲罰力度非常大芥备。