共计 2807 个字符,预计需要花费 8 分钟才能阅读完成。
BP 神经网络的基础地位
BP 神经网络(Backpropagation Neural Network)是深度学习的基础算法之一,它通过不断调整网络中的权重和偏置,使网络能够学习输入和输出之间的复杂关系。BP 算法的核心是反向传播误差,通过梯度下降优化网络参数。这种算法在图像识别、语音处理、自然语言处理等领域都有广泛应用。

数学推导
前向传播的矩阵表示
前向传播的过程可以用矩阵乘法简洁表示。对于一个三层的神经网络,输入层到隐藏层的计算可以表示为:
$$ h = \sigma(W_1 x + b_1) $$
其中,$W_1$ 是权重矩阵,$x$ 是输入向量,$b_1$ 是偏置向量,$\sigma$ 是激活函数(如 Sigmoid 或 ReLU)。
隐藏层到输出层的计算类似:
$$ y = \sigma(W_2 h + b_2) $$
损失函数对权重的偏导
反向传播的关键是计算损失函数对权重的偏导数。以均方误差(MSE)为例,损失函数为:
$$ L = \frac{1}{2} (y – \hat{y})^2 $$
通过链式法则,可以分解为:
$$ \frac{\partial L}{\partial W_2} = \frac{\partial L}{\partial y} \cdot \frac{\partial y}{\partial W_2} $$
$$ \frac{\partial L}{\partial W_1} = \frac{\partial L}{\partial y} \cdot \frac{\partial y}{\partial h} \cdot \frac{\partial h}{\partial W_1} $$
学习率与梯度下降
梯度下降的更新规则为:
$$ W = W – \eta \cdot \frac{\partial L}{\partial W} $$
其中,$\eta$ 是学习率,控制每次更新的步长。学习率过大可能导致震荡,过小则收敛缓慢。
Python 实现
纯 Python + NumPy 实现
import numpy as np
class NeuralNetwork:
def __init__(self, input_size, hidden_size, output_size):
self.W1 = np.random.randn(input_size, hidden_size) * 0.01
self.b1 = np.zeros((1, hidden_size))
self.W2 = np.random.randn(hidden_size, output_size) * 0.01
self.b2 = np.zeros((1, output_size))
def forward(self, x):
self.h = np.dot(x, self.W1) + self.b1
self.h_activated = 1 / (1 + np.exp(-self.h)) # Sigmoid
self.y = np.dot(self.h_activated, self.W2) + self.b2
return self.y
def backward(self, x, y_true, learning_rate):
m = x.shape[0]
dy = self.y - y_true
dW2 = np.dot(self.h_activated.T, dy) / m
db2 = np.sum(dy, axis=0, keepdims=True) / m
dh_activated = np.dot(dy, self.W2.T)
dh = dh_activated * self.h_activated * (1 - self.h_activated)
dW1 = np.dot(x.T, dh) / m
db1 = np.sum(dh, axis=0, keepdims=True) / m
self.W2 -= learning_rate * dW2
self.b2 -= learning_rate * db2
self.W1 -= learning_rate * dW1
self.b1 -= learning_rate * db1
标准化输入处理
def normalize(x):
return (x - np.mean(x, axis=0)) / np.std(x, axis=0)
梯度检查
梯度检查用于验证反向传播的实现是否正确。通过数值方法近似计算梯度,与反向传播的结果对比:
def gradient_check(x, y_true, network, epsilon=1e-7):
params = network.W1.flatten()
grad = np.zeros_like(params)
for i in range(len(params)):
params_plus = params.copy()
params_plus[i] += epsilon
network.W1 = params_plus.reshape(network.W1.shape)
loss_plus = np.mean((network.forward(x) - y_true) ** 2)
params_minus = params.copy()
params_minus[i] -= epsilon
network.W1 = params_minus.reshape(network.W1.shape)
loss_minus = np.mean((network.forward(x) - y_true) ** 2)
grad[i] = (loss_plus - loss_minus) / (2 * epsilon)
return grad
工程实践
权重初始化
- Xavier 初始化 :适用于 Sigmoid 和 Tanh 激活函数,权重初始化为 $W \sim U(-\sqrt{6/n_{in} + n_{out}}, \sqrt{6/n_{in} + n_{out}})$
- He 初始化 :适用于 ReLU 激活函数,权重初始化为 $W \sim N(0, \sqrt{2/n_{in}})$
学习率衰减
常见的学习率衰减策略包括:
- 固定步长衰减:每隔一定 epoch,学习率乘以一个衰减系数
- 指数衰减:学习率按指数函数衰减
- 余弦退火:学习率按余弦函数周期变化
批量归一化
批量归一化(Batch Normalization)通常在全连接层或卷积层之后、激活函数之前应用:
def batch_norm(x, gamma, beta, eps=1e-5):
mu = np.mean(x, axis=0)
var = np.var(x, axis=0)
x_norm = (x - mu) / np.sqrt(var + eps)
return gamma * x_norm + beta
思考题
- 计算图优化 :如何利用计算图(如 TensorFlow 或 PyTorch 的自动微分)优化反向传播的效率?
- 自动微分与手动实现 :对比自动微分框架(如 Autograd)与手动实现反向传播的优缺点,哪种更适合大规模网络?
总结
BP 神经网络是深度学习的基础,理解其数学原理和实现细节对后续学习更复杂的模型至关重要。通过手动实现 BP 算法,可以深入理解梯度下降和反向传播的工作机制。在实际工程中,合理的权重初始化、学习率策略和批量归一化能显著提升训练效果。
