Reputation: 9655
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
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
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