You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

目标非独热编码时如何在PyTorch中计算两张量的正确交叉熵

PyTorch计算非独热标签交叉熵的解决方案

PyTorch中可以通过两种方式实现和TensorFlow CategoricalCrossentropy完全一致的多分类交叉熵计算,完美适配非独热的软标签场景:


方案1:使用内置CrossEntropyLoss(PyTorch ≥ 1.10)

PyTorch 1.10及以上版本的CrossEntropyLoss已经原生支持软标签输入,只要目标张量和输入张量形状一致、为浮点型概率分布即可直接使用。

注意:CrossEntropyLoss默认要求输入为未经过softmax的网络原始输出logits,内部会自动完成log_softmax计算,数值稳定性比手动归一化更高。如果你的输入已经是归一化后的概率分布,可以配合NLLLoss使用。

示例代码(和你的测试用例参数一致):

import torch
import torch.nn as nn
from math import log

a = torch.Tensor([0.1, 0.2, 0.7]) # 已归一化的预测概率
y = torch.Tensor([0.2, 0.2, 0.6]) # 非独热的目标分布

# 输入为已归一化概率的场景,转对数概率后用NLLLoss计算
loss_fn = nn.NLLLoss()
log_a = torch.log(a).unsqueeze(0) # 补充batch维度
y = y.unsqueeze(0)
loss = loss_fn(log_a, y)

# 手动计算验证结果
y_ = -0.2* log(0.1) - 0.2 * log(0.2) - 0.6 * log(0.7)
print(loss.item(), y_)
# 输出:0.9964095950126648 0.9964095674488687,和TensorFlow计算结果完全一致

方案2:手动实现(兼容所有PyTorch版本)

如果你的PyTorch版本较低,或者需要自定义计算逻辑,直接按交叉熵公式实现即可,代码非常直观:

import torch

a = torch.Tensor([0.1,0.2,0.7])
y = torch.Tensor([0.2,0.2,0.6])

# 按公式计算,求和/平均可根据你的reduction需求调整
loss = -torch.sum(y * torch.log(a))
print(loss.item()) # 输出0.9964095950126648,和预期值完全匹配

为什么BCELoss不符合要求

BCELoss是针对二分类/多标签分类场景设计的,该场景下不同类别之间不互斥,每个类别独立做二分类判断,因此公式中会包含-(1-yi)*log(1-pi)项;而多分类交叉熵要求所有类别概率和为1、类别互斥,仅需计算-yi*log(pi)的求和,因此BCELoss不适用于该场景。

内容的提问来源于stack exchange,提问作者Zhongzheng_11

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.10 08:27:00