FEATURED · 精选文章

PyTorch实战:波士顿房价预测项目全流程解析与神经网络回归实践

发布时间 / 2026/8/28 7:49:28
来源 / 创域科博编辑部
栏目 / 资讯中心
PyTorch实战:波士顿房价预测项目全流程解析与神经网络回归实践 简介机器学习中的回归任务是预测连续数值输出的基础问题其核心原理是通过建立输入特征与目标变量之间的映射关系来最小化预测误差。在深度学习框架中PyTorch以其动态计算图和直观的API设计为构建和训练神经网络模型提供了高效灵活的工具特别适合教学和原型开发。通过实现经典的波士顿房价预测项目可以贯通PyTorch的核心组件如Tensor、Dataset、DataLoader、Module、Optimizer和Loss Function掌握从数据预处理、模型定义、训练循环到评估可视化的完整工作流。该项目不仅演示了如何使用前馈神经网络处理结构化数据还涵盖了特征标准化、损失函数选择、优化器配置以及过拟合防治等工程实践关键点为后续处理图像分类、文本生成等更复杂任务奠定了可迁移的范式基础。1. 项目缘起与核心价值最近在整理一些经典的机器学习入门项目发现波士顿房价预测这个“老伙计”依然有着不可替代的教学价值。它不像图像识别那样需要庞大的计算资源也不像自然语言处理那样涉及复杂的序列建模但它却是一个绝佳的、能让你亲手触摸到机器学习全流程的“麻雀”。从数据加载、预处理、模型定义、训练到评估每一个环节都清晰可见非常适合用来理解一个预测系统是如何从零到一构建起来的。这次我决定用PyTorch来实现它。虽然现在TensorFlow和PyTorch在学术界和工业界都平分秋色但PyTorch以其动态计算图和更“Pythonic”的API设计对于初学者和研究者来说上手和理解模型内部运作的直观性要强得多。你写的每一行代码几乎都能直接对应到数学公式或数据处理逻辑上这种透明感是快速建立信心的关键。波士顿房价数据集本身是一个小型回归数据集包含506个样本每个样本有13个特征如人均犯罪率、住宅平均房间数等目标是预测房屋的中位数价值。用前馈神经网络FNN来解决这个回归问题既能让我们实践PyTorch的基础操作又能深入理解神经网络如何处理结构化数据。这个项目的核心价值在于“贯通”。它不是一个炫技的复杂模型而是一个让你把PyTorch的Tensor、Dataset、DataLoader、Module、Optimizer、Loss Function这几个核心组件串起来形成一个完整工作流的实战案例。做完这个项目你不仅能得到一个可以预测房价的简单系统更重要的是你能掌握用PyTorch解决一个真实机器学习问题的标准范式这个范式可以无缝迁移到图像分类、文本生成等更复杂的任务中去。无论你是刚学完Python基础想踏入AI大门的新手还是想从其他框架切换到PyTorch的开发者这个项目都是一个理想的起点。2. 环境搭建与数据初探避开第一个坑工欲善其事必先利其器。搭建一个稳定、隔离的PyTorch开发环境是第一步这里也是最容易出问题的地方。我强烈建议使用Anaconda来管理Python环境和包依赖它能有效避免版本冲突。2.1 创建并激活Conda环境打开你的终端Windows用Anaconda PromptMac/Linux用终端执行以下命令来创建一个名为pytorch_boston的新环境并指定Python版本这里用3.9一个比较稳定且兼容性广的版本conda create -n pytorch_boston python3.9 conda activate pytorch_boston2.2 安装PyTorchCPU还是GPU这是关键一步。安装命令需要去PyTorch官网https://pytorch.org/根据你的系统配置生成。官网的安装选择器非常直观你需要选择PyTorch Build稳定版Stable。Your OS你的操作系统Windows, Linux, Mac。Package推荐使用Conda或Pip。Conda有时能更好地处理一些底层依赖如CUDA相关的库。LanguagePython。Compute Platform计算平台。这是核心选择如果你有NVIDIA显卡并想使用GPU加速选择对应的CUDA版本如CUDA 11.8。你需要先确认你的显卡驱动支持该CUDA版本。GPU训练在小数据集上优势不明显但对于建立正确的流程和未来处理大数据至关重要。如果你没有GPU或想先简化流程选择“CPU”。完全没问题波士顿数据集很小CPU训练也很快。以在Windows系统下使用Conda安装CPU版本的PyTorch为例官网生成的命令可能类似于conda install pytorch torchvision torchaudio cpuonly -c pytorch等待安装完成。安装后可以在Python环境中验证import torch print(torch.__version__) # 输出PyTorch版本如 2.2.0 print(torch.cuda.is_available()) # 输出FalseCPU版本或TrueGPU版本2.3 加载与审视波士顿房价数据集PyTorch本身不包含这个数据集但我们可以从sklearnscikit-learn中方便地获取。首先安装scikit-learn和后续会用到的pandas、matplotlibpip install scikit-learn pandas matplotlib接下来我们加载数据并看看它的“长相”import numpy as np import pandas as pd from sklearn.datasets import load_boston # 注意新版本sklearn中已移除需用替代方案 import torch from torch.utils.data import Dataset, DataLoader import matplotlib.pyplot as plt # 由于sklearn新版本移除了load_boston我们使用一种兼容性更好的方式 # 从网络或本地加载数据 try: # 方法1尝试从sklearn加载旧版本 boston load_boston() X boston.data y boston.target feature_names boston.feature_names except AttributeError: # 方法2如果失败使用pandas从网络获取推荐更稳定 data_url http://lib.stat.cmu.edu/datasets/boston raw_df pd.read_csv(data_url, sep\s, skiprows22, headerNone) data np.hstack([raw_df.values[::2, :], raw_df.values[1::2, :2]]) target raw_df.values[1::2, 2] X data y target # 波士顿数据集的标准特征名 feature_names [CRIM, ZN, INDUS, CHAS, NOX, RM, AGE, DIS, RAD, TAX, PTRATIO, B, LSTAT] print(f数据形状: X{X.shape}, y{y.shape}) # 输出: X(506, 13), y(506,) print(f特征名: {feature_names}) # 将数据转换为PyTorch张量并指定数据类型为浮点数 X_tensor torch.from_numpy(X).float() y_tensor torch.from_numpy(y).float().view(-1, 1) # 将y从(506)变为(506, 1)与模型输出维度匹配 # 查看前5个样本 df pd.DataFrame(X, columnsfeature_names) df[MEDV] y print(df.head())运行这段代码你会看到一个DataFrame清晰地展示了13个特征和1个目标值MEDV即房价中位数。这一步看似简单但至关重要。一个常见的坑是忽略了对数据本身的观察。你需要留意数据的尺度比如TAX房产税和RM房间数数值相差巨大以及是否有缺失值波士顿数据集是完整的。这些观察直接决定了下一步——数据预处理——该如何进行。3. 数据预处理与数据集封装为模型提供“标准餐”原始数据很少能直接丢给神经网络。不同的特征具有不同的量纲和范围这会导致梯度下降过程收敛缓慢甚至不稳定。因此标准化Standardization是必不可少的一步。它的目的是将每个特征的分布调整为均值为0、标准差为1的标准正态分布。3.1 特征标准化与数据集划分我们使用sklearn的StandardScaler来方便地计算训练集的均值和标准差并用它们来转换所有数据包括后续的测试集避免数据泄露。from sklearn.model_selection import train_test_split from sklearn.preprocessing import StandardScaler # 1. 划分训练集和测试集通常8:2 X_train, X_test, y_train, y_test train_test_split(X, y, test_size0.2, random_state42) print(f训练集大小: {X_train.shape}, 测试集大小: {X_test.shape}) # 2. 标准化特征 scaler StandardScaler() X_train_scaled scaler.fit_transform(X_train) # 拟合训练集并转换 X_test_scaled scaler.transform(X_test) # 使用训练集的参数转换测试集 # 3. 转换为PyTorch张量 X_train_tensor torch.from_numpy(X_train_scaled).float() y_train_tensor torch.from_numpy(y_train).float().view(-1, 1) X_test_tensor torch.from_numpy(X_test_scaled).float() y_test_tensor torch.from_numpy(y_test).float().view(-1, 1)这里有一个非常重要的经验点scaler的fit计算均值和标准差只能在训练集上进行。然后用这个训练好的scaler去转换训练集和测试集。如果用了测试集的数据参与fit就相当于在训练时“偷看”了测试集的信息会严重高估模型在真实未知数据上的性能这是机器学习中一个典型的数据泄露错误。3.2 构建PyTorch Dataset与DataLoaderPyTorch通过Dataset和DataLoader来高效地管理和加载数据。Dataset负责定义如何读取单个样本DataLoader负责批量加载、打乱顺序、多进程读取等。class BostonHousingDataset(Dataset): 波士顿房价数据集封装 def __init__(self, features, targets): self.features features self.targets targets def __len__(self): return len(self.features) def __getitem__(self, idx): return self.features[idx], self.targets[idx] # 创建Dataset实例 train_dataset BostonHousingDataset(X_train_tensor, y_train_tensor) test_dataset BostonHousingDataset(X_test_tensor, y_test_tensor) # 创建DataLoader batch_size 32 train_loader DataLoader(train_dataset, batch_sizebatch_size, shuffleTrue) test_loader DataLoader(test_dataset, batch_sizebatch_size, shuffleFalse) # 测试集不需要打乱为什么使用DataLoader它带来了几个好处批量训练神经网络通常使用小批量随机梯度下降DataLoader自动将数据分成指定大小的批次。数据打乱在每个训练周期epoch开始时打乱数据有助于模型学习更通用的模式避免因数据顺序带来的偏差。并行加载通过设置num_workers参数可以利用多进程预加载数据到内存减少GPU等待数据的时间对于大数据集尤其重要。4. 前馈神经网络模型设计从公式到代码前馈神经网络也叫多层感知机MLP是深度学习中最基础的架构。对于波士顿房价预测这个回归任务我们的网络结构可以设计为输入层13个神经元 - 隐藏层164个神经元 - 隐藏层232个神经元 - 输出层1个神经元。4.1 模型类定义与层结构在PyTorch中我们通过继承torch.nn.Module类来定义自己的模型。import torch.nn as nn class BostonPricePredictor(nn.Module): def __init__(self, input_dim): super(BostonPricePredictor, self).__init__() # 定义网络层 self.fc1 nn.Linear(input_dim, 64) # 全连接层1: 13 - 64 self.fc2 nn.Linear(64, 32) # 全连接层2: 64 - 32 self.fc3 nn.Linear(32, 1) # 输出层: 32 - 1 (房价) # 定义激活函数和Dropout层用于防止过拟合可选 self.relu nn.ReLU() self.dropout nn.Dropout(p0.2) # 以20%的概率随机丢弃神经元 def forward(self, x): # 定义前向传播路径 out self.fc1(x) out self.relu(out) out self.dropout(out) # 通常在激活函数后加Dropout out self.fc2(out) out self.relu(out) # 第二个隐藏层后也可以加Dropout这里省略了 out self.fc3(out) # 输出层不使用激活函数因为回归任务直接输出数值 return out关键点解析nn.Linear全连接层实现y xA^T b的线性变换。你需要指定输入特征数和输出特征数。nn.ReLU修正线性单元激活函数引入非线性使网络能够学习复杂的模式。公式为f(x) max(0, x)。nn.Dropout在训练过程中随机将一部分神经元的输出置零。这是一种正则化技术可以防止网络对某些特定的神经元产生过度的依赖从而减轻过拟合。注意Dropout只在训练时启用在模型评估验证/测试时需要关闭。PyTorch的model.eval()模式会自动处理这一点。forward方法定义了数据从输入到输出的计算图。必须重写此方法。4.2 为什么选择这样的结构隐藏层维度从64到32是常见的做法逐层压缩特征信息。初始维度不宜过小如8否则模型容量不足也不宜过大如512对于这个小数据集容易过拟合。64和32是一个经验性的平衡点。激活函数隐藏层使用ReLU因为它计算高效能缓解梯度消失问题在实践中效果通常很好。输出层回归任务的输出层通常不使用激活函数因为我们希望输出任何实数范围内的值。如果使用了Sigmoid或Tanh输出会被限制在(0,1)或(-1,1)内这与房价范围不符。Dropout在第一个隐藏层后添加Dropout是一种有效的正则化手段。概率p0.2意味着每次前向传播时该层有20%的神经元会被随机屏蔽。5. 训练循环的构建损失、优化与迭代模型定义好后我们需要定义如何衡量它的好坏损失函数以及如何让它变得更好优化器。5.1 初始化模型、损失函数与优化器# 初始化模型 input_dim X_train_tensor.shape[1] # 13 model BostonPricePredictor(input_dim) # 定义损失函数 - 均方误差损失回归任务最常用的损失函数 criterion nn.MSELoss() # 定义优化器 - Adam优化器自适应学习率通常比SGD收敛更快更稳 optimizer torch.optim.Adam(model.parameters(), lr0.001) # 学习率是一个超参数 # 如果有GPU将模型和数据移动到GPU上 device torch.device(cuda if torch.cuda.is_available() else cpu) model.to(device) print(f使用设备: {device})为什么是MSE和AdamMSE均方误差计算预测值与真实值之差的平方的平均值。它对大的误差给予更大的惩罚这使得优化过程更关注于减少那些预测得特别不准的样本的影响非常符合回归任务的目标。Adam优化器它结合了动量Momentum和自适应学习率RMSProp的优点。对于大多数问题Adam的默认参数就能工作得很好不需要像SGD那样精细地调整学习率和动量参数对初学者更友好。5.2 完整的训练与验证循环训练是一个迭代的过程前向传播计算预测和损失 - 反向传播计算梯度 - 优化器更新模型参数。num_epochs 500 # 遍历整个训练集的次数 train_losses [] val_losses [] for epoch in range(num_epochs): # -------------------- 训练阶段 -------------------- model.train() # 设置为训练模式启用Dropout等 running_train_loss 0.0 for batch_features, batch_targets in train_loader: # 将数据移动到设备CPU/GPU batch_features, batch_targets batch_features.to(device), batch_targets.to(device) # 前向传播 predictions model(batch_features) loss criterion(predictions, batch_targets) # 反向传播与优化 optimizer.zero_grad() # 清空上一轮的梯度非常重要 loss.backward() # 反向传播计算梯度 optimizer.step() # 根据梯度更新参数 running_train_loss loss.item() * batch_features.size(0) epoch_train_loss running_train_loss / len(train_loader.dataset) train_losses.append(epoch_train_loss) # -------------------- 验证阶段 -------------------- model.eval() # 设置为评估模式禁用Dropout等 running_val_loss 0.0 with torch.no_grad(): # 在此上下文中不计算梯度节省内存和计算 for batch_features, batch_targets in test_loader: batch_features, batch_targets batch_features.to(device), batch_targets.to(device) predictions model(batch_features) loss criterion(predictions, batch_targets) running_val_loss loss.item() * batch_features.size(0) epoch_val_loss running_val_loss / len(test_loader.dataset) val_losses.append(epoch_val_loss) # 每50个epoch打印一次日志 if (epoch 1) % 50 0: print(fEpoch [{epoch1:04d}/{num_epochs}], Train Loss: {epoch_train_loss:.4f}, Val Loss: {epoch_val_loss:.4f})几个必须注意的细节optimizer.zero_grad()千万不能省略PyTorch的梯度是累加的。如果不清零下一次loss.backward()时梯度会与上一次的梯度相加导致更新方向错误。model.train()和model.eval()这两个模式主要影响Dropout和BatchNorm等层的行为。训练时必须用train()评估时必须用eval()。with torch.no_grad()在验证和测试时我们不需要计算梯度因为不更新参数。使用这个上下文管理器可以显著减少内存消耗并加速计算。损失计算我们在每个batch里累加的是loss.item() * batch_size最后除以数据集总大小来得到平均损失。这是因为loss是当前这个batch的平均损失。6. 模型评估、可视化与结果分析训练完成后我们不能只看最后的损失值还需要多维度地评估模型性能并可视化训练过程来诊断模型行为。6.1 绘制训练与验证损失曲线损失曲线是观察模型学习状态的“心电图”。plt.figure(figsize(10, 5)) plt.plot(range(1, num_epochs1), train_losses, labelTraining Loss, colorblue, linewidth2) plt.plot(range(1, num_epochs1), val_losses, labelValidation Loss, colorred, linestyle--, linewidth2) plt.xlabel(Epoch) plt.ylabel(Mean Squared Error Loss) plt.title(Training and Validation Loss over Epochs) plt.legend() plt.grid(True, linestyle--, alpha0.7) plt.show()如何解读损失曲线理想情况训练损失和验证损失都平稳下降并最终收敛到一个较低的值且两者之间差距很小。这说明模型学习良好没有过拟合或欠拟合。过拟合训练损失持续下降但验证损失在某个点后开始上升或停滞。这意味着模型记住了训练数据的噪声而非一般规律。解决方案包括增加Dropout比率、使用更小的网络、获取更多数据、使用更强的数据增强对于图像等或早停Early Stopping。欠拟合训练损失和验证损失都很高且下降缓慢或很早就停滞了。这说明模型复杂度不够无法捕捉数据中的模式。解决方案包括增加网络层数或神经元数量、训练更多轮次、减少正则化强度。6.2 在测试集上进行最终评估我们用训练好的模型在整个测试集上做一次前向传播计算几个关键的回归评估指标。model.eval() all_predictions [] all_targets [] with torch.no_grad(): for batch_features, batch_targets in test_loader: batch_features, batch_targets batch_features.to(device), batch_targets.to(device) predictions model(batch_features) all_predictions.append(predictions.cpu()) all_targets.append(batch_targets.cpu()) # 合并所有batch的结果 all_predictions torch.cat(all_predictions, dim0).numpy() all_targets torch.cat(all_targets, dim0).numpy() # 计算评估指标 from sklearn.metrics import mean_squared_error, mean_absolute_error, r2_score mse mean_squared_error(all_targets, all_predictions) rmse np.sqrt(mse) # 均方根误差与目标值单位一致更直观 mae mean_absolute_error(all_targets, all_predictions) # 平均绝对误差对异常值不敏感 r2 r2_score(all_targets, all_predictions) # 决定系数越接近1越好 print(f测试集评估结果:) print(f 均方误差 (MSE): {mse:.2f}) print(f 均方根误差 (RMSE): {rmse:.2f} (千美元)) # 波士顿房价单位是千美元 print(f 平均绝对误差 (MAE): {mae:.2f} (千美元)) print(f 决定系数 (R² Score): {r2:.4f})指标解读RMSE大约是预测房价的平均误差单位千美元。例如RMSE4.5意味着平均预测误差约为4500美元。这是最直观的指标。MAE另一个平均误差指标它对极端预测误差的惩罚小于RMSE。R²表示模型对目标变量方差的解释比例。0.75意味着模型解释了房价75%的波动。对于波士顿房价数据集R²达到0.8以上通常就算是一个不错的模型了。6.3 可视化预测值与真实值的对比散点图可以直观地看出模型的预测效果。plt.figure(figsize(8, 8)) plt.scatter(all_targets, all_predictions, alpha0.6, edgecolorsk) # 绘制理想预测线yx min_val min(all_targets.min(), all_predictions.min()) max_val max(all_targets.max(), all_predictions.max()) plt.plot([min_val, max_val], [min_val, max_val], r--, lw2, labelPerfect Prediction) plt.xlabel(True House Price (MEDV)) plt.ylabel(Predicted House Price (MEDV)) plt.title(True vs. Predicted House Prices on Test Set) plt.legend() plt.grid(True, linestyle--, alpha0.5) plt.show()如果点紧密分布在红色对角线附近说明预测准确。如果点呈现明显的系统性偏离如整体偏高或偏低或者有特殊的分布模式则说明模型存在某种偏差。7. 模型优化与超参数调优实战我们构建的第一个模型只是一个基线。要提升性能需要进行系统的调优。超参数调优有点像“炼丹”但有其科学方法。7.1 构建一个更灵活的模型类为了方便实验不同的网络结构我们改进一下模型类使其可以通过参数配置。class FlexibleBostonPredictor(nn.Module): def __init__(self, input_dim, hidden_dims[64, 32], dropout_rate0.2): super(FlexibleBostonPredictor, self).__init__() layers [] prev_dim input_dim # 动态构建隐藏层 for i, hidden_dim in enumerate(hidden_dims): layers.append(nn.Linear(prev_dim, hidden_dim)) layers.append(nn.ReLU()) layers.append(nn.Dropout(dropout_rate)) prev_dim hidden_dim # 输出层 layers.append(nn.Linear(prev_dim, 1)) # 将层序列包装成 Sequential self.network nn.Sequential(*layers) def forward(self, x): return self.network(x)7.2 尝试不同的超参数组合我们可以手动尝试几组不同的超参数观察效果。def train_and_evaluate(config, X_train_t, y_train_t, X_val_t, y_val_t): 训练并评估给定配置的模型 hidden_dims config[hidden_dims] dropout config[dropout] lr config[lr] batch_size config[batch_size] epochs config[epochs] # 创建DataLoader train_dataset BostonHousingDataset(X_train_t, y_train_t) val_dataset BostonHousingDataset(X_val_t, y_val_t) train_loader DataLoader(train_dataset, batch_sizebatch_size, shuffleTrue) val_loader DataLoader(val_dataset, batch_sizebatch_size, shuffleFalse) # 初始化模型、损失、优化器 model FlexibleBostonPredictor(input_dim, hidden_dimshidden_dims, dropout_ratedropout).to(device) criterion nn.MSELoss() optimizer torch.optim.Adam(model.parameters(), lrlr) # 简化的训练循环省略详细日志 for epoch in range(epochs): model.train() for feats, targs in train_loader: feats, targs feats.to(device), targs.to(device) optimizer.zero_grad() loss criterion(model(feats), targs) loss.backward() optimizer.step() # 在验证集上评估 model.eval() val_loss 0.0 with torch.no_grad(): for feats, targs in val_loader: feats, targs feats.to(device), targs.to(device) val_loss criterion(model(feats), targs).item() * feats.size(0) avg_val_loss val_loss / len(val_loader.dataset) return avg_val_loss, model # 假设我们从训练集中再分出一个验证集用于调参 from sklearn.model_selection import train_test_split indices np.arange(len(X_train_scaled)) X_train_sub, X_val, y_train_sub, y_val train_test_split(X_train_scaled, y_train, test_size0.2, random_state42) # ... 转换为Tensor ... # 定义几组不同的配置 configs [ {hidden_dims: [64, 32], dropout: 0.2, lr: 0.001, batch_size: 16, epochs: 300}, {hidden_dims: [128, 64, 32], dropout: 0.3, lr: 0.0005, batch_size: 32, epochs: 400}, {hidden_dims: [256, 128], dropout: 0.1, lr: 0.01, batch_size: 64, epochs: 200}, ] best_loss float(inf) best_model None best_config None for config in configs: print(f尝试配置: {config}) val_loss, model train_and_evaluate(config, X_train_sub_tensor, y_train_sub_tensor, X_val_tensor, y_val_tensor) print(f 验证集损失: {val_loss:.4f}\n) if val_loss best_loss: best_loss val_loss best_model model best_config config print(f最佳配置: {best_config}) print(f最佳验证损失: {best_loss:.4f})7.3 使用学习率调度器固定学习率可能不是最优的。我们可以在训练中动态调整学习率例如当验证损失不再下降时降低学习率。from torch.optim.lr_scheduler import ReduceLROnPlateau # 在训练循环中初始化优化器后添加调度器 optimizer torch.optim.Adam(model.parameters(), lr0.01) # 初始学习率可以设大一点 scheduler ReduceLROnPlateau(optimizer, modemin, factor0.5, patience20, verboseTrue) # 参数说明监控指标验证损失在20个epoch内没有下降min模式时将学习率乘以0.5。 # 在每个epoch的验证阶段结束后更新调度器 # ... 计算 epoch_val_loss ... scheduler.step(epoch_val_loss) # 将当前验证损失传给调度器学习率调度器是一种“早停”的温和形式它不是在性能停滞时完全停止训练而是降低学习率让模型在参数空间中进行更精细的搜索往往能获得更好的最终性能。8. 项目总结与扩展思考通过这个项目我们完整地走了一遍基于PyTorch的深度学习项目流程从环境配置、数据加载与预处理、模型定义、训练循环构建、到最终的评估与可视化。这个流程是具有高度通用性的模板。几个值得深入思考和扩展的方向特征工程我们直接使用了原始的13个特征。你可以尝试创建新的特征例如房间数与年龄的比率。使用领域知识选择更重要的特征。尝试不同的标准化方法如MinMaxScaler或分位数转换。使用sklearn.feature_selection中的方法进行特征选择。更好的特征往往比更复杂的模型带来更大的提升。模型架构探索尝试更深的网络如4-5层或更宽的网络每层更多神经元。引入批归一化层nn.BatchNorm1d它通常能加速训练并提升模型稳定性。尝试不同的激活函数如LeakyReLU、ELU等。对于结构化数据可以探索树模型如LightGBM、XGBoost或TabNet等专门架构并与简单的MLP对比。正则化技术调整Dropout比率。在优化器中加入权重衰减L2正则化torch.optim.Adam(..., weight_decay1e-4)。使用早停Early Stopping在验证损失不再改善时停止训练防止过拟合。超参数自动化调优使用optuna、Ray Tune或sklearn的GridSearchCV配合PyTorch包装器如skorch进行系统的超参数搜索而不是手动尝试。部署与推理将训练好的模型保存下来torch.save(model.state_dict(), boston_model.pth)。学习如何加载模型并进行单样本或批量预测这更接近真实的应用场景。这个波士顿房价预测项目就像一块“敲门砖”它涉及的每一个环节——数据管道、模型定义、训练逻辑、评估指标——都是构建更复杂AI系统的基石。理解了这个流程当你面对图像分类、机器翻译等任务时你会发现核心框架惊人地相似只是Dataset、Model和Loss的具体内容发生了变化。动手把这个项目做一遍调试通并尝试上述的一两个扩展点你对PyTorch和深度学习工作流的理解会上一个坚实的台阶。本文还有配套的精品资源点击获取
RELATED — 相关阅读

相关资讯

LATEST — 最新资讯

最新发布

TODAY — 本日精选

新闻

WEEKLY — 本周精选

新闻

MONTHLY — 本月精选

新闻