当前位置:   article > 正文

损失函数:交叉熵损失torch.nn.CrossEntropyLoss_torch.nn.crossentropyloss()

torch.nn.crossentropyloss()

交叉熵

  交叉熵主要是用来判定实际输出(概率)与期望输出(概率)的接近程度。也就是交叉熵的值越小,两个概率分布就越接近。假设概率分布p为期望输出,概率分布q为实际输出。
  则:
H ( p , q ) = − ∑ k = 1 n p ( x k ) l o g q ( x k ) H(p,q)=-\sum_{k=1}^np(x_k)logq(x_k) H(p,q)=k=1np(xk)logq(xk)

  • p ( x k ) p(x_k) p(xk) — 真值(期望输出),即target/label,oen-hot向量标签。
  • q ( x k ) q(x_k) q(xk) — 预测值(实际输出),即网络经过Softmax的结果, ∑ k = 1 n q ( x k ) = 1 \sum_{k=1}^nq(x_k)=1 k=1nq(xk)=1

  举个例子:在做分类的训练的时候,如果一个样本属于第K类,那么这个类别所对应的的输出节点的输出值应该为1,而其他节点的输出都为0,即[0,0,1,0,….0,0],这个数组也就是样本的Label,是神经网络最期望的输出结果。也就是说用它来衡量网络的输出与标签的差异,利用这种差异经过反向传播去更新网络参数。

  交叉熵损失用于分类问题的损失计算,可以适用于二分类,多分类问题,它可以捕捉预测概率相对大小的差异,进一步可以更加细致的衡量不同分类器的性能。

  • 对于多分类问题,不需要做one-hot编码,pytorch中会自动做one hot编码,接下来再进行crossentropy的损失的求解。
  • 对于二分类问题,需要做one-hot编码,然后再求损失。

torch.nn.CrossEntropyLoss

pytorch官方链接
在这里插入图片描述

pytorch中的所有损失函数都可以通过reduction = ‘mean’或者reduction = ‘sum’来设置均值还是总值。

Pytorch中CrossEntropyLoss()函数的主要是将softmax+log+NLLLoss合并到一块得到的结果。(下面会给出代码验证)

  1. Softmax后的数值都在0~1之间,所以ln之后值域是负无穷到0。
  2. 然后将Softmax之后的结果取log,将乘法改成加法减少计算量,同时保障函数的单调性 。
  3. NLLLoss的结果就是把上面的输出与Label对应的那个值拿出来(下面例子中就是:将log_output\logsoftmax_output中与y_target对应的值拿出来),去掉负号,再求均值。

**总结:**不管是二分类,多分类问题,还是多标签分类,其实在计算损失函数的过程都经历了三个步骤:

(1)激活函数:通过激活函数sigmoid或者是softmax将输出值缩放到[0,1]之间。

(2)求对数:计算缩放之后的向量的对数值,即所谓的logy的值,求对数之后的值在[-infinite,0]之间。

(3)累加求和:根据损失函数的定义,将标签和输出值逐元素相乘再求和,最后再添加一个负号求相反数,得到一个正数损失。

不管什么样的实现方式,都会经历这三个步骤,不同的是,可能有的函数会将其中的一个或者是几个步骤封装在一起。
求多分类交叉熵损失有三种途径可以实现,分别是:

  • (1)三步实现:softmax+log+nll_loss
  • (2)两步实现:log_softmax+nll_loss
  • (3)一步实现:crossEntropyLoss
import torch
import torch.nn as nn
x_input=torch.randn(3,3)#随机生成输入 
print('x_input:\n',x_input) 
y_target=torch.tensor([1,2,0])#设置输出具体值 print('y_target\n',y_target)

#计算输入softmax,此时可以看到每一行加到一起结果都是1
softmax_func=nn.Softmax(dim=1)
soft_output=softmax_func(x_input)
print('soft_output:\n',soft_output)

#在softmax的基础上取log
log_output=torch.log(soft_output)
print('log_output:\n',log_output)

#对比softmax与log的结合与nn.LogSoftmaxloss(负对数似然损失)的输出结果,发现两者是一致的。
logsoftmax_func=nn.LogSoftmax(dim=1)
logsoftmax_output=logsoftmax_func(x_input)
print('logsoftmax_output:\n',logsoftmax_output)

#pytorch中关于NLLLoss的默认参数配置为:reducetion=True、size_average=True
nllloss_func=nn.NLLLoss()
nlloss_output=nllloss_func(logsoftmax_output,y_target)
print('nlloss_output:\n',nlloss_output)

#直接使用pytorch中的loss_func=nn.CrossEntropyLoss()看与经过NLLLoss的计算是不是一样
crossentropyloss=nn.CrossEntropyLoss()
crossentropyloss_output=crossentropyloss(x_input,y_target)
print('crossentropyloss_output:\n',crossentropyloss_output)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
x_input:
 tensor([[ 2.8883,  0.1760,  1.0774],
        [ 1.1216, -0.0562,  0.0660],
        [-1.3939, -0.0967,  0.5853]])
y_target
 tensor([1, 2, 0])
soft_output:
 tensor([[0.8131, 0.0540, 0.1329],
        [0.6039, 0.1860, 0.2102],
        [0.0841, 0.3076, 0.6083]])
log_output:
 tensor([[-0.2069, -2.9192, -2.0178],
        [-0.5044, -1.6822, -1.5599],
        [-2.4762, -1.1790, -0.4970]])
logsoftmax_output:
 tensor([[-0.2069, -2.9192, -2.0178],
        [-0.5044, -1.6822, -1.5599],
        [-2.4762, -1.1790, -0.4970]])
nlloss_output:
 tensor(2.3185)
crossentropyloss_output:
 tensor(2.3185)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22

参考:
https://zhuanlan.zhihu.com/p/98785902?ivk_sa=1024320u
https://zhuanlan.zhihu.com/p/421830591

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/秋刀鱼在做梦/article/detail/878143
推荐阅读
  

闽ICP备14008679号