PyTorch中x²回归预测效果不佳,寻求代码优化方案
代码优化思路与问题修正
你当前的代码存在几个核心问题,是导致模型效果不佳的主要原因,以下是针对性的优化方案:
一、数据处理核心问题修正
归一化后的数据未转换为Tensor,且训练时未使用归一化数据
你用MinMaxScaler得到的归一化数据是numpy数组,但训练循环里依然用原始的未归一化Tensor,这会导致输入输出数值范围过大,模型难以收敛。
修正代码:# 归一化后转换为Tensor X_train = torch.tensor(scaler_x.transform(X_train), dtype=torch.float32) y_train = torch.tensor(scaler_y.transform(y_train), dtype=torch.float32) # 测试集必须用训练集的scaler做归一化,禁止重新拟合 X_test = torch.tensor(scaler_x.transform(X_test), dtype=torch.float32) y_test = torch.tensor(scaler_y.transform(y_test), dtype=torch.float32)y值生成效率低且冗余
替换列表推导为PyTorch原生操作,避免不必要的类型转换:y = torch.pow(X, 2.0) # 替代[i**2.0 for i in X[0:]]
二、模型结构优化
- 优化层结构可读性,避免冗余赋值
重复赋值激活函数会降低代码可读性,建议用nn.Sequential组织层结构,同时可先缩小模型规模验证基础效果(200节点的两层隐藏层易过拟合):class FunctionEstimatorModel(nn.Module): def __init__(self): super().__init__() self.layers = nn.Sequential( nn.Linear(in_features=1, out_features=64), nn.LeakyReLU(), nn.Linear(in_features=64, out_features=32), nn.LeakyReLU(), nn.Linear(in_features=32, out_features=1) ) def forward(self, x: torch.Tensor) -> torch.Tensor: return self.layers(x)
三、训练循环优化
修正学习率调度器调用逻辑
如果使用ReduceLROnPlateau这类依赖验证损失的调度器,需要传入验证损失值:scheduler.step(test_loss) # 替代直接scheduler.step()若使用
StepLR等固定步长调度器,保持当前位置即可,但需确保每个epoch仅调用一次。添加梯度裁剪防止梯度爆炸
针对回归任务的数值范围问题,在反向传播后添加梯度裁剪:loss.backward() torch.nn.utils.clip_grad_norm_(model_0.parameters(), max_norm=1.0) # 限制梯度范围 optimizer.step()测试时反归一化查看真实效果
模型输出是归一化后的值,需反归一化才能和原始y值对比:with torch.inference_mode(): test_pred = model_0(X_test) # 反归一化还原真实数值 test_pred_unscaled = scaler_y.inverse_transform(test_pred.cpu().numpy()) y_test_unscaled = scaler_y.inverse_transform(y_test.cpu().numpy()) test_loss = loss_fn(torch.tensor(test_pred_unscaled), torch.tensor(y_test_unscaled))
四、其他建议
- 调整损失函数:若原始y值范围过大,可尝试用
nn.L1Loss(MAE)辅助训练,或对y取对数后再训练(注意后续反变换)。 - 增加正则化:在层中添加
nn.Dropout(0.1),或在optimizer中设置weight_decay=1e-4,防止过拟合。 - 固定基础训练参数:先设置学习率为1e-3、epochs为500-1000,观察损失变化后再逐步调整节点数、学习率等参数。
内容的提问来源于stack exchange,提问作者user21244712
相关产品推荐
相关产品推荐

