共计 2040 个字符,预计需要花费 6 分钟才能阅读完成。
神经网络基础回顾
神经网络由多层神经元组成,每一层通过权重矩阵 $W$ 和偏置向量 $b$ 连接到下一层。一个典型的全连接网络(FCN)中,第 $l$ 层的输出 $a^l$ 通过激活函数 $\sigma$ 处理:

$$
a^l = \sigma(W^l a^{l-1} + b^l)
$$
其中输入层 $a^0=X$ 为原始数据,输出层 $a^L$ 为预测结果。训练目标是找到最优参数 $\theta={W,b}$ 使得损失函数 $J(\theta)$ 最小化。
前向传播算法详解
前向传播是数据从输入层流向输出层的过程,核心步骤:
- 线性变换:$z^l = W^l a^{l-1} + b^l$
- 激活计算:$a^l = \sigma(z^l)$
以 Sigmoid 激活函数为例:
$$
\sigma(z) = \frac{1}{1+e^{-z}}
$$
前向传播最终输出预测值 $\hat{y}=a^L$,并与真实值 $y$ 比较计算损失(如交叉熵损失):
$$
J(\theta) = -\frac{1}{m}\sum_{i=1}^m [y^{(i)}\log\hat{y}^{(i)} + (1-y^{(i)})\log(1-\hat{y}^{(i)})]
$$
反向传播算法推导
反向传播通过链式法则计算损失对各参数的梯度:
- 输出层误差:$\delta^L = \nabla_a J \odot \sigma'(z^L)$
- 隐藏层误差:$\delta^l = (W^{l+1})^T \delta^{l+1} \odot \sigma'(z^l)$
- 参数梯度:
- $\frac{\partial J}{\partial W^l} = \delta^l (a^{l-1})^T$
- $\frac{\partial J}{\partial b^l} = \delta^l$
其中 $\odot$ 表示逐元素乘法。推导时需注意 Sigmoid 的导数为 $\sigma'(z)=\sigma(z)(1-\sigma(z))$。
Python 实现与代码解析
import numpy as np
class NeuralNetwork:
def __init__(self, layers):
# 初始化权重和偏置
self.W = [np.random.randn(y, x)*0.01 for x,y in zip(layers[:-1], layers[1:])]
self.b = [np.zeros((y,1)) for y in layers[1:]]
def sigmoid(self, z):
return 1/(1+np.exp(-z))
def forward(self, X):
# 前向传播
self.a = [X]
for W, b in zip(self.W, self.b):
z = np.dot(W, self.a[-1]) + b
self.a.append(self.sigmoid(z))
return self.a[-1]
def backward(self, X, y, learning_rate):
# 反向传播
m = X.shape[1]
delta = (self.a[-1] - y) * self.a[-1] * (1-self.a[-1]) # 输出层误差
for l in range(len(self.W)-1, -1, -1):
dW = np.dot(delta, self.a[l].T)/m
db = np.sum(delta, axis=1, keepdims=True)/m
# 参数更新
self.W[l] -= learning_rate * dW
self.b[l] -= learning_rate * db
if l > 0: # 计算下一层误差
delta = np.dot(self.W[l].T, delta) * self.a[l] * (1-self.a[l])
关键实现说明:
1. 权重初始化采用小随机数(乘以 0.01),避免初始激活值饱和
2. 批量处理时梯度需除以样本数 m(/m)
3. 反向传播时需倒序处理各层参数
常见问题与优化方案
梯度消失 / 爆炸
- 现象:深层网络中梯度指数级减小或增大
- 解决方案:
- 使用 ReLU 等非饱和激活函数
- 权重初始化改进(如 He 初始化)
- 残差连接(ResNet)
训练振荡
- 现象:损失值波动大
- 解决方案:
- 学习率衰减(如
lr *= 0.95每 epoch) - 动量优化(Momentum/RMSprop)
- 梯度裁剪(
np.clip(grad, -1, 1))
过拟合
- 方案:
- Dropout(训练时随机断开神经元)
- L2 正则化(损失函数中添加 $\frac{\lambda}{2}||W||^2$)
实践任务与思考题
任务:修改上述代码实现以下实验:
1. 将网络结构改为[2,4,3,1],观察训练效果变化
2. 尝试用 ReLU 替换 Sigmoid,需调整反向传播的导数计算
3. 添加学习率衰减策略(如每 100 步降低 10%)
思考:
– 为什么深层网络更容易出现梯度消失?
– 批量归一化(BatchNorm)如何帮助解决梯度问题?
– 如何验证反向传播计算的正确性?(提示:梯度检查)
通过这篇教程,你应该已经掌握了前向传播与反向传播的核心原理和实现方法。建议动手实践时配合 TensorBoard 等工具可视化训练过程,这将帮助你更直观地理解神经网络的运作机制。
