Guillermina
Guillermina

Reputation: 3657

set_weights() in Tensorflow model

I have pretrained weights as np.array of shape (3, 3, 3, 64). I want to initialize this Tensorflow CNN with those weights using set_weights() like I show below.

However, when I try that, the following error pops up: ValueError: You called set_weights(weights) on layer "conv2d_3" with a weight list of length 3, but the layer was expecting 2 weights. Provided weights: [[[[-0.15836713 -0.178757 0.16782044 ...

model = models.Sequential()
model.add(layers.Conv2D(64, (3, 3), activation='relu', input_shape=(224, 224, 3)))
model.layers[0].set_weights(weights)
model.add(layers.MaxPooling2D((2, 2)))

model.add(layers.Conv2D(128, (3, 3), activation='relu'))
model.add(layers.MaxPooling2D((2, 2)))

model.add(layers.Conv2D(256, (3, 3), activation='relu'))
model.add(layers.MaxPooling2D((2, 2)))

model.add(layers.Conv2D(256, (3, 3), activation='relu'))
model.add(layers.MaxPooling2D((2, 2)))

model.add(layers.Conv2D(512, (3, 3), activation='relu'))
model.add(layers.MaxPooling2D((2, 2)))

model.add(layers.Conv2D(512, (3, 3), activation='relu'))

model.add(layers.GlobalAveragePooling2D())
model.add(layers.Dense(4, activation='softmax'))
print(model.summary())


adam = optimizers.Adam(learning_rate=0.0001, amsgrad=False)
model.compile(loss='categorical_crossentropy',
              optimizer=adam,
              metrics=['accuracy'])


history = model.fit_generator(
    train_generator,
    steps_per_epoch=np.ceil(nb_train_samples/batch_size),
    epochs=epochs,
    validation_data=validation_generator,
    validation_steps=np.ceil(nb_validation_samples / batch_size),
    class_weight=class_weight
    )

My question is: how do I pass those (3, 3, 3, 64) shaped weights to initialize that CNN? I have already checked the weight shapes required for each layer and the shapes I am trying to pass and the required shape match.

Upvotes: 3

Views: 11965

Answers (1)

Vlad
Vlad

Reputation: 8585

You could just use kernel_initializer and bias_initializer arguments like this:

import numpy as np

# init_kernel and init_bias are initialization weights that you have
init_kernel = np.random.normal(0, 1, (3, 3, 3, 64))
init_bias = np.zeros((64,))
kernel_initializer = tf.keras.initializers.constant(init_kernel)
bias_initializer = tf.keras.initializers.constant(init_bias)

conv_layer = tf.keras.layers.Conv2D(64, (3, 3),
                                    activation='relu',
                                    input_shape=(224, 224, 3),
                                    kernel_initializer=kernel_initializer,
                                    bias_initializer=bias_initializer)

Note the kernel's and bias' shapes that I've chosen. The values with which you initialise your layer must have the exact same shapes.

Upvotes: 5

Related Questions