bp反向传播算法计算题实战:从数学推导到Python实现

1次阅读
没有评论

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

image.webp

从单层感知机到多层网络

反向传播(Backpropagation, BP)是神经网络训练的核心算法,但初学者常被其矩阵运算和梯度计算绕晕。我们从最简单的单层感知机开始,逐步拆解这个 ” 黑箱 ”。

bp 反向传播算法计算题实战:从数学推导到 Python 实现

1. 单层感知机的梯度计算

假设单层网络输出为:

y = \sigma(w^Tx + b)

其中 σ 是 sigmoid 函数。损失函数用均方误差:

L = \frac{1}{2}(y - t)^2

根据链式法则,权重 w 的梯度为:

\frac{\partial L}{\partial w} = (y - t) \cdot \sigma'(z) \cdot x

2. 扩展到多层网络

对于三层网络(输入层→隐藏层→输出层),反向传播需要逐层计算:

  1. 输出层梯度:
    \delta^{(3)} = (y - t) \odot \sigma'(z^{(3)})
  2. 隐藏层梯度:
    \delta^{(2)} = (W^{(2)T}\delta^{(3)}) \odot \sigma'(z^{(2)})
  3. 权重更新量:
    \Delta W^{(l)} = \delta^{(l+1)} a^{(l)T}

Python 实现详解

import numpy as np

class NeuralNetwork:
    def __init__(self):
        # 初始化权重(注意维度匹配)self.W1 = np.random.randn(2, 2) * 0.01  # 输入→隐藏层
        self.W2 = np.random.randn(1, 2) * 0.01  # 隐藏→输出层

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

    def sigmoid_deriv(self, x):
        return x*(1-x)

    def forward(self, X):
        # 前向传播(记录中间结果供反向传播使用)self.z1 = np.dot(X, self.W1.T)  # 注意转置
        self.a1 = self.sigmoid(self.z1)
        self.z2 = np.dot(self.a1, self.W2.T)
        self.output = self.sigmoid(self.z2)
        return self.output

    def backward(self, X, y, output, lr=0.1):
        # 反向传播
        error = output - y

        # 输出层梯度
        delta2 = error * self.sigmoid_deriv(output)  # (1,1)
        dW2 = np.dot(delta2.T, self.a1)  # (1,2)

        # 隐藏层梯度
        delta1 = np.dot(delta2, self.W2) * self.sigmoid_deriv(self.a1)  # (1,2)
        dW1 = np.dot(delta1.T, X)  # (2,2)

        # 更新权重
        self.W2 -= lr * dW2
        self.W1 -= lr * dW1

关键陷阱与调试技巧

矩阵维度不匹配

  • 典型错误:(4,3)矩阵无法乘以 (2,1) 矩阵
  • 解决方法:

  • 打印每层输出的 shape

  • 确保 W 的维度是(本层神经元数, 前层神经元数)
  • 矩阵乘法前检查是否需要转置

学习率设置

  • 经验法则:
  • 从 0.01 开始尝试
  • 观察损失曲线:震荡→调小,下降慢→调大
  • 可尝试自适应方法(如 Adam)

激活函数选择

  • ReLU:小心 ” 死亡神经元 ”(导数永远为 0)
  • Sigmoid:注意梯度消失问题(输出值接近 0 或 1 时导数趋近 0)

XOR 问题实战演练

问题描述

X1 X2 y
0 0 0
0 1 1
1 0 1
1 1 0

推导步骤(以第一个样本为例)

  1. 前向传播:
    a_1 = \sigma(0\cdot w_{11} + 0\cdot w_{12} + b_1) \\
    output = \sigma(a_1\cdot w_{21} + b_2)
  2. 计算误差:
    L = \frac{1}{2}(0 - output)^2
  3. 反向传播:
    \delta_{output} = (0 - output) \cdot \sigma'(z_{output}) \\
    \delta_{hidden} = \delta_{output} \cdot w_{21} \cdot \sigma'(z_{hidden})

延伸思考

  1. 如果隐藏层使用 ReLU 激活函数,反向传播公式需要如何修改?
  2. 如何证明反向传播算法得到的梯度是正确的(梯度检查技巧)?
  3. 当处理批量数据(batch_size > 1)时,梯度计算需要进行哪些调整?

通过这个完整的推导→代码→调试流程,相信你对 BP 算法有了更直观的理解。建议亲手实现代码并尝试不同的激活函数组合,这是掌握神经网络精髓的最佳途径。

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