共计 1774 个字符,预计需要花费 5 分钟才能阅读完成。
从单层感知机到多层网络
反向传播(Backpropagation, BP)是神经网络训练的核心算法,但初学者常被其矩阵运算和梯度计算绕晕。我们从最简单的单层感知机开始,逐步拆解这个 ” 黑箱 ”。

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. 扩展到多层网络
对于三层网络(输入层→隐藏层→输出层),反向传播需要逐层计算:
- 输出层梯度:
\delta^{(3)} = (y - t) \odot \sigma'(z^{(3)}) - 隐藏层梯度:
\delta^{(2)} = (W^{(2)T}\delta^{(3)}) \odot \sigma'(z^{(2)}) - 权重更新量:
\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 |
推导步骤(以第一个样本为例)
- 前向传播:
a_1 = \sigma(0\cdot w_{11} + 0\cdot w_{12} + b_1) \\ output = \sigma(a_1\cdot w_{21} + b_2) - 计算误差:
L = \frac{1}{2}(0 - output)^2 - 反向传播:
\delta_{output} = (0 - output) \cdot \sigma'(z_{output}) \\ \delta_{hidden} = \delta_{output} \cdot w_{21} \cdot \sigma'(z_{hidden})
延伸思考
- 如果隐藏层使用 ReLU 激活函数,反向传播公式需要如何修改?
- 如何证明反向传播算法得到的梯度是正确的(梯度检查技巧)?
- 当处理批量数据(batch_size > 1)时,梯度计算需要进行哪些调整?
通过这个完整的推导→代码→调试流程,相信你对 BP 算法有了更直观的理解。建议亲手实现代码并尝试不同的激活函数组合,这是掌握神经网络精髓的最佳途径。
正文完
