Pytorch--新手入门,对于内置交叉熵损失函数torch.nn.CrossEntropyLoss()的了解

         对于pytorch的内置交叉熵损失函数torch.nn.CrossEntropyLoss(),其中的具体运算公式如下图所示:

         乍一看,看不懂,继续看,还是不理解?!别怕,具体带入数值进行流程解析!

        假设神经网络的输出(经过softmax概率化)为x=[0.2, 0.7, 0.1],假设是一个三分类问题三个输出,输入图像的标签为"1"--也就是公式中的”class“。

        带入到损失函数进行计算:

        接下来,我们到pycharm里验证以下: 

import torch
from torch import nn

input = torch.tensor([[0.2, 0.7, 0.1]])
#注意输入要是二维的矩阵--1*3,而不是一维的向量,具体可以看最左边方括号,有几个方括号就是几维
target = torch.tensor([1])  #target也必须是tensor类型的,不然会报错
print(target)
print(input)
loss = nn.CrossEntropyLoss()
output = loss(input, target)
print(output)

        输出结果:

tensor([1])
tensor([[0.2000, 0.7000, 0.1000]])
tensor(0.7679)

        咦,可以发现,代码运行的结果与我们公式计算的结果不同?为啥?

        其实,是因为log是自然对数,即--ln

        真实的计算过程如下:

         这样,就对了吧!!!

        另外,我想说一下,众所周知,交叉熵损失函数是利用神经网络输出的概率化和输入图像的标签作为输入,那如果没有将神经网络的输出概率化,直接输入到交叉熵损失函数会怎么样??

try一下吧!

import torch
from torch import nn

input = torch.tensor([[1.2, 2.4, 3.6]])
#注意输入要是二维的矩阵--1*3,而不是一维的向量,具体可以看最左边方括号,有几个方括号就是几维
target = torch.tensor([1])   #target也必须是tensor类型的,不然会报错
print(target)
print(input)
loss = nn.CrossEntropyLoss()
output = loss(input, target)
print(output)

        输出结果:

tensor([1])
tensor([[1.2000, 2.4000, 3.6000]])
tensor(1.5307)

        可以看到,我的输入改成了大于1的数,概率总和为1,已经超过了!

        但是pycharm并没有报错!

        所以,当你的多分类神经网络的最后一层没有进行softmax函数,直接送到交叉熵损失函数中,你跑的训练集和测试集程序正确率可能依然会有很高的正确率,因为nn.CrossEntropyLoss()函数已经将softmax包含进去了,是将softmax-log-NLLLoss合并到一块得到的结果,这就是加载pytorch编辑好的神经网络,而最后一层通常没有softmax函数原因。

        让我们看看具体的运算:

        nn.CrossEntropyLoss()=nn.LogSoftmax()+nn.NLLLoss()

        就是先执行nn.LogSoftmax(),再执行nn.NLLLoss()的结果。

        看代码:

import torch
from torch import nn
input1 = torch.tensor([[1.2, 2.4, 3.6]])
target = torch.tensor([1])
print(target)
print(input1)
loss1 = nn.LogSoftmax()
loss2 = nn.NLLLoss()
input2 = loss1(input1)
output = loss2(input2, target)
print(output)

        输出结果:

tensor([1])
D:UserWarning: Implicit dimension choice for log_softmax has been deprecated. Change the call to include dim=X as an argument.
  input2 = loss1(input1)
tensor([[1.2000, 2.4000, 3.6000]])
tensor(1.5307)
 

        为啥会警告嘞???Let us see see!

        【对于log_softmax的隐式维度选择已经被弃用。更改调用包含dim = X作为参数】

        看来,log_softmax已经被抛弃了,不是亲儿子了!!需要自己加上维度dim即可!

        代码更新:

import torch
from torch import nn
input1 = torch.tensor([[1.2, 2.4, 3.6]])
target = torch.tensor([1])
print(target)
print(input1)
loss1 = nn.LogSoftmax(dim=1)   #dim=1好像是按行进行计算,注意是好像,别骂!!!
loss2 = nn.NLLLoss()
input2 = loss1(input1)
output = loss2(input2, target)
print(output)

        结果如下:

tensor([1])
tensor([[1.2000, 2.4000, 3.6000]])
tensor(1.5307)

        这样就没有警告了!!!终于结束了,码字真累啊!!!赶紧溜!!!Bye!!!

  • 8
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值