共计 1325 个字符,预计需要花费 4 分钟才能阅读完成。
背景:交叉熵损失的数学本质
交叉熵损失 (Cross-Entropy Loss) 是分类任务中最常用的损失函数,其数学表达式为:

$$
L_{CE} = -\sum_{i=1}^C y_i \log(p_i)
$$
其中 $y_i$ 是真实标签的 one-hot 编码,$p_i$ 是模型预测的类别概率。通过链式法则可推导出梯度:
$$
\frac{\partial L}{\partial z_i} = p_i – y_i
$$
这个简洁的梯度形式使得 CE 损失成为反向传播的高效选择。
传统 CE 的三大实战痛点
-
类别不平衡问题:当 90% 样本属于类别 A 时,模型只需将所有预测偏向 A 就能获得 90% 准确率,此时损失函数失去指导意义
-
噪声标签敏感:若标签存在错误(如将猫误标为狗),CE 会迫使模型拟合这些错误样本
-
过度自信预测:softmax 容易产生接近 1 的概率值,可能导致模型泛化能力下降
改进方案一:Focal Loss
Focal Loss 通过引入可调节的聚焦参数解决样本不平衡问题:
$$
L_{FL} = -\alpha_t (1-p_t)^\gamma \log(p_t)
$$
- $\alpha$ 控制类别权重(常用 0.25-0.75)
- $\gamma$ 调节难易样本关注度(常用 2.0)
在 CIFAR-10 上的消融实验显示:
| 配置 | 准确率 |
|---|---|
| CE Baseline | 92.1% |
| FL(γ=1) | 92.3% |
| FL(γ=2,α=0.25) | 93.7% |
改进方案二:Label Smoothing
通过软化真实标签分布缓解过拟合:
$$
y_i^{LS} = y_i(1-\epsilon) + \epsilon/K
$$
其中 $\epsilon$ 建议设置在 0.05-0.2 之间。实验表明该技术对噪声标签的鲁棒性提升显著:
# PyTorch 实现示例
class LabelSmoothingCE(nn.Module):
def __init__(self, epsilon=0.1):
super().__init__()
self.epsilon = epsilon
def forward(self, preds, target):
n_classes = preds.size(-1)
log_probs = F.log_softmax(preds, dim=-1)
loss = -log_probs.mean(dim=-1)
smooth_loss = -log_probs.sum(dim=-1) / n_classes
return (1-self.epsilon)*loss + self.epsilon*smooth_loss
工程实现避坑指南
-
数值稳定性 :始终使用
log_softmax而非softmax+log组合 -
GPU 优化:避免在损失函数内部进行张量拷贝
-
随机种子固定:
def set_seed(seed): torch.manual_seed(seed) np.random.seed(seed) random.seed(seed) if torch.cuda.is_available(): torch.cuda.manual_seed_all(seed)
开放问题讨论
- 如何设计动态调整 γ 参数的策略?
- 在多任务学习中不同任务是否应该使用不同的损失函数?
- 当类别数极大(如推荐系统中的百万级分类)时,CE 损失应该如何优化?
期待大家在评论区分享实战经验!
正文完
发表至: 未分类
近两天内
