PyTorch的十七个损失函数
20220113
選損失函數(shù)的標(biāo)準(zhǔn):能使得真實(shí)值和預(yù)測(cè)值越相近的時(shí)候總損失越小
20220303
機(jī)器學(xué)習(xí)大牛是如何選擇回歸損失函數(shù)的?
MSE,MAE,huber loss
20210925
交叉熵適合 標(biāo)簽為0和1的取值?
指數(shù)函數(shù)適合標(biāo)簽為-1和1的取值,意味著f(x)也在-1和1之間,如果預(yù)測(cè)和真實(shí)值都相等的話
則得到e的-1
20210620
機(jī)器學(xué)習(xí)常用損失函數(shù)小結(jié) - 知乎
深度學(xué)習(xí)常用損失函數(shù)總覽:基本形式、原理、特點(diǎn)
本文截取自《PyTorch 模型訓(xùn)練實(shí)用教程》,獲取全文pdf請(qǐng)點(diǎn)擊:
tensor-yu/PyTorch_Tutorial?github.com
版權(quán)聲明:本文為博主原創(chuàng)文章,轉(zhuǎn)載請(qǐng)附上博文鏈接!
我們所說(shuō)的優(yōu)化,即優(yōu)化網(wǎng)絡(luò)權(quán)值使得損失函數(shù)值變小。但是,損失函數(shù)值變小是否能代表模型的分類/回歸精度變高呢?那么多種損失函數(shù),應(yīng)該如何選擇呢?請(qǐng)來(lái)了解PyTorch中給出的十七種損失函數(shù)吧。
1.L1loss
2.MSELoss
3.CrossEntropyLoss
4.NLLLoss
5.PoissonNLLLoss
6.KLDivLoss
7.BCELoss
8.BCEWithLogitsLoss
9.MarginRankingLoss
10.HingeEmbeddingLoss
11.MultiLabelMarginLoss
12.SmoothL1Loss
13.SoftMarginLoss
14.MultiLabelSoftMarginLoss
15.CosineEmbeddingLoss
16.MultiMarginLoss
17.TripletMarginLoss
請(qǐng)運(yùn)行配套代碼,代碼中有詳細(xì)解釋,有手動(dòng)計(jì)算,這些都有助于理解損失函數(shù)原理。 本小節(jié)配套代碼: /Code/3_optimizer/3_1_lossFunction
1.L1loss
class torch.nn.L1Loss(size_average=None, reduce=None) 官方文檔中仍有reduction='elementwise_mean'參數(shù),但代碼實(shí)現(xiàn)中已經(jīng)刪除該參數(shù)
功能: 計(jì)算output和target之差的絕對(duì)值,可選返回同維度的tensor或者是一個(gè)標(biāo)量。
計(jì)算公式:
參數(shù): reduce(bool)- 返回值是否為標(biāo)量,默認(rèn)為True
size_average(bool)- 當(dāng)reduce=True時(shí)有效。為True時(shí),返回的loss為平均值;為False時(shí),返回的各樣本的loss之和。
實(shí)例: /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'參數(shù),但代碼實(shí)現(xiàn)中已經(jīng)刪除該參數(shù)
功能: 計(jì)算output和target之差的平方,可選返回同維度的tensor或者是一個(gè)標(biāo)量。
計(jì)算公式:
參數(shù): reduce(bool)- 返回值是否為標(biāo)量,默認(rèn)為True
size_average(bool)- 當(dāng)reduce=True時(shí)有效。為True時(shí),返回的loss為平均值;為False時(shí),返回的各樣本的loss之和。
實(shí)例: /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')
功能: 將輸入經(jīng)過(guò)softmax激活函數(shù)之后,再計(jì)算其與target的交叉熵?fù)p失。即該方法將nn.LogSoftmax()和 nn.NLLLoss()進(jìn)行了結(jié)合。嚴(yán)格意義上的交叉熵?fù)p失函數(shù)應(yīng)該是nn.NLLLoss()。
補(bǔ)充:小談交叉熵?fù)p失函數(shù) 交叉熵?fù)p失(cross-entropy Loss) 又稱為對(duì)數(shù)似然損失(Log-likelihood Loss)、對(duì)數(shù)損失;二分類時(shí)還可稱之為邏輯斯諦回歸損失(Logistic Loss)。交叉熵?fù)p失函數(shù)表達(dá)式為 L = - sigama(y_i * log(x_i))。pytroch這里不是嚴(yán)格意義上的交叉熵?fù)p失函數(shù),而是先將input經(jīng)過(guò)softmax激活函數(shù),將向量“歸一化”成概率形式,然后再與target計(jì)算嚴(yán)格意義上交叉熵?fù)p失。 在多分類任務(wù)中,經(jīng)常采用softmax激活函數(shù)+交叉熵?fù)p失函數(shù),因?yàn)榻徊骒孛枋隽藘蓚€(gè)概率分布的差異,然而神經(jīng)網(wǎng)絡(luò)輸出的是向量,并不是概率分布的形式。所以需要softmax激活函數(shù)將一個(gè)向量進(jìn)行“歸一化”成概率分布的形式,再采用交叉熵?fù)p失函數(shù)計(jì)算loss。 再回顧PyTorch的CrossEntropyLoss(),官方文檔中提到時(shí)將nn.LogSoftmax()和 nn.NLLLoss()進(jìn)行了結(jié)合,nn.LogSoftmax() 相當(dāng)于激活函數(shù) , nn.NLLLoss()是損失函數(shù),將其結(jié)合,完整的是否可以叫做softmax+交叉熵?fù)p失函數(shù)呢?
計(jì)算公式:
參數(shù): weight(Tensor)- 為每個(gè)類別的loss設(shè)置權(quán)值,常用于類別不均衡問(wèn)題。weight必須是float類型的tensor,其長(zhǎng)度要于類別C一致,即每一個(gè)類別都要設(shè)置有weight。帶weight的計(jì)算公式:
size_average(bool)- 當(dāng)reduce=True時(shí)有效。為True時(shí),返回的loss為平均值;為False時(shí),返回的各樣本的loss之和。 reduce(bool)- 返回值是否為標(biāo)量,默認(rèn)為True ignore_index(int)- 忽略某一類別,不計(jì)算其loss,其loss會(huì)為0,并且,在采用size_average時(shí),不會(huì)計(jì)算那一類的loss,除的時(shí)候的分母也不會(huì)統(tǒng)計(jì)那一類的樣本。
實(shí)例: /Code/3_optimizer/3_1_lossFunction/3_CroosEntropyLoss.py
補(bǔ)充: output不僅可以是向量,還可以是圖片,即對(duì)圖像進(jìn)行像素點(diǎn)的分類,這個(gè)例子可以從NLLLoss()中看到,這在圖像分割當(dāng)中很有用。
4.NLLLoss? 多分類
class torch.nn.NLLLoss(weight=None, size_average=None, ignore_index=-100, reduce=None, reduction='elementwise_mean')
功能: 不好用言語(yǔ)描述其功能!請(qǐng)看計(jì)算公式:loss(input, class) = -input[class]。舉個(gè)例,三分類任務(wù),input=[-1.233, 2.657, 0.534], 真實(shí)標(biāo)簽為2(class=2),則loss為-0.534。就是對(duì)應(yīng)類別上的輸出,取一個(gè)負(fù)號(hào)!感覺(jué)被NLLLoss的名字欺騙了。 實(shí)際應(yīng)用: 常用于多分類任務(wù),但是input在輸入NLLLoss()之前,需要對(duì)input進(jìn)行l(wèi)og_softmax函數(shù)激活,即將input轉(zhuǎn)換成概率分布的形式,并且取對(duì)數(shù)。其實(shí)這些步驟在CrossEntropyLoss中就有,如果不想讓網(wǎng)絡(luò)的最后一層是log_softmax層的話,就可以采用CrossEntropyLoss完全代替此函數(shù)。
參數(shù): weight(Tensor)- 為每個(gè)類別的loss設(shè)置權(quán)值,常用于類別不均衡問(wèn)題。weight必須是float類型的tensor,其長(zhǎng)度要于類別C一致,即每一個(gè)類別都要設(shè)置有weight。 size_average(bool)- 當(dāng)reduce=True時(shí)有效。為True時(shí),返回的loss為除以權(quán)重之和的平均值;為False時(shí),返回的各樣本的loss之和。
reduce(bool)- 返回值是否為標(biāo)量,默認(rèn)為True。
ignore_index(int)- 忽略某一類別,不計(jì)算其loss,其loss會(huì)為0,并且,在采用size_average時(shí),不會(huì)計(jì)算那一類的loss,除的時(shí)候的分母也不會(huì)統(tǒng)計(jì)那一類的樣本。
實(shí)例: /Code/3_optimizer/3_1_lossFunction/4_NLLLoss.py
特別注意: 當(dāng)帶上權(quán)值,reduce = True, size_average = True, 其計(jì)算公式為:
例如當(dāng)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.20.2 = - 0.24 loss = -0.36/(0.6+0.2) + -0.24/(0.6+0.2) = -0.75
NLLLoss CrossEntropyLoss Pytorch_kyle1314608的博客-CSDN博客
5.PoissonNLLLoss
class torch.nn.PoissonNLLLoss(log_input=True, full=False, size_average=None, eps=1e-08, reduce=None, reduction='elementwise_mean')
功能: 用于target服從泊松分布的分類任務(wù)。
計(jì)算公式:
參數(shù):
log_input(bool)- 為True時(shí),計(jì)算公式為:loss(input,target)=exp(input) - target * input; 為False時(shí),loss(input,target)=input - target * log(input+eps)
full(bool)- 是否計(jì)算全部的loss。
例如,當(dāng)采用斯特林公式近似階乘項(xiàng)時(shí),此為 target*log(target) - target+0.5?log(2πtarget) eps(float)- 當(dāng)log_input = False時(shí),用來(lái)防止計(jì)算log(0),而增加的一個(gè)修正項(xiàng)。即 loss(input,target)=input - target * log(input+eps)
size_average(bool)- 當(dāng)reduce=True時(shí)有效。為True時(shí),返回的loss為平均值;為False時(shí),返回的各樣本的loss之和。
reduce(bool)- 返回值是否為標(biāo)量,默認(rèn)為True
實(shí)例: /Code/3_optimizer/3_1_lossFunction/5_PoissonNLLLoss.py
6.KLDivLoss
class torch.nn.KLDivLoss(size_average=None, reduce=None, reduction='elementwise_mean')
功能: 計(jì)算input和target之間的KL散度( Kullback–Leibler divergence) 。
計(jì)算公式:
(后面有代碼手動(dòng)計(jì)算,證明計(jì)算公式確實(shí)是這個(gè),但是為什么沒(méi)有對(duì)x_n計(jì)算對(duì)數(shù)呢?)
補(bǔ)充:KL散度 KL散度( Kullback–Leibler divergence) 又稱為相對(duì)熵(Relative Entropy),用于描述兩個(gè)概率分布之間的差異。計(jì)算公式(離散時(shí)):
其中p表示真實(shí)分布,q表示p的擬合分布, D(P||Q)表示當(dāng)用概率分布q來(lái)擬合真實(shí)分布p時(shí),產(chǎn)生的信息損耗。這里的信息損耗,可以理解為損失,損失越低,擬合分布q越接近真實(shí)分布p。同時(shí)也可以從另外一個(gè)角度上觀察這個(gè)公式,即計(jì)算的是 p 與 q 之間的對(duì)數(shù)差在 p 上的期望值。 特別注意,D(p||q) ≠ D(q||p), 其不具有對(duì)稱性,因此不能稱為K-L距離。
信息熵 = 交叉熵 - 相對(duì)熵?從信息論角度觀察三者,其關(guān)系為信息熵 = 交叉熵 - 相對(duì)熵。在機(jī)器學(xué)習(xí)中,當(dāng)訓(xùn)練數(shù)據(jù)固定,最小化相對(duì)熵 D(p||q) 等價(jià)于最小化交叉熵 H(p,q) 。
參數(shù):
size_average(bool)- 當(dāng)reduce=True時(shí)有效。為True時(shí),返回的loss為平均值,平均值為element-wise的,而不是針對(duì)樣本的平均;為False時(shí),返回是各樣本各維度的loss之和。 reduce(bool)- 返回值是否為標(biāo)量,默認(rèn)為True。
使用注意事項(xiàng): 要想獲得真正的KL散度,需要如下操作:
1. reduce = True ;size_average=False
2. 計(jì)算得到的loss 要對(duì)batch進(jìn)行求平均
實(shí)例: /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')
功能: 二分類任務(wù)時(shí)的交叉熵計(jì)算函數(shù)。此函數(shù)可以認(rèn)為是nn.CrossEntropyLoss函數(shù)的特例。其分類限定為二分類,y必須是{0,1}。還需要注意的是,input應(yīng)該為概率分布的形式,這樣才符合交叉熵的應(yīng)用。所以在BCELoss之前,input一般為sigmoid激活層的輸出,官方例子也是這樣給的。該損失函數(shù)在自編碼器中常用。 計(jì)算公式:
參數(shù):
weight(Tensor)- 為每個(gè)類別的loss設(shè)置權(quán)值,常用于類別不均衡問(wèn)題。
size_average(bool)- 當(dāng)reduce=True時(shí)有效。為True時(shí),返回的loss為平均值;為False時(shí),返回的各樣本的loss之和。
reduce(bool)- 返回值是否為標(biāo)量,默認(rèn)為True
8.BCEWithLogitsLoss
class torch.nn.BCEWithLogitsLoss(weight=None, size_average=None, reduce=None, reduction='elementwise_mean', pos_weight=None)
功能: 將Sigmoid與BCELoss結(jié)合,類似于CrossEntropyLoss(將nn.LogSoftmax()和 nn.NLLLoss()進(jìn)行結(jié)合)。即input會(huì)經(jīng)過(guò)Sigmoid激活函數(shù),將input變成概率分布的形式。 計(jì)算公式:
σ() 表示Sigmoid函數(shù) 特別地,當(dāng)設(shè)置weight時(shí):
參數(shù):
weight(Tensor)- : 為batch中單個(gè)樣本設(shè)置權(quán)值,If given, has to be a Tensor of size “nbatch”.
pos_weight-: 正樣本的權(quán)重, 當(dāng)p>1,提高召回率,當(dāng)P<1,提高精確度。可達(dá)到權(quán)衡召回率(Recall)和精確度(Precision)的作用。 Must be a vector with length equal to the number of classes.
size_average(bool)- 當(dāng)reduce=True時(shí)有效。為True時(shí),返回的loss為平均值;為False時(shí),返回的各樣本的loss之和。
reduce(bool)- 返回值是否為標(biāo)量,默認(rèn)為True
9.MarginRankingLoss
class torch.nn.MarginRankingLoss(margin=0, size_average=None, reduce=None, reduction='elementwise_mean')
功能: 計(jì)算兩個(gè)向量之間的相似度,當(dāng)兩個(gè)向量之間的距離大于margin,則loss為正,小于margin,loss為0。
計(jì)算公式:
y == 1時(shí),x1要比x2大,才不會(huì)有l(wèi)oss,反之,y == -1 時(shí),x1要比x2小,才不會(huì)有l(wèi)oss。
參數(shù): margin(float)- x1和x2之間的差異。
size_average(bool)- 當(dāng)reduce=True時(shí)有效。為True時(shí),返回的loss為平均值;為False時(shí),返回的各樣本的loss之和。
reduce(bool)- 返回值是否為標(biāo)量,默認(rèn)為True。
10.HingeEmbeddingLoss
class torch.nn.HingeEmbeddingLoss(margin=1.0, size_average=None, reduce=None, reduction='elementwise_mean')
功能: 未知。為折頁(yè)損失的拓展,主要用于衡量?jī)蓚€(gè)輸入是否相似。 used for learning nonlinear embeddings or semi-supervised 。 計(jì)算公式:
參數(shù):
margin(float)- 默認(rèn)值為1,容忍的差距。
size_average(bool)- 當(dāng)reduce=True時(shí)有效。為True時(shí),返回的loss為平均值;為False時(shí),返回的各樣本的loss之和。
reduce(bool)- 返回值是否為標(biāo)量,默認(rèn)為True。
11.MultiLabelMarginLoss
class torch.nn.MultiLabelMarginLoss(size_average=None, reduce=None, reduction='elementwise_mean')
功能: 用于一個(gè)樣本屬于多個(gè)類別時(shí)的分類任務(wù)。例如一個(gè)四分類任務(wù),樣本x屬于第0類,第1類,不屬于第2類,第3類。 計(jì)算公式:
x[y[j]] 表示 樣本x所屬類的輸出值,x[i]表示不等于該類的輸出值。
參數(shù):
size_average(bool)- 當(dāng)reduce=True時(shí)有效。為True時(shí),返回的loss為平均值;為False時(shí),返回的各樣本的loss之和。
reduce(bool)- 返回值是否為標(biāo)量,默認(rèn)為True。 Input: (C) or (N,C) where N is the batch size and C is the number of classes. Target: (C) or (N,C), same shape as the input.
12.SmoothL1Loss
class torch.nn.SmoothL1Loss(size_average=None, reduce=None, reduction='elementwise_mean')
功能: 計(jì)算平滑L1損失,屬于 Huber Loss中的一種(因?yàn)閰?shù)δ固定為1了)。
補(bǔ)充: Huber Loss常用于回歸問(wèn)題,其最大的特點(diǎn)是對(duì)離群點(diǎn)(outliers)、噪聲不敏感,具有較強(qiáng)的魯棒性。 公式為:
理解為,當(dāng)誤差絕對(duì)值小于δ,采用L2損失;若大于δ,采用L1損失。 回到SmoothL1Loss,這是δ=1時(shí)的Huber Loss。 計(jì)算公式為:
對(duì)應(yīng)下圖紅色線:
參數(shù): size_average(bool)- 當(dāng)reduce=True時(shí)有效。為True時(shí),返回的loss為平均值;為False時(shí),返回的各樣本的loss之和。 reduce(bool)- 返回值是否為標(biāo)量,默認(rèn)為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). (暫時(shí)看不懂怎么用,有了解的朋友歡迎補(bǔ)充!)
計(jì)算公式:
參數(shù): size_average(bool)- 當(dāng)reduce=True時(shí)有效。為True時(shí),返回的loss為平均值;為False時(shí),返回的各樣本的loss之和。 reduce(bool)- 返回值是否為標(biāo)量,默認(rèn)為True。
14.MultiLabelSoftMarginLoss
class torch.nn.MultiLabelSoftMarginLoss(weight=None, size_average=None, reduce=None, reduction='elementwise_mean')
功能: SoftMarginLoss多標(biāo)簽版本,a multi-label one-versus-all loss based on max-entropy,
計(jì)算公式:
參數(shù): weight(Tensor)- 為每個(gè)類別的loss設(shè)置權(quán)值。weight必須是float類型的tensor,其長(zhǎng)度要于類別C一致,即每一個(gè)類別都要設(shè)置有weight。
15.CosineEmbeddingLoss
class torch.nn.CosineEmbeddingLoss(margin=0, size_average=None, reduce=None, reduction='elementwise_mean')
功能: 用Cosine函數(shù)來(lái)衡量?jī)蓚€(gè)輸入是否相似。 used for learning nonlinear embeddings or semi-supervised 。
計(jì)算公式:
參數(shù):
margin(float)- : 取值范圍[-1,1], 推薦設(shè)置范圍 [0, 0.5]
size_average(bool)- 當(dāng)reduce=True時(shí)有效。為True時(shí),返回的loss為平均值;為False時(shí),返回的各樣本的loss之和。
reduce(bool)- 返回值是否為標(biāo)量,默認(rèn)為True。
16.MultiMarginLoss
class torch.nn.MultiMarginLoss(p=1, margin=1, weight=None, size_average=None, reduce=None, reduction='elementwise_mean')
功能: 計(jì)算多分類的折頁(yè)損失。
計(jì)算公式:
其中,0≤y≤x.size(1) ; i == 0 to x.size(0) and i≠y; p==1 or p ==2; w[y]為各類別的weight。
參數(shù):
p(int)- 默認(rèn)值為1,僅可選1或者2。
margin(float)- 默認(rèn)值為1
weight(Tensor)- 為每個(gè)類別的loss設(shè)置權(quán)值。weight必須是float類型的tensor,其長(zhǎng)度要于類別C一致,即每一個(gè)類別都要設(shè)置有weight。
size_average(bool)- 當(dāng)reduce=True時(shí)有效。為True時(shí),返回的loss為平均值;為False時(shí),返回的各樣本的loss之和。
reduce(bool)- 返回值是否為標(biāo)量,默認(rèn)為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')
功能: 計(jì)算三元組損失,人臉驗(yàn)證中常用。 如下圖Anchor、Negative、Positive,目標(biāo)是讓Positive元和Anchor元之間的距離盡可能的小,Positive元和Negative元之間的距離盡可能的大。
從公式上看,Anchor元和Positive元之間的距離加上一個(gè)threshold之后,要小于Anchor元與Negative元之間的距離。
計(jì)算公式:
參數(shù):
margin(float)- 默認(rèn)值為1
p(int)- The norm degree ,默認(rèn)值為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)- 當(dāng)reduce=True時(shí)有效。為True時(shí),返回的loss為平均值;為False時(shí),返回的各樣本的loss之和。 reduce(bool)- 返回值是否為標(biāo)量,默認(rèn)為True。
log 部分相當(dāng)概率 整體相當(dāng)于求二者的平均概率?
總結(jié)
以上是生活随笔為你收集整理的PyTorch的十七个损失函数的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: pytorch之Tensor与Varia
- 下一篇: 深度学总结:skip-gram pyto