Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Keras you are trying to load a weight file containing 2 layers into a model with 1 layers

Tags:

python

keras

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

like image 421
konstantin Avatar asked Oct 01 '19 08:10

konstantin


1 Answers

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.

like image 149
OverLordGoldDragon Avatar answered Oct 21 '22 05:10

OverLordGoldDragon