I have train a CNN model using Keras and store the weights. When I am trying to load them back to the same model I am receiving the following error:
ValueError: You are trying to load a weight file containing 2 layers into a model with 1 layers.
I figure out that this is a common error. However, the proposed remedies did not seem to work for me. I tried to downgrade my current Keras version of 2.2.4
to 2.1.6
. My model looks like:
def build_model(self):
model = Sequential()
#pdb.set_trace()
model.add(Dense(128 * 7 * 7, activation="relu", input_shape=(None, self.latent_dim)))
model.add(Reshape((7, 7, 128)))
model.add(UpSampling2D())
model.add(Conv2D(128, kernel_size=4, padding="same"))
model.add(BatchNormalization(momentum=0.8))
model.add(Activation("relu"))
model.add(UpSampling2D())
model.add(Conv2D(64, kernel_size=4, padding="same"))
model.add(BatchNormalization(momentum=0.8))
model.add(Activation("relu"))
model.add(UpSampling2D(size=(1, 2)))
model.add(Conv2D(64, kernel_size=4, padding="same"))
model.add(BatchNormalization(momentum=0.8))
model.add(Activation("relu"))
model.add(UpSampling2D(size=(1, 2)))
model.add(Conv2D(64, kernel_size=4, padding="same"))
model.add(BatchNormalization(momentum=0.8))
model.add(Activation("relu"))
model.add(Conv2D(self.channels, kernel_size=4, padding="same"))
model.add(Activation("tanh"))
model.summary()
noise = Input(shape=(self.latent_dim,))
img = model(noise)
return Model(noise, img)
Then, for loading the weights I am doing something like:
self.my_model = self.build_model()
input = Input(shape=(self.latent_dim,))
img = self.my_model(input)
output = self.my_critic(img)
self.the_model = Model(input, output)
self.the_model.compile(loss= self.wasserstein_loss,optimizer=optimizer)
self.the_model.compile(...) # the same options as in case of training
self.the_model.load_weights('models/stored_weights')
EDIT:
I checked more carefully my code and I figured out that my issue was something different and more complicated. My code correspond to an implementation of Wasserstein GANs. The model that I am training is not directly build using only the build_model. However, it is a combination of that model and a critic (therefore a combination of these two models). Firstly, I define my model (is my generator) self.my_model = self.build_model()
and then I have self.the_model = Model(input, output) where input is the input of my_model: input = Input(shape=(self.latent_dim,))
and output is the output of critic:
img = self.my_model(input)
output = self.my_critic(img)
Therefore, I am not training and storing the weights of my_model but the one of the the_model
(since I want to train my_model and critic in the same time).
Thus, I tried to do: self.the_model.load_weights('models/gen_vv_face_feats__')
instead of my_model.load_weights
Now I am receiving the following error:
ValueError: axes don't match array
Part of the problem may lie in Model(noise, img)
, where img
is the entire Sequential
model that could treated as a single layer when loading weights (see below) - depending on how the weights were saved.
To better understand the problem, it'd help seeing your save code - since your code provided as-is (w/ save code added) works for me. For a workaround you could try, see below.
Possible problem:
model = build_model()
model.summary()
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
input_1 (InputLayer) (None, 12) 0
_________________________________________________________________
sequential_1 (Sequential) (None, 28, 112, 16) 623824
=================================================================
Total params: 623,824
Trainable params: 623,184
Non-trainable params: 640
What worked for me:
model_to_save = build_model()
model_to_save.compile()
model_to_save.save_weights(path)
model_to_load = build_model()
model_to_load.compile()
model_to_load.load_weights(path)
Workaround + tip:
To fix as-is, drop the noise =
, image =
, and Model(...)
lines entirely, and simply do return model
: your original Input
should already do what you intend to with noise =
.
Also, if you require advanced functionality with multiple inputs/outputs, use Model
, lot easier to work with - and don't mix Model
w/ Sequential
unless for very specific reasons.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With