4

【转】交叉熵损失函数CrossEntropyLoss(),softmax()函数,与NLLLoss()函数在 PyTorch...

 3 years ago
source link: https://blog.popkx.com/difference-and-connections-between-CrossEntropyLoss-softmax-NLLLoss-in-pytorch/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

【转】交叉熵损失函数CrossEntropyLoss(),softmax()函数,与NLLLoss()函数在 PyTorch 中的区别与联系

发表于 2021-03-25 11:03:00   |   已被 访问: 13 次   |   分类于:   PyTorch基础   |   暂无评论

来源:知乎,作者:ShuYini 原帖

    在使用pytorch深度学习框架,计算损失函数的时候经常会遇到这么一个函数:

nn.CrossEntropyLoss()

    该损失函数结合了nn.LogSoftmax()和nn.NLLLoss()两个函数。它在做分类(具体几类)训练的时候是非常有用的。在训练过程中,对于每个类分配权值,可选的参数权值应该是一个1D张量。当你有一个不平衡的训练集时,这是是非常有用的。那么针对这个函数,下面将做详细的介绍。

什么是交叉熵?

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

交叉熵原理?

Pytorch中的CrossEntropyLoss()函数

它是交叉熵的另外一种方式。

  • Softmax后的数值都在0~1之间,所以ln之后值域是负无穷到0。
  • 然后将Softmax之后的结果取log,将乘法改成加法减少计算量,同时保障函数的单调性 。
  • 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计算得到的结果是一致的。

阅读更多:   PyTorch基础


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK