引言 在使用pytorch深度学习框架,计算损失函数的时候经常会遇到这个函数:nn.CrossEntropyLoss() 该损失函数结合了nn.LogSoftmax()和nn.NLLLoss()两个函数。它在做分类(具体几类)训练的时候是非常有用的。在训练过程中,对于每个类分配权值,可选的参数权值应该是一个1D张量。当你有一个不平衡的训练集时,这是是非常有用的。那么针对这个函数,下面将做详细的介绍。
什么是交叉熵? 交叉熵主要是用来判定实际的输出与期望的输出的接近程度,为什么这么说呢,举个例子:在做分类的训练的时候,如果一个样本属于第K类,那么这个类别所对应的的输出节点的输出值应该为1,而其他节点的输出都为0,即[0,0,1,0,….0,0],这个数组也就是样本的Label,是神经网络最期望的输出结果。也就是说用它来衡量网络的输出与标签的差异,利用这种差异经过反向传播去更新网络参数。
交叉熵原理? 在说交叉熵之前,先说一下信息量与熵。
它是交叉熵的另外一种方式。
Pytorch中CrossEntropyLoss()函数的主要是将softmax-log-NLLLoss合并到一块得到的结果。
1、Softmax后的数值都在0~1之间,所以ln之后值域是负无穷到0。
2、然后将Softmax之后的结果取log,将乘法改成加法减少计算量,同时保障函数的单调性 。
3、NLLLoss的结果就是把上面的输出与Label对应的那个值拿出来(下面例子中就是:将log_output\logsoftmax_output中与y_target对应的值拿出来),去掉负号,再求均值。 下面是我仿真写的一个例子:
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)最后计算得到的结果为:
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)通过上面的结果可以看出,直接使用pytorch中的loss_func=nn.CrossEntropyLoss()计算得到的结果与softmax-log-NLLLoss计算得到的结果是一致的。
来源:AINLPer微信公众号 链接:知乎:ShuYini