Oblomov
Oblomov

Reputation: 9655

Exception training Resnet50: "The shape of the input to "Flatten" is not fully defined"

I want to use keras.applications.resnet50 to train a Resnet for a two class problem using the following setup:

from keras.layers import Dropout, Flatten, Dense
from keras.applications.resnet50 import ResNet50
from keras.models import Model

resNet = ResNet50(include_top=False, weights=None)
y = resNet.output
y = Flatten()(y)
y = Dense(2, activation='softmax')(y)
model = Model(inputs=resNet.input, outputs=y)
opt = keras.optimizers.Adam()
model.compile(optimizer=opt, loss='categorical_crossentropy', metrics=['accuracy'])
epochs = 15
model.fit(train_tensors, train_targets, 
          validation_data=(valid_tensors, valid_targets),
          epochs=epochs, batch_size=10, callbacks=[checkpointer], verbose=1)

Running the code throws the error

Exception: The shape of the input to "Flatten" is not fully defined 

So there must be something wrong with the input tensor to the output layer, which in my case is a one-hot encoded vector, i.e. a one-dimensional array of size 2. What am I doing wrong?

Upvotes: 1

Views: 1962

Answers (2)

Ioannis Nasios
Ioannis Nasios

Reputation: 8537

You get

Exception: The shape of the input to "Flatten" is not fully defined

because you have not set the input shape in your resnet network. Try:

resNet = ResNet50(include_top=False, weights=None, input_shape=(224, 224, 3)) 

Also since you are using binary_crossentropy with sigmoid activation in you output layer you should use only 1 neuron not 2, like this:

y = Dense(1, activation='sigmoid')(y)

Upvotes: 1

Ankit Paliwal
Ankit Paliwal

Reputation: 156

Since you are applying no pooling(avg or max) to the output of your Resnet model, the output that it is providing is a 4-D tensor, being passed to your Dense layer. Its a good idea to apply pooling before the dense layer, which will extract either the avg or max of each feature from previous layer and will then pass onto the Dense layer. Another option is if you don;t want to apply pooling layer, then you can just apply a Flatten() layer to Resnet output, that would also convert the 4-D tensor to 2-D tensor, expected by your Dense layer.

Upvotes: 1

Related Questions