Keras二分类正类精确率为0是否因Dense层过多
异常和Dense层数量无关,核心错误出在训练参数设置和预测逻辑上。
核心错误1:训练参数配置错误
你在模型训练时手动设置了steps_per_epoch=5,这个参数控制每个epoch迭代的batch数量。你的数据集总样本量接近13万,按常规8:2拆分训练集约10万样本,默认batch_size为32的情况下,每个epoch需要跑约3200步才能遍历完一次训练集。你设置成5意味着每个epoch仅喂给模型160个样本,哪怕训练100轮,模型也没有充分学习全量数据的规律,输出的预测概率整体偏移,没有校准到0.5分类阈值的水平。
这也是为什么你算出来ROC-AUC很高(说明模型对正负样本的排序能力是对的),但按0.5阈值判断时所有样本都被分到负类——AUC是排序类指标,不关心概率绝对值,只要正样本预测概率整体高于负样本就能拿到高分,哪怕所有正样本概率在0.4-0.49、负样本在0.1-0.3,AUC也能接近1,但0.5阈值下所有样本都会被判为负类,和你现在的分类报告结果完全吻合。
核心错误2:预测代码冗余且逻辑混乱
你的输出层是单节点+sigmoid激活,属于标准的二分类输出结构,不需要用np.argmax做标签转换(argmax是多分类softmax输出场景用的)。你代码里虽然写了y_predict_label = np.argmax(y_pred, axis=1),但生成分类报告时根本没用到这个变量,传的是阈值判断后的布尔值,没有走规范的标签转换流程。
修复方案
直接按下面的代码修改即可:
- 调整训练代码,删掉手动设置的
steps_per_epoch参数,让框架自动计算每轮迭代步数,建议加上验证集监控方便早停:
# 训练时去掉steps_per_epoch=5,加上验证集拆分 history = keras_model.fit( scaled_X_train, y_train, validation_split=0.1, # 拆分10%训练集当验证集 epochs=100, batch_size=32, # 显式指定batch size callbacks=earlystopping )
- 修正预测逻辑,先取原始概率再做阈值判断:
# 获取原始预测概率(shape: [样本数,]) y_pred_prob = keras_model.predict(scaled_X_test, verbose=0).flatten() # 按阈值转分类标签,单sigmoid输出不需要argmax y_pred_label = (y_pred_prob > 0.5).astype(int) # 生成分类报告 report = classification_report(y_test.flatten(), y_pred_label) print(report)
- 如果调整后还是出现概率整体偏移的情况,可以先统计
y_pred_prob的分布,不要硬用0.5当阈值,找能让F1分数最优的分类阈值即可,毕竟0.9934的AUC说明模型的区分能力已经非常强。
模型结构说明
你现在用的3层Dense隐藏层结构对于22维输入的表格二分类任务完全不算复杂,不存在层过多导致异常的问题,不需要调整层数量。
运行结果参考截图


内容的提问来源于stack exchange,提问作者Edison

