You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Keras分类器准确率高但预测结果异常求助

解决Keras分类器准确率高但全输出0的问题

嘿,我一眼就看出你碰到了一个典型的「准确率陷阱」——模型在数据集上准确率漂亮,但实际预测全输出0,这背后大概率是类别不平衡或者模型输出层配置错误在搞鬼,咱们一步步拆解排查:

1. 先排查数据集的类别分布

这是最常见的原因:如果你的数据集里类别0的样本占比特别高(比如90%以上),模型只要无脑输出0,准确率自然会很高,但完全没学到分类能力。你赶紧统计下每个类别的样本数量,比如用这段代码:

import pandas as pd
print(pd.Series(y_train).value_counts())

要是发现类别0占绝对多数,那问题根源就在这儿了。

2. 检查模型的输出层配置

你贴的代码里没写完输出层,这可是关键中的关键!因为你是0-4的5分类任务,输出层必须这么设置:

model.add(Dense(units=5, activation='softmax'))

同时,损失函数要对应匹配:

  • 如果你的标签是独热编码(比如[1,0,0,0,0]代表类别0),用loss='categorical_crossentropy'
  • 如果标签是整数形式(比如直接用0、1、2、3、4),用loss='sparse_categorical_crossentropy'

要是你不小心把输出层写成了Dense(1, activation='sigmoid'),模型会当成二分类任务来训练,自然只会输出0/1,就会出现全输出0的情况。

3. 别再只看准确率了!

准确率在类别不平衡的场景下完全是个“虚假繁荣”的指标,你得用更靠谱的评估方式:

  • 用混淆矩阵看模型对每个类别的分类情况
  • 用精确率、召回率、F1分数评估模型的真实性能

可以用sklearn的工具快速生成报告:

from sklearn.metrics import classification_report, confusion_matrix

y_pred = model.predict(X_test)
y_pred_classes = y_pred.argmax(axis=1)  # 把softmax输出转成类别标签
print("混淆矩阵:")
print(confusion_matrix(y_test, y_pred_classes))
print("\n分类报告:")
print(classification_report(y_test, y_pred_classes))

4. 其他可能的坑

  • 标签编码错误:如果用了categorical_crossentropy,必须把标签转成独热编码,比如用keras.utils.to_categorical(y_train, num_classes=5)
  • Dropout过度:你加了两层0.5的Dropout,如果数据集本身不大,可能会让模型难以学习到少数类的特征,可以尝试把Dropout比例降到0.3,或者暂时去掉看看效果
  • 类别权重设置:如果确实是类别不平衡,在训练时加上class_weight='balanced',让模型给少数类更高的权重:
model.fit(X_train, y_train_onehot, epochs=50, batch_size=32, 
          validation_split=0.2, class_weight='balanced')

修正后的完整示例代码

from keras.models import Sequential
from keras.layers import Dense, Dropout
from keras import optimizers
from keras.utils import to_categorical
from sklearn.metrics import classification_report
import pandas as pd

# 假设你的数据已经准备好:X_train, y_train, X_test, y_test
# 先检查类别分布
print("训练集类别分布:")
print(pd.Series(y_train).value_counts())

# 处理标签(独热编码)
y_train_onehot = to_categorical(y_train, num_classes=5)
y_test_onehot = to_categorical(y_test, num_classes=5)

# 构建模型
model = Sequential()
model.add(Dense(units=14, activation='relu', input_shape=(14,)))
model.add(Dropout(0.3))
model.add(Dense(units=14, activation='relu'))
model.add(Dropout(0.3))
# 正确的多分类输出层
model.add(Dense(units=5, activation='softmax'))

# 编译模型
model.compile(optimizer=optimizers.Adam(learning_rate=0.001),
              loss='categorical_crossentropy',
              metrics=['accuracy'])

# 训练模型,加上类别权重
model.fit(X_train, y_train_onehot, epochs=50, batch_size=32, 
          validation_split=0.2, class_weight='balanced')

# 评估模型
y_pred = model.predict(X_test)
y_pred_classes = y_pred.argmax(axis=1)
print("\n分类报告:")
print(classification_report(y_test, y_pred_classes))

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 03:53:26