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实现与机制

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值