使用TensorFlow实现波士顿数据集回归模型时预测全错问题求助
解决波士顿房价回归预测全错的问题
我帮你分析了代码里的几个关键问题,这些问题直接导致了你的预测完全失效,下面逐个拆解并给出修正方案:
核心问题1:输出层误用ReLU激活函数
回归任务的目标是预测连续数值(房价),但你在输出层用了tf.nn.relu,这会把所有小于0的预测值直接截断为0。波士顿房价虽是正数,但随机初始化的模型很容易输出负数被截断,而且ReLU完全不适合回归任务的输出层——应该去掉输出层的激活函数,直接输出线性结果。
核心问题2:用精确相等判断回归“正确性”
你用tf.equal(pred, y_train)来判断预测是否正确,这在回归任务里完全不合理!回归是预测连续值,两个浮点数几乎不可能完全相等,所以correct_eval自然全是False,求和为0。对于回归任务,我们应该用均方误差(MSE)、平均绝对误差(MAE)这类指标来评估模型,而不是精确匹配。
核心问题3:根本没有训练模型!
你的代码只初始化了变量,然后直接做了前向传播,但完全没有定义损失函数和优化器,也没有执行训练步骤。模型的权重和偏置都是随机初始化的,根本没学习任何数据规律,预测结果当然是随机的或者全0。
核心问题4:数据未做归一化
波士顿数据集的特征尺度差异极大(比如CRIM犯罪率范围是0-88,RM房间数范围是3-9),不做归一化会导致模型训练时梯度不稳定,难以收敛。必须对特征做标准化或归一化处理。
修正后的完整代码
import pandas as pd import numpy as np from sklearn.model_selection import train_test_split from sklearn.preprocessing import StandardScaler import tensorflow as tf # 加载并预处理数据 data = pd.read_csv("Boston_Housing.csv") x = data.iloc[:, 0:13].values y = data.iloc[:, 13].values.reshape(-1, 1) # 转成二维数组,适配TensorFlow输入格式 # 划分数据集 x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.2, random_state=42) # 特征归一化(关键步骤) scaler = StandardScaler() x_train = scaler.fit_transform(x_train) x_test = scaler.transform(x_test) # 模型参数定义 input_width = 13 n_hidden_layer1 = 13 n_hidden_layer2 = 13 n_op = 1 weights = { "w_h1": tf.Variable(tf.random_normal([input_width, n_hidden_layer1], stddev=0.1)), "w_h2": tf.Variable(tf.random_normal([n_hidden_layer1, n_hidden_layer2], stddev=0.1)), "w_op": tf.Variable(tf.random_normal([n_hidden_layer2, n_op], stddev=0.1)) } biases = { "b_h1": tf.Variable(tf.zeros([n_hidden_layer1])), "b_h2": tf.Variable(tf.zeros([n_hidden_layer2])), "b_op": tf.Variable(tf.zeros([n_op])) } # 前向传播函数(输出层去掉ReLU) def forwardPropagation(x, weights, biases): ip_h1 = tf.add(tf.matmul(x, weights['w_h1']), biases['b_h1']) op_h1 = tf.nn.relu(ip_h1) ip_h2 = tf.add(tf.matmul(op_h1, weights['w_h2']), biases['b_h2']) op_h2 = tf.nn.relu(ip_h2) ip_op = tf.add(tf.matmul(op_h2, weights['w_op']), biases['b_op']) # 输出层直接返回线性结果,不用激活函数 return ip_op # 构建计算图 x_placeholder = tf.placeholder("float", [None, input_width]) y_placeholder = tf.placeholder("float", [None, n_op]) pred = forwardPropagation(x_placeholder, weights, biases) # 定义损失函数(均方误差,适合回归) loss = tf.reduce_mean(tf.square(pred - y_placeholder)) # 定义优化器(Adam优化器,比梯度下降更稳定) optimizer = tf.train.AdamOptimizer(learning_rate=0.001).minimize(loss) # 训练模型 epochs = 500 with tf.Session() as s: s.run(tf.global_variables_initializer()) # 执行训练 for epoch in range(epochs): _, train_loss = s.run([optimizer, loss], feed_dict={x_placeholder: x_train, y_placeholder: y_train}) if epoch % 50 == 0: print(f"Epoch {epoch}, Training Loss: {train_loss:.4f}") # 评估模型(用MSE而不是精确相等) test_loss = s.run(loss, feed_dict={x_placeholder: x_test, y_placeholder: y_test}) print(f"\nTest MSE: {test_loss:.4f}") # 查看部分预测结果 pred_eval = s.run(pred, feed_dict={x_placeholder: x_test[:5]}) print("\nSample Predictions vs Actual:") for p, a in zip(pred_eval, y_test[:5]): print(f"Predicted: {p[0]:.2f}, Actual: {a[0]:.2f}")
修正后的关键变化说明
- 去掉了输出层的ReLU激活函数,回归任务输出层必须是线性的
- 用**均方误差(MSE)**作为损失函数,并用Adam优化器训练模型
- 对特征做了标准化处理,解决尺度差异问题
- 把
y转成二维数组,适配TensorFlow的输入格式 - 用合理的回归指标(MSE)评估模型,而不是错误的精确相等判断
内容的提问来源于stack exchange,提问作者Ishan Sarkar
相关产品推荐
相关产品推荐

