PyTorch學習筆記|神經(jīng)網(wǎng)絡的損失函數(shù)

優(yōu)化思想

之前我們提到過,這是神經(jīng)網(wǎng)絡的正向傳播過程。但很明顯,這并不是神經(jīng)網(wǎng)絡算法的全流程,這個流程雖然可以輸出預測結果,但卻無法保證神經(jīng)網(wǎng)絡的輸出結果與真實值接近。

那我就來講解一下模型訓練的全過程。

(1)提出基本模型,明確目標
我們的基本模型就是我們自建的神經(jīng)網(wǎng)絡架構,我們需要求解的就是神經(jīng)網(wǎng)絡架構中的權重向量。
(2)確定損失函數(shù)/目標函數(shù)
我們需要定義某個評估指標,用以衡量模型權重為w的情況下,預測結果與真實結果的差異。當真實值與預測值差異越大時,我們就認為神經(jīng)網(wǎng)絡學習過程中丟失了許多信息,丟失的這部分被形象地稱為”損失",因此評估真實值與預測值差異的函數(shù)被我們稱為"損失函數(shù)”。
3)確定適合的優(yōu)化算法
4)利用優(yōu)化算法,最小化損失函數(shù),求解最佳權重(訓練)

回歸優(yōu)化算法:誤差平方和SSE

import torch
from torch.nn import MSELoss

yhat = torch.randn(size=(50,),dtype=torch.float32)
y = torch.randn(size=(50,),dtype=torch.float32)

criterion =MSELoss() #實例化
loss = criterion(yhat,y)
#在MSELoss中有重要的參數(shù),reduction
#當reduction = "mean" (默認也是mean),則輸出MSE
#當reduction = "sum",則輸出SSE
criterion = MSELoss(reduction = "mean") #實例化
criterion(yhat,y)
criterion = MSELoss(reduction = "sum")
criterion(yhat,y)
print(loss)

二分類交叉熵損失函數(shù)

推導過程大家自己學習。

對于二分類交叉熵損失,nn提供了兩個類:BCEWithLogitsLoss以及BCELoss。雖然PyTorch官方?jīng)]有直接明確,但實際上兩個函數(shù)所需要輸入的參數(shù)不同。

BCEWithLogitsLoss內(nèi)置了sigmoid函數(shù)與交叉熵函數(shù),它會自動計算輸入值的sigmoid值,因此需要輸入zhat與真實標簽,且順序不能變化,zhat必須在前。

相對的,BCELoss中只有交叉熵函數(shù),沒有sigmoid層,因此需要輸入sigma與真實標簽,且順序不能變化。

同時,這兩個函數(shù)都要求預測值與真實標簽的數(shù)據(jù)類型以及結構(shape)必須相同,否則運行就會報錯。

import torch
import torch.nn as nn

X = torch.rand((500,4),dtype=torch.float32)
w = torch.rand((4,1),dtype=torch.float32,requires_grad=True)
y = torch.randint(low=0,high=2,size=(500,1),dtype=torch.float32)
zhat = torch.mm(X,w)
sigma = torch.sigmoid(zhat)

criterion1 = nn.BCELoss()
loss1 = criterion1(sigma, y)
criterion2 = nn.BCEWithLogitsLoss()
loss2 = criterion2(zhat, y)
print(loss1,loss2)

#tensor(0.8342, grad_fn=<BinaryCrossEntropyBackward0>) tensor(0.8342, grad_fn=<BinaryCrossEntropyWithLogitsBackward0>)

與MSELoss相同,二分類交叉熵的類們也有參數(shù)reduction,默認是”mean“,表示求解所有樣本平均的損失,也可換為”sum”,要求輸出整體的損失。以及,還可以使用選項“none”,表示不對損失結果做任何聚合運算,直接輸出每個樣本對應的損失矩陣。

多分類交叉熵損失函數(shù)

我們可以直接調用CrossEntropyLoss。

import torch
import torch.nn as nn

X = torch.rand((500,4),dtype=torch.float32)
w = torch.rand((4,3),dtype=torch.float32,requires_grad=True)
y = torch.randint(low=0,high=3,size=(500,),dtype=torch.long)
zhat = torch.mm(X,w)

criterion1 = nn.CrossEntropyLoss()
loss1 = criterion1(zhat, y)
print(loss1)

# tensor(1.1369, grad_fn=<NllLossBackward0>)

這里我們需要注意兩點,就是真實標簽必須是1維tensor,同時類型必須是整數(shù)。這是因為交叉熵損失需要將標簽轉化為獨熱形式來進行計算。

?著作權歸作者所有,轉載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容