Keras: Loading saved model weight fails showing ValueError: You are trying to load a weight file containing 2 layers into a model with 3 layers.

Created on 9 Nov 2018  路  5Comments  路  Source: keras-team/keras

Hello, whenever I am trying to load the saved weight it is showing the error: You are trying to load a weight file containing 2 layers into a model with 3 layers.

This is the code:

def predict(image_path):
    class_dictionary = np.load('class_indices.npy').item()

    num_classes = len(class_dictionary)

    #image_path = 'test/cherry/1056.jpg'

    orig = cv2.imread(image_path)

    print('[INFO] loading and preprocessing image...')
    image = load_img(image_path, target_size=(224, 224))
    image = img_to_array(image)
    image = image / 255
    image = np.expand_dims(image, axis=0)

    model = applications.VGG16(include_top=False, weights='imagenet')

    bottleneck_prediction = model.predict(image)

    # build top model
    model = Sequential()
    model.add(Flatten(input_shape=bottleneck_prediction.shape[1:]))
    model.add(BatchNormalization())
    model.add(Dense(256, activation='relu'))
    model.add(Dropout(0.5))
    model.add(Dense(num_classes, activation='sigmoid'))
    model.load_weights(top_model_weights_path)

    # use the bottleneck prediction on the top model to get the final classification
    class_predicted = model.predict_classes(bottleneck_prediction)

    # probabilities = model.predict_proba(bottleneck_prediction)

    inID = class_predicted[0]

    inv_map = {v: k for k, v in class_dictionary.items()}

    label = inv_map[inID]

    print("Image ID: {}, Label: {}".format(inID, label))

    cv2.putText(orig, "Predicted: {}".format(label), (10, 30),
                cv2.FONT_HERSHEY_PLAIN, 1.5, (0, 0, 0), 2)

    cv2.imshow('Classification', orig)
    cv2.imwrite('predicted.jpg', orig)
    cv2.waitKey(0) 

The error I am getting is:

  File "/home/user/PycharmProjects/training_keras/new.py", line 225, in <module>
    predict(image_path)
  File "/home/user/PycharmProjects/training_keras/new.py", line 198, in predict
    model.load_weights(top_model_weights_path)
  File "/home/user/PycharmProjects/training_keras/venv/lib/python3.6/site-packages/keras/models.py", line 768, in load_weights
    topology.load_weights_from_hdf5_group(f, layers, reshape=reshape)
  File "/home/user/PycharmProjects/training_keras/venv/lib/python3.6/site-packages/keras/engine/topology.py", line 3365, in load_weights_from_hdf5_group
    str(len(filtered_layers)) + ' layers.')
ValueError: You are trying to load a weight file containing 2 layers into a model with 3 layers.

I'm not quite certain what the cause of the problem is. Is something going wrong in saving the model? Or is something wrong in this logic for loading the weights?

Any help on this issue is highly appreciated.

To investigate

Most helpful comment

The problem is the batchnorm. This layer wasn't there before, so keras is complaining that the model isn't the same.

If you really want to load weights into a different model, use model.load_weights(..., by_name=True) and ensure that the layers have the same names before and after.

All 5 comments

Can you try with the functional API?

Yes sure, I am trying.

You should also give the script which you used to save the model if you still have it.

This is the code used for training the model:

def train_top_model():
    datagen_top = ImageDataGenerator(rescale=1. / 255)
    generator_top = datagen_top.flow_from_directory(train_data_dir,
                                                    target_size=(img_width, img_height),
                                                    batch_size=batch_size,
                                                    class_mode='categorical',
                                                    shuffle=False)

    # save the class indices to use later in predictions
    np.save('class_indices.npy', generator_top.class_indices)


    train_data = np.load('bottleneck_features_train.npy')
    train_labels = np.array([0] * (nb_train_samples // 2) + [1] * (nb_train_samples // 2))

    validation_data = np.load('bottleneck_features_validation.npy')
    validation_labels = np.array([0] * (nb_validation_samples // 2) + [1] * ((nb_validation_samples // 2) - 4))

    visible = Input(shape=train_data.shape[1:])
    flatten = Flatten()(visible)
    hidden1 = Dense(256, activation='relu')(flatten)
    hidden2 = Dropout(0.5)(hidden1)
    output = Dense(1, activation='sigmoid')(hidden2)
    model = Model(inputs=visible, outputs=output)


    model.compile(optimizer='rmsprop',
                  loss='binary_crossentropy', metrics=['accuracy'])

    model.fit(train_data, train_labels,
              epochs=epochs,
              batch_size=batch_size,
              validation_data=(validation_data, validation_labels))
    model.save_weights(top_model_weights_path)

This is the code i have written for loading the moddel:

```
visible = Input(shape=bottleneck_prediction.shape[1:])
flatten = Flatten()(visible)
batch = BatchNormalization()(flatten)
hidden1 = Dense(256, activation='relu')(batch)
hidden2 = Dropout(0.5)(hidden1)
output = Dense(num_classes, activation='sigmoid')(hidden2)
model = Model(inputs=visible, outputs=output)
# summarize layers
print(model.summary())

model.load_weights(top_model_weights_path)

```
The result is all the same still.

The problem is the batchnorm. This layer wasn't there before, so keras is complaining that the model isn't the same.

If you really want to load weights into a different model, use model.load_weights(..., by_name=True) and ensure that the layers have the same names before and after.

Was this page helpful?
0 / 5 - 0 ratings