共计 1488 个字符,预计需要花费 4 分钟才能阅读完成。
背景痛点:为什么我们需要关注 BP 和梯度下降?
在深度学习中,反向传播 (Backpropagation, BP) 算法和梯度下降 (Gradient Descent) 是模型训练的核心机制。简单来说,BP 负责计算每个参数对最终损失的贡献(梯度),而梯度下降则利用这些梯度来更新参数。

但在实际应用中,我们常遇到这些问题:
- 梯度消失 / 爆炸:深度网络中梯度可能指数级减小或增大,导致早期层无法更新或数值溢出
- 局部最优:非凸损失函数中容易陷入次优解
- 训练震荡:学习率不当导致收敛过程不稳定
数学原理:BP 算法如何工作?
BP 本质是链式法则的递归应用。以一个简单全连接层为例:
z^l = W^l a^{l-1} + b^l \quad (前向传播)
\delta^l = \frac{\partial \mathcal{L}}{\partial z^l} = (W^{l+1})^T \delta^{l+1} \odot \sigma'(z^l) \quad (反向传播)
计算图可视化:
输入 X → 卷积层 → ReLU → 全连接层 → 输出 Loss
↑梯度反向传播↓
优化方案:主流优化器对比
- SGD (随机梯度下降)
\theta_{t+1} = \theta_t - \eta \nabla_\theta J(\theta) - 优点:简单
-
缺点:容易陷入局部最优
-
Momentum
v_t = \gamma v_{t-1} + \eta \nabla_\theta J(\theta)\theta_{t+1} = \theta_t - v_t -
优点:加速收敛,减少震荡
-
Adam
m_t = \beta_1 m_{t-1} + (1-\beta_1) g_tv_t = \beta_2 v_{t-1} + (1-\beta_2) g_t^2\theta_{t+1} = \theta_t - \eta \frac{m_t}{\sqrt{v_t} + \epsilon} - 优点:自适应学习率,适合稀疏梯度
代码实战:PyTorch 实现关键技巧
# 自定义网络结构
class Net(nn.Module):
def __init__(self):
super().__init__()
self.fc1 = nn.Linear(784, 128)
self.fc2 = nn.Linear(128, 10)
def forward(self, x):
x = F.relu(self.fc1(x))
return self.fc2(x)
# 学习率动态调整
optimizer = torch.optim.SGD(model.parameters(), lr=0.1)
scheduler = torch.optim.lr_scheduler.CosineAnnealingLR(optimizer, T_max=100)
# 梯度裁剪
torch.nn.utils.clip_grad_norm_(model.parameters(), max_norm=1.0)
避坑指南:生产环境常见问题
- 初始学习率选择
- 太大:训练震荡
- 太小:收敛慢
-
方案:使用学习率探测(LR Finder)
-
Batch Size 影响
- 过大:内存不足,泛化性差
- 过小:梯度噪声大
-
方案:根据 GPU 内存选择最大可用值
-
权重初始化
- 不当初始化导致梯度问题
- 方案:使用 He/Kaiming 初始化
性能验证:MNIST 上的对比实验
| 优化器 | 最终准确率 | 收敛步数 |
|------------|------------|----------|
| SGD | 98.2% | 1500 |
| Momentum | 98.5% | 1200 |
| Adam | 98.7% | 800 |
开放性问题
当训练数据存在严重类别不平衡时,应如何调整梯度更新策略?可以考虑:
- 类别加权损失函数
- 梯度重加权技术
- 过采样 / 欠采样策略
欢迎在评论区分享你的实践经验!
正文完
