Keras: ValueError: Dimension 0 in both shapes must be equal (VGGNets)

0

I'm following a tutorial and I loaded the pre-trained VGGNet16 model using Keras

vgg16_model = keras.applications.vgg16.VGG16()

model = Sequential()
for layer in vgg16_model.layers:
  model.add(layer)

model.layers.pop()

for layer in model.layers:
  layer.trainable = False

model.add(Dense(10, activation='softmax', name='predict'))
#model.summary()

I used model.save('path/model_1.h5') to save the model after training it with model.fit_generator(...)

Then I ran out of time in Colaboratory . so I wanted to use model = load_model('path/model_1.h5') to load my model again instead of loading it as I showed previously with vgg16_model = keras.applications.vgg16.VGG16()...

And now I'm having this error:

ValueError: Dimension 0 in both shapes must be equal, but are 4096 and
1000. Shapes are [4096,10] and [1000,10]. for 'Assign_61' (op: 'Assign') with input shapes: [4096,10], [1000,10].

What am I doing wrong? Thanks!

    
asked by virtualdvid 15.04.2018 в 21:02
source

1 answer

0

Thanks to the people of @deeplizard for helping me find this reply in the English version of StackOverflow.

Here is the translation:

The problem is with line model.layers.pop() . when we use .pop to jump a direct line of layer model.layers , the topology of this model is not updated accordingly. Therefore all the following operations will be bad, giving us a wrong definition of the model.

Specifically, when we add a layer with model.add(layer) , the model.outputs list is updated to be the output of the layer tensor. You can find the following lines in the code source of Sequential.add() :

        output_tensor = layer(self.outputs[0])
        # ... skipping irrelevant lines
        self.outputs = [output_tensor]

When they call model.layers.pop() , However, model.outputs is not updated accordingly as a result, the new layer added will be called with a bad input of the tensor (because self.outputs[0] continues being the output of the tensioner of the removed layer ).

This can be demonstrated with the following lines:

model = Sequential()
for layer in vgg16_model.layers:
    model.add(layer)

model.layers.pop()
model.add(Dense(3, activation='softmax'))

print(model.layers[-1].input)
# => Tensor("predictions_1/Softmax:0", shape=(?, 1000), dtype=float32)
# the new layer is called on a wrong input tensor

print(model.layers[-1].kernel)
# => <tf.Variable 'dense_1/kernel:0' shape=(1000, 3) dtype=float32_ref>
# the kernel shape is also wrong

The incorrect form of the kernel is why we are seeing the size incompatibility error in the [4096,3] versus [1000,3] fixes.

To solve this problem, simply do not add the last layer to the Sequential sequence.

model = Sequential()
for layer in vgg16_model.layers[:-1]:
    model.add(layer)
    
answered by 16.04.2018 / 18:16
source