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

迁移学习图像分类模型验证精度停滞45%,训练精度达90%求解

图像分类任务严重过拟合:训练精度90%但验证精度停滞45%

我正在进行一个包含70000张图像、375个类别的图像分类任务,先后尝试了Vgg16、Xception、Resnet及Mobilenet等模型,训练精度能达到90%,但验证精度始终卡在45%左右。已经尝试添加Dropout层、正则化以及数据增强,均未改善验证效果。以下是我使用的Xception模型代码片段:

from keras.models import Sequential
from keras.layers import Dense
from tensorflow import keras
from tensorflow.keras.preprocessing.image import ImageDataGenerator
from keras import regularizers
from PIL import Image
from PIL import ImageFile
ImageFile.LOAD_TRUNCATED_IMAGES = True

validation_datagen = ImageDataGenerator(rescale=1./255)
target_size = (height, width)

datagen = ImageDataGenerator(rescale=1./255,
    validation_split=0.2)

train_generator = datagen.flow_from_directory(
    path,
    target_size=(height, width),
    batch_size=batchSize,
    shuffle=True,
    class_mode='categorical',
    subset='training')

validation_generator = datagen.flow_from_directory(
    path,
    target_size=(height, width),
    batch_size=batchSize,
    class_mode='categorical',
    subset='validation')

num_classes = len(train_generator.class_indices)

xception_model = Xception(weights='imagenet',input_shape=(width, height, 3), include_top=False,classes=num_classes)
x = xception_model.output
x = GlobalAveragePooling2D()(x)
x = Dense(512, activation='relu')(x)
out = Dense(num_classes, activation='softmax')(x)

opt = Adam()
model.compile(optimizer=opt, loss='categorical_crossentropy', metrics=['accuracy'])

n_epochs = 15

history = model.fit(
    train_generator,
    steps_per_epoch = train_generator.samples // batchSize,
    validation_data = validation_generator, 
    validation_steps = validation_generator.samples // batchSize,
    verbose=1, 
    epochs = n_epochs)

原因分析

  • 类别分布失衡:375个类别如果存在严重样本不均衡(部分类别仅几十张图,部分类别上千张),模型会优先拟合样本多的类别,导致验证时小众类别识别极差,拉低整体精度。
  • 预训练模型适配不足:Imagenet预训练权重针对通用1000类图像,直接冻结全部卷积层会导致特征提取与特定任务不匹配;全量解冻又容易引发过拟合。
  • 数据增强力度/方向不对:当前仅用validation_split做划分,训练集增强操作过于单一,未针对任务场景的图像变化(如角度、光照、缩放)做针对性增强。
  • 分类头设计不合理:单一层512维Dense层对375类的特征映射能力不足,或参数过多引发过拟合。
  • 训练策略有缺陷:15个epoch可能不足以让模型收敛;Adam默认学习率0.001对预训练模型偏高,易导致权重震荡;validation_split未做分层划分,可能出现类别分布不均的验证集。

解决思路

1. 处理类别不均衡

  • 统计每个类别的样本量,对小众类别采用过采样、针对性数据增强生成新样本,或在model.compile中设置class_weight参数,给小众类别更高权重。
  • 用F1-score、混淆矩阵替代单纯准确率,直观定位表现差的类别。

2. 优化预训练模型微调策略

  • 先冻结Xception所有卷积层,仅训练顶层分类头,待收敛后逐步解冻底层卷积层(如最后10层),用更小学习率(1e-5)微调,让底层特征适配任务。
  • 避免一开始全量解冻,防止预训练的通用特征被破坏。

3. 强化数据增强针对性

  • 扩展ImageDataGenerator的增强参数:
    datagen = ImageDataGenerator(
        rescale=1./255,
        validation_split=0.2,
        rotation_range=30,
        width_shift_range=0.2,
        height_shift_range=0.2,
        shear_range=0.2,
        zoom_range=0.2,
        horizontal_flip=True,
        brightness_range=[0.8,1.2]
    )
    
  • 保持验证集仅做rescale,确保验证逻辑正确。

4. 调整分类头结构

  • 在Dense层间添加Dropout:x = Dropout(0.5)(x)(尝试0.3-0.5的 dropout 率)。
  • 给Dense层加L2正则化:Dense(512, activation='relu', kernel_regularizer=regularizers.l2(1e-4))。
  • 尝试调整Dense层维度(如从512降到256),或增加一层小维度Dense层,让特征逐步映射到分类空间。

5. 优化训练策略

  • 增加epoch到30-50,同时加入早停机制:
    from tensorflow.keras.callbacks import EarlyStopping, ReduceLROnPlateau
    early_stop = EarlyStopping(monitor='val_loss', patience=5, restore_best_weights=True)
    lr_scheduler = ReduceLROnPlateau(monitor='val_loss', factor=0.5, patience=3)
    
    将回调加入model.fit的callbacks参数。
  • 调整学习率:初始用1e-4训练分类头,微调时用1e-5;或用学习率衰减策略自动调整。
  • 手动分层划分数据集,替代validation_split,确保每个类别按比例分配到训练/验证集。

6. 其他排查点

  • 随机查看训练/验证集图像,确认标签是否正确,检查LOAD_TRUNCATED_IMAGES=True是否导致损坏图像混入。
  • 尝试结合全局平均池化与全局最大池化:
    from tensorflow.keras.layers import concatenate, GlobalMaxPooling2D
    x = concatenate([GlobalAveragePooling2D()(x), GlobalMaxPooling2D()(x)])
    
    增强特征鲁棒性。

内容的提问来源于stack exchange,提问作者Ibrahima S Wade

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 16:16:10