转移学习的准确性差 [英] Transfer learning bad accuracy

查看:62
本文介绍了转移学习的准确性差的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的任务是根据缺陷对种子进行分类.我在7个班级中有大约14k图像(它们的大小不相等,有些班级的照片更多,有些班级的照片更少).我尝试从头开始训练Inception V3,我的准确率大约为90%.然后,我尝试使用带有ImageNet权重的预训练模型进行迁移学习.我从 applications 导入了 inception_v3 ,但没有顶层fc层,然后像在文档中一样添加了自己的代码.我以以下代码结束:

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). I tried to train Inception V3 from scratch and I've got around 90% accuracy. Then I tried transfer learning using pre-trained model with ImageNet weights. I imported inception_v3 from applications without top fc layers, then added my own like in documentation. 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])

但是我得到了可怕的结果:45%的准确性.我认为应该会更好.我有一些假设,可能会出问题:

But I've got terrible results: 45% accuracy. I thought it should be better. I have some hypothesis what could go wrong:

  • 我从头开始在缩放图像(299x299)和非缩放图像上进行了训练,同时又进行了转移学习(227x454),但它却失败了一些(或者可能是维度顺序失败了.)
  • 在进行转移学习时,我使用的是 preprocessing_function = preprocess_input (网络上的文章非常重要,因此我决定添加它).
  • 在传输时添加了 rotation_range = 30 width_shift_range = 0.2 height_shift_range = 0.2 horizo​​ntal_flip = True 学习更多地扩充数据.
  • 也许亚当优化器不是一个好主意?例如,我应该尝试RMSprop吗?
  • 我也应该在学习率较低的情况下用SGD调整一些转换层吗?
  • 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).
  • 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).
  • 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.
  • Maybe Adam optimizer is a bad idea? Should I try RMSprop for example?
  • Should I fine-tune some conv layers with SGD with small learning rate too?

还是我在其他方面做不到?

Or did I failed something else?

编辑:我发布了一份训练历史图.也许其中包含有价值的信息:

I post a plot of training history. Maybe it contains valuable information:

,其中InceptionV3的参数已更改:

With changing parameters of InceptionV3:

VGG16进行比较:

VGG16 for comparison:

推荐答案

@today,我发现了一个问题.这是因为批归一化"层及其冻结时的行为发生了一些变化.Chollet先生提供了一种解决方法,但是我使用了datumbox制造的Keras叉,它解决了我的问题.主要问题描述如下:

@today, I found a problem. It is because of some changes in Batch Normalisation layers and its behavior while freezing them. Mr. Chollet gave a workaround, but I used a Keras fork made by datumbox, which solved my problem. The main problem is described here:

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

现在,我的准确率达到了〜85%,并试图提高它.

Now I get ~85% accuracy and am trying to raise it.

这篇关于转移学习的准确性差的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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