BP神经网络反向传播计算例题详解:从数学推导到Python实现

1次阅读
没有评论

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

image.webp

神经网络基础概念

神经网络是一种模仿生物神经元连接方式的计算模型,通过多层神经元的组合来实现复杂的非线性映射。一个典型的神经网络由输入层、隐藏层和输出层组成,每层包含若干个神经元。

BP 神经网络反向传播计算例题详解:从数学推导到 Python 实现

  • 前向传播 :数据从输入层经过隐藏层传递到输出层的过程。每个神经元接收上一层神经元的输出,经过加权求和和激活函数处理后,传递给下一层。
  • 反向传播 :通过比较网络输出和真实标签的误差,逐层反向调整各层权重和偏置的过程。反向传播的核心是链式法则,用于计算误差对每个权重的梯度。

3 层神经网络计算例题

我们以一个简单的 3 层神经网络为例,包括输入层(2 个神经元)、隐藏层(2 个神经元)和输出层(1 个神经元)。激活函数使用 sigmoid,损失函数使用平方误差。

前向传播计算过程

假设输入为 (x_1 = 0.5) 和 (x_2 = 0.8),初始权重和偏置如下:

  • 输入层到隐藏层权重:(w_{11} = 0.1), (w_{12} = 0.2), (w_{21} = 0.3), (w_{22} = 0.4)
  • 隐藏层到输出层权重:(w_{31} = 0.5), (w_{32} = 0.6)
  • 偏置:(b_1 = 0.1), (b_2 = 0.2)

  • 隐藏层输入:
    [h_1 = w_{11}x_1 + w_{21}x_2 + b_1 = 0.1 \times 0.5 + 0.3 \times 0.8 + 0.1 = 0.39 ]
    [h_2 = w_{12}x_1 + w_{22}x_2 + b_2 = 0.2 \times 0.5 + 0.4 \times 0.8 + 0.2 = 0.62 ]

  • 隐藏层输出(sigmoid 激活):
    [a_1 = \frac{1}{1 + e^{-h_1}} = \frac{1}{1 + e^{-0.39}} \approx 0.596 ]
    [a_2 = \frac{1}{1 + e^{-h_2}} = \frac{1}{1 + e^{-0.62}} \approx 0.650 ]

  • 输出层输入:
    [o = w_{31}a_1 + w_{32}a_2 = 0.5 \times 0.596 + 0.6 \times 0.650 \approx 0.688 ]

  • 输出层输出(sigmoid 激活):
    [y = \frac{1}{1 + e^{-o}} = \frac{1}{1 + e^{-0.688}} \approx 0.666 ]

误差反向传播的数学推导

假设真实标签为 (t = 1),平方误差损失为:
[E = \frac{1}{2}(y – t)^2 = \frac{1}{2}(0.666 – 1)^2 \approx 0.0556 ]

  1. 输出层误差:
    [\delta_y = (y – t) \cdot y(1 – y) = (0.666 – 1) \times 0.666 \times (1 – 0.666) \approx -0.074 ]

  2. 隐藏层误差:
    [\delta_{a1} = \delta_y \cdot w_{31} \cdot a_1(1 – a_1) \approx -0.074 \times 0.5 \times 0.596 \times (1 – 0.596) \approx -0.0054 ]
    [\delta_{a2} = \delta_y \cdot w_{32} \cdot a_2(1 – a_2) \approx -0.074 \times 0.6 \times 0.650 \times (1 – 0.650) \approx -0.0061 ]

  3. 权重更新(学习率 (\eta = 0.5)):

  4. 输出层权重:
    [w_{31} = w_{31} – \eta \cdot \delta_y \cdot a_1 \approx 0.5 – 0.5 \times (-0.074) \times 0.596 \approx 0.522 ]
    [w_{32} = w_{32} – \eta \cdot \delta_y \cdot a_2 \approx 0.6 – 0.5 \times (-0.074) \times 0.650 \approx 0.624 ]
  5. 隐藏层权重:
    [w_{11} = w_{11} – \eta \cdot \delta_{a1} \cdot x_1 \approx 0.1 – 0.5 \times (-0.0054) \times 0.5 \approx 0.101 ]
    [w_{12} = w_{12} – \eta \cdot \delta_{a2} \cdot x_1 \approx 0.2 – 0.5 \times (-0.0061) \times 0.5 \approx 0.202 ]
    [w_{21} = w_{21} – \eta \cdot \delta_{a1} \cdot x_2 \approx 0.3 – 0.5 \times (-0.0054) \times 0.8 \approx 0.302 ]
    [w_{22} = w_{22} – \eta \cdot \delta_{a2} \cdot x_2 \approx 0.4 – 0.5 \times (-0.0061) \times 0.8 \approx 0.402 ]

Python 代码实现

import numpy as np

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

def sigmoid_derivative(x):
    return x * (1 - x)

# 初始化参数
X = np.array([0.5, 0.8])
Y = np.array([1])

# 权重和偏置
W1 = np.array([[0.1, 0.2], [0.3, 0.4]])
W2 = np.array([[0.5], [0.6]])
B1 = np.array([0.1, 0.2])

# 前向传播
hidden_input = np.dot(X, W1) + B1
hidden_output = sigmoid(hidden_input)
output = sigmoid(np.dot(hidden_output, W2))

# 计算误差
error = 0.5 * (output - Y) ** 2
print(f"Initial error: {error[0]:.4f}")

# 反向传播
output_error = (output - Y) * sigmoid_derivative(output)
hidden_error = np.dot(W2, output_error) * sigmoid_derivative(hidden_output)

# 更新权重
learning_rate = 0.5
W2 -= learning_rate * np.dot(hidden_output.reshape(-1, 1), output_error.reshape(1, -1))
W1 -= learning_rate * np.dot(X.reshape(-1, 1), hidden_error.reshape(1, -1))

讨论

学习率对训练的影响

学习率决定了权重更新的步长。过大的学习率可能导致震荡或无法收敛,过小的学习率会减慢收敛速度。通常需要通过实验选择合适的学习率。

梯度消失问题简介

在深层网络中,梯度可能会在反向传播过程中逐渐减小,导致浅层权重更新缓慢甚至停止学习。使用 ReLU 等激活函数或残差连接可以缓解这个问题。

实际应用中的注意事项

  • 数据标准化:输入数据应进行标准化处理,避免某些特征主导训练过程。
  • 权重初始化:合适的初始化(如 Xavier 初始化)可以加速收敛。
  • 批量训练:使用小批量数据(mini-batch)可以减少训练波动并加速收敛。

关键公式总结

  • Sigmoid 激活函数:(\sigma(x) = \frac{1}{1 + e^{-x}} )
  • Sigmoid 导数:(\sigma'(x) = \sigma(x)(1 – \sigma(x)) )
  • 平方误差损失:(E = \frac{1}{2}(y – t)^2 )
  • 输出层误差:(\delta_y = (y – t) \cdot y(1 – y) )
  • 隐藏层误差:(\delta_h = \delta_y \cdot w \cdot a(1 – a) )

推荐进一步学习的资源

  • 《神经网络与深度学习》(Michael Nielsen)
  • Coursera 课程:Deep Learning Specialization(Andrew Ng)
  • PyTorch 官方教程

建议读者尝试的扩展练习

  1. 尝试使用不同的激活函数(如 ReLU)并观察训练效果。
  2. 实现一个完整的训练循环,包括多次迭代和损失函数监控。
  3. 扩展网络结构,增加更多隐藏层,观察梯度消失现象。

希望通过这个例题,你能更清晰地理解 BP 神经网络的反向传播过程。动手实践是掌握神经网络的最佳方式,建议你尝试修改代码并观察结果的变化。

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