pytorch的八種損失函數測試

1 L1Loss
創建一個標準來測量標準中每個元素之間的平均絕對誤差(MAE)輸入:math:x和目標:mat​​h:y
在這裏插入圖片描述
where :math:N is the batch size. If :attr:reduction is not 'none'(default 'mean')

import torch.nn as nn
import torch
lossfun=nn.L1Loss()
input=torch.randn(3,5,requires_grad=True)
print(input)
target=torch.randn(3,5)
print(target)
output=lossfun(input,target)
print(output)

輸出:

tensor([[ 0.7341,  0.8461,  0.4790, -0.9401, -0.4948],
        [-0.2035, -0.9376,  1.4283, -0.6767, -0.8932],
        [-0.7168,  0.5816, -0.7438,  0.7729, -1.3174]], requires_grad=True)
tensor([[ 0.5610, -0.6015, -1.0363, -0.8383, -0.7778],
        [-0.3118, -0.0527,  1.6309, -0.1973, -0.9312],
        [-0.2851,  1.9037,  0.1077, -0.2446,  0.4352]])
tensor(0.7073, grad_fn=<L1LossBackward>)

由此我們可以看出L1損失函數的輸入和輸出的維度是相同的,是直接使用兩個向量的對應的元素想減得到最後的誤差,例如 |x1-y1|。

2、NLLLoss

負對數似然損失。用C類訓練分類問題很有用。這裏的C是分類數目。
在這裏插入圖片描述

m=nn.LogSoftmax(dim=1)
loss=nn.NLLLoss()
input=torch.randn(3,5,requires_grad=True)
print(input)
target=torch.tensor([1,0,4])
print(m(input))
output=loss(m(input),target)
print(output)

輸出:

tensor([[-0.0511,  0.8704, -0.8625, -0.1377,  1.0202],
        [ 0.7554, -0.1908,  0.2453, -0.0432,  1.4448],
        [-0.3516, -0.2297,  0.1724,  0.3413, -1.3402]], requires_grad=True)
tensor([[-2.0533, -1.1318, -2.8647, -2.1399, -0.9820],
        [-1.4887, -2.4349, -1.9988, -2.2872, -0.7992],
        [-1.8230, -1.7010, -1.2990, -1.1300, -2.8115]],
       grad_fn=<LogSoftmaxBackward>)
tensor(1.8107, grad_fn=<NllLossBackward>)

LogSoftmax就是輸入數據在softmax之後取一個對數,輸出的數值都在0~1之間,求的是一個概率。
NLLLoss的結果就是把上面的輸出與Label對應的那個值拿出來,再將取出的值去掉負號,再求均值。
注意以上的“與Label對應的那個值”指的是位置的對應,而不是數值上的接近。
如上的的標籤爲(1,0,4),就分別取出第一行的第二個數,第二行的第一個數,第三行的第五個數。即(1.1318+1.4887+2.8115)/3=1.8107。

3、PoissonNLLLoss

目標的泊松分佈具有負對數似然損失。
在這裏插入圖片描述

loss=nn.PoissonNLLLoss()
log_input=torch.randn(5,2,requires_grad=True)
print(log_input)
target=torch.randn(5,2)
print(target)
output=loss(log_input,target)
print(output)

輸出:

tensor([[ 1.1679, -0.0214],
        [-0.8557, -0.0265],
        [ 0.9068,  0.7410],
        [ 2.1148, -0.3213],
        [-0.1708, -1.1462]], requires_grad=True)
tensor([[-0.2232,  0.8796],
        [-0.1447, -1.0068],
        [ 0.7258, -1.8143],
        [-1.0545,  1.1487],
        [-0.9435, -1.4581]])
tensor(2.1924, grad_fn=<MeanBackward1>)

查看實現源碼之後,還是沒能知道具體的實現步驟,發現如上申明的PoissonNLLLoss 中的計算代碼時:
loss = torch.exp(input) - target * input
ret = torch.mean(loss)
如有知曉具體解答過程的,望解答。

4、KLDivLoss

KL散度,也叫相對熵,是用於連續分佈的有用距離度量,並且在對(離散採樣)連續輸出分佈的空間進行直接回歸時通常很有用。
在這裏插入圖片描述
主要參數reduction中,除了經典的三個以外,還多出了batchmean這一選項,如果給reduction賦值爲’batchmean’,那麼就代表着在batchsize維度求平均值(就是計算得到的每一個元素的損失全部加起來之後除以batchsize,而不是mean計算方法下的元素個數)。

inputs=torch.tensor([[0.5,0.3,0.2],[0.2,0.3,0.5]])
target=torch.tensor([[0.9,0.05,0.05],[0.1,0.7,0.2]],dtype=torch.float)
loss_f_none=nn.KLDivLoss(reduction='none')
loss_f_mean=nn.KLDivLoss(reduction='mean')
loss_f_bs_mean=nn.KLDivLoss(reduction='batchmean')
loss_none=loss_f_none(inputs,target)
loss_mean=loss_f_mean(inputs,target)
loss_bs_mean=loss_f_bs_mean(inputs,target)
print("loss_none:\n{}\nloss_mean:\n{}\nloss_bs_mean:\n{}".format(loss_none, loss_mean, loss_bs_mean))

輸出:

loss_none:
tensor([[-0.5448, -0.1648, -0.1598],
        [-0.2503, -0.4597, -0.4219]])
loss_mean:
-0.3335360586643219
loss_bs_mean:
-1.000608205795288

5、MSELoss

創建一個標準來測量輸入:math:x和目標:mat​​h:`y中每個元素之間的均方誤差(L2範數平方)在這裏插入圖片描述

lossfun=nn.MSELoss()
lossfun1=nn.MSELoss(reduction='none')
input=torch.randn(3,5,requires_grad=True)
print(input)
target=torch.randn(3,5)
print(target)
output=lossfun(input,target)
print(output)
output=lossfun1(input,target)
print(output)

輸出:

tensor([[-1.0748, -0.7300, -0.7085,  1.4914,  1.5150],
        [ 0.7312, -1.6615,  0.8111,  1.7772,  1.0513],
        [ 0.9700, -0.7969, -1.0133, -0.5023,  0.3190]], requires_grad=True)
tensor([[-1.6405,  1.9781, -0.7997, -1.3708, -1.4618],
        [ 0.0414,  0.5810, -0.1028,  0.4886, -0.3905],
        [-0.2697,  1.0235, -1.3026,  3.2425, -0.2109]])
tensor(3.6022, grad_fn=<MseLossBackward>)
tensor([[3.2006e-01, 7.3339e+00, 8.3100e-03, 8.1922e+00, 8.8612e+00],
        [4.7579e-01, 5.0289e+00, 8.3517e-01, 1.6605e+00, 2.0787e+00],
        [1.5369e+00, 3.3140e+00, 8.3715e-02, 1.4023e+01, 2.8076e-01]],
       grad_fn=<MseLossBackward>)

第三個輸出的reduction爲默認的“mean”,給第四個輸出取了平均值。我們來根據公式計算這個對應的損失值。(x1-y1)2=(-1.0748+1.6405)2=0.320001649.

6、BCELoss

創建一個標準,用於測量目標和輸出之間的二進制交叉熵:
在這裏插入圖片描述

m=nn.Sigmoid()
loss=nn.BCELoss()
loss1=nn.BCELoss(reduction='none')
input=torch.randn(3,requires_grad=True)
print(input)
target=torch.empty(3).random_(2)
print(target)
print(m(input))
output=loss(m(input),target)
print(output)
output=loss1(m(input),target)
print(output)

輸出:

tensor([-0.1348, -0.2154,  0.1736], requires_grad=True)
tensor([1., 1., 1.])
tensor([0.4663, 0.4464, 0.5433], grad_fn=<SigmoidBackward>)
tensor(0.7265, grad_fn=<BinaryCrossEntropyBackward>)
tensor([0.7628, 0.8066, 0.6101], grad_fn=<BinaryCrossEntropyBackward>)

將x1和y1帶入上面的公式去計算,發現l1=-W1[-0.33133]。至於W1是多少,我就不得而知了。

7、CrossEntropyLoss

該標準將nn.LogSoftmax和nn.NLLLoss合併到一個類中。
在這裏插入圖片描述

loss=nn.CrossEntropyLoss()
input=torch.randn(3,5,requires_grad=True)
print(input)
target=torch.empty(3,dtype=torch.long).random_(5)
print(target)
output=loss(input,target)
print(output)

輸出:

tensor([[ 1.1205, -0.7146,  0.2124, -0.3854, -0.5209],
        [-1.4408, -1.5053, -1.4333, -1.7397, -0.3800],
        [-0.6021,  0.6240, -0.1252, -0.3854, -1.0135]], requires_grad=True)
tensor([1, 1, 4])
tensor(2.3155, grad_fn=<NllLossBackward>)

這個函數和NLLLoss()的區別在於就是不用自己申明一個nn.Logsoftmax().

8、SoftMarginLoss
創建一個標準,優化輸入張量:math:x和目標張量:math:`y(包含1或-1)之間的兩類分類邏輯損失。
在這裏插入圖片描述

inputs = torch.tensor([[0.3, 0.7], [0.5, 0.5]])
target = torch.tensor([[-1, 1], [1, -1]], dtype=torch.float)

loss_f = nn.SoftMarginLoss(reduction='none')
loss = loss_f(inputs, target)

print("SoftMargin: ", loss)
SoftMargin:  tensor([[0.8544, 0.4032],
        [0.4741, 0.9741]])

參考文獻:

Pytorch詳解NLLLoss和CrossEntropyLoss
Pytorch的各種損失函數
18種損失函數全詳解及其PyTorch實現與機制

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