Keras神经网络回归实战:波士顿房价预测与多层感知器调参
发布时间:2026/9/28 14:38:27来源:尧图网络
简介面向机器学习初学者与希望掌握神经网络回归建模的开发者这份实战代码包使用Keras构建神经网络解决回归问题围绕经典波士顿房价数据集完整演示了从数据预处理到模型训练评估的完整流程包括加载数据、标准化特征、划分训练集与测试集、搭建含隐藏层与线性输出层的多层感知器并以均方误差作为损失函数、优化器进行训练同时绘制训练与验证的损失曲线以及平均绝对误差曲线以检查过拟合情况。包内共2个Python脚本一个为基础实现另一个使用优化后的参数进行预测便于直观对比不同配置下的模型效果与调参影响。压缩包整体仅3KB轻量便携适合边看边练。目前已有2681人学习下载是快速入门Keras回归任务的高性价比参考。1. 神经网络的回归问题这份波士顿房价预测资源到底值不值得跑提到 Keras 入门十篇文章有八篇在讲 MNIST 分类一到回归问题就变成“改个损失函数就行”一句话带过。实际上回归任务的坑比分类深得多输出层不能用 softmax、损失选错曲线直接不收敛、数据不标准化训练几轮 loss 就飞了。这份《keras 神经网络解决回归问题实例_波士顿房价预测.rar》正好补上这块短板——里面是一套完整的课程章节源码包含基础版神经网络波士顿房价预测脚本、优化参数版预测脚本以及多层感知器进阶内容。适合刚学完 Keras 分类、想转向回归预测的从业者也适合做课程设计时需要一份可复现代码的人。波士顿房价数据集虽然是 1970 年代的经典数据但作为理解回归网络训练流程的载体依然干净高效特征数量适中、样本量小、跑一轮只要几秒拿来验证网络结构变化对结果的影响非常顺手。2. 数据加载与预处理波士顿房价数据集的三个关键动作2.1 从 sklearn 加载数据到划分训练集random_state 不是玄学这份资源的代码入口很直接用 sklearn 内置的load_boston加载数据。虽然新版 scikit-learn 已经移除了这个数据集1.2 版本之后需要用替代方案后面避坑章会细说但在课程录制时的版本里这是最省事的数据来源。加载之后拿到的是两个部分X是 506 条样本、13 个特征y是对应的房价中位数单位是千美元。这里提醒一句波士顿房价数据集的样本量不大训练集和测试集的划分质量直接影响模型评估的可信度。from sklearn.datasets import load_boston from sklearn.model_selection import train_test_split from sklearn.preprocessing import StandardScaler boston load_boston() X boston.data y boston.target X_train, X_test, y_train, y_test train_test_split( X, y, test_size0.2, random_state42 )test_size0.2表示留出 20% 的样本做测试大概 101 条random_state42固定随机种子保证每次跑出来的划分一致。这个参数在实际项目中容易被忽略但它的作用不可小觑——没有固定种子你没法比较两次实验到底是模型变好了还是数据划分变了。我平时调试时习惯固定一个值等确定模型结构后再换几个种子验证稳定性。这套代码里把划分放在标准化之前严格来说有一点数据泄漏风险但在这个小数据集和教学场景下问题不大进阶做法是先划分再标准化后面避坑章会展开。2.2 特征标准化为什么三个尺度的特征必须先归一波士顿房价数据集的 13 个特征量纲差异很大CRIM犯罪率取值在 0.01 到 90 之间TAX房产税率在 180 到 700 之间B黑人比例指数甚至能到 400 多。如果直接把原始特征喂进神经网络数值大的特征会在权重更新中占据主导地位网络训练会变得异常缓慢甚至难以收敛。这就是标准化的核心原因——让每个特征都在零均值、单位方差附近让梯度下降在每一维上步伐一致。scaler StandardScaler() X_scaled scaler.fit_transform(X)这段代码对全部数据做了标准化fit_transform先计算训练数据的均值和标准差再用它们把数据转换到标准正态分布。注意这里因为是在划分训练集之前调用实际是用全量数据计算统计量。如果严格一点应该先train_test_split再对训练集fit_transform、测试集transform避免测试集信息提前“泄漏”到训练过程里。教学代码从简可以理解但你自己做项目时要养成先划分再标准化的习惯。2.3 输出层的线性激活回归和分类的本质分界线整套网络的输出层只有 1 个神经元激活函数用linear这是回归模型与分类模型最本质的区别。分类任务的输出层需要 softmax 或 sigmoid 把结果压到概率区间而回归任务要输出连续数值必须让神经元原样输出加权求和的结果。如果手误把输出层改成sigmoid输出范围就会被锁死在 0~1 之间而波士顿房价的中位数分布在 5~50 千美元区间模型永远学不到正确量级。第 5 章会讲到对应故障的排查方法因为我的学员里至少有三位在这个问题上翻过车——表现是训练损失前期还在下降后期无论如何都压不到合理范围。3. 搭建与训练回归网络Sequential 三层结构逐层拆解3.1 Sequential 堆叠 Dense 层神经元数与 input_shape 的配合这份资源里的网络结构非常经典三层全连接输入层 64 神经元、隐藏层 32 神经元、输出层 1 神经元。这个结构本质上就是一个多层感知器MLP也叫前馈神经网络信息从输入层逐层向前传播没有循环和跳跃连接。对波士顿房价这种 506 条样本的小数据集这个容量已经足够表达特征之间的非线性关系再加大网络反而容易过拟合。from keras.models import Sequential from keras.layers import Dense model Sequential() model.add(Dense(64, activationrelu, input_shape(X_train.shape[1],))) model.add(Dense(32, activationrelu)) model.add(Dense(1, activationlinear))第一层的input_shape(X_train.shape[1],)从训练数据的特征数量动态获取这里就是 13权重矩阵的维度是13 × 64加上 64 个偏置。第二层不再需要指定input_shapeKeras 会自动根据上一层的输出推断输入维度。隐藏层用relu是为了引入非线性并缓解梯度消失输出层用linear则是回归任务的硬性要求。你可以把 64 和 32 看成两个旋钮往后调大或调小都会影响模型的拟合能力课程资源里的优化版脚本就是针对这两个数值做了调整。3.2 编译参数MSE 损失与 Adam 优化器的搭配逻辑模型搭完必须编译这一步告诉 Keras 三件事用什么损失函数衡量预测偏差、用什么优化器更新权重、用什么指标评估效果。回归任务最常见的搭配就是均方误差MSE配 Adam 优化器评估指标用平均绝对误差MAE。MSE 对异常值敏感能把大误差的样本快速拉回正常区域MAE 更直观直接告诉你平均预测偏差了多少千美元。model.compile( lossmean_squared_error, optimizeradam, metrics[mae] )optimizeradam用的是 Keras 默认参数学习率 0.001。这个学习率在大多数回归任务上表现稳定不需要额外调节。如果你的验证损失出现震荡不收敛可以试试调低学习率方法是用keras.optimizers.Adam(learning_rate0.0001)替换默认的字符串写法。注意metrics[mae]里的 MAE 只是给我们看的指标不参与梯度计算真正驱动权重更新的一直是损失函数。3.3 fit 训练与 history 对象验证集从哪来训练过程调用model.fit()数据分批喂入网络每完成一个 epoch 计算一次损失并更新权重。这里有一个容易被忽略的点validation_data(X_test, y_test)直接把测试集当作验证集使用。这意味着训练过程中模型的每个 epoch 结束都会看一眼测试集的表现并记录到history对象里——这虽然方便但如果用验证集指标来调参本质上就是在用测试集信息做决策严格建模流程里是不允许的。资源这么写是教学演示需要实际项目应该从训练集再切一块做验证集。history model.fit( X_train, y_train, batch_size32, epochs100, validation_data(X_test, y_test) )batch_size32表示每 32 条样本计算一次梯度并更新权重这个值越小更新越频繁、训练越震荡epochs100是遍历整个训练集的次数100 轮对这个数据集来说够用但不算充裕我实际跑下来的经验是 loss 还在缓慢下降加码到 200 轮效果略好但收益边际递减。训练返回的history对象记录了每个 epoch 的损失和指标是判断过拟合和欠拟合的关键素材下一章要用到它。4. 预测与参数优化从模型评估到多层感知器进阶4.1 损失曲线怎么读训练损失与验证损失分开看训练结束后做的第一件事不应该是看测试集误差而是先读history里记录的训练曲线。这套资源专门画了两张图——一张是训练损失与验证损失随 epoch 的变化另一张是训练 MAE 与验证 MAE 的变化。绘制代码简洁直接import matplotlib.pyplot as plt plt.plot(history.history[loss], labelTraining Loss) plt.plot(history.history[val_loss], labelValidation Loss) plt.legend() plt.show() plt.plot(history.history[mae], labelTraining MAE) plt.plot(history.history[val_mae], labelValidation MAE) plt.legend() plt.show()怎么看这两张图核心是观察训练曲线和验证曲线的间距。如果训练损失持续下降但验证损失在第 30 轮左右开始反弹就是典型的过拟合信号——网络开始死记训练样本的细节丧失泛化能力。如果两条曲线都居高不下说明模型容量不够或学习率不合适属于欠拟合。波士顿房价数据集上跑 100 轮经验值是训练 MAE 能压到 2.5 千美元左右验证 MAE 在 3~4 千美元之间差距不大说明模型状态健康。4.2 模型预测测试集MAE 是最直白的业务指标模型训练完、曲线确认没有明显异常就可以拿测试集做最终评估。测试集在训练期间只是被用来看验证曲线并没有真正参与权重更新因此它给出的误差数值是可信的最终成绩。资源里用一句model.predict(X_test)得到预测值数组再手动计算平均绝对误差。y_pred model.predict(X_test) print(Mean Absolute Error:, np.mean(np.abs(y_test - y_pred)))这段代码有两个细节值得说。model.predict()返回的是一个形状为(101, 1)的二维数组y_test形状是(101,)虽然 numpy 能广播相减但严谨一点可以用y_pred.flatten()把预测值压成一维再算避免某些操作符在处理形状差异时给出意外结果。数值含义上MAE 表示平均预测偏差了多少千美元跑出来的结果在 3.5 左右意味着平均误差约 3500 美元对波士顿房价中位数 21.6 千美元来说误差占比约 16%这个精度对教学演示足够但要落地商用还有很大调优空间。4.3 优化版脚本在调什么神经元数与层数的两个旋钮资源里的第二个脚本叫“使用优化后的参数预测波士顿房价”我特意对比了它与基础版的差异优化集中在三个方面一是中间层的神经元数从 64/32 上调或改写为更深的层次组合二是把训练轮数从 100 增加到 200 甚至 300三是部分版本中把batch_size调小到 16 以提高梯度更新频率。参数选择上没有标准答案但有通用的试探逻辑。参数基础版优化版倾向调整理由隐藏层结构64→32128→64→32加大模型容量捕捉更复杂非线性训练轮数100200~300让损失充分收敛批大小3216更频繁更新权重稳定收敛验证划分固定测试集做验证从训练集再切 10%~20% 验证避免测试集信息泄漏从“多层感知器进阶”这个课程章节标题也能看出这部分的重点是讲清楚前馈神经网络的层数加深、宽度加大是如何影响回归表现的。我的建议是不要迷信“层数越多越好”先跑通基础版拿到误差基线再逐个调参每次只改一个变量。资源里两个脚本正好对应了这种对照实验的思路——先有一个基线再做一次改动对比 MAE 变化。4.4 预测结果可视化散点图比数值更诚实只盯着 MAE 一个数字会掩盖一个典型问题——模型可能在均值附近预测得很准但对高房价和低房价样本完全不敏感。这时候把预测值和真实值画成散点图一眼就能看出端倪。plt.scatter(y_test, y_pred.flatten(), alpha0.6) plt.plot([y_test.min(), y_test.max()], [y_test.min(), y_test.max()], r--, linewidth2) plt.xlabel(True Price) plt.ylabel(Predicted Price) plt.show()图中红色虚线是理想预测线y x。如果散点均匀分布在这条线两侧说明模型对高中低价位的预测都算均衡如果高价区段的点全部落在线的下方说明模型系统性低估了高房价——这是回归任务里很常见的偏差根源是训练样本中高房价样本数量较少模型缺乏足够的数据去学习那段区间。检查这个图的习惯我看模型的视角就变成了“哪里不准”而不是“平均来看准不准”。5. 避坑指南波士顿房价预测的五个高频翻车点5.1 现象训练损失不降反升或者验证损失剧烈震荡新手最容易撞上的问题训练了二三十个 epochloss 曲线像心电图一样跳动数值不降反升。原因通常是学习率过大Adam 优化器的默认学习率 0.001 在大部分情况下适用但个别网络结构或数据分布下权重更新步长过大直接跨过了最优区域。解决方法是显式指定优化器的学习率例如Adam(learning_rate0.0001)同时把batch_size调大一点让每次权重更新的方向更稳定。我一般会优先调学习率因为改这一个参数的成本最低、对结果的影响最直接。5.2 现象训练完成后预测结果几乎全部是同一个值模型“学废了”的表现是不管输入是什么预测输出都落在某个固定值附近。原因有两个一是数据没有标准化输入特征的尺度差异让梯度更新被大数值特征主导网络退化成近似线性回归甚至更加退化二是输出层误用了sigmoid或tanh激活函数把输出限制在一个很窄的区间内。解决方法是检查两处确认输出层用linear确认输入数据经过了StandardScaler变换。这两个检查项基本能覆盖 90% 的“预测值恒定”故障。5.3 现象每次重新运行代码训练出的模型误差都不一样运行两次脚本结果一次 MAE 是 3.2一次是 4.8。原因梳理下来有两个层面第一层是train_test_split没设置random_state训练集和测试集的划分每次都变第二层是 Keras / TensorFlow 在 CPU 和 GPU 上运行时如果不固定全局随机种子模型初始化和训练过程中的随机性会导致结果波动。解决办法是开头加上固定种子的代码import numpy as np import tensorflow as tf import random as python_random np.random.seed(42) python_random.seed(42) tf.random.set_seed(42)注意tf.random.set_seed是 TensorFlow 2.x 的写法老版本里对应的是tf.set_random_seed。固定种子之后同一个脚本在同一环境下跑两次结果基本一致。但不同硬件比如 CPU 和 GPU之间依然可能有细微差异这属于正常现象不必死磕。5.4 现象load_boston 直接报错 ImportError新版 scikit-learn1.2 及以上版本移除了波士顿房价数据集原因是数据本身存在一些社会伦理方面的问题。如果环境里安装了新版 sklearnfrom sklearn.datasets import load_boston会直接报错。解决思路有三条一是安装旧版 sklearn如pip install scikit-learn1.1.3适合课程复现场景二是改用fetch_california_housing数据集它是同样量级、同样面向回归任务的数据集特征维度也接近三是用keras.datasets.boston_housing加载虽然目录结构和sklearn版本不完全一样但也是经典教学数据集。资源里的代码是按旧版 sklearn 写的如果你复现报错优先换 sklearn 版本因为数据内容对应得最精确。5.5 现象测试集表现尚可但真实新数据上预测结果完全离谱这个是波士顿房价场景里最容易踩的数据泄漏坑。资源里的代码是先标准化再划分训练测试集fit_transform用到了全量数据的统计量。如果只是演示模型效果问题不大但如果你把它搬到实际项目新来的数据要用scaler.transform()而不是fit_transform()否则新数据的分布会被重新计算导致输入空间不一致。更规范的流程是X_train, X_test, y_train, y_test train_test_split(X, y, test_size0.2, random_state42) scaler StandardScaler() X_train_scaled scaler.fit_transform(X_train) X_test_scaled scaler.transform(X_test)这里的关键点是fit_transform只对训练集调用测试集只用transform。这样测试集的统计量永远不会参与训练更不会在生产环境部署时出现“模型训练时看到的测试数据分布和线上数据分布对不上”的问题。我那段时间给一个量化项目写回归脚本就差点把StandardScaler在整份数据上fit了两遍幸好最后做数据审查时发现了这个细节否则预测结果会带着系统性偏移。6. 验证模型可用性的三个习惯复现这份资源后我还要做什么网络训练完、MAE 也算了是不是就收工了不是。我复盘这份资源的完整流程后给自己定了一套强制验证清单每次做回归任务必须走一遍。第一步是回到业务本身。波士顿房价的 MAE 是 3.5 千美元但脱离业务谈误差没有意义。这时候我会把预测结果按真实房价分组观察计算不同价位区间的平均误差分布。如果低房价段误差是 2 千美元高房价段误差是 6 千美元说明模型不是均匀地“不准”而是对某个区间结构性失明。这个信息比一个总 MAE 值有用得多。第二步是检查样本是否被标准化后正确还原。很多人训练完模型想看看原始尺度的预测值直接用y_pred去跟真实房价对比得出的结论完全不可读。正确做法是如果训练时对y也做了标准化这批代码里没做但实际项目经常做预测输出必须inverse_transform还原到原始量纲再算误差否则 MAE 会被压缩在 0 到 1 的区间里根本看不出业务含义。第三步是把模型结构和训练结果存盘。用model.save(boston_model.h5)保存模型权重同时把scaler对象用pickle.dump序列化保存。这里我有一个血泪教训有一次给同事交付房价预测脚本模型和标准化器的保存步骤没写进交付文档对方拿到的预测结果全在错误量级上。从那以后我每次交付回归模型都会把 scaler 的均值、方差参数存成 json并在代码注释里写明“预测新数据前必须先加载 scaler 并执行 transform”。这套习惯从复现这份波士顿房价资源时就固定下来了希望你也能从第一次跑通开始就带上它后面换任何数据集都能少踩暗坑。希望帮到你。本文还有配套的精品资源点击获取
网站建设高端定制企业官网