使用ResNet-50迁移学习训练Fruits360数据集准确率极低求助
问题描述
- 任务:用ResNet-50迁移学习对新版Fruits360数据集做图像分类,训练集共6000张图像、24个类别
- 异常情况:训练50轮后准确率不足0.07,表现极差
- 对比情况:用相同数据训练CNN和VGG16时效果正常,仅验证准确率略高于训练准确率
- 尝试过的调整:更换池化方式、调整Flatten层神经元数量/新增Flatten层、修改dropout率、加载/移除模型检查点,均无改善
- 框架与配置:基于TensorFlow开发,采用Softmax激活函数、Categorical Cross entropy损失函数
代码实现
base_model = tf.keras.applications.resnet.ResNet50( input_shape=(img_height, img_width, 3), include_top=False, weights='imagenet' ) base_model.trainable = False dropout_rate=0.2 model = models.Sequential() model.add(model) # 此处存在致命错误 model.add(layers.GlobalAveragePooling2D(name="gap")) if dropout_rate > 0: model.add(layers.Dropout(dropout_rate, name="dropout_out")) model.add(layers.Dense(24, activation='softmax', name="fc_out")) model.compile(optimizer='adam', loss='categorical_crossentropy', metrics=['Accuracy','Precision','Recall','AUC']) hist=model.fit(train_generator, epochs = epochs, steps_per_epoch=97, validation_data = test_generator, validation_steps=48 )
问题排查与解决
1. 修正致命代码错误
你代码里model.add(model)这一行完全逻辑错误——把刚创建的Sequential模型自己加到了自己里面,导致整个模型结构混乱,根本没用到预训练的ResNet-50骨干网络。
修正方式:把这一行改成model.add(base_model),这样才会将预训练的ResNet-50作为特征提取器加入模型。
2. 验证输入数据预处理
ResNet-50有固定的输入要求,需要确保数据生成器符合规范:
- 用
tf.keras.applications.resnet.preprocess_input处理输入图像,将像素值从[0,255]归一化到[-1,1],匹配ResNet的预训练权重要求 - 确认数据生成器的
class_mode设置为'categorical',因为你用的是CategoricalCrossentropy损失,标签必须是one-hot编码格式 - 检查训练集、验证集的类别数量都是24,避免类别不匹配
3. 调整训练参数合理性
- 重新计算
steps_per_epoch和validation_steps:steps_per_epoch = 训练集样本数 / batch_size,比如batch_size为64的话,6000/64≈94,用准确值避免训练时重复或遗漏样本 - 初始冻结backbone训练到一定准确率后,可以尝试解冻ResNet-50的顶层权重进行微调,提升模型拟合能力
4. 排查其他潜在问题
- 检查数据生成器是否存在数据泄露,比如训练集和验证集有重叠样本
- 确认图像尺寸
img_height和img_width符合ResNet-50要求(至少32x32,推荐224x224),尺寸过小会严重削弱ResNet的特征提取能力
内容的提问来源于stack exchange,提问作者user21408341
相关产品推荐
相关产品推荐

