使用KERAS进行转移学习,验证精度不会从一开始就提高(超过朴素的基准),而训练精度会提高 [英] Transfer learning with Keras, validation accuracy does not improve from outset (beyond naive baseline) while train accuracy improves

查看:26
本文介绍了使用KERAS进行转移学习,验证精度不会从一开始就提高(超过朴素的基准),而训练精度会提高的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在为Food-101数据集(图像数据集w/101类和每个类1k图像)构建分类器。我的方法是使用KERAS,并通过ResNet50(来自ImageNet的权重)转移学习。

在训练模型时,训练精度在几个历元(30%-->45%)内有较好的提高,但验证精度基本上保持在0.9%-1.0%。我尝试过简化、交换优化器、减少和增加隐藏层中的单位、剥离所有图像增强,并在flow_from_directory()上设置一致的随机种子。

当我查看验证集上的模型所做的预测时,它始终是同一个类。

我的感觉是,模型的拟合程度还不至于太差,以至于无法解释在验证准确性方面如此缺乏动态性。

如有任何提高验证准确性的建议,我们将不胜感激。

供参考,以下是相关代码片段:

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

train_datagen = datagen.flow_from_directory('data/train/', seed=42, class_mode='categorical', subset='training', target_size=(256,256))
# prints "60603 images belonging to 101 classes"
val_datagen = datagen.flow_from_directory('data/train/', seed=42, class_mode='categorical', subset='validation', target_size=(256,256)) 
# prints "15150 images belonging to 101 classes"

train_steps = len(train_datagen) #1894
val_steps = len(val_datagen) #474
classes = len(list(train_datagen.class_indices.keys())) #101

conv_base = ResNet50(weights='imagenet', include_top=False, pooling='avg', input_shape=(256, 256, 3))

from keras.layers import GlobalAveragePooling2D
from keras.layers import Dropout
from keras.layers import Flatten
from keras.layers import BatchNormalization

model = Sequential()

model.add(conv_base)
model.add(BatchNormalization())
model.add(Dropout(0.2))
model.add(Dense(512, activation='relu'))
model.add(Dropout(0.5))
model.add(Dense(classes, activation='softmax'))

conv_base.trainable = False

from keras.optimizers import Adam

model.compile(loss='categorical_crossentropy',
              optimizer=Adam(),
              metrics=['acc','top_k_categorical_accuracy'])

history = model.fit_generator(
    train_datagen,
    steps_per_epoch=train_steps,
    epochs=5,
    verbose=2,
    validation_data=val_datagen,
    validation_steps=val_steps
)

以下是.fit_generator()的结果:

  • 纪元1/5
    • 724s-损耗:3.1305-Acc:0.3059-TOP_k_Category_Accuracy:0.5629-val_Loss:6.5914 val_acc:0.0099-val_top_k_Categical_Accuracy:0.0494
  • 纪元2/5
    • 715s-损耗:2.4812-Acc:0.4021-TOP_k_Category_Accuracy:0.6785-val_Loss:7.4093-val_acc:0.0099-val_top_k_Categical_Accuracy:0.0495
  • 纪元3/5
    • 714s-损耗:2.3559-Acc:0.4248-TOP_k_Category_Accuracy:0.7026-val_Loss:8.9146-val_acc:0.0094-val_top_k_Categical_Accuracy:0.0495
  • 纪元4/5
    • 714s-损耗:2.2661-Acc:0.4459-TOP_k_Category_Accuracy:0.7200-val_Loss:8.0597-val_acc:0.0100-val_top_k_Categical_Accuracy:0.0494
  • 纪元5/5
    • 715s-损耗:2.1870-Acc:0.4583-TOP_k_Category_Accuracy:0.7348-val_Loss:7.5171-val_acc:0.0100-val_top_k_Categical_Accuracy:0.0483

这里是model.summary()

Layer (type)                 Output Shape              Param #   
=================================================================
resnet50 (Model)             (None, 2048)              23587712  
_________________________________________________________________
batch_normalization_1 (Batch (None, 2048)              8192      
_________________________________________________________________
dropout_1 (Dropout)          (None, 2048)              0         
_________________________________________________________________
dense_1 (Dense)              (None, 512)               1049088   
_________________________________________________________________
dropout_2 (Dropout)          (None, 512)               0         
_________________________________________________________________
dense_2 (Dense)              (None, 101)               51813     
=================================================================
Total params: 24,696,805
Trainable params: 1,104,997
Non-trainable params: 23,591,808
_________________________________________________________________

推荐答案

验证准确率低的原因与构建模型的方式有关。我们有理由期待迁移学习在这种情况下会很好地发挥作用。但是,您的前1名和前5名分别在1/101和5/101附近徘徊。这将表明您的模型是偶然分类的,并且没有学习到您的数据集的基本信号(特征)。因此,迁移学习在这种情况下不起作用。但是,这确实意味着它不会永远起作用。

我重复了您的实验,得到了相同的结果,即TOP-1和TOP-5精度反映了随机选择的分类。然而,我随后解冻了ResNet50模型的各层,并重复了这个实验。这只是进行迁移学习的略微不同的方式。经过10个时期的训练,我得到了以下结果:

纪元10/50 =

这并不完美。但是,模型尚未收敛,并且有一些预处理步骤可以应用以进一步改善结果。

您观察到的原因在于冻结的ResNet50模型是从与Food101数据集根本不同的图像分布中训练而来的。数据分布中的这种不匹配导致了较差的性能,因为冻结网络执行的变换没有调到Food101图像。解冻网络可以让神经元实际学习Food101图像,从而获得更好的结果。

希望这对您有帮助。

这篇关于使用KERAS进行转移学习,验证精度不会从一开始就提高(超过朴素的基准),而训练精度会提高的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆