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

分类报告表现良好但模型预测错误的原因及解决方法

问题

我运行MobileNetV2垃圾分类模型,在Colab用2100张6类图片训练后,分类报告表现良好,但添加预测上传图片的代码后,模型预测结果始终错误(比如常误判为trash类,重启后会切换类别但仍错误)。

预测代码如下:

from google.colab import files
from PIL import Image


def process_uploaded_image(image_path, target_size=(224, 224)):
    img = Image.open(image_path)
    img = img.resize(target_size)  
    img_array = np.array(img) 

    if img_array.shape[-1] == 4:  
        img_array = img_array[..., :3]

    img_array = img_array / 255.0 
    img_array = np.expand_dims(img_array, axis=0)  
    img_array = mobilenetv2.preprocess_input(img_array) 

    return img_array

uploaded = files.upload()

for fn in uploaded.keys():  
    processed_image = process_uploaded_image(fn, target_size=IMAGE_SIZE)    
    preds = model.predict(processed_image)
    pred_class = np.argmax(preds, axis=1)
  
    plt.imshow(Image.open(fn))  # Display the uploaded image
    plt.title(f'Predicted class: {categories[pred_class[0]]}')
    plt.axis('off')
    plt.show()
    print(f'File {fn} is predicted as: {categories[pred_class[0]]}')

添加概率输出代码后,得到如下结果:

1/1 ━━━━━━━━━━━━━━━━━━━━ 0s 24ms/step 
Prediction probabilities: [0.31027108 0.12315894 0.47848797 0.00863316 0.07789086 0.00155797]   
Predicted class: metal  

请问问题原因是什么?如何让模型做出正确预测?

问题原因

  • 预处理流程不一致:手动将像素值除以255后又调用mobilenetv2.preprocess_input,但MobileNetV2的预处理函数本身会将0-255范围的像素值转换为[-1,1],重复处理会导致输入分布与训练时不符。
  • 类别顺序不匹配:训练时flow_from_directory生成的类别顺序(存在class_indices字典中),可能和预测时用的categories列表顺序不一致,导致索引对应错误的类别。
  • 模型加载错误:如果预测时加载的是初始预训练的MobileNetV2模型,而非训练完成后的微调模型,自然无法得到正确结果。
  • 图像插值方式差异:训练时的图像resize插值方式(如Keras默认插值)和PILresize的默认插值不同,会导致输入图像的特征分布偏移。
  • 数据集分布差异:上传的测试图片在角度、光照、背景等方面和训练集差异过大,模型泛化能力不足。

解决方法

  • 对齐预处理流程:删除img_array = img_array / 255.0这一行,直接用原始像素值(0-255)调用mobilenetv2.preprocess_input,同时指定插值方式匹配训练设置:
    def process_uploaded_image(image_path, target_size=(224, 224)):
        img = Image.open(image_path)
        img = img.resize(target_size, resample=Image.BICUBIC)  # 匹配训练时的插值方式
        img_array = np.array(img) 
    
        if img_array.shape[-1] == 4:  
            img_array = img_array[..., :3]
    
        img_array = np.expand_dims(img_array, axis=0)  
        img_array = mobilenetv2.preprocess_input(img_array) 
    
        return img_array
    
  • 确认类别顺序一致:训练时打印train_generator.class_indices,将categories列表设置为对应顺序,比如:
    # 假设train_generator.class_indices输出为{'glass':0, 'paper':1, 'metal':2, 'plastic':3, 'cardboard':4, 'trash':5}
    categories = ['glass', 'paper', 'metal', 'plastic', 'cardboard', 'trash']
    
  • 验证模型加载正确性:训练完成后保存模型,预测时加载训练好的模型:
    # 训练完成后保存
    model.save('garbage_classifier.h5')
    # 预测时加载
    from tensorflow.keras.models import load_model
    model = load_model('garbage_classifier.h5')
    
  • 提升模型泛化能力:训练时添加数据增强,丰富训练集多样性:
    from tensorflow.keras.preprocessing.image import ImageDataGenerator
    train_datagen = ImageDataGenerator(
        preprocessing_function=mobilenetv2.preprocess_input,
        rotation_range=20,
        width_shift_range=0.2,
        height_shift_range=0.2,
        horizontal_flip=True,
        zoom_range=0.2
    )
    
  • 先验证测试集:用训练拆分出的测试集图片做预测,确认模型本身没问题后,再测试上传的外部图片。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.18 12:13:12