深度學習 (DeepLearning) 基礎 [2]---神經網路常用的損失函式
Introduce
在上一篇“深度學習 (DeepLearning) 基礎 [1]---監督學習和無監督學習”中我們介紹了監督學習和無監督學習相關概念。本文主要介紹神經網路常用的損失函式。
以下均為個人學習筆記,若有錯誤望指出。
神經網路常用的損失函式
pytorch損失函式封裝在torch.nn中。
損失函式反映了模型預測輸出與真實值的區別,模型訓練的過程即讓損失函式不斷減小,最終得到可以擬合預測訓練樣本的模型。
note:由於PyTorch神經網路模型訓練過程中每次傳入一個mini-batch的資料,因此pytorch內建損失函式的計算出來的結果如果沒有指定reduction引數,則預設對mini-batch取平均。
以下對幾個常用的損失函式以及其應用場景做一個簡單總結。(以下損失函式的公式均代表單個min-batch的損失,且假設x為神經網路的預測輸出,y為樣本的真實值,xi為一個mini-batch中第i個樣本的預測輸出,yi同理,n為一個批量mini-batch的大小)
- nn.L1Loss(L1損失,也稱平均絕對誤差MAE):計算模型輸出x與目標y之間差的絕對值。常用於迴歸任務。
\[loss(x,y) = {1\over n}\sum|x_i-y_i|
\]
'''程式碼示例'''
loss_func = torch.nn.L1Loss(reduction='mean')
'''note:
reduction=None 啥也不幹
reduction='mean' 返回loss和的平均值
reduction='mean' 返回loss的和。
不指定即預設mean。
'''
- nn.MSELoss(L2損失,也稱均方誤差MSE):計算模型輸出x與目標y之間差的平方的均值,均方差。常用於迴歸任務。
\[loss(x,y) = {1\over n}\sum(x_i-y_i)^2
\]
'''程式碼示例'''
loss_func = torch.nn.MSELoss(reduction='mean')
# note: reduction同上。
- nn.BCELoss(二進位制交叉熵損失):計算模型輸出x與目標y之間的交叉熵。(我對於交叉熵的理解,交叉熵為相對熵(即KL散度,用來衡量兩個分佈的差異程度)中的一項,最小化兩個分佈的差異,即最小化相對熵,由相對熵公式,由於真實分佈是確定的,那麼最小化相對熵就是最小化交叉熵,而最小化交叉熵的目標就是尋找一個預測分佈儘可能逼近真實分佈,這和我們模型的訓練目標是一致的,即讓模型預測逼近樣本真實值,參考連結)常用於二分類任務。
\[loss(x,y) = {1\over n}\sum-w_i[y_i*logx_i + (1-y_i)*log(1-x_i)]
\]
'''程式碼示例'''
loss_func = torch.nn.BCELoss(weight=None, reduction='mean')
# note:
# weight為長度為n的tensor,用來指定一個batch中各樣本佔有的權重,如公式中的wi,不指定預設為各樣本權重均為1。
# reduction同上。
# 用的時候需要在該層前面加上 Sigmoid 函式。
- nn.NLLLoss(負對數似然損失):將神經網路輸出的隸屬各個類的概率向量x與對應真實標籤向量(個人理解應該是one-hot向量吧)相差再相加,最後再取負。如果不取負的話,應該是loss值越大預測標籤越接近真實標籤,取負的話反過來,越小則越接近真實標籤,符合loss函式的定義。常用於多分類任務。 以下公式假設節點xi屬於第j類,x[j]為預測的x屬於第j類的概率,且w[j]為第j類的權重。
\[loss(x,class) = {1\over n}\sum -w[j]*x[j]
\]
'''程式碼示例'''
loss_func = torch.nn.NLLLoss(weight=None, reduction='mean')
# note:
# weight同上,如公式中的w代表各個類在損失中佔有的權重,即類的重要程度,若不賦予權重w,則各類同等重要,上述公式中的w[class]去掉。
# reduction同上。
- nn.CrossEntropyLoss (交叉熵損失):如上述二進位制交叉熵所示,隨著預測的概率分佈越來越接近實際標籤,交叉熵會逐漸減小。pytorch將nn.LogSoftmax()和nn.NLLLoss()組合到nn.CrossEntropyLoss(),即呼叫nn.CrossEntropyLoss() 底層會呼叫上述兩個函式,可以理解為 CrossEntropyLoss = LogSoftmax + NLLLoss。因此一般多分類任務都常用交叉熵損失。 以下label_i代表節點xi的真實標籤,c為總的標籤數。
\[loss(x,class) = {1 \over n}\sum-w[label_i]log{exp(x_i[label_i])\over \sum_{j=1}^cexp(x[j])} = {1 \over n}\sum w[label_i](-x_i[label_i]+log(\sum_{j=1}^c)exp(x[j]))
\]
'''程式碼示例'''
loss_func = torch.nn.CrossEntropyLoss(weight=None,reduction='mean')
# note:
# weight同nn.NLLLoss。
# reduction同上。