BP神经网络框架图解析:从数学原理到Python实现

1次阅读
没有评论

共计 1193 个字符,预计需要花费 3 分钟才能阅读完成。

image.webp

神经网络的数据流动可视化

我们先从一个三层的 BP 神经网络框架图开始理解(假设输入层、隐藏层、输出层节点数分别为 n、m、k):

BP 神经网络框架图解析:从数学原理到 Python 实现

输入 x ∈ Rⁿ → 隐藏层 W₁∈Rⁿˣᵐ → Sigmoid → 输出层 W₂∈Rᵐˣᵏ → Sigmoid → 预测值 ŷ
           ↑                    ↑                    ↑
           δ₂=g'(z₂)∘(ŷ-y)      δ₁=g'(z₁)∘(W₂ᵀδ₂)   

矩阵维度变化规律:

  • 前向传播时:(batch_size, n) × (n, m) → (batch_size, m)
  • 反向传播时:δ₂ ∈ Rᵏ会通过 W₂ᵀ ∈ Rᵏˣᵐ 反向传播到隐藏层

核心实现细节

1. Sigmoid 的数值稳定性处理

传统实现直接套公式会导致数值溢出:

def unsafe_sigmoid(x):
    return 1 / (1 + np.exp(-x))  # 当 x <-100 时返回 0 

改进方案添加边界判断:

def safe_sigmoid(x):
    mask = x >= 0
    positive = 1 / (1 + np.exp(-x[mask]))
    negative = np.exp(x[~mask]) / (1 + np.exp(x[~mask]))
    return np.concatenate([positive, negative])

2. 向量化梯度计算对比

循环版本(慢):

for i in range(batch_size):
    grad_W += X[i].T.dot(delta[i])  # 每次处理单个样本

矩阵版本(快 10 倍):

grad_W = X.T.dot(delta) / batch_size  # 一次性计算所有样本

3. 学习率衰减策略

余弦退火示例:

lr = base_lr * (1 + math.cos(epoch * math.pi / max_epoch)) / 2

避坑实践指南

权重初始化

  • Xavier 初始化:W = np.random.randn(n, m) * np.sqrt(2/(n+m))
  • 适用于 Sigmoid/Tanh 的变种:scale = np.sqrt(6/(n+m))

梯度检查

用数值梯度验证解析梯度:

def check_grad(W, f, eps=1e-5):
    analytical_grad = compute_grad(W) 
    numerical_grad = (f(W+eps) - f(W-eps)) / (2*eps)
    return np.allclose(analytical_grad, numerical_grad)

性能优化技巧

Numba 加速

from numba import jit

@jit(nopython=True)
def forward(x, W):
    return x.dot(W)  # 编译为机器码

内存映射大文件

X = np.memmap('data.bin', dtype='float32', 
              mode='r', shape=(1e6, 1000))

思考题延伸

当使用 ReLU 时:

  1. 反向传播路径中:δ₁ = (W₂ᵀδ₂) * (z₁ > 0)
  2. 需要调整初始化策略(He 初始化)
  3. 框架图中需增加对负梯度的截断处理

完整实现代码见:[GitHub 链接]

正文完
 0
评论(没有评论)