Pytorch BCELoss和BCEWithLogitsLoss的使用
BCELoss
在圖片多標(biāo)簽分類時,如果3張圖片分3類,會輸出一個3*3的矩陣。
先用Sigmoid給這些值都搞到0~1之間:
假設(shè)Target是:
下面我們用BCELoss來驗證一下Loss是不是0.7194!
emmm應(yīng)該是我上面每次都保留4位小數(shù),算到最后誤差越來越大差了0.0001。不過也很厲害啦哈哈哈哈哈!
BCEWithLogitsLoss
BCEWithLogitsLoss就是把Sigmoid-BCELoss合成一步。我們直接用剛剛的input驗證一下是不是0.7193:
嘻嘻,我可真是太厲害啦!
補充:Pytorch中BCELoss,BCEWithLogitsLoss和CrossEntropyLoss的區(qū)別
BCEWithLogitsLoss = Sigmoid+BCELoss
當(dāng)網(wǎng)絡(luò)最后一層使用nn.Sigmoid時,就用BCELoss,當(dāng)網(wǎng)絡(luò)最后一層不使用nn.Sigmoid時,就用BCEWithLogitsLoss。
(BCELoss)BCEWithLogitsLoss
用于單標(biāo)簽二分類或者多標(biāo)簽二分類,輸出和目標(biāo)的維度是(batch,C),batch是樣本數(shù)量,C是類別數(shù)量,對于每一個batch的C個值,對每個值求sigmoid到0-1之間,所以每個batch的C個值之間是沒有關(guān)系的,相互獨立的,所以之和不一定為1。
每個C值代表屬于一類標(biāo)簽的概率。如果是單標(biāo)簽二分類,那輸出和目標(biāo)的維度是(batch,1)即可。
CrossEntropyLoss用于多類別分類
輸出和目標(biāo)的維度是(batch,C),batch是樣本數(shù)量,C是類別數(shù)量,每一個C之間是互斥的,相互關(guān)聯(lián)的,對于每一個batch的C個值,一起求每個C的softmax,所以每個batch的所有C個值之和是1,哪個值大,代表其屬于哪一類。如果用于二分類,那輸出和目標(biāo)的維度是(batch,2)。
補充:Pytorch踩坑記之交叉熵(nn.CrossEntropy,nn.NLLLoss,nn.BCELoss的區(qū)別和使用)
在Pytorch中的交叉熵函數(shù)的血淚史要從nn.CrossEntropyLoss()這個損失函數(shù)開始講起。
從表面意義上看,這個函數(shù)好像是普通的交叉熵函數(shù),但是如果你看過一些Pytorch的資料,會告訴你這個函數(shù)其實是softmax()和交叉熵的結(jié)合體。
然而如果去官方看這個函數(shù)的定義你會發(fā)現(xiàn)是這樣子的:
哇,竟然是nn.LogSoftmax()和nn.NLLLoss()的結(jié)合體,這倆都是什么玩意兒啊。再看看你會發(fā)現(xiàn)甚至還有一個損失叫nn.Softmax()以及一個叫nn.nn.BCELoss()。我們來探究下這幾個損失到底有何種關(guān)系。
nn.Softmax和nn.LogSoftmax
首先nn.Softmax()官網(wǎng)的定義是這樣的:
嗯...就是我們認識的那個softmax。那nn.LogSoftmax()的定義也很直觀了:
果不其然就是Softmax取了個log。可以寫個代碼測試一下:
import torch import torch.nn as nn a = torch.Tensor([1,2,3]) #定義Softmax softmax = nn.Softmax() sm_a = softmax=nn.Softmax() print(sm) #輸出:tensor([0.0900, 0.2447, 0.6652]) #定義LogSoftmax logsoftmax = nn.LogSoftmax() lsm_a = logsoftmax(a) print(lsm_a) #輸出tensor([-2.4076, -1.4076, -0.4076]),其中l(wèi)n(0.0900)=-2.4076
nn.NLLLoss
上面說過nn.CrossEntropy()是nn.LogSoftmax()和nn.NLLLoss的結(jié)合,nn.NLLLoss官網(wǎng)給的定義是這樣的:
The negative log likelihood loss. It is useful to train a classification problem with C classes
負對數(shù)似然損失 ,看起來好像有點晦澀難懂,寫個代碼測試一下:
import torch import torch.nn a = torch.Tensor([[1,2,3]]) nll = nn.NLLLoss() target1 = torch.Tensor([0]).long() target2 = torch.Tensor([1]).long() target3 = torch.Tensor([2]).long() #測試 n1 = nll(a,target1) #輸出:tensor(-1.) n2 = nll(a,target2) #輸出:tensor(-2.) n3 = nll(a,target3) #輸出:tensor(-3.)
看起來nn.NLLLoss做的事情是取出a中對應(yīng)target位置的值并取負號,比如target1=0,就取a中index=0位置上的值再取負號為-1,那這樣做有什么意義呢,要結(jié)合nn.CrossEntropy往下看。
nn.CrossEntropy
看下官網(wǎng)給的nn.CrossEntropy()的表達式:
看起來應(yīng)該是softmax之后取了個對數(shù),寫個簡單代碼測試一下:
import torch import torch.nn as nn a = torch.Tensor([[1,2,3]]) target = torch.Tensor([2]).long() logsoftmax = nn.LogSoftmax() ce = nn.CrossEntropyLoss() nll = nn.NLLLoss() #測試CrossEntropyLoss cel = ce(a,target) print(cel) #輸出:tensor(0.4076) #測試LogSoftmax+NLLLoss lsm_a = logsoftmax(a) nll_lsm_a = nll(lsm_a,target) #輸出tensor(0.4076)
看來直接用nn.CrossEntropy和nn.LogSoftmax+nn.NLLLoss是一樣的結(jié)果。為什么這樣呢,回想下交叉熵的表達式:
其中y是label,x是prediction的結(jié)果,所以其實交叉熵損失就是負的target對應(yīng)位置的輸出結(jié)果x再取-log。這個計算過程剛好就是先LogSoftmax()再NLLLoss()。
------------------------------------
所以我認為nn.CrossEntropyLoss其實應(yīng)該叫做softmaxloss更為合理一些,這樣就不會誤解了。
nn.BCELoss
你以為這就完了嗎,其實并沒有。還有一類損失叫做BCELoss,寫全了的話就是Binary Cross Entropy Loss,就是交叉熵應(yīng)用于二分類時候的特殊形式,一般都和sigmoid一起用,表達式就是二分類交叉熵:
直覺上和多酚類交叉熵的區(qū)別在于,不僅考慮了的樣本,也考慮了
的樣本的損失。
總結(jié)
nn.LogSoftmax是在softmax的基礎(chǔ)上取自然對數(shù)nn.NLLLoss是負的似然對數(shù)損失,但Pytorch的實現(xiàn)就是把對應(yīng)target上的數(shù)取出來再加個負號,要在CrossEntropy中結(jié)合LogSoftmax來用BCELoss是二分類的交叉熵損失,Pytorch實現(xiàn)中和多分類有區(qū)別
Pytorch是個深坑,讓我們一起扎根使用手冊,結(jié)合實踐踏平這些坑吧暴風(fēng)哭泣。
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
Python實現(xiàn)監(jiān)控Nginx配置文件的不同并發(fā)送郵件報警功能示例
這篇文章主要介紹了Python實現(xiàn)監(jiān)控Nginx配置文件的不同并發(fā)送郵件報警功能,涉及Python基于difflib模塊的文件比較及smtplib模塊的郵件發(fā)送相關(guān)操作技巧,需要的朋友可以參考下2019-02-02IPython庫中的display函數(shù)的簡介、使用方法、應(yīng)用案例詳細攻略
display 函數(shù)可以接受一個或多個參數(shù),每個參數(shù)都是一個 Python 對象。它會自動根據(jù)對象的類型選擇合適的顯示方式,并在 Jupyter Notebook 中顯示出來,這篇文章主要介紹了IPython庫中的display函數(shù)的簡介、使用方法、應(yīng)用案例詳細攻略,需要的朋友可以參考下2023-04-04python內(nèi)建類型與標(biāo)準(zhǔn)類型
這篇文章主要介紹了python內(nèi)建類型與標(biāo)準(zhǔn)類型,文章圍繞主題展開詳細的內(nèi)容介紹,具有一定的參考價值,需要的小伙伴可以參考一下2022-08-08合并Excel工作薄中成績表的VBA代碼,非常適合教育一線的朋友
每次學(xué)生考試,評分完畢之后,把每個科的成績收集起來,就得到了一個有若干工作表,每個表有學(xué)生學(xué)號、分?jǐn)?shù)等列的Excel工作薄。2009-04-04