Pytorch loss 函数详解

Pytorch loss 函数详解,第1张

Pytorch loss 函数详解

reduce参数如果为True,计算结果“坍缩”,"坍缩"方法有两种:求和(size_average=False)与平均(size_average=True)

1. torch.nn.L1Loss   (MAE:Mean Absolute Error)

计算绝对值差的总和,输入输出的维度应该相同

loss = torch.nn.L1Loss(reduce=False, size_average=False)
loss(torch.tensor([1.,2.]),torch.tensor([3.,4.]))  # tensor([2., 2.])  3-1=2,4-2=2

loss = torch.nn.L1Loss(reduce=True, size_average=False)
loss(torch.tensor([1.,2.]),torch.tensor([3.,4.]))  # tensor(4.)  (3-1)+(4-2)=4

loss = torch.nn.L1Loss(reduce=True, size_average=True)
loss(torch.tensor([1.,2.]),torch.tensor([3.,4.]))  # tensor(2.)   [(3-1)+(4-2)]/2=2

常用于回归任务和简单的模型

2.torch.nn.MSELoss  (也可以说是L2loss,MSE:mean-square error)

也要求输入输出的形状相同

loss = torch.nn.MSELoss(reduce=False, size_average=False)
loss(torch.tensor([1.,2.]),torch.tensor([3.,4.])) # tensor([4., 4.]) (3-1)^2=4

如果以输入为条件的目标数据正态分布在平均值附近,并且对异常值进行额外惩罚很重要,那么 MSE 非常适合使用。

3.torch.nn.SmoothL1Loss

它是L1 loss 与 L2 loss 的结合,在接近目标值的附近是L2 loss,相比L1更加平滑,在远离目标值的地方是L1,可以避免L2 loss的梯度爆炸

 4.torch.nn.BCELoss

以下loss适用于分类问题,使用交叉熵,其中p是真实概率分布,q为分真实分布,这里就是我们的预测分布

a = torch.tensor([-4, 4, 4, 0])
x = torch.sigmoid(a)                         # tensor([0.0180, 0.9820, 0.9820, 0.5000])
y = torch.FloatTensor([1, 0, 1, 1])          # tensor([1., 0., 1., 1.])
loss = torch.nn.BCELoss(reduce=False, size_average=False)
#   -1  *log(0.0180)  =4.0181   
# -(1-0)*log(1-0.9820)=4.0181    
loss(x, y)                                   # tensor([4.0181, 4.0181, 0.0181, 0.6931])

 请关注上面代码的注释部分,可以看到我们的输入数据要经过Sigmoid函数将其映射为概率的形式,我们x的每一个值都代表预测当前例子是“1”的概率,比如看x的第二个数据是0.98,代表模型有98%的确定性把该输入分类为“1”(2%的确定性把该输入分类为“0”),但是真实标签是0,所以交叉熵的p为(1-0)=1,代表当前数据是0的真实分布为100%,那么q就是(1-0.98),所以-(1-0)*log(1-0.9820)=4.0181即为答案所求

5.torch.nn.BCEWithLogitsLoss

不需要再手动计算sigmoid    (log_sum_exp trick)

x = torch.FloatTensor([-4, 4, 4, 0])
#x = torch.sigmoid(a)
y = torch.FloatTensor([1, 0, 1, 1])
loss = torch.nn.BCEWithLogitsLoss(reduce=False, size_average=False)
loss(x, y)         #tensor([4.0181, 4.0181, 0.0181, 0.6931])

可见答案与BCELoss相同

6.torch.nn.NLLLoss

为选中的元素添加负号

nllloss = torch.nn.NLLLoss( reduce=False,reduction='sum')
predict = torch.Tensor([[2, 3, 1],
                        [3, 7, 9]])
label = torch.tensor([1, 2])
loss=nllloss(predict, label)
print(loss)     #tensor([-3., -9.])

predict中[2,3,1]代表是类别1的“可能性”是2,是类别2的“可能性”是3,是类别3的“可能性”是1,label第一个元素是1,取predict中第一个元素加负号(输入必须是batch_size的形式)

7.torch.nn.CrossEntropyLoss

输入经过softmax,log后调用NLLLoss即是CrossEntropyLoss

nllloss = nn.NLLLoss()
predict = torch.Tensor([[2, 3, 1],
                        [3, 7, 9]])
predict = torch.log(torch.softmax(predict, dim=-1))
label = torch.tensor([1, 2])
nllloss(predict, label)
# output: tensor(0.2684)
cross_loss = nn.CrossEntropyLoss()

predict = torch.Tensor([[2, 3, 1],
                        [3, 7, 9]])
label = torch.tensor([1, 2])
cross_loss(predict, label)
# output: tensor(0.2684)

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/5480569.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-12
下一篇 2022-12-12

发表评论

登录后才能评论

评论列表(0条)

保存