PyTorch中的交叉熵

blu*_*nox 15 machine-learning entropy loss deep-learning pytorch

我对PyTorch中的交叉熵损失感到有些困惑.

考虑这个例子:

import torch
import torch.nn as nn
from torch.autograd import Variable

output = Variable(torch.FloatTensor([0,0,0,1])).view(1, -1)
target = Variable(torch.LongTensor([3]))

criterion = nn.CrossEntropyLoss()
loss = criterion(output, target)
print(loss)
Run Code Online (Sandbox Code Playgroud)

我希望损失为0.但我得到:

Variable containing:
 0.7437
[torch.FloatTensor of size 1]
Run Code Online (Sandbox Code Playgroud)

据我所知,交叉熵可以像这样计算:

在此输入图像描述

但不应该是1*log(1)= 0的结果?

我尝试了不同的输入,如单热编码,但这根本不起作用,所以看起来损失函数的输入形状是可以的.

如果有人可以帮助我并告诉我我的错误在哪里,我将非常感激.

提前致谢!

小智 38

在您的示例中,您将输出[0,0,0,1]视为交叉熵的数学定义所要求的概率.但PyTorch将它们视为输出,不需要求和为1,并且需要首先将其转换为使用softmax函数的概率.

因此H(p,q)变为H(p,softmax(输出)).将输出[0,0,0,1]转换为概率:softmax [0,0,0,1] = [0.1749,0.1749,0.1749,0.4754] whence -log(0.4754)= 0.7437

  • 很好的答案,但是 pytorch 中是否有可用的损失函数可以像原始问题中描述的那样计算损失? (3认同)

Was*_*mad 17

你的理解是正确的,但是pytorch不会以这种方式计算交叉熵.Pytorch使用以下公式.

loss(x, class) = -log(exp(x[class]) / (\sum_j exp(x[j])))
               = -x[class] + log(\sum_j exp(x[j]))
Run Code Online (Sandbox Code Playgroud)

因为,在你的情况下,x = [0, 0, 0, 1]class = 3,如果评估上述表达式,你会得到:

loss(x, class) = -1 + log(exp(0) + exp(0) + exp(0) + exp(1))
               = 0.7437
Run Code Online (Sandbox Code Playgroud)

Pytorch考虑自然对数.

  • 谢谢你的回答,这对我很有帮助!那么有没有办法通过 CE 损失达到零? (3认同)

oez*_*nsi 12

我想添加一个重要的说明,因为这通常会导致混淆。

Softmax 不是损失函数,也不是真正的激活函数。它有一个非常具体的任务:它用于多类分类以标准化给定类的分数。通过这样做,我们得到每个类的概率总和为1

Softmax 结合 Cross-Entropy-Loss来计算模型的损失。

不幸的是,由于这种组合非常常见,所以经常被缩写。有些人使用术语Softmax-Loss,而 PyTorch 仅称其为Cross-Entropy-Loss


uke*_*emi 7

nn.LogSoftmax和的组合nn.NLLLoss相当于使用 nn.CrossEntropyLoss。这个术语是 PyTorch 的一个特殊性,因为 nn.NLLoss实际上,[原文如此] 计算交叉熵,但以对数概率预测作为输入,其中nn.CrossEntropyLoss获取分数(有时称为logits)。从技术上讲,nn.NLLLoss它是狄拉克分布(将所有质量放在目标上)与对数概率输入给出的预测分布之间的交叉熵。

PyTorchCrossEntropyLoss期望无界分数(可解释为 logits / log-odds)作为输入,而不是概率(如 CE 的传统定义)。