BP反向传播算法PPT详解:从数学推导到Python实现

1次阅读
没有评论

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

image.webp

BP 算法在深度学习中的地位

BP 反向传播算法是神经网络的训练基石,它通过误差反向传播高效计算梯度。没有 BP 算法,深度学习模型的参数更新将变得极其低效。可以说,现代深度学习的繁荣很大程度上得益于 BP 算法的广泛应用。

BP 反向传播算法 PPT 详解:从数学推导到 Python 实现

单隐层网络的前向传播

考虑一个具有 1 个隐层的简单神经网络结构:

  • 输入层:(x_1, x_2)
  • 隐层:2 个神经元,激活函数为 sigmoid
  • 输出层:1 个神经元,激活函数为 sigmoid

前向传播过程可以用以下公式表示:

  1. 隐层输入:(z_h = W_h X + b_h)
  2. 隐层输出:(a_h = \sigma(z_h))
  3. 输出层输入:(z_o = W_o a_h + b_o)
  4. 最终输出:(a_o = \sigma(z_o))

其中 (\sigma) 表示 sigmoid 函数,损失函数采用均方误差:
(L = \frac{1}{2}(y – a_o)^2)

反向传播的 4 个关键步骤

1. 输出层梯度计算

首先计算损失对输出层输入的梯度:
(\frac{\partial L}{\partial z_o} = (a_o – y) \cdot \sigma'(z_o))

2. 隐层梯度计算

然后计算损失对隐层输入的梯度:
(\frac{\partial L}{\partial z_h} = (W_o^T \cdot \frac{\partial L}{\partial z_o}) \odot \sigma'(z_h))

3. 权重更新

计算权重梯度并更新:
(\frac{\partial L}{\partial W_o} = \frac{\partial L}{\partial z_o} \cdot a_h^T)
(\frac{\partial L}{\partial W_h} = \frac{\partial L}{\partial z_h} \cdot X^T)

4. 偏置更新

计算偏置梯度并更新:
(\frac{\partial L}{\partial b_o} = \frac{\partial L}{\partial z_o})
(\frac{\partial L}{\partial b_h} = \frac{\partial L}{\partial z_h})

Python 实现代码

import numpy as np

# 激活函数及其导数
def sigmoid(x):
    return 1 / (1 + np.exp(-x))

def sigmoid_derivative(x):
    s = sigmoid(x)
    return s * (1 - s)

# 网络参数
input_size = 2
hidden_size = 2
output_size = 1
learning_rate = 0.1

# 初始化权重
W_h = np.random.randn(hidden_size, input_size)
W_o = np.random.randn(output_size, hidden_size)
b_h = np.zeros((hidden_size, 1))
b_o = np.zeros((output_size, 1))

# 前向传播
def forward(X):
    z_h = np.dot(W_h, X) + b_h
    a_h = sigmoid(z_h)
    z_o = np.dot(W_o, a_h) + b_o
    a_o = sigmoid(z_o)
    return z_h, a_h, z_o, a_o

# 反向传播
def backward(X, y, z_h, a_h, z_o, a_o):
    # 输出层梯度
    dL_dzo = (a_o - y) * sigmoid_derivative(z_o)

    # 隐层梯度
    dL_dzh = np.dot(W_o.T, dL_dzo) * sigmoid_derivative(z_h)

    # 权重更新
    dL_dWo = np.dot(dL_dzo, a_h.T)
    dL_dWh = np.dot(dL_dzh, X.T)

    # 偏置更新
    dL_dbo = dL_dzo
    dL_dbh = dL_dzh

    return dL_dWh, dL_dWo, dL_dbh, dL_dbo

# 训练循环
for epoch in range(1000):
    # 这里应该添加数据输入和训练循环
    pass

避坑指南

梯度消失问题

当网络层数较深时,梯度可能会变得非常小,导致训练停滞。可以通过以下方法识别:

  • 检查各层权重的更新幅度
  • 观察损失函数下降速度
  • 使用梯度裁剪或更好的激活函数(如 ReLU)

学习率设置

学习率太大可能导致震荡,太小则收敛缓慢。建议:

  • 从 0.01 开始尝试
  • 使用学习率衰减策略
  • 考虑自适应优化器(如 Adam)

权重初始化

不当的初始化会导致训练困难:

  • 避免全零初始化
  • 考虑 Xavier 或 He 初始化
  • 小随机数通常效果不错

思考题

  1. 如何将当前实现扩展为多层网络?
  2. 如果将 sigmoid 改为 ReLU,反向传播需要做哪些调整?
  3. 批量训练与在线训练的梯度计算有何不同?

总结

通过本文的学习,我们深入理解了 BP 算法的数学原理和实现细节。虽然看起来有些复杂,但只要一步步拆解,其实并不难掌握。建议读者动手实现代码,通过实践来加深理解。

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