【问题标题】:Error in layers while loading weights from a pretrained model in keras for finetuning从 keras 中的预训练模型加载权重以进行微调时,层中的错误
【发布时间】:2018-07-11 01:40:05
【问题描述】:

我正在尝试遵循教程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')

错误可能是什么问题? 是预训练模型和分类模型层的维度不同吗?

【问题讨论】:

    标签: python machine-learning keras


    【解决方案1】:

    首先,您尝试将权重加载到分类器模型中,而不是 VGGFace 模型中。在您的代码中,您必须编写 vggface.load_weights(top_model_weights_path) 而不是 model.load_weights(top_model_weights_path)。假设两个模型在架构上是相同的,这应该可行。但是你为什么还要以如此复杂的方式来做这件事呢? VGGFace 似乎提供了一种简单方便的方法来(下载)加载预训练的权重,方法是在创建 VGGFace 时传递 weights='vggface'。除非你真的想使用 keras-facenet 中的权重,否则你应该使用所描述的方式。

    此外,VGGFace 模型看起来甚至没有与您的自定义分类器相关联。我不确定这是否可以使用顺序模型来实现。可能您需要使用functional API 并使用vggface 调用分类器的第一层。

    另请注意,使用model(vggface.output),您调用 VGGFace 模型将您的自定义模型作为输入,而不是像预期的那样相反。

    【讨论】:

    【解决方案2】:

    我之前遇到过这个错误,尽管是在另一个数据集和架构上。问题是拓扑不同。你可以试试下面的代码:

    model.load_weights('filename.h5' , by_name = True, skip_mismatch = True) 
    

    它只会加载与权重数量相对应的层。

    文档在 topology.py 中

    【讨论】:

      猜你喜欢
      • 2018-10-08
      • 2017-06-05
      • 2017-07-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-12-09
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多