【深度学习笔记 Ⅱ】8 mini-batch 梯度下降法

1. 什么是Mini-Batch梯度下降法

Mini-Batch梯度下降法是介于批量梯度下降(Batch Gradient Descent)和随机梯度下降(Stochastic Gradient Descent, SGD)之间的一种优化算法。它的工作原理是:

  • 将整个训练集分成若干个小批量(mini-batches)
  • 每次迭代使用一个小批量来计算梯度并更新参数
  • 遍历完所有小批量称为一个epoch

三种梯度下降方法对比:

方法 每次迭代使用的样本量 优点 缺点
批量梯度下降 全部训练样本 梯度计算准确,收敛稳定 计算量大,内存要求高
随机梯度下降 单个样本 计算快,可在线学习 梯度波动大,收敛不稳定
Mini-Batch梯度下降 小批量样本 平衡计算效率和收敛稳定性 需要选择合适的小批量大小

2. Mini-Batch梯度下降的优点

  1. 计算效率:比批量梯度下降更快,因为每次迭代计算量小
  2. 收敛稳定性:比随机梯度下降更稳定,梯度估计方差小
  3. 内存友好:特别适合无法将全部数据放入内存的大数据集
  4. 硬件加速:可以利用现代计算硬件的并行计算能力

3. 代码实现

以下是使用Python和NumPy实现Mini-Batch梯度下降的示例代码:

3.1 线性回归的Mini-Batch梯度下降

python 复制代码
import numpy as np
import matplotlib.pyplot as plt

# 生成模拟数据
np.random.seed(42)
X = 2 * np.random.rand(100, 1)
y = 4 + 3 * X + np.random.randn(100, 1)

# 添加偏置项
X_b = np.c_[np.ones((100, 1)), X]

# Mini-Batch梯度下降参数
n_epochs = 50
batch_size = 10
m = len(X_b)  # 样本数量
learning_rate = 0.1

# 随机初始化参数
theta = np.random.randn(2, 1)

# 存储损失历史
loss_history = []

for epoch in range(n_epochs):
    # 打乱数据
    shuffled_indices = np.random.permutation(m)
    X_b_shuffled = X_b[shuffled_indices]
    y_shuffled = y[shuffled_indices]
    
    for i in range(0, m, batch_size):
        # 获取当前mini-batch
        xi = X_b_shuffled[i:i+batch_size]
        yi = y_shuffled[i:i+batch_size]
        
        # 计算梯度
        gradients = 2/batch_size * xi.T.dot(xi.dot(theta) - yi)
        
        # 更新参数
        theta = theta - learning_rate * gradients
    
    # 计算并存储整个训练集的损失
    loss = np.mean((X_b.dot(theta) - y)**2)
    loss_history.append(loss)

# 绘制训练过程
plt.plot(range(n_epochs), loss_history, 'b-')
plt.xlabel('Epochs')
plt.ylabel('MSE')
plt.title('Mini-Batch Gradient Descent')
plt.show()

print("最终参数:", theta)

3.2 使用PyTorch实现Mini-Batch梯度下降

python 复制代码
import torch
import torch.nn as nn
from torch.utils.data import DataLoader, TensorDataset

# 生成数据
X = torch.rand(100, 1) * 2
y = 4 + 3 * X + torch.randn(100, 1)

# 创建数据集和数据加载器
dataset = TensorDataset(X, y)
dataloader = DataLoader(dataset, batch_size=10, shuffle=True)

# 定义线性模型
model = nn.Linear(1, 1)
criterion = nn.MSELoss()
optimizer = torch.optim.SGD(model.parameters(), lr=0.1)

# 训练循环
n_epochs = 50
loss_history = []

for epoch in range(n_epochs):
    for X_batch, y_batch in dataloader:
        # 前向传播
        y_pred = model(X_batch)
        loss = criterion(y_pred, y_batch)
        
        # 反向传播
        optimizer.zero_grad()
        loss.backward()
        optimizer.step()
    
    # 计算整个数据集的损失
    with torch.no_grad():
        y_pred = model(X)
        epoch_loss = criterion(y_pred, y)
        loss_history.append(epoch_loss.item())

# 绘制训练过程
plt.plot(range(n_epochs), loss_history, 'b-')
plt.xlabel('Epochs')
plt.ylabel('MSE')
plt.title('PyTorch Mini-Batch Gradient Descent')
plt.show()

print("最终参数:")
print("权重:", model.weight.data)
print("偏置:", model.bias.data)

4. Mini-Batch梯度下降的注意事项

  1. 批量大小的选择

    • 常用值:32, 64, 128, 256
    • 较小的批量:更快的训练,但梯度估计噪声大
    • 较大的批量:梯度估计更准确,但计算量增加
  2. 学习率调整

    • Mini-Batch通常需要比批量梯度下降更小的学习率
    • 可以考虑学习率衰减策略
  3. 数据洗牌(Shuffling)

    • 每个epoch前洗牌数据很重要,防止模型学习到数据顺序
  4. 归一化

    • 对输入特征进行归一化可以加速收敛
  5. 早停(Early Stopping)

    • 监控验证集性能,防止过拟合

Mini-Batch梯度下降是现代深度学习中最常用的优化方法之一,大多数深度学习框架都提供了高效实现。在实际应用中,通常使用框架内置的优化器(如PyTorch的SGD或Adam)而不是手动实现。

相关推荐
葡萄成熟时 !3 小时前
JAVA 常用API学习笔记
java·笔记·学习
DevOpenClub4 小时前
个人公开市场研究笔记功能需求文档
笔记
十三画者5 小时前
【文献分享】ConfRetro:融合3D构象信息的逆合成预测Transformer框架
人工智能·深度学习·数据挖掘·数据分析·transformer·数据可视化
雷帝木木7 小时前
数据湖与数据仓库:从理论到实践
人工智能·python·深度学习·机器学习
yanghuashuiyue8 小时前
RNN结构记录
人工智能·rnn·深度学习
不会代码的小猴9 小时前
7. JSON
开发语言·c++·笔记·qt·算法·json
GGMM78910 小时前
富士 EP‑3955D 变频器主板维修调试笔记
笔记·变频器·变频器维修
今儿敲了吗11 小时前
CN——网络层(上)
网络·笔记
PC2005-cloud11 小时前
Go学习笔记:基本概念与项目结构——GOPATH、Go Modules 与常用命令
笔记·学习·golang
%4711 小时前
DAY 38
人工智能·pytorch·深度学习