Keras训练CNN二分类模型fit准确率高但精确率召回率低求解
问题原因分析
- 最核心的问题是测试集预测结果和真实标签的顺序不匹配:你处理测试集时沿用了训练集的shuffle逻辑,测试集被随机打乱。调用
model.predict(valid_ds)时遍历了一次打乱后的测试集,后续提取valid_labels时又重新遍历了一次测试集,两次遍历的样本顺序完全不同,导致标签和预测结果无法对应,看起来就像随机预测,分类指标自然严重失准。 - 类别不平衡的干扰:你的数据集负样本是正样本的2倍,即便模型预测存在偏差,只要更多预测为占比更高的负样本,也能得到较高的准确率,你看到的95%测试准确率存在一定的"水分",无法反映真实的分类能力。
- 过拟合问题:训练集准确率达到99%,明显高于测试集的95%,说明模型对训练集的特征学习过拟合,泛化能力不足,也会导致实际分类效果变差。
- 无效参数冗余:你代码中
model.fit传入的batch_size=100是无效参数,因为你已经对训练集和测试集做了batch(12)的处理,该参数不会生效,属于冗余配置。
修复方案
- 优先修复标签匹配问题
测试集不需要做shuffle处理,首先修改测试集的构造逻辑,去掉shuffle步骤;也可以一次性提取测试集的所有样本和标签,保证预测输入和标签的对应关系,参考代码:
# 一次性获取测试集的所有特征和标签,避免两次遍历顺序不一致 valid_features, valid_labels = [], [] for x, y in valid_ds: valid_features.append(x.numpy()) valid_labels.append(y.numpy()) valid_features = np.concatenate(valid_features, axis=0) valid_labels = np.concatenate(valid_labels, axis=0) # 直接用提取的特征做预测,保证顺序完全对应 y_pred = model.predict(valid_features) y_pred = (y_pred > 0.5).astype(float)
- 优化类别不平衡处理
训练时添加类别权重,让模型更关注占比更少的正样本:
# 负样本数量是正样本的2倍,正样本权重设为2平衡损失贡献 class_weight = {0: 1, 1: 2} history= model.fit(train_ds, validation_data=valid_ds, epochs=5, callbacks=[checkpoint_cb, early_stopping_cb], class_weight=class_weight)
也可以替换损失函数为Focal Loss,进一步降低易分类的负样本的权重。
3. 优化模型降低过拟合
可以适当减少全连接层的神经元数量,或者增加Dropout比例,也可以添加L2正则化约束,缩小训练集和测试集的准确率差距。
4. 调整分类阈值
不平衡数据集不适合用默认的0.5作为分类阈值,可以根据PR曲线的平衡点选择最优阈值,进一步提升精确率和召回率。
内容的提问来源于stack exchange,提问作者Javier Decena Castillo
相关产品推荐
相关产品推荐

