Pytorch详解NLLLoss和CrossEntropyLoss、以及softmax和log_softmax
數據
import torch import torch.nn.functional as F import numpy as np# 隨機新建3個樣例數據,每個樣例數據包含4個屬性特征 input = torch.randn(3,4) tensor([[ 0.0054, -0.8030, -0.5758, -0.6518],[-0.5518, 0.3904, 0.5296, 0.4973],[ 0.1608, 0.5822, 0.9536, -0.3173]])softmax
使用softmax對數據進行處理:
F.softmax(input, dim=1)dim=1表示跨列操作,行數不變。輸出結果:
tensor([[0.3963, 0.1766, 0.2216, 0.2054],[0.1067, 0.2738, 0.3147, 0.3047],[0.1868, 0.2847, 0.4127, 0.1158]])每一行元素相加為1.
log_softmax
使用log_softmax進行處理:
F.log_softmax(input, dim=1)輸出結果:
tensor([[-0.9255, -1.7339, -1.5067, -1.5827],[-2.2375, -1.2953, -1.1561, -1.1883],[-1.6778, -1.2564, -0.8850, -2.1558]])softmax和log_softmax聯系
log_softmax相當于對softmax做了log操作,下面進行驗證:
# 首先將tensor類型轉為numpy類型 np_data = F.softmax(input, dim=1).data.numpy() np.log(np_data)輸出結果為:
array([[-0.9255125 , -1.7338518 , -1.5066911 , -1.5826656 ],[-2.2374916 , -1.2952974 , -1.1560525 , -1.1883242 ],[-1.6778362 , -1.2563533 , -0.88496906, -2.155847 ]],dtype=float32)可以看出與log_softmax的結果一致,log_softmax就是對softmax的結果做了log。
softmax將數值壓縮至0~1,而log_softmax將數據壓縮至負無窮~0
NLLLoss
NLLLoss的結果就是把上面的輸出與Label對應的那個值拿出來,再去掉負號,再求均值。
NLLLoss的輸入是一個log_softmax和一個目標label。
假設我們的數據正確的label是[0,2,3],第一行取第0個元素,第二行取第2個,第三行取第3個,去掉負號,得到[0.9255125,1.1560525,2.155847],然后求平均,結果是:(0.9255125+1.1560525 + 2.155847)/3=1.4124706666666667
下面使用NLLLoss函數驗證一下:
target = torch.tensor([0,2,3]) loss = F.nll_loss(F.log_softmax(input, dim=1),target)得到loss=tensor(1.4125)
結果一致。
CrossEntropyLoss
交叉熵的計算公式為:
crossentropy=?∑k=1N(pk?logqk)cross_entropy=-\sum_{k=1}^N(p_k*log q_k) crosse?ntropy=?k=1∑N?(pk??logqk?)
其中ppp表示真實值,在這個公式中是one-hot形式;qqq是預測值,在這里假設已經是經過softmaxsoftmaxsoftmax后的結果了。
仔細觀察可以知道,因為ppp的元素不是0就是1,而且又是乘法,所以很自然地我們如果知道1所對應的index,那么就不用做其他無意義的運算了。所以在pytorch代碼中target不是以one-hot形式表示的,而是直接用scalar表示。所以交叉熵的公式(m表示真實類別)可變形為:
cross_entropy=?∑k=1N(pk?logqk)=?∑k=1Nqmcross\_entropy=-\sum_{k=1}^N(p_k*log q_k)=-\sum_{k=1}^Nq_m cross_entropy=?k=1∑N?(pk??logqk?)=?k=1∑N?qm?
仔細看看,是不是就是等同于log_softmax和nll_loss兩個步驟。
CrossEntropyLoss就是把以上Softmax–Log–NLLLoss合并成一步,我們用剛剛隨機出來的input直接驗證一下結果是不是1.4125:
F.cross_entropy(input,target)輸出結果為tensor(1.4125),結果一致
總結
以上是生活随笔為你收集整理的Pytorch详解NLLLoss和CrossEntropyLoss、以及softmax和log_softmax的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 小米电视4怎样外接音响
- 下一篇: 三个肾是怎么回事