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

PyTorch单变量线性回归斜率始终错误问题排查求助

单变量线性回归模型斜率错误、损失偏高的排查方向

1. 数据未做标准化/归一化

梯度下降类优化器(SGD、Adam)对输入特征和目标变量的尺度极其敏感。scikit-learn的LinearRegression基于最小二乘法求解,不受特征尺度影响;但PyTorch的优化器依赖梯度更新,若身高、体重的数值尺度差异(或绝对值过大),会导致梯度步长难以适配,模型无法收敛到最优解。

解决方法:
对输入特征(身高)做标准化处理(减均值除以标准差),目标变量(体重)可选择标准化或保留原尺度:

# 假设female_data是筛选后的女性数据集
height_mean = female_data['Height'].mean()
height_std = female_data['Height'].std()
# 仅标准化输入特征
female_data['Height'] = (female_data['Height'] - height_mean) / height_std

# 若同时标准化目标,后续可反转换回原尺度
weight_mean = female_data['Weight'].mean()
weight_std = female_data['Weight'].std()
female_data['Weight'] = (female_data['Weight'] - weight_mean) / weight_std

2. 模型输入/输出维度不匹配

若输入特征的维度为(batch_size,)而非(batch_size, 1),或标签维度与模型输出维度不匹配,会导致损失计算时的广播错误,间接影响梯度更新方向,最终使模型参数偏离最优值。

解决方法:
确保输入和标签的维度与模型输出一致:

# 数据加载时,为输入添加维度
inputs = torch.tensor(female_data['Height'].values, dtype=torch.float32).unsqueeze(1)
targets = torch.tensor(female_data['Weight'].values, dtype=torch.float32).unsqueeze(1)

# 模型定义需保持输入输出为1维
class LinearRegressor(nn.Module):
    def __init__(self):
        super().__init__()
        self.linear = nn.Linear(1, 1)
    
    def forward(self, x):
        return self.linear(x)

3. 学习率设置不合理

即使更换优化器,若学习率过大,模型会在最优值附近震荡;学习率过小,训练轮次不足时无法收敛到最优解。尤其在数据未标准化的情况下,过大的学习率会直接导致参数更新失控。

解决方法:

  • 尝试缩小学习率(如SGD用lr=0.001,Adam用默认0.001但需配合数据标准化)
  • 加入学习率调度器,随训练轮次逐步降低学习率:
optimizer = torch.optim.SGD(model.parameters(), lr=0.001)
scheduler = torch.optim.lr_scheduler.StepLR(optimizer, step_size=10, gamma=0.1)

# 训练循环中更新学习率
for epoch in range(epochs):
    # 训练步骤...
    scheduler.step()

4. 数据处理逻辑错误

需确认以下几点:

  • 是否正确筛选了女性数据(如female_data = data[data['Gender'] == 'Female'],注意字符串大小写是否匹配)
  • 是否将特征与标签搞反(如误把体重当输入、身高当标签)
  • DataLoader是否存在重复采样或数据打乱的异常(如shuffle=True是否合理,是否遗漏了drop_last=False导致样本数不完整)

5. 损失计算的细节差异

scikit-learn的MSE是全数据集总误差除以样本数;PyTorch的nn.MSELoss默认reduction='mean',即每个batch内的误差均值,若训练时用小批次,最终epoch的平均损失可能与全数据集MSE存在偏差。

解决方法:
训练结束后,用全数据集计算MSE,与scikit-learn结果对比:

model.eval()
with torch.no_grad():
    full_inputs = torch.tensor(female_data['Height'].values, dtype=torch.float32).unsqueeze(1)
    full_outputs = model(full_inputs)
    full_mse = nn.MSELoss()(full_outputs, torch.tensor(female_data['Weight'].values, dtype=torch.float32).unsqueeze(1)).item()
print(f"全数据集MSE: {full_mse}")

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.07 14:18:10