使用KERAS进行转移学习,验证精度不会从一开始就提高(超过朴素的基准),而训练精度会提高 [英] Transfer learning with Keras, validation accuracy does not improve from outset (beyond naive baseline) while train accuracy improves
问题描述
我正在为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屋!