TensorFlow搭建的评分预测模型结果全为1、准确率为0如何排查
问题背景
我是人工智能领域初学者,此前无TensorFlow使用经验,搭建模型时遇到预测结果全为1、指标异常的问题。需求是基于13个特征预测Critic_Score评分,使用的代码如下:
inputs = tf.keras.Input(shape=(13,)) x = tf.keras.layers.Dense(64, activation='relu')(inputs) x = tf.keras.layers.Dense(64, activation='relu')(x) outputs = tf.keras.layers.Dense(1, activation='sigmoid')(x) model = tf.keras.Model(inputs, outputs) model.compile( optimizer='adam', loss= tf.keras.losses.MeanSquaredError(), metrics=[tf.keras.metrics.AUC(name='auc')] ) batch_size = 32 epochs = 30 history = model.fit( X_train, y_train, validation_split=0.2, batch_size = batch_size, epochs = epochs, callbacks=[tf.keras.callbacks.ReduceLROnPlateau()], verbose=0, ) deepLearningEv = model.evaluate(X_test, y_test) prediction = model.predict(X_test)
训练完成后所有预测结果均为1。
问题原因
代码存在3个核心错误,直接导致模型训练失效:
- 任务与网络配置不匹配:预测
Critic_Score属于回归任务,目标是输出连续数值,但输出层误用二分类场景的sigmoid激活函数,会把所有输出强制压缩到0-1区间。如果你的评分标签没有归一化到0-1范围(比如常见评分是0-10、0-100区间),模型训练时梯度会快速爆炸,参数最终塌缩到输出上限1,就会出现全预测1的现象。 - 评估指标选择错误:
AUC是分类任务专用指标,依赖离散分类标签和分类概率计算结果,回归任务使用AUC没有任何参考意义,你看到的准确率为0本质是指标错配,不是模型完全无效。 - 训练流程缺少必要校验:没有对特征、标签做标准化/归一化处理的情况下,特征尺度差异过大会直接导致神经网络训练不稳定,很容易出现输出塌缩。同时训练时
verbose设为0,完全看不到loss变化趋势,没法及时发现训练发散、loss异常的问题。
修正方案
- 先做数据预处理,统一特征和标签的尺度:
from sklearn.preprocessing import StandardScaler # 特征标准化 x_scaler = StandardScaler() X_train = x_scaler.fit_transform(X_train) X_test = x_scaler.transform(X_test) # 标签标准化,如果你要把标签映射到0-1区间也可以用MinMaxScaler,注意要和输出层范围匹配 y_scaler = StandardScaler() y_train = y_scaler.fit_transform(y_train.reshape(-1, 1)).flatten() y_test = y_scaler.transform(y_test.reshape(-1, 1)).flatten()
- 修改模型结构和编译配置,匹配回归任务要求:
inputs = tf.keras.Input(shape=(13,)) x = tf.keras.layers.Dense(64, activation='relu')(inputs) x = tf.keras.layers.Dense(64, activation='relu')(x) # 回归任务输出层使用默认线性激活,不要加sigmoid outputs = tf.keras.layers.Dense(1)(x) model = tf.keras.Model(inputs, outputs) model.compile( optimizer='adam', loss= tf.keras.losses.MeanSquaredError(), # 回归任务使用MAE、MSE等回归指标,不要用分类的AUC、Accuracy metrics=[tf.keras.metrics.MeanAbsoluteError(name='mae')] ) batch_size = 32 epochs = 30 history = model.fit( X_train, y_train, validation_split=0.2, batch_size = batch_size, epochs = epochs, # 给学习率衰减回调指定监控指标,默认监控val_loss更合理 callbacks=[tf.keras.callbacks.ReduceLROnPlateau(monitor='val_loss', patience=3)], # 打开训练日志,实时观察loss变化 verbose=1, ) deepLearningEv = model.evaluate(X_test, y_test) prediction = model.predict(X_test) # 预测结果逆变换回原始评分区间 prediction = y_scaler.inverse_transform(prediction)
注意:如果你一定要用sigmoid作为输出层激活,必须先把标签值归一化到0-1区间,否则sigmoid永远无法输出大于1的结果,不可能拟合超出范围的标签值。
内容的提问来源于stack exchange,提问作者Albastrali
相关产品推荐
相关产品推荐

