基于California Housing数据集的回归神经网络无法学习求助
问题排查与修正方案
你的代码存在几个核心问题导致回归模型无法正常学习,以下是具体问题和修正步骤:
1. 回归任务错误引入分类准确率计算
这是最致命的错误:你在回归任务中错误使用了分类任务的准确率计算逻辑。回归预测的是连续数值,outputs.max(1)和predicted.eq(labels)完全不适用于回归场景,这些代码计算出的“准确率”毫无意义,还会误导你对模型训练状态的判断。
修正方式:删除train和test函数中所有与准确率相关的代码,只保留损失计算逻辑。
2. 特征未做标准化处理
California Housing数据集的特征数值范围差异极大(例如MedInc在0-15之间,AveOccup可达到100以上),神经网络对输入数据的尺度非常敏感,未标准化的特征会导致梯度爆炸/消失,模型无法有效收敛。
修正方式:使用sklearn.preprocessing.StandardScaler对训练数据做标准化,测试数据必须使用训练数据的均值和方差进行转换,避免数据泄露。
3. 模型结构过于复杂(可选优化)
你构建了5层全连接网络+批量归一化+Dropout,对于加州房价预测这种简单回归任务来说,过深的模型会增加训练难度,甚至导致过拟合。可以先简化模型,等模型稳定收敛后再逐步增加复杂度。
修正后的完整代码
import torch.nn.functional as F import torch.nn as nn import torch import pandas as pd import sklearn.datasets import matplotlib.pyplot as plt from sklearn.model_selection import train_test_split from sklearn.preprocessing import StandardScaler # 加载数据 data = sklearn.datasets.fetch_california_housing(as_frame=True) # 划分数据集并标准化特征 X_train, X_test, y_train, y_test = train_test_split(data.data, data.target, test_size=0.25, random_state=13) # 特征标准化 scaler = StandardScaler() X_train_scaled = scaler.fit_transform(X_train) X_test_scaled = scaler.transform(X_test) class MyDataset(torch.utils.data.Dataset): def __init__(self, x, y): self.f_tensor = torch.tensor(x, dtype=torch.float32) self.t_tensor = torch.tensor(y.values, dtype=torch.float32).reshape(-1, 1) def __len__(self): return len(self.f_tensor) def __getitem__(self, idx): return self.f_tensor[idx], self.t_tensor[idx] train_dataset = MyDataset(X_train_scaled, y_train) train_loader = torch.utils.data.DataLoader(train_dataset, batch_size=128, shuffle=True, drop_last=True) test_dataset = MyDataset(X_test_scaled, y_test) test_loader = torch.utils.data.DataLoader(test_dataset, batch_size=16, shuffle=False, drop_last=True) # 简化模型结构 class FeedForward(nn.Module): def __init__(self, input_dim, hidden_dims, output_dim=1): super().__init__() self.fc1 = nn.Linear(input_dim, hidden_dims[0]) self.fc2 = nn.Linear(hidden_dims[0], hidden_dims[1]) self.fc3 = nn.Linear(hidden_dims[1], output_dim) def forward(self, x): x = F.relu(self.fc1(x)) x = F.relu(self.fc2(x)) x = self.fc3(x) return x def train(model, optimizer, criterion, train_loader, device): model.train() running_loss = 0.0 for inputs, labels in train_loader: inputs, labels = inputs.to(device), labels.to(device) optimizer.zero_grad() outputs = model(inputs) loss = criterion(outputs, labels) loss.backward() optimizer.step() running_loss += loss.item() train_loss = running_loss / len(train_loader) return train_loss def test(model, criterion, test_loader, device): model.eval() running_loss = 0.0 with torch.no_grad(): for inputs, labels in test_loader: inputs, labels = inputs.to(device), labels.to(device) outputs = model(inputs) loss = criterion(outputs, labels) running_loss += loss.item() test_loss = running_loss / len(test_loader) return test_loss def train_model(model, optimizer, criterion, train_loader, test_loader, device, num_epochs=50): train_losses = [] test_losses = [] for epoch in range(num_epochs): train_loss = train(model, optimizer, criterion, train_loader, device) test_loss = test(model, criterion, test_loader, device) train_losses.append(train_loss) test_losses.append(test_loss) print(f"Epoch [{epoch+1}/{num_epochs}]: Train Loss: {train_loss:.4f}, Test Loss: {test_loss:.4f}") return train_losses, test_losses device = torch.device("cuda" if torch.cuda.is_available() else "cpu") hidden_dims = [64, 32] # 简化隐藏层 model = FeedForward(8, hidden_dims).to(device) criterion = nn.MSELoss() optimizer = torch.optim.Adam(model.parameters(), lr=0.001) train_losses, test_losses = train_model(model, optimizer, criterion, train_loader, test_loader, device) # 绘制损失曲线 plt.figure(figsize=(8, 4)) plt.plot(train_losses, label="Train Loss") plt.plot(test_losses, label="Test Loss") plt.xlabel("Epochs") plt.ylabel("MSE Loss") plt.legend() plt.show()
关键修改说明
- 移除了所有与“准确率”相关的错误代码,回归任务只需要关注MSE损失的变化。
- 添加了特征标准化步骤,确保所有特征处于同一尺度,帮助模型稳定收敛。
- 简化了模型结构,减少了隐藏层数量和正则化组件,降低训练难度。
- 增加了训练轮数到50,确保模型有足够时间学习数据模式。
运行修正后的代码,你会看到训练损失和测试损失稳步下降,说明模型已经正常学习。
内容的提问来源于stack exchange,提问作者Greg Avsyannikov
相关产品推荐
相关产品推荐

