深入解析bp梯度下降公式:从数学原理到代码实现

1次阅读
没有评论

共计 1795 个字符,预计需要花费 5 分钟才能阅读完成。

image.webp

为什么需要梯度下降?

神经网络的核心是通过调整权重参数来最小化损失函数。想象你在山上蒙眼找下山路,梯度下降就是靠感知脚下坡度(梯度)来决定移动方向。每次迭代时,我们计算损失函数对每个参数的偏导数(梯度),然后沿着负梯度方向更新参数。

深入解析 bp 梯度下降公式:从数学原理到代码实现

数学表达为:
$$
w_{new} = w_{old} – \eta \cdot \frac{\partial L}{\partial w}
$$
其中 $\eta$ 是学习率,控制步长大小。

BP 梯度下降的数学推导

反向传播 (BP) 本质是链式法则的递归应用。以单隐藏层网络为例:

  1. 前向传播 计算预测值:
    $$
    z = w^Tx + b,\quad a = \sigma(z)
    $$
    $\sigma$ 是激活函数(如 Sigmoid)

  2. 反向传播 时从输出层开始:

  3. 输出层梯度:
    $$
    \frac{\partial L}{\partial a} = a – y
    $$
  4. 通过链式法则逐层回传:
    $$
    \frac{\partial L}{\partial w} = \frac{\partial L}{\partial a} \cdot \frac{\partial a}{\partial z} \cdot \frac{\partial z}{\partial w}
    $$

主流优化算法对比

  • SGD(随机梯度下降):
  • 优点:实现简单,内存占用小
  • 缺点:容易陷入局部最优,收敛震荡

  • Momentum:

  • 引入动量项积累历史梯度:
    $$
    v_t = \gamma v_{t-1} + \eta \nabla L
    $$
  • 有效缓解震荡,加速收敛

  • Adam:

  • 结合动量与自适应学习率
  • 实际工程中最常用的选择

Python 实现代码

import numpy as np

class NeuralNetwork:
    def __init__(self, input_size, hidden_size):
        self.w1 = np.random.randn(input_size, hidden_size) * 0.01
        self.b1 = np.zeros(hidden_size)
        self.w2 = np.random.randn(hidden_size, 1) * 0.01
        self.b2 = np.zeros(1)

    def sigmoid(self, x):
        return 1 / (1 + np.exp(-x))

    def forward(self, X):
        self.z1 = np.dot(X, self.w1) + self.b1
        self.a1 = self.sigmoid(self.z1)
        self.z2 = np.dot(self.a1, self.w2) + self.b2
        return self.sigmoid(self.z2)

    def backward(self, X, y, lr=0.1):
        m = X.shape[0]
        # 输出层梯度
        dz2 = self.forward(X) - y
        dw2 = np.dot(self.a1.T, dz2) / m
        db2 = np.sum(dz2, axis=0) / m

        # 隐藏层梯度
        dz1 = np.dot(dz2, self.w2.T) * (self.a1 * (1 - self.a1))
        dw1 = np.dot(X.T, dz1) / m
        db1 = np.sum(dz1, axis=0) / m

        # 参数更新
        self.w2 -= lr * dw2
        self.b2 -= lr * db2
        self.w1 -= lr * dw1
        self.b1 -= lr * db1

实战注意事项

  1. 学习率选择:
  2. 常用策略:从 0.1 开始尝试,每 10 轮乘以 0.5
  3. 高级技巧:使用学习率预热 (warmup) 或周期性调整

  4. 梯度消失 / 爆炸:

  5. 现象:深层网络训练时梯度指数级缩小 / 增大
  6. 解决方案:

    • 使用 ReLU 等激活函数
    • 梯度裁剪(gradient clipping)
    • 残差连接(residual connection)
  7. 批量大小:

  8. 太小:训练不稳定,收敛慢
  9. 太大:内存不足,可能陷入局部最优
  10. 经验值:32-256 之间

性能优化建议

  • 使用向量化操作替代循环
  • 对输入数据进行归一化
  • 定期保存模型检查点(checkpoint)
  • 监控训练过程中的 loss 和 accuracy 曲线

常见错误排查

  • 现象:Loss 不下降
  • 检查梯度计算是否正确
  • 验证数据标签是否匹配
  • 现象:Loss 出现 NaN
  • 降低学习率
  • 检查数据中是否存在异常值

思考题延伸

如何将 BP 梯度下降应用到 CNN 中?关键点在于:
1. 卷积核权重同样通过梯度下降更新
2. 需要处理池化层的梯度传递
3. 利用 im2col 技巧加速卷积运算

希望这篇笔记帮你打通 BP 算法的任督二脉!在实际项目中,建议先用现成框架(如 PyTorch)验证想法,再考虑自定义实现。

正文完
 0
评论(没有评论)