【深度学习笔记 Ⅱ】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)而不是手动实现。

相关推荐
BarbaraChow16 分钟前
Seed-VC:零样本语音转换与扩散transformer
人工智能·深度学习·transformer
ChironW39 分钟前
Ubuntu 22.04 离线环境下完整安装 Anaconda、CUDA 12.1、NVIDIA 驱动及 cuDNN 8.9.3 教程
linux·运维·人工智能·深度学习·yolo·ubuntu
我们从未走散1 小时前
JVM学习笔记-----图解方法执行流程
笔记·学习
zl291 小时前
论文学习22:UNETR: Transformers for 3D Medical Image Segmentation
深度学习·学习·transformer
再睡一夏就好2 小时前
【排序算法】④堆排序
c语言·数据结构·c++·笔记·算法·排序算法
是Dream呀2 小时前
YOLOv9:重构实时目标检测的技术革命
深度学习·机器学习
码流怪侠3 小时前
Google SoundStream音频编解码器技术解析
深度学习·音视频开发
丰锋ff4 小时前
计算机网络摘星题库800题笔记 第4章 网络层
网络·笔记·计算机网络
计算机sci论文精选5 小时前
CVPR 2025丨机器人如何做看懂世界
人工智能·深度学习·机器学习·机器人·github·人机交互·cvpr
草莓熊Lotso5 小时前
【C语言强化训练16天】--从基础到进阶的蜕变之旅:Day2
c语言·经验分享·笔记·其他