多类别图像分类CNN模型全类别输出相同结果问题排查
多分类CNN固定输出问题修复方案
核心问题1:预处理不一致(最高概率诱因)
你在训练阶段通过ImageDataGenerator的rescale=1/255把输入像素值归一化到了[0,1]区间,但预测阶段加载图像后没有做相同的归一化操作,模型拿到和训练分布完全不符的输入,自然会输出错误的固定结果
修复方法:预测时对输入做相同的归一化,代码调整如下:
def predictImage(filename): img1 = image.load_img(filename,target_size=(150,150)) plt.imshow(img1) Y = image.img_to_array(img1) # 新增归一化步骤,和训练预处理逻辑保持一致 X = np.expand_dims(Y,axis=0) / 255.0 val = model.predict(X) print(val) # 可新增类别索引输出方便校验 print("预测类别:", np.argmax(val))
核心问题2:训练参数配置错误
- 你硬编码了
steps_per_epoch = 250,如果你的训练集总样本数/批次大小32的结果远小于250,生成器会强制重复采样,导致训练效果异常,建议改为自动计算的步数:steps_per_epoch = len(train_dataset) - 当前只设置了10轮训练,对于图像分类任务大概率没有收敛,可调整到20-30轮,同时加入早停回调防止过拟合
核心问题3:类别不平衡
如果你的训练数据中第二类样本占比极高(比如超过90%),模型会直接学习到"预测第二类就能拿到最高准确率"的偷懒逻辑,表现为所有输入都输出第二类结果。
排查&修复:
- 执行
print(np.unique(train_dataset.classes, return_counts=True))查看三类样本占比 - 如果存在不平衡,引入类别权重再训练:
from sklearn.utils.class_weight import compute_class_weight import numpy as np class_weights = compute_class_weight( class_weight='balanced', classes=np.unique(train_dataset.classes), y=train_dataset.classes ) class_weight_dict = {i: class_weights[i] for i in range(len(class_weights))} # 训练时传入类别权重 model.fit( train_dataset, steps_per_epoch = len(train_dataset), epochs = 20, validation_data = test_dataset, class_weight=class_weight_dict )
注:fit_generator在新版TensorFlow中已弃用,直接用fit即可支持生成器输入。
附加排查项
- 执行
print(train_dataset.class_indices)确认三个类的索引对应关系是否符合你的预期,避免索引对应错误导致你误判输出结果 - 检查数据集目录结构是否符合
flow_from_directory的要求:训练/测试文件夹下每个类别对应一个独立子文件夹,确认flow_from_directory执行后输出Found N images belonging to 3 classes,避免目录结构错误导致标注异常 - 如果训练准确率很高但验证准确率极低,说明模型过拟合,可在
Flatten()层后加入Dropout(0.5)层,同时给训练集的ImageDataGenerator增加随机翻转、平移等数据增强逻辑,提升泛化能力
内容的提问来源于stack exchange,提问作者Vanshita Garg
相关产品推荐
相关产品推荐

