首页 > 解决方案 > Keras 迁移学习问题

问题描述

我已经在我的小数据集上训练并保存了一个较小的网络,我想使用迁移学习。

我想在预训练的 VGG16 的 conv 部分之上使用这个保存的网络,特别是我想冻结一些 VGG 层但不是全部然后我想使用我已经在我的较小数据集上训练过的 fc,并学习模型是两者与转移权重的组合。

我正在学习大量教程:https ://blog.keras.io/building-powerful-image-classification-models-using-very-little-data.html和https://machinelearningmastery.com/how- to-develop-a-convolutional-neural-network-to-classify-photos-of-dogs-and-cats/我不只是想使用预训练的特征,而且我不只是想在 VGG 中添加两个新层conv net,正如我所提到的,我想转移较小网络的 fc 层并冻结除 VGG 之一之外的所有 conv 层块并再次训练。下面是我的代码,但出现错误(无论我如何尝试更改代码,我都会收到类似的错误)

from keras import applications
from keras.preprocessing.image import ImageDataGenerator
from keras import optimizers
from keras.models import Sequential, Model
from keras.layers import Dropout, Flatten, Dense

# path to the model weights files.
weights_path = '/home/d/Desktop/s/vgg16_weights.h5'
top_model_weights_path = '/home/d/Desktop/s/model_weights.h5'
# dimensions of our images.
img_width, img_height = 256, 256

# build the VGG16 network
base_model = applications.VGG16(weights='imagenet', include_top=False, input_shape=(256, 256, 3))
print('Model loaded.')

# set the first 25 layers (up to the last conv block)
# to non-trainable (weights will not be updated)
for layer in base_model.layers[:15]:
    layer.trainable = False

# build a classifier model to put on top of the convolutional model
top_model = Sequential()
top_model.add(Flatten(input_shape=base_model.output_shape[1:]))
top_model.add(Dense(256, activation='relu'))
top_model.add(Dropout(0.5))
top_model.add(Dense(1, activation='sigmoid'))


# note that it is necessary to start with a fully-trained
# classifier, including the top classifier,
# in order to successfully do fine-tuning
top_model.load_weights(top_model_weights_path)

model= Model(inputs=base_model.input, outputs=top_model(base_model.output))



# add the model on top of the convolutional base
#model.add(top_model)


print(top_model.summary())

# compile the model with a SGD/momentum optimizer
# and a very slow learning rate.
model.compile(loss='binary_crossentropy',
              optimizer=optimizers.SGD(lr=1e-4, momentum=0.9),
              metrics=['accuracy'])

import matplotlib.pyplot as plt
from keras.preprocessing.image import ImageDataGenerator
import os

os.environ["CUDA_VISIBLE_DEVICES"]="0"

train_dir = '/home/d/Desktop/s/data/train'
eval_dir = '/home/d/Desktop/s/data/eval'
test_dir = '/home/d/Desktop/s/data/test'



# create a data generator
train_datagen = ImageDataGenerator(rescale=1./255,   #Scale the image between 0 and 1
                                    rotation_range=40,
                                    width_shift_range=0.2,
                                    height_shift_range=0.2,
                                    shear_range=0.2,
                                    zoom_range=0.2,
                                    horizontal_flip=True,)

val_datagen = ImageDataGenerator(rescale=1./255)  #We do not augment validation data. we only perform rescale

test_datagen = ImageDataGenerator(rescale=1./255)  #We do not augment validation data. we only perform rescale

# load and iterate training dataset
train_generator = train_datagen.flow_from_directory(train_dir, class_mode='binary', batch_size=16, shuffle='True', seed=42)
# load and iterate validation dataset
val_generator = val_datagen.flow_from_directory(eval_dir, class_mode='binary', batch_size=16, shuffle='True', seed=42)
# load and iterate test dataset
test_generator = test_datagen.flow_from_directory(test_dir, class_mode=None, batch_size=1, shuffle='False', seed=42)

#The training part
#We train for 64 epochs with about 100 steps per epoch
history = model.fit_generator(train_generator,
                              steps_per_epoch=train_generator.n // train_generator.batch_size,
                              epochs=6,
                              validation_data=val_generator,
                              validation_steps=val_generator.n // val_generator.batch_size)

我得到的错误是:

Model loaded.
Traceback (most recent call last):
  File "/home/d/Desktop/s/transferLearningS.py", line 33, in <module>
    top_model.load_weights(top_model_weights_path)
  File "/usr/local/lib/python3.5/dist-packages/keras/engine/network.py", line 1166, in load_weights
    f, self.layers, reshape=reshape)
  File "/usr/local/lib/python3.5/dist-packages/keras/engine/saving.py", line 1030, in load_weights_from_hdf5_group
    str(len(filtered_layers)) + ' layers.')
ValueError: You are trying to load a weight file containing 6 layers into a model with 2 layers.

我的小型网络是这样构建的:

model = models.Sequential()
model.add(layers.Conv2D(32, (3, 3), activation='relu', kernel_initializer='he_uniform', input_shape=(256, 256, 3)))
model.add(layers.MaxPooling2D((2, 2)))
model.add(Dropout(0.2))
model.add(layers.Conv2D(64, (3, 3), activation='relu', kernel_initializer='he_uniform'))
model.add(layers.MaxPooling2D((2, 2)))
model.add(Dropout(0.2))
model.add(layers.Conv2D(128, (3, 3), activation='relu', kernel_initializer='he_uniform'))
model.add(layers.MaxPooling2D((2, 2)))
model.add(Dropout(0.2))
model.add(layers.Conv2D(128, (3, 3), activation='relu', kernel_initializer='he_uniform'))
model.add(layers.MaxPooling2D((2, 2)))
model.add(Dropout(0.2))
model.add(layers.Flatten())
model.add(layers.Dropout(0.5))  #Dropout for regularization
model.add(layers.Dense(512, activation='relu'))
model.add(layers.Dense(1, activation='sigmoid'))  #Sigmoid function at the end because we have just two classes

有什么建议可以解决这个问题吗?

标签: kerasneural-networktransfer-learningvgg-net

解决方案


推荐阅读