CrossEntropy Loss(交叉熵损失)
:类别总数
:模型输出 (未经过softmax)
:真实类别索引(非one-hot)
3分类,类别 C=3,单样本损失:
对logits做Softmax归一化得到各类概率
单样本交叉熵损失
批量样本(batch size=N)
数据设定
3个样本、3类 logits:
-
样本1:
, 真实标签
-
样本2:
,真实标签
-
样本3:
,真实标签
分步手动计算
样本1
样本2
样本3
批量平均损失
PyTorch 代码验证
import torch
import torch.nn as nn
import torch.nn.functional as F
# 3个样本,3分类 logits
logits = torch.tensor([
[2.0, 1.0, 0.0], # 样本1
[-1.0, 3.0, 0.0], # 样本2
[0.0, -2.0, 4.0] # 样本3
])
labels = torch.tensor([0, 1, 2]) # 对应真实类别索引
# 交叉熵损失 # 默认 reduction="mean" 输出3个样本损失平均值;
loss_fn = nn.CrossEntropyLoss()
loss = loss_fn(logits, labels)
print("批量平均损失:", loss.item())
# 输出结果:
# 批量平均损失: 0.16468988358974457
# 和手算 0.164690 完全吻合。
# 若想输出每个样本单独损失:reduction="none"
loss_fn_none = nn.CrossEntropyLoss(reduction="none")
loss_each = loss_fn_none(logits, labels)
print("每个样本损失:", loss_each)
# 每个样本损失: tensor([0.4076, 0.0659, 0.0206])
NLLLoss(负对数似然损失)
:模型输出(未经过softmax)
CrossEntropy = LogSoftmax + NLLLoss,一般优先用 CrossEntropy
公式等价转换
二者数学完全等价,只是输入预处理不同。
概率
损失函数
以单样本 拆解:
:模型预测真实标签类别的概率,
:对数压缩概率值域
(预测完全正确):
,损失
(完全预测错误):
,损失
-
负号 - :把最大化对数似然转为最小化损失,适配梯度下降优化
import torch
import torch.nn as nn
import torch.nn.functional as F
# 3个样本,3分类 logits
logits = torch.tensor([
[2.0, 1.0, 0.0], # 样本1
[-1.0, 3.0, 0.0], # 样本2
[0.0, -2.0, 4.0] # 样本3
])
labels = torch.tensor([0, 1, 2]) # 对应真实类别索引
# 交叉熵损失 # 默认 reduction="mean" 输出3个样本损失平均值;
loss_fn = nn.CrossEntropyLoss()
loss = loss_fn(logits, labels)
print("批量平均损失:", loss.item())
# 拆分验证 LogSoftmax + NLLLoss
log_sm = F.log_softmax(logits, dim=1)
nll_loss = F.nll_loss(log_sm, labels)
print("手动拆解损失:", nll_loss.item())
# 输出结果:
# 批量平均损失: 0.16468988358974457
# 手动拆解损失: 0.16468988358974457
# 和手算 0.164690 完全吻合。


2750

被折叠的 条评论
为什么被折叠?



