32. 小批量梯度下降法(Mini-batch Gradient Descent)

在深度学习模型的训练过程中,梯度下降法是最常用的优化算法之一。我们前面介绍了批量梯度下降法(Batch Gradient Descent)和随机梯度下降法(Stochastic Gradient Descent),两者各有优缺点。为了在计算速度和收敛稳定性之间找到平衡,小批量梯度下降法(Mini-batch Gradient Descent)应运而生。下面我们详细介绍其基本思想、优缺点,并通过代码实现来比较三种梯度下降法。

小批量梯度下降法的基本思想

小批量梯度下降法在每次迭代中,使用一小部分随机样本(称为小批量)来计算梯度,并更新参数值。具体来说,算法步骤如下:

  1. 初始化参数 \( w \) 和 \( b \)。

  2. 在每次迭代中,从训练集中随机抽取 \( m \) 个样本。

  3. 使用这 \( m \) 个样本计算损失函数的梯度。

  4. 更新参数 \( w \) 和 \( b \)。

其梯度计算公式如下:

\[

\begin{align*}

w &= w - \alpha \cdot \frac{1}{m} \sum_{i=1}^{m} \nabla_w L(w, b, x_i, y_i), \\

b &= b - \alpha \cdot \frac{1}{m} \sum_{i=1}^{m} \nabla_b L(w, b, x_i, y_i),

\end{align*}

\]

其中,\( \alpha \) 是学习率,\( m \) 是小批量的大小。

优缺点

优点

  1. 计算速度快:与批量梯度下降法相比,每次迭代只需计算小批量样本的梯度,速度更快。

  2. 减少振荡:与随机梯度下降法相比,梯度的计算更加稳定,减少了参数更新时的振荡。

  3. 控制灵活:可以调整小批量的大小,使得训练速度和精度之间达到平衡。

缺点

  1. 需要调整学习率和小批量大小:学习率决定每次更新的步长,小批量大小决定每次计算梯度使用的样本数量。

  2. 内存消耗:小批量大小的选择受限于内存容量,尤其在使用GPU运算时,需要选择合适的小批量大小。

代码实现

下面通过代码实现和比较三种梯度下降法的执行效果。

python 复制代码
import torch
import torch.nn as nn
import torch.optim as optim
from torch.utils.data import DataLoader, TensorDataset
import numpy as np
import matplotlib.pyplot as plt
from tqdm import tqdm

# 定义数据集
np.random.seed(42)
X = np.random.rand(1000, 1)
y = 3*X + 2 + np.random.randn(1000, 1) * 0.1

# 转换为tensor
X_tensor = torch.tensor(X, dtype=torch.float32)
y_tensor = torch.tensor(y, dtype=torch.float32)

# 封装为数据集
dataset = TensorDataset(X_tensor, y_tensor)

# 定义模型
class LinearRegressionModel(nn.Module):
    def __init__(self):
        super(LinearRegressionModel, self).__init__()
        self.linear = nn.Linear(1, 1)
    
    def forward(self, x):
        return self.linear(x)

# 损失函数
criterion = nn.MSELoss()

# 定义梯度下降法的批量大小
batch_sizes = [1000, 1, 128]
batch_labels = ['Batch Gradient Descent', 'Stochastic Gradient Descent', 'Mini-batch Gradient Descent']
colors = ['r', 'g', 'b']

# 定义超参数
learning_rate = 0.01
num_epochs = 1000

# 存储损失值
losses = {label: [] for label in batch_labels}

# 训练模型
for batch_size, label, color in zip(batch_sizes, batch_labels, colors):
    model = LinearRegressionModel()
    optimizer = optim.SGD(model.parameters(), lr=learning_rate)
    
    data_loader = DataLoader(dataset, batch_size=batch_size, shuffle=True)
    
    for epoch in tqdm(range(num_epochs), desc=label):
        epoch_loss = 0.0
        for batch_x, batch_y in data_loader:
            optimizer.zero_grad()
            outputs = model(batch_x)
            loss = criterion(outputs, batch_y)
            loss.backward()
            optimizer.step()
            epoch_loss += loss.item()
        
        losses[label].append(epoch_loss / len(data_loader))

# 绘制损失值变化曲线
for label, color in zip(batch_labels, colors):
    plt.plot(losses[label], color=color, label=label)
plt.xlabel('Epoch')
plt.ylabel('Loss')
plt.legend()
plt.show()

结果分析

运行上述代码后,会显示三种梯度下降法在每个迭代周期(epoch)中的损失变化曲线。可以看到:

  1. 批量梯度下降法:损失曲线平滑,但训练速度较慢。

  2. 随机梯度下降法:训练速度快,但损失曲线波动较大。

  3. 小批量梯度下降法:在训练速度和损失曲线的稳定性之间达到了平衡,效果较为理想。

总结

小批量梯度下降法结合了批量梯度下降法和随机梯度下降法的优点,是深度学习中常用的优化算法。通过调整小批量大小和学习率,可以在训练速度和模型精度之间找到最佳平衡。在实际应用中,小批量梯度下降法由于其较高的效率和较好的收敛效果,被广泛应用于各类深度学习模型的训练中。

相关推荐
侃侃_天下3 天前
最终的信号类
开发语言·c++·算法
echoarts3 天前
Rayon Rust中的数据并行库入门教程
开发语言·其他·算法·rust
Aomnitrix3 天前
知识管理新范式——cpolar+Wiki.js打造企业级分布式知识库
开发语言·javascript·分布式
每天回答3个问题3 天前
UE5C++编译遇到MSB3073
开发语言·c++·ue5
伍哥的传说3 天前
Vite Plugin PWA – 零配置构建现代渐进式Web应用
开发语言·前端·javascript·web app·pwa·service worker·workbox
小莞尔3 天前
【51单片机】【protues仿真】 基于51单片机八路抢答器系统
c语言·开发语言·单片机·嵌入式硬件·51单片机
我是菜鸟0713号3 天前
Qt 中 OPC UA 通讯实战
开发语言·qt
JCBP_3 天前
QT(4)
开发语言·汇编·c++·qt·算法
Brookty3 天前
【JavaEE】线程安全-内存可见性、指令全排序
java·开发语言·后端·java-ee·线程安全·内存可见性·指令重排序
百锦再3 天前
[特殊字符] Python在CentOS系统执行深度指南
开发语言·python·plotly·django·centos·virtualenv·pygame