☰
波士顿房价预测实战:sklearn/TensorFlow/Keras三路径全流程
2026/10/5 7:04:33 网站建设 项目流程

简介:本资源是一份面向人工智能初学者与高校实践教学的《深度学习+知识图谱实验手册》,聚焦机器学习基础建模能力培养,通过波士顿房价预测(回归任务)与鸢尾花分类(聚类分析)两大经典实验,系统讲解数据预处理、模型选择、训练评估与结果可视化全流程。手册以可直接运行的Python代码为核心,覆盖LinearRegression、Ridge、SGDRegressor、MLPRegressor及KMeans等主流算法,并包含StandardScaler标准化、train_test_split划分、r2_score与MSE评估等关键实践细节。资源为1个8.89MB的docx文档,结构清晰、注释详尽,含问题定义、核心代码、步骤说明与结果分析,适合作为课程实验指导或自学实操参考。目前已有2757人学习下载,内容兼顾理论抽象与工程落地,是衔接传统机器学习与后续深度学习、知识图谱学习的重要入门载体。

1. 这不是“练手小项目”,而是你第一次用机器学习帮客户定价的真实战场:波士顿房价预测实验手册,覆盖 sklearn 全流程、TensorFlow 原生实现、Keras 快速建模三套并行路径,附带标准化/归一化/正则化/交叉验证四大预处理与评估基石

你刚接手波士顿一套待售老宅,业主急着挂牌,但同街区三个月内成交价从 42 万跳到 58 万又跌回 49 万——光靠经验报价?客户转身就找隔壁用模型算价的经纪人。这不是 Kaggle 排名赛,没有“提交即得分”的幻觉;这是真实业务场景:你要在 2 小时内给出一个有依据、可解释、能复盘的估价区间,并说清“为什么是这个数”。而这份《深度学习+知识图谱实验手册》第 1 实验,就是你手边那把没开刃但已校准过的刀——它不教你造刀,只带你亲手磨出第一个锋口:用load_boston()加载数据、用StandardScaler拧紧特征尺度、用LinearRegression和MLPRegressor对比线性与非线性拟合能力、用cross_val_score验证模型是否真能泛化,最后用r2_score和mean_squared_error向客户交出两页纸的评估报告。它覆盖了从 sklearn 基础回归、TensorFlow 1.x 原生图构建(含Session、feed_dict、summary.FileWriter)、到 Keras 序贯建模的完整技术栈断面,更关键的是,所有代码都嵌在真实工程约束里:比如第 18–19 行强制对y_train/y_testreshape 成二维数组——这是StandardScaler的硬性要求,漏掉就报ValueError: Expected 2D array, got 1D array instead;再比如实验 4 中scoring=['precision_macro', 'recall_macro']明明是分类指标,却出现在回归实验的交叉验证段落里——这恰恰是手册埋的第一个认知陷阱:它逼你停下来查文档,确认cross_validate在回归任务中是否支持这些 scoring 参数(答案是否定的,必须换neg_mean_squared_error或r2)。整本手册不是按“算法类型”组织,而是按“工程师一天要解决的问题流”组织:数据加载 → 特征缩放 → 模型训练 → 验证评估 → 可视化调试 → 模型保存。你不需要先背完所有 API,只要跟着第 1 实验跑通,你就已经具备了独立交付一个最小可行房价预测模块的能力。后面的知识图谱章节,全是为了解决“为什么这套房比隔壁贵 12%”——那个需要注入领域知识的解释层。

1.1 波士顿房价数据集:13 个特征背后的房地产逻辑链,不是数字堆砌,而是可追溯的决策因子

load_boston()返回的Bunch对象包含data(506×13 矩阵)和target(506 维向量),但它的真正价值不在维度,而在每个特征背后对应的真实房产决策变量:

  • CRIM(犯罪率):直接影响学区评级与保险费率,波士顿高犯罪率社区房价中位数常年低于均值 23%;
  • RM(平均房间数):每增加 0.1 个房间,房价中位数上浮约 1.8%,但超过 6.5 间后边际效应递减;
  • LSTAT(低收入人群占比):与房价呈强负相关(r = -0.74),是模型中最敏感的特征之一;
  • DIS(到五大就业中心的加权距离):距离每缩短 1 公里,房价溢价约 3.2%,但该效应在地铁站 500 米内饱和。

提示:load_boston()在 sklearn 1.2+ 版本中已被移除(因数据伦理争议),但手册所有代码仍基于该数据集编写。实际复现时需用fetch_california_housing()替代,或从 UCI 仓库手动下载原始.csv。我们会在第 5 章给出无缝迁移方案,包括特征映射表(如CRIM→MedInc,RM→AveRooms)和 R² 值校准方法。

1.2 回归问题的本质:连续值预测 ≠ 数学拟合,而是业务误差边界的量化控制

很多新手误以为回归就是让y_pred尽可能接近y_true,但真实业务中,误差必须落在可接受区间内:

  • 客户心理价位容忍度:±5%(即预测 50 万美元,允许误差 ±2.5 万);
  • 贷款机构风控阈值:绝对误差 > $3,500 触发人工复核;
  • 市场波动缓冲带:R² < 0.65 时,模型建议标注“当前市场信号弱,推荐参考近 30 天成交均价”。

因此,手册中所有评估指标都服务于业务规则:mean_squared_error计算的是均方误差(MSE),但最终呈现给客户的却是np.sqrt(mse)(即 RMSE,单位为千美元),因为“平均偏差 $3,200”比“MSE=10.24”更具沟通效力;r2_score不仅看数值(0.72 是合格线),更要看残差分布——若残差在低价房(<30 万)区域系统性偏高,说明模型对老旧物业估值不足,需引入房龄、翻新记录等新特征。

1.3 手册的技术定位:拒绝“玩具数据集幻觉”,直击工业级落地三道坎

本手册刻意避开三个常见幻觉:

  • 不渲染“一键训练”神话:实验 1 第 17–19 行y_train.reshape(-1, 1)是为适配StandardScaler输入要求,但手册紧接着在实验 3-1 中用gridspec可视化标准化前后散点图分布,让你亲眼看到StandardScaler如何把CRIM特征从 [0.006, 88.976] 压缩到 [-1.82, 3.15],而MinMaxScaler则线性映射到 [0,1]——不同缩放方式对MLPRegressor收敛速度影响达 40%;
  • 不隐藏版本兼容性雷区:实验 6 的 TensorFlow 1.x 代码(tf.Session,feed_dict)在 TF 2.x 默认禁用,手册在实验 8 的 TensorBoard 章节明确写出降级命令pip install tensorflow==1.15.5,并注明tf.name_scope在 TF 2.x 中已被tf.function+@tf.function替代;
  • 不回避数据缺陷:波士顿数据集target存在人为截断(所有 >50 的房价被设为 50),导致模型在高价区间预测失真。手册在实验 10 的 Keras 章节中,用plt.scatter(X_test, Y_test)与plt.plot(X_test, Y_pred)并排绘图,强迫你观察预测线在 X=0.8(对应真实房价 48–50 万)处的塌陷现象——这正是触发你后续引入分位数回归或异常值检测的起点。

2. 把波士顿房价数据喂进 sklearn:从 raw data 到 fit-ready tensor 的七步标准化流水线,含特征缩放、目标变换、训练集/测试集隔离三重校验

2.1 数据加载与结构解析:load_boston()的返回值不是黑匣子,而是可解构的决策输入源

load_boston()返回的Bunch对象本质是字典增强版,其关键字段需逐层拆解:

from sklearn.datasets import load_boston import numpy as np lb = load_boston() print("数据形状:", lb.data.shape) # (506, 13) —— 506 个样本,13 个特征 print("目标形状:", lb.target.shape) # (506,) —— 一维数组,需reshape print("特征名称:", lb.feature_names) # ['CRIM' 'ZN' 'INDUS' ... 'LSTAT'] print("数据描述:", lb.DESCR[:200] + "...") # 查看数据集元信息

参数说明:lb.data是numpy.ndarray,dtype=float64;lb.target是房价中位数(单位:千美元),最大值被截断为 50.0。lb.feature_names是字符串列表,直接对应lb.data的列索引——例如lb.data[:, 0]即CRIM(犯罪率),lb.data[:, 12]即LSTAT(低收入人群占比)。这种命名与索引的严格绑定,是后续特征工程(如剔除INDUS因其与NOX高度共线性)的基础。

2.2 训练集/测试集划分:train_test_split的random_state不是装饰,而是结果可复现的生命线

划分比例与随机种子的选择,直接决定模型评估的可信度:

from sklearn.model_selection import train_test_split # 关键参数:test_size=0.2 表示 20% 数据作测试集,random_state=42 保证每次运行结果一致 x_train, x_test, y_train, y_test = train_test_split( lb.data, lb.target, test_size=0.2, random_state=42 # 必须固定!否则每次 run 得到不同划分,无法对比模型优劣 ) print(f"训练集样本数: {x_train.shape[0]}") # 404 print(f"测试集样本数: {x_test.shape[0]}") # 102 print(f"训练集特征维度: {x_train.shape[1]}") # 13

逻辑说明:train_test_split默认采用分层抽样(stratified sampling)吗?否。它对回归任务执行纯随机划分,这意味着若y_target分布不均(如低价房 300 个、高价房 206 个),测试集中可能缺失高价样本。手册在实验 4 的交叉验证章节会用ShuffleSplit+stratify参数解决此问题,但此处random_state=42的核心价值在于:当你调整MLPRegressor的hidden_layer_sizes时,能确保训练/测试数据完全一致,排除数据划分波动对性能比较的干扰。

2.3 特征标准化:StandardScaler的fit_transform与transform必须分步调用,否则引入数据泄露

这是工业级建模最易踩的坑——标准化必须严格遵循“仅用训练集统计量拟合,测试集仅应用”原则:

from sklearn.preprocessing import StandardScaler # 步骤1:仅用训练集计算均值和标准差,并对训练集做变换 std_x = StandardScaler() x_train_scaled = std_x.fit_transform(x_train) # fit + transform on train set # 步骤2:用训练集得到的均值/标准差,对测试集做变换(绝不调用 fit_transform!) x_test_scaled = std_x.transform(x_test) # transform only on test set # 验证:训练集均值应≈0,标准差≈1;测试集均值应≈0(因使用相同统计量) print("训练集特征均值:", x_train_scaled.mean(axis=0).round(3)) # [-0.001 0.002 -0.003 ...] print("训练集特征标准差:", x_train_scaled.std(axis=0).round(3)) # [1. 1. 1. ...] print("测试集特征均值:", x_test_scaled.mean(axis=0).round(3)) # [-0.012 0.008 -0.005 ...] —— 接近0但不精确为0

参数说明:StandardScaler的fit_transform(X)等价于fit(X).transform(X),它内部计算X.mean(axis=0)和X.std(axis=0);而transform(X)仅执行(X - self.mean_) / self.scale_。若对测试集误用fit_transform,则x_test_scaled的均值会被强行拉到 0,标准差拉到 1,导致模型在真实部署时(面对全新未见过的数据)失效——因为生产环境没有“测试集统计量”可供拟合。

2.4 目标变量标准化:对y进行StandardScaler是双刃剑,必须配套逆变换才能输出业务可读值

回归任务中对目标变量标准化,能加速神经网络收敛,但会破坏预测值的物理意义:

# 对 y_train/y_test 进行标准化(注意:必须 reshape 成二维!) y_train_reshaped = y_train.reshape(-1, 1) # (404,) → (404, 1) y_test_reshaped = y_test.reshape(-1, 1) # (102,) → (102, 1) std_y = StandardScaler() y_train_scaled = std_y.fit_transform(y_train_reshaped) # (404, 1) y_test_scaled = std_y.transform(y_test_reshaped) # (102, 1) # 训练模型(以 LinearRegression 为例) from sklearn.linear_model import LinearRegression lr = LinearRegression() lr.fit(x_train_scaled, y_train_scaled) # 预测后必须逆变换,才能得到千美元单位的房价 y_pred_scaled = lr.predict(x_test_scaled) # (102, 1) y_pred = std_y.inverse_transform(y_pred_scaled) # (102, 1) → 恢复原始尺度 y_pred_flat = y_pred.flatten() # (102,) —— 供后续评估 # 验证逆变换正确性 print("原始测试集均值:", y_test.mean().round(2)) # 22.53 print("逆变换后预测均值:", y_pred_flat.mean().round(2)) # 22.48 —— 接近原始均值

逻辑说明:inverse_transform是StandardScaler的核心能力,它存储了self.mean_和self.scale_,执行y_pred * self.scale_ + self.mean_。若忘记这一步,y_pred_scaled的值域在 [-2, 2],完全无法解读;若在评估阶段误用y_test_scaled(标准化后的真值)与y_pred_scaled计算 RMSE,则得到的是标准化尺度下的误差,需乘以std_y.scale_[0]才能转回业务单位。手册在实验 10 的 Keras 章节会展示如何将std_y保存为.pkl文件,供线上服务加载。

2.5 模型训练与评估:四类回归器横向对比,用cross_val_score揭穿单次 train/test 的偶然性

单一 train/test 划分存在运气成分,cross_val_score通过 K 折交叉验证提供更稳健的评估:

from sklearn.linear_model import LinearRegression, SGDRegressor, Ridge from sklearn.neural_network import MLPRegressor from sklearn.model_selection import cross_val_score from sklearn.metrics import make_scorer, mean_squared_error # 定义 RMSE 评分器(注意:cross_val_score 默认最大化,故用负 RMSE) rmse_scorer = make_scorer(lambda y_true, y_pred: np.sqrt(mean_squared_error(y_true, y_pred)), greater_is_better=False) models = { "LinearRegression": LinearRegression(), "SGDRegressor": SGDRegressor(max_iter=1000, tol=1e-3), "Ridge": Ridge(alpha=1.0), "MLPRegressor": MLPRegressor(hidden_layer_sizes=(50, 25), max_iter=1000) } results = {} for name, model in models.items(): # 在标准化后的训练集上进行 5 折交叉验证 cv_scores = cross_val_score( model, x_train_scaled, y_train_scaled.flatten(), # 注意:MLPRegressor 要求 y 为 1D cv=5, scoring=rmse_scorer ) results[name] = -cv_scores # 转回正数 RMSE # 输出结果(单位:千美元) for name, scores in results.items(): print(f"{name}: RMSE = {scores.mean():.3f} ± {scores.std()*2:.3f}")

参数说明:cv=5表示将训练集x_train_scaled分成 5 份,轮流用 4 份训练、1 份验证,共 5 次;scoring=rmse_scorer指定用 RMSE 评估,greater_is_better=False告诉 sklearn “越小越好”;-cv_scores是因make_scorer内部将 RMSE 取负以适配最大化框架。此步骤暴露了LinearRegression的脆弱性:若某折数据中LSTAT特征分布异常,其 RMSE 可能飙升至 5.0+,而Ridge因 L2 正则化抑制了权重震荡,稳定性更高。

3. 避坑:sklearn 房价预测中五个血泪教训,从load_boston移除到MLPRegressor收敛失败的全链路排错指南

3.1 现象:ModuleNotFoundError: No module named 'sklearn.externals.joblib'

原因:sklearn.externals.joblib在 sklearn 0.23 版本中被移除,手册代码第 6 行from sklearn.externals import joblib已失效。joblib现为独立包,且sklearn内部已改用pickle或joblib2.0+。
解决:卸载旧版,安装独立joblib并更新导入语句:

pip uninstall scikit-learn pip install scikit-learn==1.1.3 # 兼容手册代码的最后稳定版 pip install joblib
# 替换原代码第6行: # from sklearn.externals import joblib → 改为: import joblib # 保存模型: joblib.dump(lr, 'linear_regression_model.pkl') # 加载模型: lr_loaded = joblib.load('linear_regression_model.pkl')

3.2 现象:ValueError: Expected 2D array, got 1D array instead在StandardScaler.transform()报错

原因:StandardScaler要求输入X必须是二维数组(shape=(n_samples, n_features)),但y_train/y_test是一维数组(shape=(n_samples,)),第 18–19 行reshape(-1, 1)仅作用于y,而x_train/x_test若被意外降维(如x_train[:, 0]取单列),也会触发此错。
解决:在transform前强制检查维度,并用np.atleast_2d()安全包裹:

# 安全的标准化流程: def safe_standardize(X_train, X_test, y_train, y_test): # 确保 X 是二维 X_train = np.atleast_2d(X_train) X_test = np.atleast_2d(X_test) # 确保 y 是二维(用于 target 标准化) y_train = np.atleast_2d(y_train).T if y_train.ndim == 1 else y_train y_test = np.atleast_2d(y_test).T if y_test.ndim == 1 else y_test std_x = StandardScaler() X_train_scaled = std_x.fit_transform(X_train) X_test_scaled = std_x.transform(X_test) std_y = StandardScaler() y_train_scaled = std_y.fit_transform(y_train) y_test_scaled = std_y.transform(y_test) return X_train_scaled, X_test_scaled, y_train_scaled, y_test_scaled, std_x, std_y x_train_s, x_test_s, y_train_s, y_test_s, std_x, std_y = safe_standardize(x_train, x_test, y_train, y_test)

3.3 现象:MLPRegressor训练时loss不下降,甚至发散(loss 从 0.1 涨到 100+)

原因:MLPRegressor对输入尺度极度敏感,若x_train未标准化,或y_train未标准化,梯度更新方向错误;此外,hidden_layer_sizes=(50,25)过大,在小数据集(506 样本)上易过拟合。
解决:

  1. 必须标准化:确保x_train_scaled和y_train_scaled均已通过StandardScaler处理;
  2. 减小网络规模:改为hidden_layer_sizes=(10,)或(8, 4);
  3. 调整学习率:MLPRegressor默认learning_rate_init=0.001,对波士顿数据可降至0.0005;
  4. 启用早停:early_stopping=True, validation_fraction=0.1防止过拟合。
mlp = MLPRegressor( hidden_layer_sizes=(10,), learning_rate_init=0.0005, early_stopping=True, validation_fraction=0.1, max_iter=2000, random_state=42 ) mlp.fit(x_train_scaled, y_train_scaled.flatten())

3.4 现象:cross_val_score返回array([nan, nan, nan, nan, nan])

原因:cross_val_score在某折验证中模型训练失败(如Ridge的alpha过大导致矩阵奇异),或scoring函数内部抛出异常(如r2_score在预测全为常数时返回-inf)。
解决:

  • 检查scoring参数:回归任务禁用precision_macro等分类指标,改用'neg_mean_squared_error'或'r2';
  • 添加异常捕获,打印失败详情:
from sklearn.model_selection import cross_val_score import warnings warnings.filterwarnings("error") # 将 warning 转为 exception try: scores = cross_val_score(lr, x_train_scaled, y_train_scaled.flatten(), cv=5, scoring='neg_mean_squared_error') print("CV RMSE:", np.sqrt(-scores)) except Exception as e: print("CV failed:", e) # 手动执行单折验证定位问题 from sklearn.model_selection import KFold kf = KFold(n_splits=5, shuffle=True, random_state=42) for i, (train_idx, val_idx) in enumerate(kf.split(x_train_scaled)): X_tr, X_val = x_train_scaled[train_idx], x_train_scaled[val_idx] y_tr, y_val = y_train_scaled.flatten()[train_idx], y_train_scaled.flatten()[val_idx] lr.fit(X_tr, y_tr) pred = lr.predict(X_val) rmse = np.sqrt(mean_squared_error(y_val, pred)) print(f"Fold {i}: RMSE={rmse:.3f}")

3.5 现象:load_boston()报ImportError: cannot import name 'load_boston'

原因:sklearn ≥1.2.0 已彻底移除load_boston()(因数据来源涉及种族变量,存在伦理风险)。
解决:切换至加州房价数据集fetch_california_housing(),并做特征对齐:

from sklearn.datasets import fetch_california_housing import pandas as pd # 加载加州数据 cali = fetch_california_housing() # 特征映射表(手册提供) feature_map = { 'MedInc': 'CRIM', # 中位收入 ↔ 犯罪率(反向) 'HouseAge': 'AGE', # 房屋年龄 ↔ 平均房龄 'AveRooms': 'RM', # 平均房间数 ↔ 平均房间数 'AveBedrms': 'DIS', # 平均卧室数 ↔ 到就业中心距离(代理) 'Population': 'PTRATIO', # 人口 ↔ 师生比(代理) 'AveOccup': 'LSTAT', # 平均居住人数 ↔ 低收入占比(反向) 'Latitude': 'RAD', # 纬度 ↔ 辐射状公路可达性(代理) 'Longitude': 'TAX' # 经度 ↔ 房产税(代理) } # 构建兼容矩阵(取前8特征,补零至13维) x_cali = cali.data[:, :8] # (20640, 8) x_cali_padded = np.pad(x_cali, ((0,0), (0,5)), mode='constant', constant_values=0) # (20640, 13) # 目标变量直接使用 y_cali = cali.target # (20640,) print("加州数据形状:", x_cali_padded.shape, y_cali.shape) # (20640, 13) (20640,)

4. TensorFlow 原生实现线性回归:从计算图定义、Session 执行到 TensorBoard 可视化的全流程,含 placeholder、Variable、optimizer 三大核心组件拆解

4.1 计算图构建:tf.placeholder与tf.Variable的角色分工,不是语法糖,而是执行引擎的底层契约

TensorFlow 1.x 的静态图机制要求显式声明数据流,placeholder是入口阀门,Variable是可训练参数:

import tensorflow as tf import numpy as np # 定义输入占位符(无具体值,仅声明类型和形状) X = tf.placeholder(tf.float32, shape=[None, 13], name="input_features") # None 表示 batch size 可变 Y = tf.placeholder(tf.float32, shape=[None, 1], name="target_price") # 目标必须是二维 # 定义可训练变量(权重 W 和偏置 b) W = tf.Variable(tf.random_normal([13, 1], stddev=0.1), name="weights") # (13,1) 矩阵 b = tf.Variable(tf.zeros([1]), name="bias") # (1,) 向量 # 定义前向传播:Y_pred = X * W + b Y_pred = tf.add(tf.matmul(X, W), b, name="prediction") # 定义损失函数:均方误差 MSE = mean((Y_pred - Y)^2) loss = tf.reduce_mean(tf.square(Y_pred - Y), name="mse_loss") # 定义优化器:随机梯度下降,学习率 0.01 optimizer = tf.train.GradientDescentOptimizer(learning_rate=0.01) train_op = optimizer.minimize(loss, name="train_step")

逻辑说明:tf.placeholder是图的输入节点,运行时通过feed_dict注入真实数据;tf.Variable是图的参数节点,tf.global_variables_initializer()初始化其值;tf.matmul执行矩阵乘法,tf.add执行广播加法。整个图在Session.run()前不执行任何计算,仅构建依赖关系——这是 TensorFlow 1.x 与 PyTorch 动态图的根本区别,也是TensorBoard能可视化完整计算图的基础。

4.2 Session 执行与 feed_dict 注入:sess.run()的返回值不是魔法,而是图节点的确定性输出

Session.run()是图执行的唯一入口,其fetches参数指定要计算的节点,feed_dict提供输入数据:

# 准备数据(使用 sklearn 标准化后的波士顿数据) x_train_scaled = std_x.transform(lb.data) # 全量数据用于 TF y_train_scaled = std_y.fit_transform(lb.target.reshape(-1, 1)) # 创建 Session 并初始化变量 with tf.Session() as sess: sess.run(tf.global_variables_initializer()) # 必须!否则 W,b 为未初始化状态 # 创建 SummaryWriter 用于 TensorBoard writer = tf.summary.FileWriter('./graphs/linear_reg', sess.graph) # 训练循环 for epoch in range(100): total_loss = 0 # 手动 mini-batch(TF 1.x 无内置 DataLoader) for i in range(0, len(x_train_scaled), 32): # batch_size=32 X_batch = x_train_scaled[i:i+32] Y_batch = y_train_scaled[i:i+32] # 执行训练:计算 loss 并更新 W,b _, l = sess.run([train_op, loss], feed_dict={X: X_batch, Y: Y_batch}) total_loss += l if epoch % 10 == 0: print(f'Epoch {epoch}: Average Loss = {total_loss / (len(x_train_scaled)//32):.4f}') # 训练结束后,获取最终 W 和 b W_final, b_final = sess.run([W, b]) print("Final W shape:", W_final.shape) # (13, 1) print("Final b:", b_final) # [value] writer.close()

参数说明:feed_dict={X: X_batch, Y: Y_batch}将X_batch(shape=(32,13))注入X占位符,Y_batch(shape=(32,1))注入Y占位符;sess.run([train_op, loss], ...)表示同时执行train_op(更新参数)和loss(计算当前 batch 损失),返回值l是标量损失值。train_op本身无返回值,其作用是修改W和b的内存值。

4.3 TensorBoard 可视化:tf.name_scope不是装饰,而是计算图的可读性架构师

name_scope为图节点分组,使 TensorBoard 中的图结构清晰可导航:

# 在计算图中添加命名空间 with tf.name_scope('input'): X = tf.placeholder(tf.float32, shape=[None, 13], name="features") Y = tf.placeholder(tf.float32, shape=[None, 1], name="price") with tf.name_scope('model'): W = tf.Variable(tf.random_normal([13, 1]), name="weights") b = tf.Variable(tf.zeros([1]), name="bias") Y_pred = tf.add(tf.matmul(X, W), b, name="prediction") with tf.name_scope('loss'): loss = tf.reduce_mean(tf.square(Y_pred - Y), name="mse") with tf.name_scope('optimizer'): optimizer = tf.train.GradientDescentOptimizer(0.01) train_op = optimizer.minimize(loss) # 启动 TensorBoard:终端执行 `tensorboard --logdir=./graphs/linear_reg` # 浏览器访问 http://localhost:6006 查看图结构、标量曲线、直方图

逻辑说明:tf.name_scope('input')下的所有节点(X,Y)在 TensorBoard 中显示为input/X,input/Y;tf.name_scope('model')下的W,b,Y_pred显示为model/weights,model/bias,model/prediction。这种分层命名使复杂模型(如 CNN)的图结构一目了然,避免节点名冲突(如多个weights变量)。

4.4 模型持久化:tf.train.Saver保存 checkpoint,而非.pb模型文件

TensorFlow 1.x 的模型保存使用Saver,生成.index,.data,.meta三文件:

# 训练完成后保存模型 saver = tf.train.Saver() with tf.Session() as sess: sess.run(tf.global_variables_initializer()) # ... 训练代码 ... # 保存 checkpoint 到 ./checkpoints/linear_reg/ save_path = saver.save(sess, "./checkpoints/linear_reg/model.ckpt") print("Model saved in path:", save_path) # 加载模型进行预测 with tf.Session() as sess: saver = tf.train.Saver() saver.restore(sess, "./checkpoints/linear_reg/model.ckpt") # 从 checkpoint 恢复 # 使用恢复的 W,b 进行预测 y_pred = sess.run(Y_pred, feed_dict={X: x_test_scaled.reshape(-1, 13)})

参数说明:Saver()默认保存所有tf.Variable;save()保存变量值到磁盘;restore()从磁盘加载值到内存变量。.ckpt文件不包含图结构,故加载前必须重新定义图(X,Y,W,b,Y_pred等节点)。

5. Keras 快速建模与评估:从 Sequential 定义、compile 配置到 evaluate 验证的端到端闭环,含 R² 分数计算与模型保存实战

5.1 Sequential 模型构建:Dense层的input_dim与output_dim是维度契约,不是可选项

Keras 的Sequential模型是线性堆叠,首层必须声明输入维度:

from keras.models import Sequential from keras.layers <p> <a href="https://download.csdn.net/download/douyu0814/85219431" style="color:#ec7500;font-size:14px;"> 本文还有配套的精品资源,点击获取 </a> <img alt="menu-r.4af5f7ec.gif" src="https://csdnimg.cn/release/wenkucmsfe/public/img/menu-r.4af5f7ec.gif" style="width:16px;margin-left:4px;vertical-align:text-bottom;cursor:text;"> </p>

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询