共计 1671 个字符,预计需要花费 5 分钟才能阅读完成。
为什么损失函数如此重要?
在训练神经网络时,损失函数(Loss Function)就像是导航系统中的指南针。它告诉模型当前的预测结果与真实值相差多远,并通过反向传播算法指导参数更新。如果选择不当,可能会导致:

- 梯度消失:损失函数过于平缓时,梯度值接近零,参数几乎不更新
- 震荡发散:损失函数曲面崎岖会导致优化过程在局部极值点附近振荡
- 收敛缓慢:不恰当的损失函数可能使模型需要更多迭代才能达到理想效果
深入理解两种基础损失函数
1. 均方误差(MSE)
数学表达式:
$$ L_{MSE} = \frac{1}{2N}\sum_{i=1}^N (y_i – \hat{y}_i)^2 $$
梯度推导:
$$ \frac{\partial L}{\partial \hat{y}_i} = \frac{1}{N}(\hat{y}_i – y_i) $$
适用于回归任务,对异常值敏感是其显著特点。
2. 交叉熵损失(Cross-Entropy)
数学表达式:
$$ L_{CE} = -\frac{1}{N}\sum_{i=1}^N \left[y_i \log(\hat{y}_i) + (1-y_i)\log(1-\hat{y}_i) \right] $$
梯度推导:
$$ \frac{\partial L}{\partial \hat{y}_i} = \frac{\hat{y}_i – y_i}{\hat{y}_i(1-\hat{y}_i)} $$
这是分类任务的首选,特别适合输出概率的场景。
PyTorch 实战演示
MSE 实现示例
import torch
import torch.nn as nn
# 模拟数据
y_true = torch.randn(10, 1) # 真实值
y_pred = torch.randn(10, 1, requires_grad=True) # 预测值
# 定义损失
mse_loss = nn.MSELoss()
loss = mse_loss(y_pred, y_true)
# 反向传播
loss.backward()
# 查看梯度
print(f'MSE 梯度值:\n{y_pred.grad}')
关键点说明:
– requires_grad=True 启用自动求导
– .backward() 自动计算梯度
– 框架已内置向量化实现
交叉熵实现示例
# 分类任务示例
logits = torch.randn(10, 5) # 未归一化的预测值
labels = torch.randint(5, (10,)) # 真实类别索引
# 使用内置函数
ce_loss = nn.CrossEntropyLoss()
loss = ce_loss(logits, labels)
# 手动实现(理解原理)probs = torch.softmax(logits, dim=1)
ell_loss = -torch.log(probs[range(10), labels]).mean()
print(f'框架计算:{loss.item():.4f}, 手动实现:{ell_loss.item():.4f}')
注意事项:
– 框架已处理数值稳定性问题
– 标签应使用类别索引而非 one-hot 编码
如何选择合适的损失函数?
- 回归任务 首选 MSE,但当存在异常值时考虑 Huber Loss
- 二分类 使用二元交叉熵(BCE)
- 多分类 选择交叉熵(CE)
- 多标签分类 需要 BCE 配合 sigmoid
新手常见陷阱及解决方案
- 数值不稳定
- 现象:计算 log(0)导致 NaN
-
方案:添加微小 epsilon(如 1e-8)或使用框架内置函数
-
梯度爆炸
- 现象:参数更新过大导致溢出
-
方案:梯度裁剪(
torch.nn.utils.clip_grad_norm_) -
类别不平衡
- 现象:少数类被模型忽略
- 方案:加权交叉熵(
weight参数)或 Focal Loss
进阶思考方向
当面对极度不平衡的数据(如欺诈检测中正负样本 1:1000),常规交叉熵会导致模型倾向于预测多数类。可以探索:
- 动态调整类别权重
- 设计对难例样本惩罚更重的损失函数(如 Focal Loss)
- 采样策略与损失函数协同优化
通过理解损失函数的数学本质并掌握其实现细节,我们能够更精准地控制模型训练过程。建议初学者在实战中多尝试不同损失函数的组合,观察它们对训练曲线和最终指标的影响。
