共计 2220 个字符,预计需要花费 6 分钟才能阅读完成。
1. 核心概念:前向传播与反向传播
BP 神经网络的核心计算分为前向传播和反向传播两个阶段。我们先从数学公式入手理解这两个过程。

1.1 前向传播
前向传播计算每层的激活值,公式如下:
$$
a^{(l)} = f(z^{(l)}) \
z^{(l)} = W^{(l)}a^{(l-1)} + b^{(l)}
$$
其中:
– $l$ 表示层数
– $W^{(l)}$ 是权重矩阵
– $b^{(l)}$ 是偏置向量
– $f$ 是激活函数 (如 sigmoid)
1.2 反向传播
反向传播通过链式法则计算梯度:
$$
\delta^{(l)} = \frac{\partial J}{\partial z^{(l)}} = (W^{(l+1)})^T\delta^{(l+1)} \odot f'(z^{(l)}) \
\frac{\partial J}{\partial W^{(l)}} = \delta^{(l)}(a^{(l-1)})^T \
\frac{\partial J}{\partial b^{(l)}} = \delta^{(l)}
$$
其中 $\odot$ 表示逐元素相乘。
2. 初学者常见痛点分析
新手实现 BP 神经网络时容易遇到以下问题:
- 矩阵维度不匹配:权重矩阵的行列设置错误
- 学习率选择不当:太大导致震荡,太小收敛慢
- 激活函数选择:sigmoid 容易梯度消失,ReLU 可能导致神经元死亡
- 未归一化数据:不同特征的尺度差异影响训练
3. Python 实现 BP 神经网络
3.1 网络初始化
import numpy as np
class NeuralNetwork:
def __init__(self, layers):
self.layers = layers
self.weights = []
self.biases = []
# 初始化权重和偏置
for i in range(len(layers)-1):
# He 初始化
w = np.random.randn(layers[i+1], layers[i]) * np.sqrt(2./layers[i])
b = np.zeros((layers[i+1], 1))
self.weights.append(w)
self.biases.append(b)
3.2 激活函数实现
# Sigmoid 激活函数
def sigmoid(self, x):
return 1 / (1 + np.exp(-x))
# Sigmoid 的导数
def sigmoid_derivative(self, x):
s = self.sigmoid(x)
return s * (1 - s)
3.3 训练过程
def train(self, X, y, epochs, learning_rate):
losses = []
for epoch in range(epochs):
# 前向传播
activations = [X]
zs = []
a = X
for w, b in zip(self.weights, self.biases):
z = np.dot(w, a) + b
a = self.sigmoid(z)
zs.append(z)
activations.append(a)
# 计算损失
loss = np.mean((a - y)**2)
losses.append(loss)
# 反向传播
delta = (a - y) * self.sigmoid_derivative(zs[-1])
# 更新参数
for l in range(len(self.weights)-1, -1, -1):
dw = np.dot(delta, activations[l].T) / X.shape[1]
db = np.mean(delta, axis=1, keepdims=True)
self.weights[l] -= learning_rate * dw
self.biases[l] -= learning_rate * db
if l > 0:
delta = np.dot(self.weights[l].T, delta) * self.sigmoid_derivative(zs[l-1])
4. 避坑指南
4.1 调试维度错误
- 打印每层的矩阵维度
- 确保 $W^{(l)}$ 的维度是 (n_l, n_{l-1})
- 确保 $a^{(l)}$ 的维度是 (n_l, m),其中 m 是样本数
4.2 学习率选择
- 初始尝试 0.1
- 观察损失曲线:震荡则减小,下降太慢则增大
- 可以使用学习率衰减策略
4.3 数据归一化
# MinMax 归一化
X = (X - X.min()) / (X.max() - X.min())
5. XOR 问题验证
# XOR 问题
X = np.array([[0,0], [0,1], [1,0], [1,1]]).T
y = np.array([[0,1,1,0]])
# 创建网络
nn = NeuralNetwork([2,4,1])
# 训练
nn.train(X, y, epochs=10000, learning_rate=0.1)
# 测试
print(nn.predict(X)) # 应接近 [0,1,1,0]
6. 结果可视化
import matplotlib.pyplot as plt
plt.plot(losses)
plt.xlabel('Epoch')
plt.ylabel('Loss')
plt.title('Training Loss Curve')
plt.show()
总结
通过本文的数学推导和 Python 实现,我们完整展示了 BP 神经网络的计算过程。关键点包括:
- 理解前向传播和反向传播的数学原理
- 正确处理矩阵维度关系
- 选择合适的学习率和激活函数
- 通过 XOR 问题验证网络效果
建议读者可以尝试修改网络结构 (如增加隐藏层)、更换激活函数 (如 ReLU)、或尝试更复杂的数据集来加深理解。
正文完
