简体   繁体   English

转移学习准确性差

[英]Transfer learning bad accuracy

I have a task to classify seeds depending on the defect. 我有一项任务是根据缺陷对种子进行分类。 I have around 14k images in 7 classes (they are not equal size, some classes have more photos, some have less). 我在7个班级中有大约14k图像(它们的大小不同,有些班级有更多的照片,有些班级有更少的照片)。 I tried to train Inception V3 from scratch and I've got around 90% accuracy. 我试图从头开始训练初始V3,我的准确率大约为90%。 Then I tried transfer learning using pre-trained model with ImageNet weights. 然后我尝试使用具有ImageNet权重的预训练模型进行转移学习。 I imported inception_v3 from applications without top fc layers, then added my own like in documentation. 我从没有顶级fc层的applications导入了inception_v3 ,然后在文档中添加了我自己的。 I ended with the following code: 我以下面的代码结束:

# Setting dimensions
img_width = 454
img_height = 227

###########################
# PART 1 - Creating Model #
###########################

# Creating InceptionV3 model without Fully-Connected layers
base_model = InceptionV3(weights='imagenet', include_top=False, input_shape = (img_height, img_width, 3))

# Adding layers which will be fine-tunned
x = base_model.output
x = GlobalAveragePooling2D()(x)
x = Dense(1024, activation='relu')(x)
predictions = Dense(7, activation='softmax')(x)

# Creating final model
model = Model(inputs=base_model.input, outputs=predictions)

# Plotting model
plot_model(model, to_file='inceptionV3.png')

# Freezing Convolutional layers
for layer in base_model.layers:
    layer.trainable = False

# Summarizing layers
print(model.summary())

# Compiling the CNN
model.compile(optimizer = 'adam', loss = 'categorical_crossentropy', metrics = ['accuracy'])

##############################################
# PART 2 - Images Preproccessing and Fitting #
##############################################

# Fitting the CNN to the images

train_datagen = ImageDataGenerator(rescale = 1./255,
                                   rotation_range=30,
                                   width_shift_range=0.2,
                                   height_shift_range=0.2,
                                   shear_range = 0.2,
                                   zoom_range = 0.2,
                                   horizontal_flip = True,
                                   preprocessing_function=preprocess_input,)

valid_datagen = ImageDataGenerator(rescale = 1./255,
                                   preprocessing_function=preprocess_input,)

train_generator = train_datagen.flow_from_directory("dataset/training_set",
                                                    target_size=(img_height, img_width),
                                                    batch_size = 4,
                                                    class_mode = "categorical",
                                                    shuffle = True,
                                                    seed = 42)

valid_generator = valid_datagen.flow_from_directory("dataset/validation_set",
                                                    target_size=(img_height, img_width),
                                                    batch_size = 4,
                                                    class_mode = "categorical",
                                                    shuffle = True,
                                                    seed = 42)

STEP_SIZE_TRAIN = train_generator.n//train_generator.batch_size
STEP_SIZE_VALID = valid_generator.n//valid_generator.batch_size

# Save the model according to the conditions  
checkpoint = ModelCheckpoint("inception_v3_1.h5", monitor='val_acc', verbose=1, save_best_only=True, save_weights_only=False, mode='auto', period=1)
early = EarlyStopping(monitor='val_acc', min_delta=0, patience=10, verbose=1, mode='auto')

#Training the model
history = model.fit_generator(generator=train_generator,
                         steps_per_epoch=STEP_SIZE_TRAIN,
                         validation_data=valid_generator,
                         validation_steps=STEP_SIZE_VALID,
                         epochs=25,
                         callbacks = [checkpoint, early])

But I've got terrible results: 45% accuracy. 但是我得到了可怕的结果:45%的准确率。 I thought it should be better. 我认为应该会更好。 I have some hypothesis what could go wrong: 我有一些假设可能会出错:

  • I trained from scratch on scaled images (299x299) and on non-scaled while transfer-learning (227x454) and it failed something (or maybe I failed dimensions order). 我从头开始训练缩放图像(299x299)和非缩放时转移学习(227x454)并且它失败了(或者我的尺寸顺序失败)。
  • While transfer-learning I used preprocessing_function=preprocess_input (found article on the web that it is extremely important, so I decided to add that). 虽然转移学习我使用了preprocessing_function=preprocess_input (在网上发现这篇文章非常重要,所以我决定添加它)。
  • Added rotation_range=30 , width_shift_range=0.2 , height_shift_range=0.2 , and horizontal_flip = True while transfer learning to augment data even more. 添加了rotation_range=30width_shift_range=0.2height_shift_range=0.2horizontal_flip = True同时传输学习更加增强数据。
  • Maybe Adam optimizer is a bad idea? 也许Adam优化器是个坏主意? Should I try RMSprop for example? 我应该尝试RMSprop吗?
  • Should I fine-tune some conv layers with SGD with small learning rate too? 我应该用SGD以小学习率微调一些转换层吗?

Or did I failed something else? 或者我失败了什么?

EDIT: I post a plot of training history. 编辑:我发布了一段训练历史。 Maybe it contains valuable information: 也许它包含有价值的信息:

历史训练情节

EDIT2: With changing parameters of InceptionV3: EDIT2:改变InceptionV3的参数:

具有更改参数的InceptionV3

VGG16 for comparison: VGG16进行比较:

VGG16进行比较

@today, I found a problem. @today,我发现了一个问题。 It is because of some changes in Batch Normalisation layers and its behavior while freezing them. 这是因为Batch Normalization图层中的一些更改及其冻结时的行为。 Mr. Chollet gave a workaround, but I used a Keras fork made by datumbox, which solved my problem. Chollet先生给出了一个解决方法,但我使用了由datumbox制作的Keras前叉,这解决了我的问题。 The main problem is described here: 主要问题在这里描述:

https://github.com/keras-team/keras/pull/9965 https://github.com/keras-team/keras/pull/9965

Now I get ~85% accuracy and am trying to raise it. 现在我的准确率达到了85%,我正在努力提高它。

If you want to preprocess the input using the preprocess_input method from Keras, then remove the rescale=1./255 argument. 如果要使用Keras中的preprocess_input方法预处理输入,请删除rescale=1./255参数。 Otherwise, keep the rescale argument and remove the preprocessing_function argument. 否则,请保留rescale参数并删除preprocessing_function参数。 Plus, try a lower learning rate like 1e-4 or 3e-5 or 1e-5 (the default learning rate of Adam optimizer is 1e-3) if loss does not decrease: 另外,如果损失不减少,请尝试较低的学习率,如1e-4或3e-5或1e-5(Adam优化器的默认学习率为1e-3):

from keras.optimizers import Adam

model.compile(optimizer = Adam(lr=learning_rate), ...)

Edit: After adding the training plot, you can see that is it overfitting on the training set. 编辑:添加训练图后,您可以看到它在训练集上过度拟合。 You can: 您可以:

  • add some kind of regularization like a Dropout layer, 添加某种正规化,如Dropout图层,
  • or decrease the network size by lowering the number of units in the Dense layer which is before the last layer. 或者通过降低最后一层之前的Dense层中的单元数来减小网络大小。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 Inception Resnet v2 使用迁移学习测试准确率不佳 - Inception Resnet v2 bad test accuracy with transfer learning 用坏电脑迁移学习 - transfer learning with bad computer 迁移学习准确性的令人困惑的结果 - Confusing results of transfer learning accuracy 迁移学习 model 无论架构如何都给出 0 准确度 - Transfer Learning model gives 0 accuracy regardless of architecture 应用迁移学习后验证准确度和训练准确度没有提高 - Validation Accuracy and training accuracy not improving after applying Transfer learning 迁移学习 - 将我的顶层与预训练模型合并,将准确率降至 0% - Transfer Learning - Merging my top layers with pretrained model drops accuracy to 0% 使用 Inception Resnet v2(乳腺癌)进行迁移学习,准确率低 - Transfer learning with Inception Resnet v2 (breast cancer) low accuracy PyTorch 迁移学习教程的混淆矩阵和测试准确率 - Confusion matrix and test accuracy for PyTorch Transfer Learning tutorial 如何提高我的迁移学习 BERT 的 model 的验证和测试的准确性 - How to improve an accuracy of validation and test of my model of Transfer Learning BERT 为什么我的 VGG19 迁移学习实现没有提高准确性? - Why is my transfer learning implementation of VGG19 not improving accuracy?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM