深度学习入门:从零理解BGD反向传播算法及其实现

1次阅读
没有评论

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

image.webp

背景介绍

反向传播算法是神经网络训练的基石,而批量梯度下降(BGD)是最基础但重要的优化方法之一。BGD 的核心思想是使用整个训练集计算梯度,然后更新权重。虽然计算成本较高,但梯度方向稳定,适合理解反向传播的本质。

深度学习入门:从零理解 BGD 反向传播算法及其实现

对于初学者来说,BGD 反向传播提供了一个清晰的学习路径:

  • 完整展示梯度如何从输出层反向传播到输入层
  • 帮助建立对损失函数、参数更新的直观理解
  • 为学习更复杂的优化方法奠定基础

数学原理

前向传播

对于一个简单的 3 层神经网络(输入层、隐藏层、输出层),前向传播过程可以表示为:

  1. 隐藏层激活值:
    $$h = \sigma(W_1x + b_1)$$
  2. 输出层预测值:
    $$\hat{y} = \sigma(W_2h + b_2)$$

其中 $\sigma$ 是激活函数(如 sigmoid),$W$ 是权重矩阵,$b$ 是偏置项。

损失计算

使用均方误差(MSE)作为损失函数:

$$L = \frac{1}{2N}\sum_{i=1}^N(y_i – \hat{y}_i)^2$$

反向传播

关键是通过链式法则计算各层参数的梯度:

  1. 输出层梯度:
    $$\frac{\partial L}{\partial W_2} = (\hat{y} – y) \cdot \sigma'(z_2) \cdot h^T$$
  2. 隐藏层梯度:
    $$\frac{\partial L}{\partial W_1} = W_2^T \cdot [(\hat{y} – y) \cdot \sigma'(z_2)] \cdot \sigma'(z_1) \cdot x^T$$

其中 $z$ 表示激活函数的输入。

Python 实现

import numpy as np

# 定义 sigmoid 激活函数及其导数
def sigmoid(x):
    return 1 / (1 + np.exp(-x))

def sigmoid_derivative(x):
    return x * (1 - x)

# 初始化参数
input_size = 2
hidden_size = 3
output_size = 1
lr = 0.1
epochs = 1000

# 随机初始化权重
W1 = np.random.randn(input_size, hidden_size)
W2 = np.random.randn(hidden_size, output_size)

# 模拟训练数据
X = np.array([[0,0], [0,1], [1,0], [1,1]])  # 输入
Y = np.array([[0], [1], [1], [0]])           # 输出(XOR 问题)

# BGD 训练过程
for epoch in range(epochs):
    # 前向传播
    hidden_input = np.dot(X, W1)
    hidden_output = sigmoid(hidden_input)

    final_input = np.dot(hidden_output, W2)
    final_output = sigmoid(final_input)

    # 计算损失
    loss = np.mean(0.5 * (Y - final_output) ** 2)

    # 反向传播
    # 输出层误差
    output_error = Y - final_output
    output_delta = output_error * sigmoid_derivative(final_output)

    # 隐藏层误差
    hidden_error = output_delta.dot(W2.T)
    hidden_delta = hidden_error * sigmoid_derivative(hidden_output)

    # 更新权重
    W2 += hidden_output.T.dot(output_delta) * lr
    W1 += X.T.dot(hidden_delta) * lr

    if epoch % 100 == 0:
        print(f'Epoch {epoch}, Loss: {loss:.4f}')

print("Training complete")
print("Final predictions:", final_output)

参数调优

学习率 (lr) 是 BGD 中最重要的超参数:

  • 学习率太小:收敛速度慢,需要更多 epoch
  • 学习率太大:可能导致震荡甚至发散

调参建议:

  1. 初始尝试 0.1,观察训练曲线
  2. 如果损失波动大,尝试降低学习率
  3. 使用学习率衰减策略,如每 100 个 epoch 减半
  4. 结合验证集监控模型性能

对比分析

方法 批量大小 稳定性 计算效率 适用场景
BGD 全部样本 小型数据集
SGD 1 个样本 在线学习
Mini-batch 小批量 中等 中等 大多数场景

避坑指南

  1. 梯度消失:使用 ReLU 等激活函数替代 sigmoid
  2. 初始化问题:避免全零初始化,使用 Xavier/Glorot 初始化
  3. 学习率选择:建议从 0.01-0.1 开始尝试
  4. 特征缩放:确保输入特征在相似范围
  5. 梯度检查:实现后建议用数值梯度验证

实践建议

  1. 在 MNIST 等标准数据集上练习实现
  2. 尝试可视化权重和梯度的变化
  3. 扩展实现不同的激活函数和损失函数
  4. 参考资源:
  5. 《深度学习》Ian Goodfellow
  6. CS231n 课程笔记
  7. PyTorch/TensorFlow 官方教程

思考题

  1. 如何修改代码实现学习率衰减?衰减策略如何影响训练?
  2. 当隐藏层增加到 3 层时,反向传播的公式会如何变化?尝试推导并实现。

通过这篇教程,希望你能掌握 BGD 反向传播的核心思想。虽然现代深度学习框架已经封装了这些细节,但理解底层原理对于调试模型和解决实际问题至关重要。建议动手实现几次,直到能够不参考代码独立完成。

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