You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PyTorch中SGD优化器批量循环内固定LR的实现问题

解决方案

1. 调整学习率调度器的更新时机

问题根源是你把scheduler.step()放在了batch循环内部,导致每个batch都更新学习率。正确做法是将scheduler.step()移到每个epoch循环的末尾,这样整个epoch内所有batch共享同一学习率,仅在epoch结束后更新下一轮的LR。

2. 实现最优模型保存逻辑

通过跟踪验证集指标(损失或准确率),实时保存表现最优的模型权重。

完整代码示例

import torch
import torch.nn as nn
from torch.optim import SGD
from torch.optim.lr_scheduler import LinearLR

# 示例模型(根据你的任务替换为实际模型)
model = nn.Linear(X_train.shape[1], 1)
# 损失函数(分类任务替换为CrossEntropyLoss)
criterion = nn.MSELoss()
optimizer = SGD(model.parameters(), lr=0.1)
# 初始化LinearLR:比如5个epoch内从初始LR降到0.1倍
scheduler = LinearLR(optimizer, start_factor=1.0, end_factor=0.1, total_iters=5)

# 初始化最优指标与模型存储路径
best_val_loss = float('inf')
best_model_path = 'best_model.pth'

num_epochs = 10
for epoch in range(num_epochs):
    # 训练模式
    model.train()
    train_loss = 0.0

    # Batch循环(这里按32样本分batch,替换为你的DataLoader或遍历方式)
    for X_batch, y_batch in zip(X_train.split(32), y_train.split(32)):
        optimizer.zero_grad()
        outputs = model(X_batch)
        loss = criterion(outputs, y_batch)
        loss.backward()
        optimizer.step()  # 仅更新模型参数,不改动LR
        train_loss += loss.item() * X_batch.size(0)
    
    train_loss /= len(X_train)

    # 验证阶段
    model.eval()
    val_loss = 0.0
    with torch.no_grad():
        for X_batch, y_batch in zip(X_test.split(32), y_test.split(32)):
            outputs = model(X_batch)
            loss = criterion(outputs, y_batch)
            val_loss += loss.item() * X_batch.size(0)
    val_loss /= len(X_test)

    print(f'Epoch {epoch+1}/{num_epochs}, 训练损失: {train_loss:.4f}, 验证损失: {val_loss:.4f}, 当前LR: {optimizer.param_groups[0]["lr"]:.6f}')

    # 保存最优模型
    if val_loss < best_val_loss:
        best_val_loss = val_loss
        torch.save(model.state_dict(), best_model_path)
        print(f'更新最优模型,当前验证损失: {best_val_loss:.4f}')

    # 每个epoch结束后更新学习率
    scheduler.step()

# 训练完成后加载最优模型
model.load_state_dict(torch.load(best_model_path))

关键说明

  • Batch内LR固定:scheduler.step()仅在epoch末尾执行,确保整个epoch的所有batch使用同一学习率,避免LR过早下降。
  • 最优模型保存:通过比较验证集指标(这里用损失,分类任务可替换为准确率),保留性能最好的模型权重,规避训练后期过拟合导致的性能下滑。

内容的提问来源于stack exchange,提问作者Marios Karaoulis

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.29 18:07:14