1

I followed the guide at this link to build a model and stopped before the finetuning part to test the model on some other images using the following code:

img_width, img_height = 150, 150
batch_size = 1

test_model = load_model('dog_cat_model.h5')

validation_data_dir = "test1"

test_datagen = ImageDataGenerator(rescale=1. / 255)

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

predictions = test_model.predict_generator(validation_generator, len(validation_generator.filenames));

for i in range(len(validation_generator.filenames)):
    print(validation_generator.filenames[i], ": ", predictions[i])

But I get the following error:

ValueError: Error when checking : expected flatten_1_input to have shape (None, 4, 4, 512) but got array with shape (1, 150, 150, 3)

printing test_model.summary gives the following output:

_________________________________________________________________
Layer (type)                 Output Shape              Param #
=================================================================
flatten_1 (Flatten)          (None, 8192)              0
_________________________________________________________________
dense_1 (Dense)              (None, 256)               2097408
_________________________________________________________________
dropout_1 (Dropout)          (None, 256)               0
_________________________________________________________________
dense_2 (Dense)              (None, 1)                 257
=================================================================
Total params: 2,097,665
Trainable params: 2,097,665
Non-trainable params: 0
_________________________________________________________________
None

And I am clueless how to figure out what this means.

Here is the code I used for creating the model:

img_width, img_height = 150, 150
top_model_weights_path = 'bottleneck_fc_model.h5'
train_data_dir = 'data/train'
validation_data_dir = 'data/validation'
batch_size = 16
train_samples = 2000
validation_samples = 800
epochs = 50


def save_bottlebeck_features():
    datagen = ImageDataGenerator(rescale=1. / 255)

    # build the VGG16 network
    model = applications.VGG16(include_top=False, weights='imagenet')

    train_generator = datagen.flow_from_directory(
        train_data_dir,
        target_size=(img_width, img_height),
        batch_size=batch_size,
        class_mode=None,
        shuffle=False)

    validation_generator = datagen.flow_from_directory(
        validation_data_dir,
        target_size=(img_width, img_height),
        batch_size=batch_size,
        class_mode=None,
        shuffle=False)

    predict_size_train = int(math.ceil(train_samples / batch_size))

    bottleneck_features_train = model.predict_generator(train_generator, predict_size_train)
    np.save('bottleneck_features_train.npy', bottleneck_features_train)

    predict_size_validation = int(math.ceil(validation_samples / batch_size))

    bottleneck_features_validation = model.predict_generator(validation_generator, predict_size_validation)
    np.save('bottleneck_features_validation.npy', bottleneck_features_validation)


def train_top_model():
    train_data = np.load('bottleneck_features_train.npy')
    train_labels = np.array([0] * (train_samples // 2) + [1] * (train_samples // 2))

    validation_data = np.load('bottleneck_features_validation.npy')
    validation_labels = np.array([0] * (validation_samples // 2) + [1] * (validation_samples // 2))

    model = Sequential()
    model.add(Flatten(input_shape=train_data.shape[1:]))
    model.add(Dense(256, activation='relu'))
    model.add(Dropout(0.5))
    model.add(Dense(1, activation='sigmoid'))

    model.compile(optimizer='rmsprop',
                  loss='binary_crossentropy',
                  metrics=['accuracy'])

    model.fit(train_data, train_labels,
              epochs=epochs,
              batch_size=batch_size,
              validation_data=(validation_data, validation_labels))

    model.save_weights(top_model_weights_path)
    model.save('dog_cat_model.h5')


save_bottlebeck_features()
train_top_model()

I hope someone can help me out :)

8
  • Could you print out validation_data.shape from bottleneck training? Commented Nov 6, 2017 at 20:22
  • Sure, it prints this: (800, 4, 4, 512) Commented Nov 6, 2017 at 20:30
  • Ok. Now - could you print out test_model.summary()? Commented Nov 6, 2017 at 20:32
  • Sorry I don't know how to format it properly in a comment :) - I'll throw it in the original post. Commented Nov 6, 2017 at 20:36
  • 1
    So this is the reason why - in line predictions = test_model.predict_generator(validation_generator, len(validation_generator.filenames)) you are feeding an image to a bottleneck model. Commented Nov 6, 2017 at 20:37

3 Answers 3

1

You mixed bootleneck and image model logic in this line:

test_model.predict_generator(...)

Where you fed images to bottleneck model. This caused a shape error.

Sign up to request clarification or add additional context in comments.

1 Comment

can you please elaborate your solution?
1

try by replacing Flatten layer by GlobalAveragePooling2D or GlobalMaxPooling2D

4 Comments

Something like this? It says the first layer in a sequenced model must have input_shape, but I don't understand the parameters it takes: model.add(GlobalAveragePooling2D(data_format=None, input_shape=(batch_size, ?, ?, ?)))
replace model.add(Flatten(input_shape=train_data.shape[1:])) with model.add(GlobalAveragePooling2D(input_shape=train_data.shape[1:]))
I get a similar error: ValueError: Error when checking : expected global_average_pooling2d_1_input to have shape (None, 4, 4, 512) but got array with shape (1, 150, 150, 3)
change model.fit(train_data, train_labels, epochs=epochs, batch_size=batch_size, validation_data=(validation_data, validation_labels)) with model.fit(bottleneck_features_train, train_labels,epochs=epochs, batch_size=batch_size, validation_data=(bottleneck_features_validation, validation_labels))
0

Adding

data_format='channels_last' 

in model.add()

will work if backend is using Tensorflow, and

data_format='channels_first' 

if backend is using theano.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.