user11054482
user11054482

Reputation: 43

ValueError: The shape of the input to "Flatten" is not fully defined. While trying to implement the keras model

I had the following error while trying to implement a keras model:

"ValueError: The shape of the input to "Flatten" is not fully defined (got (None, None, 512). Make sure to pass a complete "input_shape" or "batch_input_shape" argument to the first layer in your model."

What could be the problem here?

from keras import applications
from keras.preprocessing.image import ImageDataGenerator
from keras import optimizers
from keras.models import Sequential
from keras.layers import Dropout, Flatten, Dense

weights_path = '../keras/examples/vgg16_weights.h5'
top_model_weights_path = 'fc_model.h5'
img_width, img_height = 240, 320

train_data_dir = 'datasetmini/train'
validation_data_dir = 'datasetmini/VALIDATION'
nb_train_samples = nb_train_samples
nb_validation_samples = nb_validation_samples
epochs = epochs
batch_size = batch_size

model = applications.VGG16(weights='imagenet', include_top=False)
print('Model loaded.')

top_model = Sequential()
top_model.add(Flatten(input_shape=model.output_shape[1:]))
top_model.add(Dense(256, activation='relu'))
top_model.add(Dropout(0.5))
top_model.add(Dense(1, activation='sigmoid'))
top_model.load_weights(top_model_weights_path)


model.add(top_model)

for layer in model.layers[:25]:
    layer.trainable = False


model.compile(loss='binary_crossentropy',
              optimizer=optimizers.SGD(lr=1e-4, momentum=0.9),
              metrics=['accuracy'])

train_datagen = ImageDataGenerator(
    rescale=1. / 255,
    shear_range=0.2,
    zoom_range=0.2,
    horizontal_flip=True)

test_datagen = ImageDataGenerator(rescale=1. / 255)

train_generator = train_datagen.flow_from_directory(
    train_data_dir,
    target_size=(img_height, img_width),
    batch_size=batch_size,
    class_mode='binary')

validation_generator = test_datagen.flow_from_directory(
    validation_data_dir,
    target_size=(img_height, img_width),
    batch_size=batch_size,
    class_mode='binary')

model.fit_generator(
    train_generator,
    samples_per_epoch=nb_train_samples,
    epochs=epochs,
    validation_data=validation_generator,
    nb_val_samples=nb_validation_samples)

Upvotes: 4

Views: 3148

Answers (1)

keineahnung2345
keineahnung2345

Reputation: 2701

According to Unable to fine tune Keras vgg16 model - input shape issue. It turns out that one should specify input_shape when loading the keras pre-trained model.

And also keras.engine.training.Model cannot add new layers, so one should build a new keras.engine.sequential.Sequential model and then use add.

A MWE:

from keras import applications
from keras import Sequential
from keras.layers import Flatten, Dense, Dropout
from keras import optimizers
import numpy as np

img_width, img_height = 240, 320
model = applications.VGG16(include_top=False, weights=None, input_shape=(img_width, img_height, 3))
print('Model loaded.')

top_model = Sequential()
top_model.add(Flatten())
top_model.add(Dense(256, activation='relu'))
top_model.add(Dropout(0.5))
top_model.add(Dense(1, activation='sigmoid'))
#top_model.load_weights(top_model_weights_path)

##this will fail
##AttributeError: 'Model' object has no attribute 'add'
#model.add(top_model)

new_model = Sequential()
new_model.add(model)
new_model.add(top_model)

for layer in new_model.layers[:25]:
    layer.trainable = False

new_model.compile(loss='binary_crossentropy',
              optimizer=optimizers.SGD(lr=1e-4, momentum=0.9),
              metrics=['accuracy'])

batch_size = 8
X = np.random.randn(batch_size,240,320,3)
Y = np.random.randn(batch_size, 1)

new_model.train_on_batch(X, Y)

Upvotes: 2

Related Questions