共计 1379 个字符,预计需要花费 4 分钟才能阅读完成。
为什么需要 BP 神经网络?
在图像识别、金融预测等领域,传统算法(如 SVM)难以处理高维非线性数据。BP 神经网络通过多层非线性变换,可实现:
- 手写数字识别(MNIST 准确率 98%+)
- 房价波动预测
- 用户行为分类
但新手常犯两个错误:
- 盲目堆叠层数导致梯度消失(如 10 层网络训练失败)
- 使用 Sigmoid 激活函数造成神经元饱和
数学原理图解
前向传播公式
隐藏层输出:
$$h = \sigma(W^T x + b)$$
其中 $\sigma$ 是激活函数,$W$ 为权重矩阵
反向传播核心
通过链式法则计算梯度:
- 输出层误差:
$$\delta^L = \nabla_a C \odot \sigma'(z^L)$$ - 隐藏层误差:
$$\delta^l = ((W^{l+1})^T \delta^{l+1}) \odot \sigma'(z^l)$$ - 参数更新:
$$W \leftarrow W – \eta \cdot \delta \cdot h^{T}$$
Python 实现关键模块
网络初始化(Xavier 方法)
def init_weights(layer_sizes):
params = {}
for i in range(1, len(layer_sizes)):
scale = np.sqrt(2./layer_sizes[i-1]) # ReLU 推荐初始化
params['W'+str(i)] = np.random.randn(layer_sizes[i], layer_sizes[i-1]) * scale
params['b'+str(i)] = np.zeros((layer_sizes[i], 1))
return params
ReLU 激活函数实现
def relu(x):
return np.maximum(0, x)
def relu_derivative(x):
return (x > 0).astype(float)
交叉熵损失计算
def cross_entropy(y_pred, y_true):
m = y_true.shape[1]
return -np.sum(y_true * np.log(y_pred + 1e-15)) / m # 加平滑项防 log(0)
训练过程可视化
损失曲线绘制
plt.plot(range(epochs), losses)
plt.xlabel('Epoch')
plt.ylabel('Loss')
plt.title('Training Loss Curve')
plt.show()

工业级优化方案
学习率衰减对比
-
指数衰减:
lr = initial_lr * (0.9 ** epoch) -
余弦退火:
lr = min_lr + 0.5*(max_lr-min_lr)*(1+np.cos(epoch/epochs * np.pi))
梯度裁剪示例
def clip_grads(grads, threshold):
total_norm = np.sqrt(sum(np.sum(g**2) for g in grads.values()))
scale = threshold / (total_norm + 1e-6)
if scale < 1:
return {k: v*scale for k,v in grads.items()}
return grads
进阶挑战
尝试用 PyTorch 重构上述代码,比较两者在 CIFAR-10 数据集上的表现差异。关键差异点:
- PyTorch 自动微分机制
- GPU 加速效果
- 内置优化器 (Adam/SGD) 性能
完整代码见:Colab 笔记本链接
正文完
