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

PyTorch ANN回归模型:不同输入输出相同预测问题求助

解决PyTorch ANN输出全相同预测值的问题

问题诊断

你的模型对所有输入输出相同预测值,核心原因集中在以下几点:

  • 缺失激活函数依赖:代码中使用F.relu但未导入torch.nn.functional,导致无法正常激活神经元
  • 输入特征未标准化:不同特征(如年龄、身高、运动时长)数值范围差异过大,模型梯度更新异常,容易陷入预测均值的局部最优
  • 模型与优化器适配性差:3层隐藏层搭配SGD优化器,在未归一化的数据上难以有效更新权重
  • 全量数据训练:直接用所有数据训练,模型易快速拟合整体均值而非学习特征关联

修复代码与步骤

1. 补全缺失库导入

import numpy as np 
import pandas as pd 
import torch 
import torch.nn as nn
import torch.nn.functional as F  # 新增:导入ReLU依赖

2. 数据预处理:添加特征标准化

calories = pd.read_csv("calories.csv")
excercise = pd.read_csv("exercise.csv")
df = pd.concat([excercise,calories],axis=1,join="outer")

df = df.drop('User_ID',axis=1)
data = pd.get_dummies(df,drop_first=True)

# 新增:标准化特征,消除量纲差异
from sklearn.preprocessing import StandardScaler
scaler = StandardScaler()
X_scaled = scaler.fit_transform(data.drop("Calories",axis=1))

X = torch.tensor(X_scaled).float()
y = torch.tensor(data['Calories'],dtype=torch.float).reshape(-1,1)

3. 调整模型结构与优化器

class Ann_Predictor(nn.Module):
    def __init__(self, n_layers, n_units):
        super().__init__()
        self.n_layers = n_layers
        self.layers = nn.ModuleDict()
    
        self.layers["input"] = nn.Linear(7,n_units)
    
        for i in range(n_layers):
            self.layers[f"hidden{i}"] = nn.Linear(n_units,n_units)
        
        self.layers["output"] = nn.Linear(n_units,1)
    
    def forward(self, x):
        # 修正:输入层后直接添加ReLU激活
        x = F.relu(self.layers['input'](x))
    
        for i in range(self.n_layers):
            x = F.relu(self.layers[f"hidden{i}"](x))
    
        x = self.layers["output"](x)
        return x

def create_model():
    ann = Ann_Predictor(2, 16)  # 简化隐藏层数量,增加单元数提升拟合能力
    loss_func = nn.MSELoss()
    learning_rate = 0.001
    optimizer = torch.optim.Adam(ann.parameters(), lr=learning_rate)  # 改用Adam自适应优化器
    return ann, loss_func, optimizer

4. 拆分数据集并优化训练流程

from sklearn.model_selection import train_test_split  # 新增:拆分训练/验证集

# 拆分数据,避免全量训练拟合均值
X_train, X_val, y_train, y_val = train_test_split(X, y, test_size=0.2, random_state=42)

numepochs = 1000
train_losses = torch.zeros(numepochs)
val_losses = torch.zeros(numepochs)

ann, loss_func, optimizer = create_model()

for epoch in range(numepochs):
    # 训练模式
    ann.train()
    y_hat = ann(X_train)
    loss = loss_func(y_hat, y_train)
    train_losses[epoch] = loss

    optimizer.zero_grad()
    loss.backward()
    optimizer.step()

    # 验证模式,监控泛化能力
    ann.eval()
    with torch.no_grad():
        val_y_hat = ann(X_val)
        val_loss = loss_func(val_y_hat, y_val)
        val_losses[epoch] = val_loss

    # 每50轮打印训练日志
    if (epoch+1) % 50 == 0:
        print(f"Epoch {epoch+1}/{numepochs}, Train Loss: {loss.item():.2f}, Val Loss: {val_loss.item():.2f}")

# 生成预测结果
ann.eval()
with torch.no_grad():
    predictions = ann(X)
print(predictions[:10])  # 打印前10个预测值验证差异

核心修复逻辑说明

  • 标准化:统一特征尺度,确保梯度更新方向稳定,避免大数值特征主导训练
  • 激活函数修正:输入层后添加ReLU,让模型具备学习非线性特征的能力
  • 优化器替换:Adam自带自适应学习率,比SGD更适合处理复杂数据和模型
  • 数据集拆分:验证集可监控模型是否过拟合,避免全量数据训练导致的均值拟合

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.27 03:47:51