手动实现交叉熵的计算

本文详细对比PyTorch内置CrossEntropyLoss与手动实现交叉熵的计算过程,阐明其等价性:内置函数隐含Softmax,而手动实现需显式执行Softmax、target转one-hot及-log(p_true)计算。强调交叉熵仅依赖真实类别预测概率,揭示损失随预测概率减小而增大的核心规律,并指出浮点精度导致的微小数值差异。

整体代码

import torch
import torch.nn as nn
import numpy as np

'''
手动实现交叉熵的计算
'''

#使用torch计算交叉熵
ce_loss = nn.CrossEntropyLoss()
#假设有3个样本,每个都在做3分类
pred = torch.FloatTensor([[0.3, 2.1, 0.3],
                          [0.19, 1.2, 0.9],
                          [0.5, 0.4, 0.2]]) #n*class_num
'''
pred经过softmax函数的输出:
tensor([[0.1242, 0.7515, 0.1242],
        [0.1730, 0.4751, 0.3519],
        [0.3780, 0.3420, 0.2800]])
'''
#正确的类别分别为1,2,0
target = torch.LongTensor([1,2,0])     #n
'''
也可以写成这种形式:
torch.LongTensor([
    [0,1,0],
    [0,0,1],
    [1,0,0],
])

交叉熵计算方式:
-(0 * log(0.1242) + 1 * log(0.7515) + 0 * log(0.1242)) = -log(0.7515)
-(0 * log(0.1730) + 0 * log(0.4751) + 1 * log(0.3519)) = -log(0.3519)
-(1 * log(0.3780) + 0 * log(0.3420) + 0 * log(0.2800)) = -log(0.3780)

如果模型对真实类别预测概率接近1 → log值接近0 → 损失小
如果模型对真实类别预测概率接近0 → log值很大 → 损失大
'''
loss = ce_loss(pred, target)
print(loss, "torch输出交叉熵")


#实现softmax函数
def softmax(matrix):
    return np.exp(matrix) / np.sum(np.exp(matrix), axis=1, keepdims=True)

#验证softmax函数
print(torch.softmax(pred, dim=1))
print(softmax(pred.numpy()))


#将输入转化为onehot矩阵
def to_one_hot(target, shape):
    one_hot_target = np.zeros(shape)
    for i, t in enumerate(target):
        one_hot_target[i][t] = 1
    return one_hot_target

#手动实现交叉熵
def cross_entropy(pred, target):
    batch_size, class_num = pred.shape
    pred = softmax(pred)
    target = to_one_hot(target, pred.shape)
    entropy = - np.sum(target * np.log(pred), axis=1)
    return sum(entropy) / batch_size

print(cross_entropy(pred.numpy(), target.numpy()), "手动实现交叉熵")

# print(np.log(2.7))

执行代码后打印结果如下

tensor(0.7677) torch输出交叉熵
tensor([[0.1242, 0.7515, 0.1242],
        [0.1730, 0.4751, 0.3519],
        [0.3780, 0.3420, 0.2800]])
[[0.1242 0.7515 0.1242]
 [0.1730 0.4751 0.3519]
 [0.3780 0.3420 0.2800]]
0.7677 手动实现交叉熵

关键点说明(PyTorch内置的CrossEntropyLoss VS 手动实现交叉熵)

两种方法结果一致:PyTorch内置的CrossEntropyLoss和手动实现的结果都是 0.7677
CrossEntropyLoss内部包含Softmax:所以不需要对pred先做softmax

手动实现的步骤:
(1)先对pred做softmax
(2)将target转为one-hot
(3)计算交叉熵
数值差异:由于浮点数精度,可能会有微小的差异(比如0.767649 vs 0.7677),但基本一致。

常见值的log对照表

概率pln( p )-ln ( p )(损失)
1.000(完美预测)
0.9-0.1050.105
0.5-0.6930.693
0.1-2.3032.303
0.01-4.6054.605
0.001-6.9086.908

规律总结

概率越小 → 负对数值越大 → 损失越大

这就是为什么:

  • 预测对(概率接近1)→ 损失小
  • 预测错(概率接近0)→ 损失大

核心规律

交叉熵只关注真实类别的预测概率:

one-hot的0 消除了所有其他类别的贡献
one-hot的1 只保留真实类别的log值
最终公式简化为:-log(真实类别的预测概率)

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值