共计 2071 个字符,预计需要花费 6 分钟才能阅读完成。
神经网络基础概念
BP 神经网络(Backpropagation Neural Network)是一种多层前馈网络,其核心是通过正向传播计算输出,再通过反向传播调整权重。理解这两个过程的关键在于掌握链式法则的应用。

-
正向传播 :输入数据从输入层经过隐藏层传递到输出层,每一层都会进行线性变换(权重与输入的乘积加上偏置)和非线性激活(如 Sigmoid 或 ReLU)。
-
反向传播 :通过计算损失函数对权重的梯度,利用梯度下降法更新权重。链式法则在此过程中起到关键作用,它将误差从输出层逐层传递回输入层。
数学推导
正向传播
假设我们有一个简单的 3 层网络(输入层、隐藏层、输出层),隐藏层和输出层的激活函数为 Sigmoid。
-
隐藏层输出 :
$$
z^{(1)} = W^{(1)}x + b^{(1)}
$$
$$
a^{(1)} = \sigma(z^{(1)})
$$ -
输出层输出 :
$$
z^{(2)} = W^{(2)}a^{(1)} + b^{(2)}
$$
$$
a^{(2)} = \sigma(z^{(2)})
$$
反向传播
反向传播的目标是计算损失函数对权重和偏置的梯度。以均方误差(MSE)为例:
-
输出层梯度 :
$$
\delta^{(2)} = (a^{(2)} – y) \cdot \sigma'(z^{(2)})
$$
$$
\frac{\partial L}{\partial W^{(2)}} = a^{(1)T} \delta^{(2)}
$$ -
隐藏层梯度 :
$$
\delta^{(1)} = (W^{(2)T} \delta^{(2)}) \cdot \sigma'(z^{(1)})
$$
$$
\frac{\partial L}{\partial W^{(1)}} = x^T \delta^{(1)}
$$
Python 实现
以下是一个简单的 BP 网络实现,包含正向传播和反向传播的核心代码:
import numpy as np
class NeuralNetwork:
def __init__(self, input_size, hidden_size, output_size):
self.W1 = np.random.randn(input_size, hidden_size)
self.b1 = np.zeros(hidden_size)
self.W2 = np.random.randn(hidden_size, output_size)
self.b2 = np.zeros(output_size)
def sigmoid(self, x):
return 1 / (1 + np.exp(-x))
def sigmoid_derivative(self, x):
return self.sigmoid(x) * (1 - self.sigmoid(x))
def forward(self, X):
self.z1 = np.dot(X, self.W1) + self.b1
self.a1 = self.sigmoid(self.z1)
self.z2 = np.dot(self.a1, self.W2) + self.b2
self.a2 = self.sigmoid(self.z2)
return self.a2
def backward(self, X, y, learning_rate):
m = X.shape[0]
# 输出层误差
delta2 = (self.a2 - y) * self.sigmoid_derivative(self.z2)
dW2 = np.dot(self.a1.T, delta2) / m
db2 = np.sum(delta2, axis=0) / m
# 隐藏层误差
delta1 = np.dot(delta2, self.W2.T) * self.sigmoid_derivative(self.z1)
dW1 = np.dot(X.T, delta1) / m
db1 = np.sum(delta1, axis=0) / m
# 更新权重
self.W2 -= learning_rate * dW2
self.b2 -= learning_rate * db2
self.W1 -= learning_rate * dW1
self.b1 -= learning_rate * db1
调优实践
学习率选择
- 学习率太大 :可能导致模型震荡甚至发散。
- 学习率太小 :收敛速度过慢。
解决方案 :使用学习率衰减或自适应优化算法(如 Adam)。
梯度消失问题
梯度消失常见于深层网络,尤其是使用 Sigmoid 激活函数时。
解决方案 :
- 使用 ReLU 等非饱和激活函数。
- 使用批量归一化(Batch Normalization)。
- 合理的参数初始化(如 He 初始化)。
参数初始化
- 全零初始化 :会导致所有神经元学习相同的特征。
- 随机初始化 :建议使用 Xavier 或 He 初始化。
常见错误排查
- 梯度爆炸或消失 :检查激活函数和初始化方法。
- 模型不收敛 :调整学习率或检查数据预处理。
- 过拟合 :添加 Dropout 或正则化项。
下一步尝试
- 比较不同激活函数 :尝试 ReLU、Tanh 等,观察训练效果。
- 实现 Mini-batch 梯度下降 :提升训练效率。
- 添加 L2 正则化 :防止过拟合。
通过本文的学习,你应该能够理解 BP 网络的核心原理,并实现一个基本的训练流程。接下来可以尝试更复杂的网络结构和优化技巧,进一步提升模型性能。
