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

基于Keras VGG16的食品分类模型验证准确率停滞在50%求助

解决VGG16在Food-101 40类分类中验证准确率停滞的问题

先拆解下你当前遇到的核心问题,再一步步给你针对性的解决方案——你的代码里有几个关键逻辑错误,这才是导致验证准确率卡壳的主要原因:

1. 必须用VGG16专属的preprocess_input()预处理

你现在只用了rescale=1./255做归一化,但VGG16是在ImageNet上预训练的,它的输入要求是减去ImageNet数据集的RGB均值,而不是简单把像素缩到0-1区间。preprocess_input()会帮你完成这个适配,这对预训练模型的特征提取效果影响极大,也是你当前准确率上不去的核心原因之一。

2. 数据增强的逻辑完全搞反了

看你的train_top_model()函数:

  • 你用不带增强的生成器加载训练数据,却用带增强的生成器加载验证数据——这完全错误!验证集绝对不能做数据增强,否则验证结果会失真;而训练集才需要靠增强提升泛化能力。
  • 更致命的是:你当前的流程是先提取固定的bottleneck特征再训练顶层,但训练集的增强根本没生效(因为bottleneck特征是提前提取好的静态文件,训练顶层时用的是固定数据,增强等于白加)。

3. 训练策略太保守:固定特征提取不如Fine-Tuning

你现在只训练了顶层全连接层,VGG16的卷积层完全冻结,这对于Food-101这种和ImageNet有差异的数据集来说,预训练特征可能不够适配。应该尝试解冻VGG16的最后几层卷积层,联合训练顶层和这些卷积层(也就是Fine-Tuning),让模型学习到更贴合食品分类的特征。

4. 正则化可以再加强

你试过调Dropout到0.75,但还可以给全连接层加上L2正则化,进一步抑制过拟合。


修改后的完整代码

我把所有问题都修正了,还加入了学习率自动调度(当验证准确率停滞时自动降学习率),你可以直接运行:

import numpy as np
from keras.preprocessing.image import ImageDataGenerator
from keras.models import Sequential
from keras.layers import Dropout, Flatten, Dense
from keras import applications
from keras.utils import to_categorical
from keras import optimizers
from keras.callbacks import ReduceLROnPlateau

# 图像尺寸
img_width, img_height = 150, 150
weights_save_path = 'food_40_classes.h5'
train_data_dir = 'D:\intallation\dataset\dataset-101/food/train'
validation_data_dir = 'D:\intallation\dataset\dataset-101/food/validation'
nb_train_samples = 28000
nb_validation_samples = 12000
epochs = 80
batch_size = 32

# 学习率调度器:验证准确率3轮没提升,学习率乘以0.1
lr_scheduler = ReduceLROnPlateau(monitor='val_accuracy', patience=3, factor=0.1, verbose=1)

def train_with_fine_tuning():
    # 1. 加载预训练VGG16,冻结前15层,保留最后3层卷积层可训练
    base_model = applications.VGG16(weights='imagenet', include_top=False, input_shape=(img_width, img_height, 3))
    for layer in base_model.layers[:15]:
        layer.trainable = False
    for layer in base_model.layers[15:]:
        layer.trainable = True

    # 2. 构建完整模型
    model = Sequential()
    model.add(base_model)
    model.add(Flatten())
    model.add(Dense(4096, activation='relu', kernel_regularizer='l2'))  # 加L2正则化
    model.add(Dropout(0.75))
    model.add(Dense(4096, activation='relu', kernel_regularizer='l2'))  # 新增全连接层提升容量
    model.add(Dropout(0.75))
    model.add(Dense(40, activation='softmax'))  # 40类分类输出

    # 3. 编译模型:用小学习率避免破坏预训练特征
    sgd = optimizers.SGD(lr=1e-5, momentum=0.9, nesterov=True)
    model.compile(optimizer=sgd, loss='categorical_crossentropy', metrics=['accuracy'])

    # 4. 数据生成器:正确应用预处理和增强
    train_datagen = ImageDataGenerator(
        preprocessing_function=applications.vgg16.preprocess_input,  # VGG专属预处理
        width_shift_range=0.1,
        height_shift_range=0.1,
        shear_range=0.1,
        zoom_range=0.1,
        horizontal_flip=True,  # 新增水平翻转增强
        fill_mode='nearest'
    )

    val_datagen = ImageDataGenerator(
        preprocessing_function=applications.vgg16.preprocess_input  # 验证集只用预处理,不用增强
    )

    train_generator = train_datagen.flow_from_directory(
        train_data_dir,
        target_size=(img_width, img_height),
        batch_size=batch_size,
        class_mode='categorical'
    )

    validation_generator = val_datagen.flow_from_directory(
        validation_data_dir,
        target_size=(img_width, img_height),
        batch_size=batch_size,
        class_mode='categorical'
    )

    # 5. 开始训练
    model.fit(
        train_generator,
        steps_per_epoch=nb_train_samples // batch_size,
        epochs=epochs,
        validation_data=validation_generator,
        validation_steps=nb_validation_samples // batch_size,
        callbacks=[lr_scheduler]
    )

    model.save_weights(weights_save_path)

# 启动Fine-Tuning训练
train_with_fine_tuning()

关键调整说明

  • 预处理修正:用applications.vgg16.preprocess_input替代简单rescale,完全匹配VGG16的预训练要求。
  • 数据增强修正:训练集用增强,验证集只用预处理,且增强参数更合理(新增水平翻转)。
  • Fine-Tuning策略:冻结VGG16前15层,训练最后3层卷积层+顶层全连接层,让模型适配食品分类的特征。
  • 正则化加强:给全连接层加L2正则化,Dropout调到0.75,新增一层全连接层提升模型容量。
  • 学习率调度:自动在验证准确率停滞时降低学习率,避免模型卡在局部最优。

额外建议

  • 可以先单独训练顶层全连接层10-20轮,再解冻卷积层进行Fine-Tuning,这样效果会更稳定。
  • 监控训练过程中的训练/验证准确率,如果训练准确率很高但验证准确率低,说明过拟合还存在,可以继续增大Dropout比例(比如0.8),或者增加更多数据增强(比如小角度旋转、亮度调整)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.29 07:44:38