我正在尝试按照教程Fine-tuning the top layers of a pre-trained network .
为此,我想使用预训练的keras-facenet并在顶部添加我的分类器 . 我使用vggface作为基本模型 . Facenet基于VGGFace . 所以这是运行我的代码后得到的错误:
ValueError Traceback (most recent call last)
<ipython-input-9-261fed5d7ddc> in <module>()
20 model.add(layers.Dense(12, activation='sigmoid'))
21
---> 22 model.load_weights(top_model_weights_path)
23
24
/usr/local/lib/python3.6/dist-packages/keras/models.py in load_weights(self, filepath, by_name, skip_mismatch, reshape)
766 reshape=reshape)
767 else:
--> 768 topology.load_weights_from_hdf5_group(f, layers, reshape=reshape)
769
770 def save_weights(self, filepath, overwrite=True):
/usr/local/lib/python3.6/dist-packages/keras/engine/topology.py in load_weights_from_hdf5_group(f, layers, reshape)
3363 'containing ' + str(len(layer_names)) +
3364 ' layers into a model with ' +
-> 3365 str(len(filtered_layers)) + ' layers.')
3366
3367 # We batch weight value assignments in a single backend call
ValueError: You are trying to load a weight file containing 245 layers into a model with 2 layers.
这是代码:
# path to the model weights files.
weights_path = 'keras-facenet/weights/facenet_keras_weights.h5'
top_model_weights_path = 'keras-facenet/model/facenet_keras.h5'
# dimensions of our images.
img_width, img_height = 224, 224
train_data_dir = 'dataset_cfps/train'
validation_data_dir = 'dataset_cfps/validation'
nb_train_samples = 1774
nb_validation_samples = 313
epochs = 50
batch_size = 16
vggface = VGGFace(model='resnet50', include_top=False, input_shape=(img_width, img_height, 3))
# Create the model
model = models.Sequential()
model.add(layers.Flatten( input_shape=vggface.output_shape[1:]))
model.add(layers.Dense(256, activation='relu'))
model.add(layers.Dropout(0.5))
model.add(layers.Dense(12, activation='sigmoid'))
model.load_weights(top_model_weights_path)
custom_vgg_model = Model(vggface.input, model(vggface.output))
for layer in custom_vgg_model.layers[:-3]:
layer.trainable = False
custom_vgg_model.compile(loss='categorical_crossentropy',
optimizer=optimizers.SGD(lr=1e-4, momentum=0.9),
metrics=['accuracy'])
# prepare data augmentation configuration
train_datagen = ImageDataGenerator(
rescale=1. / 255,
shear_range=0.2,
zoom_range=0.2,
horizontal_flip=True)
test_datagen = ImageDataGenerator(rescale=1. / 255)
train_generator = train_datagen.flow_from_directory(
train_data_dir,
target_size=(img_height, img_width),
batch_size=batch_size,
class_mode='categorical')
validation_generator = test_datagen.flow_from_directory(
validation_data_dir,
target_size=(img_height, img_width),
batch_size=batch_size,
class_mode='categorical')
custom_vgg_model.summary()
# fine-tune the model
custom_vgg_model.fit_generator(
train_generator,
steps_per_epoch=nb_train_samples // batch_size,
epochs=epochs,
validation_data=validation_generator,
validation_steps=nb_validation_samples // batch_size,
verbose=2)
# Save the model
custom_vgg_model.save('facenet_latest_lr4.h5')
错误可能是什么问题?预训练和分类模型之间的层面尺寸是否不同?
2 回答
首先,您尝试将权重加载到分类器模型中,而不是VGGFace模型 . 在您的代码中,您必须编写
vggface.load_weights(top_model_weights_path)
而不是model.load_weights(top_model_weights_path)
. 假设两个模型在架构上相同,这应该可行 . 但为什么你甚至以这么复杂的方式做到这一点呢? VGGFace似乎提供了一种简单方便的方法(通过在创建VGGFace
时传递weights='vggface'
来加载预训练的权重) . 除非你真的想使用keras-facenet的权重,否则你应该按照描述的方式使用 .此外,它不确定是否可以使用顺序模型实现这一点 . 可能你需要使用functional API并使用
vggface
调用分类器的第一层 .另请注意,使用
model(vggface.output)
您调用VGGFace模型 with your custom model as input 而不是像它可能的那样 .我之前有过这个错误,尽管是在另一个数据集和架构上 . 问题是拓扑结构不同 . 您可以尝试以下代码:
它只会加载与权重数相对应的图层 .
文档位于topology.py中