PyTorch 學習筆記(六):PyTorch的十七個損失函數

本文截取自《PyTorch 模型訓練實用教程》,獲取全文pdf請點擊:https://github.com/tensor-yu/PyTorch_Tutorial


我們所說的優化,即優化網絡權值使得損失函數值變小。但是,損失函數值變小是否能代表模型的分類/迴歸精度變高呢?那麼多種損失函數,應該如何選擇呢?請來了解PyTorch中給出的十七種損失函數吧。

請運行配套代碼,代碼中有詳細解釋,有手動計算,這些都有助於理解損失函數原理。
本小節配套代碼: /Code/3_optimizer/3_1_lossFunction

1.L1loss

class torch.nn.L1Loss(size_average=None, reduce=None)
官方文檔中仍有reduction='elementwise_mean’參數,但代碼實現中已經刪除該參數
功能:
計算output和target之差的絕對值,可選返回同維度的tensor或者是一個標量。
計算公式:
在這裏插入圖片描述
參數:
reduce(bool)- 返回值是否爲標量,默認爲True
size_average(bool)- 當reduce=True時有效。爲True時,返回的loss爲平均值;爲False時,返回的各樣本的loss之和。
實例:
/Code/3_optimizer/3_1_lossFunction/1_L1Loss.py

2.MSELoss

class torch.nn.MSELoss(size_average=None, reduce=None, reduction=‘elementwise_mean’)
官方文檔中仍有reduction='elementwise_mean’參數,但代碼實現中已經刪除該參數
功能:
計算output和target之差的平方,可選返回同維度的tensor或者是一個標量。
計算公式:
在這裏插入圖片描述
參數:
reduce(bool)- 返回值是否爲標量,默認爲True
size_average(bool)- 當reduce=True時有效。爲True時,返回的loss爲平均值;爲False時,返回的各樣本的loss之和。
實例:
/Code/3_optimizer/3_1_lossFunction/2_MSELoss.py

3.CrossEntropyLoss

class torch.nn.CrossEntropyLoss(weight=None, size_average=None, ignore_index=-100, reduce=None, reduction=‘elementwise_mean’)
功能:
將輸入經過softmax激活函數之後,再計算其與target的交叉熵損失。即該方法將nn.LogSoftmax()和 nn.NLLLoss()進行了結合。嚴格意義上的交叉熵損失函數應該是nn.NLLLoss()。

補充:小談交叉熵損失函數
交叉熵損失(cross-entropy Loss) 又稱爲對數似然損失(Log-likelihood Loss)、對數損失;二分類時還可稱之爲邏輯斯諦迴歸損失(Logistic Loss)。交叉熵損失函數表達式爲 L = - sigama(y_i * log(x_i))。pytroch這裏不是嚴格意義上的交叉熵損失函數,而是先將input經過softmax激活函數,將向量“歸一化”成概率形式,然後再與target計算嚴格意義上交叉熵損失。
在多分類任務中,經常採用softmax激活函數+交叉熵損失函數,因爲交叉熵描述了兩個概率分佈的差異,然而神經網絡輸出的是向量,並不是概率分佈的形式。所以需要softmax激活函數將一個向量進行“歸一化”成概率分佈的形式,再採用交叉熵損失函數計算loss。
再回顧PyTorch的CrossEntropyLoss(),官方文檔中提到時將nn.LogSoftmax()和 nn.NLLLoss()進行了結合,nn.LogSoftmax() 相當於激活函數 , nn.NLLLoss()是損失函數,將其結合,完整的是否可以叫做softmax+交叉熵損失函數呢?

計算公式:
在這裏插入圖片描述

參數:
weight(Tensor)- 爲每個類別的loss設置權值,常用於類別不均衡問題。weight必須是float類型的tensor,其長度要於類別C一致,即每一個類別都要設置有weight。帶weight的計算公式:

size_average(bool)- 當reduce=True時有效。爲True時,返回的loss爲平均值;爲False時,返回的各樣本的loss之和。
reduce(bool)- 返回值是否爲標量,默認爲True
ignore_index(int)- 忽略某一類別,不計算其loss,其loss會爲0,並且,在採用size_average時,不會計算那一類的loss,除的時候的分母也不會統計那一類的樣本。
實例:
/Code/3_optimizer/3_1_lossFunction/3_CroosEntropyLoss.py
補充:
output不僅可以是向量,還可以是圖片,即對圖像進行像素點的分類,這個例子可以從NLLLoss()中看到,這在圖像分割當中很有用。

4.NLLLoss

class torch.nn.NLLLoss(weight=None, size_average=None, ignore_index=-100, reduce=None, reduction=‘elementwise_mean’)
功能:
不好用言語描述其功能!請看計算公式:loss(input, class) = -input[class]。舉個例,三分類任務,input=[-1.233, 2.657, 0.534], 真實標籤爲2(class=2),則loss爲-0.534。就是對應類別上的輸出,取一個負號!感覺被NLLLoss的名字欺騙了。
實際應用:
常用於多分類任務,但是input在輸入NLLLoss()之前,需要對input進行log_softmax函數激活,即將input轉換成概率分佈的形式,並且取對數。其實這些步驟在CrossEntropyLoss中就有,如果不想讓網絡的最後一層是log_softmax層的話,就可以採用CrossEntropyLoss完全代替此函數。
參數:
weight(Tensor)- 爲每個類別的loss設置權值,常用於類別不均衡問題。weight必須是float類型的tensor,其長度要於類別C一致,即每一個類別都要設置有weight。
size_average(bool)- 當reduce=True時有效。爲True時,返回的loss爲除以權重之和的平均值;爲False時,返回的各樣本的loss之和。
reduce(bool)- 返回值是否爲標量,默認爲True。
ignore_index(int)- 忽略某一類別,不計算其loss,其loss會爲0,並且,在採用size_average時,不會計算那一類的loss,除的時候的分母也不會統計那一類的樣本。
實例:
/Code/3_optimizer/3_1_lossFunction/4_NLLLoss.py
特別注意:
當帶上權值,reduce = True, size_average = True, 其計算公式爲:
在這裏插入圖片描述
例如當input爲[[0.6, 0.2, 0.2], [0.4, 1.2, 0.4]],target= [0, 1], weight = [0.6, 0.2, 0.2]
l1 = - 0.60.6 = - 0.36
l2 = - 1.2
0.2 = - 0.24
loss = -0.36/(0.6+0.2) + -0.24/(0.6+0.2) = -0.75

5.PoissonNLLLoss

class torch.nn.PoissonNLLLoss(log_input=True, full=False, size_average=None, eps=1e-08, reduce=None, reduction=‘elementwise_mean’)
功能:
用於target服從泊松分佈的分類任務。
計算公式:
在這裏插入圖片描述
參數:
log_input(bool)- 爲True時,計算公式爲:loss(input,target)=exp(input) - target * input;
爲False時,loss(input,target)=input - target * log(input+eps)
full(bool)- 是否計算全部的loss。例如,當採用斯特林公式近似階乘項時,此爲 target*log(target) - target+0.5∗log(2πtarget)
eps(float)- 當log_input = False時,用來防止計算log(0),而增加的一個修正項。即 loss(input,target)=input - target * log(input+eps)
size_average(bool)- 當reduce=True時有效。爲True時,返回的loss爲平均值;爲False時,返回的各樣本的loss之和。
reduce(bool)- 返回值是否爲標量,默認爲True
實例:
/Code/3_optimizer/3_1_lossFunction/5_PoissonNLLLoss.py

6.KLDivLoss

class torch.nn.KLDivLoss(size_average=None, reduce=None, reduction=‘elementwise_mean’)
功能:
計算input和target之間的KL散度( Kullback–Leibler divergence) 。
計算公式:
在這裏插入圖片描述
(後面有代碼手動計算,證明計算公式確實是這個,但是爲什麼沒有對x_n計算對數呢?)

補充:KL散度
KL散度( Kullback–Leibler divergence) 又稱爲相對熵(Relative Entropy),用於描述兩個概率分佈之間的差異。計算公式(離散時):

其中p表示真實分佈,q表示p的擬合分佈, D(P||Q)表示當用概率分佈q來擬合真實分佈p時,產生的信息損耗。這裏的信息損耗,可以理解爲損失,損失越低,擬合分佈q越接近真實分佈p。同時也可以從另外一個角度上觀察這個公式,即計算的是 p 與 q 之間的對數差在 p 上的期望值。
特別注意,D(p||q) ≠ D(q||p), 其不具有對稱性,因此不能稱爲K-L距離。
信息熵 = 交叉熵 - 相對熵
從信息論角度觀察三者,其關係爲信息熵 = 交叉熵 - 相對熵。在機器學習中,當訓練數據固定,最小化相對熵 D(p||q) 等價於最小化交叉熵 H(p,q) 。

參數:
size_average(bool)- 當reduce=True時有效。爲True時,返回的loss爲平均值,平均值爲element-wise的,而不是針對樣本的平均;爲False時,返回是各樣本各維度的loss之和。
reduce(bool)- 返回值是否爲標量,默認爲True。

使用注意事項:
要想獲得真正的KL散度,需要如下操作:

  1. reduce = True ;size_average=False
  2. 計算得到的loss 要對batch進行求平均

實例:
/Code/3_optimizer/3_1_lossFunction/6_KLDivLoss.py

7.BCELoss

class torch.nn.BCELoss(weight=None, size_average=None, reduce=None, reduction=‘elementwise_mean’)
功能:
二分類任務時的交叉熵計算函數。此函數可以認爲是nn.CrossEntropyLoss函數的特例。其分類限定爲二分類,y必須是{0,1}。還需要注意的是,input應該爲概率分佈的形式,這樣才符合交叉熵的應用。所以在BCELoss之前,input一般爲sigmoid激活層的輸出,官方例子也是這樣給的。該損失函數在自編碼器中常用。
計算公式:
在這裏插入圖片描述
參數:
weight(Tensor)- 爲每個類別的loss設置權值,常用於類別不均衡問題。
size_average(bool)- 當reduce=True時有效。爲True時,返回的loss爲平均值;爲False時,返回的各樣本的loss之和。
reduce(bool)- 返回值是否爲標量,默認爲True

8.BCEWithLogitsLoss

class torch.nn.BCEWithLogitsLoss(weight=None, size_average=None, reduce=None, reduction=‘elementwise_mean’, pos_weight=None)
功能:
將Sigmoid與BCELoss結合,類似於CrossEntropyLoss(將nn.LogSoftmax()和 nn.NLLLoss()進行結合)。即input會經過Sigmoid激活函數,將input變成概率分佈的形式。
計算公式:
在這裏插入圖片描述
σ() 表示Sigmoid函數
特別地,當設置weight時:

參數:
weight(Tensor)- : 爲batch中單個樣本設置權值,If given, has to be a Tensor of size “nbatch”.
pos_weight-: 正樣本的權重, 當p>1,提高召回率,當P<1,提高精確度。可達到權衡召回率(Recall)和精確度(Precision)的作用。 Must be a vector with length equal to the number of classes.
size_average(bool)- 當reduce=True時有效。爲True時,返回的loss爲平均值;爲False時,返回的各樣本的loss之和。
reduce(bool)- 返回值是否爲標量,默認爲True

9.MarginRankingLoss

class torch.nn.MarginRankingLoss(margin=0, size_average=None, reduce=None, reduction=‘elementwise_mean’)
功能:
計算兩個向量之間的相似度,當兩個向量之間的距離大於margin,則loss爲正,小於margin,loss爲0。
計算公式:
在這裏插入圖片描述
y == 1時,x1要比x2大,纔不會有loss,反之,y == -1 時,x1要比x2小,纔不會有loss。
參數:
margin(float)- x1和x2之間的差異。
size_average(bool)- 當reduce=True時有效。爲True時,返回的loss爲平均值;爲False時,返回的各樣本的loss之和。
reduce(bool)- 返回值是否爲標量,默認爲True。

10.HingeEmbeddingLoss

class torch.nn.HingeEmbeddingLoss(margin=1.0, size_average=None, reduce=None, reduction=‘elementwise_mean’)
功能:
未知。爲摺頁損失的拓展,主要用於衡量兩個輸入是否相似。 used for learning nonlinear embeddings or semi-supervised 。
計算公式:
在這裏插入圖片描述
參數:
margin(float)- 默認值爲1,容忍的差距。
size_average(bool)- 當reduce=True時有效。爲True時,返回的loss爲平均值;爲False時,返回的各樣本的loss之和。
reduce(bool)- 返回值是否爲標量,默認爲True。

11.MultiLabelMarginLoss

class torch.nn.MultiLabelMarginLoss(size_average=None, reduce=None, reduction=‘elementwise_mean’)
功能:
用於一個樣本屬於多個類別時的分類任務。例如一個四分類任務,樣本x屬於第0類,第1類,不屬於第2類,第3類。
計算公式:
在這裏插入圖片描述
x[y[j]] 表示 樣本x所屬類的輸出值,x[i]表示不等於該類的輸出值。

參數:
size_average(bool)- 當reduce=True時有效。爲True時,返回的loss爲平均值;爲False時,返回的各樣本的loss之和。
reduce(bool)- 返回值是否爲標量,默認爲True。
Input: © or (N,C) where N is the batch size and C is the number of classes.
Target: © or (N,C), same shape as the input.

12.SmoothL1Loss

class torch.nn.SmoothL1Loss(size_average=None, reduce=None, reduction=‘elementwise_mean’)
功能:
計算平滑L1損失,屬於 Huber Loss中的一種(因爲參數δ固定爲1了)。
補充:
Huber Loss常用於迴歸問題,其最大的特點是對離羣點(outliers)、噪聲不敏感,具有較強的魯棒性。
公式爲:
在這裏插入圖片描述
理解爲,當誤差絕對值小於δ,採用L2損失;若大於δ,採用L1損失。
回到SmoothL1Loss,這是δ=1時的Huber Loss。
計算公式爲:
在這裏插入圖片描述
對應下圖紅色線:
在這裏插入圖片描述
參數:
size_average(bool)- 當reduce=True時有效。爲True時,返回的loss爲平均值;爲False時,返回的各樣本的loss之和。
reduce(bool)- 返回值是否爲標量,默認爲True。

13.SoftMarginLoss

class torch.nn.SoftMarginLoss(size_average=None, reduce=None, reduction=‘elementwise_mean’)
功能:
Creates a criterion that optimizes a two-class classification logistic loss between input tensor xand target tensor y (containing 1 or -1). (暫時看不懂怎麼用,有了解的朋友歡迎補充!)
計算公式:
在這裏插入圖片描述
參數:
size_average(bool)- 當reduce=True時有效。爲True時,返回的loss爲平均值;爲False時,返回的各樣本的loss之和。
reduce(bool)- 返回值是否爲標量,默認爲True。

14.MultiLabelSoftMarginLoss

class torch.nn.MultiLabelSoftMarginLoss(weight=None, size_average=None, reduce=None, reduction=‘elementwise_mean’)
功能:
SoftMarginLoss多標籤版本,a multi-label one-versus-all loss based on max-entropy,
計算公式:
在這裏插入圖片描述
參數:
weight(Tensor)- 爲每個類別的loss設置權值。weight必須是float類型的tensor,其長度要於類別C一致,即每一個類別都要設置有weight。

15.CosineEmbeddingLoss

class torch.nn.CosineEmbeddingLoss(margin=0, size_average=None, reduce=None, reduction=‘elementwise_mean’)
功能:
用Cosine函數來衡量兩個輸入是否相似。 used for learning nonlinear embeddings or semi-supervised 。
計算公式:
在這裏插入圖片描述
參數:
margin(float)- : 取值範圍[-1,1], 推薦設置範圍 [0, 0.5]
size_average(bool)- 當reduce=True時有效。爲True時,返回的loss爲平均值;爲False時,返回的各樣本的loss之和。
reduce(bool)- 返回值是否爲標量,默認爲True。

16.MultiMarginLoss

class torch.nn.MultiMarginLoss(p=1, margin=1, weight=None, size_average=None, reduce=None, reduction=‘elementwise_mean’)
功能:
計算多分類的摺頁損失。
計算公式:
在這裏插入圖片描述
其中,0≤y≤x.size(1) ; i == 0 to x.size(0) and i≠y; p==1 or p ==2; w[y]爲各類別的weight。
參數:
p(int)- 默認值爲1,僅可選1或者2。
margin(float)- 默認值爲1
weight(Tensor)- 爲每個類別的loss設置權值。weight必須是float類型的tensor,其長度要於類別C一致,即每一個類別都要設置有weight。
size_average(bool)- 當reduce=True時有效。爲True時,返回的loss爲平均值;爲False時,返回的各樣本的loss之和。
reduce(bool)- 返回值是否爲標量,默認爲True。

17.TripletMarginLoss

class torch.nn.TripletMarginLoss(margin=1.0, p=2, eps=1e-06, swap=False, size_average=None, reduce=None, reduction=‘elementwise_mean’)
功能:
計算三元組損失,人臉驗證中常用。
如下圖Anchor、Negative、Positive,目標是讓Positive元和Anchor元之間的距離儘可能的小,Positive元和Negative元之間的距離儘可能的大。
在這裏插入圖片描述
從公式上看,Anchor元和Positive元之間的距離加上一個threshold之後,要小於Anchor元與Negative元之間的距離。
在這裏插入圖片描述
計算公式:
在這裏插入圖片描述

參數:
margin(float)- 默認值爲1
p(int)- The norm degree ,默認值爲2
swap(float)– The distance swap is described in detail in the paper Learning shallow convolutional feature descriptors with triplet losses by V. Balntas, E. Riba et al. Default: False
size_average(bool)- 當reduce=True時有效。爲True時,返回的loss爲平均值;爲False時,返回的各樣本的loss之和。
reduce(bool)- 返回值是否爲標量,默認爲True。


轉載請註明出處:https://blog.csdn.net/u011995719/article/details/85107524

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章