默认情况下,PyTorch的cross_entropy
将logits(模型的原始输出)作为输入。我知道CrossEntropyLoss
将LogSoftmax
(log(softmax(x)))和NLLLoss
(负对数似然损失)组合在一个类中。所以,我想我可以使用NLLLoss
从概率中获得交叉熵损失,如下所示:
真实标签:[1,0,1]
概率:[0.1,0.9],[0.9,0.1],[0.2,0.8]
其中,y_i,j
表示真值,即如果样本i
属于类j
,则为1,否则为0。p_i,j表示样本i
属于类j
的模型预测的概率。
如果我用手计算,结果是:
>>> -(math.log(0.9) + math.log(0.9) + math.log(0.8))
0.4338
使用PyTorch:
>>> labels = torch.tensor([1, 0, 1], dtype=torch.long)
>>> probs = torch.tensor([[0.1, 0.9], [0.9, 0.1], [0.2, 0.8]], dtype=torch.float)
>>> F.nll_loss(torch.log(probs), labels)
tensor(0.1446)
我做错了什么?为什么答案不同?
PyTorch中的所有损失函数都有一个约简参数。从留档默认约简参数中可以看出,它是“均值”,它将总和除以批次中的元素数。要获得所需的求和行为(0.4338),您应该给出以下约简参数:
F.nll_loss(torch.log(probs), labels,reduction='sum')