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

PyTorch中优化器运行顺序为何影响线性回归预测效果?

优化器训练顺序影响线性回归结果的原因分析

问题现象

在多优化器线性回归对比实验中发现:

  • 若先运行SGD优化器,后续Adam、RMSprop的预测精度表现良好;
  • 若先运行Adam或RMSprop,这两个优化器的模型调整效果极差,预测结果几乎无拟合效果。

实验代码

原始代码(非SGD先运行)

# Generate synthetic data
X_numpy, y_numpy = datasets.make_regression(n_samples=100, n_features=1, noise=20, random_state=15)

X = torch.from_numpy(X_numpy.astype(np.float32))
y = torch.from_numpy(y_numpy.astype(np.float32))
y = y.view(y.shape[0], 1)

# Define the model
n_samples, n_features = X.shape
input_size = n_features
output_size = 1
model = nn.Linear(input_size, output_size)

# Define learning rate
learning_rate = 0.01

# Define criteria
criterion = nn.MSELoss()

# Define different optimizers
optimizers = {    
    "Adam": torch.optim.Adam(model.parameters(), lr=learning_rate),
    "RMSprop": torch.optim.RMSprop(model.parameters(), lr=learning_rate),
    "SGD": torch.optim.SGD(model.parameters(), lr=learning_rate),
}

# Training loop for each optimizer
num_epochs = 100
predictions = {}
for optimizer_name, optimizer in optimizers.items():
    print(f"Optimizer: {optimizer_name}")
    predictions[optimizer_name] = []
    for epoch in range(num_epochs):        
        y_predicted = model(X)
        loss = criterion(y_predicted, y)
        loss.backward()
        optimizer.step() #update weights
        optimizer.zero_grad() #zero the gradients
    predictions[optimizer_name] = model(X).detach().numpy()

# Plotting predictions with different colors
plt.figure(figsize=(10, 6))
plt.plot(X_numpy, y_numpy, 'ro', label='Original Data')
for optimizer_name, prediction in predictions.items():
    plt.plot(X_numpy, prediction, label=optimizer_name)
plt.legend()
plt.show()

修改后代码(SGD先运行)

仅调整优化器字典的顺序:

optimizers = {    
    "SGD": torch.optim.SGD(model.parameters(), lr=learning_rate),
    "Adam": torch.optim.Adam(model.parameters(), lr=learning_rate),
    "RMSprop": torch.optim.RMSprop(model.parameters(), lr=learning_rate),
}

实验结果

非SGD先运行的预测结果

非SGD先运行的预测结果图

SGD先运行的预测结果

SGD先运行的预测结果图

原因解析

出现这种现象的核心问题是所有优化器共享同一个模型实例,且未在训练不同优化器前重置模型参数与优化器状态,结合自适应优化器的特性具体分析:

  1. 自适应优化器的初始步长限制
    Adam、RMSprop这类自适应优化器会维护参数的梯度矩估计(一阶矩、二阶矩)。初始训练时模型参数为随机值,损失值大、梯度幅值高,会导致二阶矩估计快速增大,使得实际更新步长($\text{lr} \times \text{一阶矩} / \text{二阶矩}$)被压缩到极小,几乎无法更新模型参数。因此当先运行Adam/RMSprop时,训练100轮后模型参数仍接近初始随机值,预测结果自然无法拟合数据。

  2. SGD的无自适应特性
    SGD没有梯度矩估计机制,直接使用固定学习率更新参数,即使初始梯度大,也能快速调整参数到接近拟合的状态。当先运行SGD时,模型参数已被优化到接近最优值,此时再训练Adam/RMSprop,梯度幅值变小,自适应优化器的步长恢复到合理范围,能够继续优化参数,因此表现良好。

  3. 共享模型与优化器状态的连锁影响
    代码中所有优化器绑定到同一个模型的参数,且训练完一个优化器后未重置模型参数,也未重新初始化优化器的内部状态。这导致后续优化器是基于前一个优化器训练后的参数继续训练,而非从初始状态开始,进一步放大了自适应优化器的初始步长问题。

解决方法

要做公平的对比实验,需保证每个优化器都从相同的初始状态开始训练:

  • 针对每个优化器,重新创建模型实例或重置模型参数到初始值;
  • 每个优化器都基于新的模型参数重新初始化,避免共享内部状态。

示例修改后的训练循环:

predictions = {}
# 针对每个优化器单独初始化模型和优化器
for optimizer_name in ["Adam", "RMSprop", "SGD"]:
    # 重置模型
    model = nn.Linear(input_size, output_size)
    # 初始化对应优化器
    if optimizer_name == "Adam":
        optimizer = torch.optim.Adam(model.parameters(), lr=learning_rate)
    elif optimizer_name == "RMSprop":
        optimizer = torch.optim.RMSprop(model.parameters(), lr=learning_rate)
    elif optimizer_name == "SGD":
        optimizer = torch.optim.SGD(model.parameters(), lr=learning_rate)
    
    print(f"Optimizer: {optimizer_name}")
    # 训练
    for epoch in range(num_epochs):        
        y_predicted = model(X)
        loss = criterion(y_predicted, y)
        loss.backward()
        optimizer.step()
        optimizer.zero_grad()
    predictions[optimizer_name] = model(X).detach().numpy()

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.26 04:45:00