Fanta
Fanta

Reputation: 3089

What should the generator passed to predict_generator() return?

I am calling Keras predict_generator() like:

bottleneck_features_train = model.predict_generator(train_gen, len(telemetry))

where train_gen() is defined like

def train_gen(): # ... yield (X, y)

and X is a numpy array with shape (48, 299, 299, 3), y is a numpy array with shape (48,)

I get the error below. What should I do instead?

Otherwise, a link to a working example would help. Only examples I have found are for Keras 1 or using ImageDataGenerator.flow().

I am running Keras 2.0.2.

Here the error:

Traceback (most recent call last):
  File "/home/fanta/workspace/CarND-Behavioral-Cloning-P3/cache.py", line 143, in <module>
    tf.app.run()
  File "/usr/local/lib/python3.5/dist-packages/tensorflow/python/platform/app.py", line 44, in run
    _sys.exit(main(_sys.argv[:1] + flags_passthrough))
  File "/home/fanta/workspace/CarND-Behavioral-Cloning-P3/cache.py", line 138, in main
    bottleneck_features_train = model.predict_generator(train_gen, len(telemetry))
  File "/usr/local/lib/python3.5/dist-packages/keras/legacy/interfaces.py", line 88, in wrapper
    return func(*args, **kwargs)
  File "/usr/local/lib/python3.5/dist-packages/keras/engine/training.py", line 2094, in predict_generator
    outs = self.predict_on_batch(x)
  File "/usr/local/lib/python3.5/dist-packages/keras/engine/training.py", line 1677, in predict_on_batch
    self._feed_input_shapes)
  File "/usr/local/lib/python3.5/dist-packages/keras/engine/training.py", line 100, in _standardize_input_data
    'Found: array with shape ' + str(data.shape))
ValueError: The model expects 0 input arrays, but only received one array. Found: array with shape (48, 299, 299, 3)

Process finished with exit code 1

===== UPDATE =====

The issue is not related to the generator. Here below a short program to reproduce it. Note that if you switch the network from inception to vgg, it works fine.

from keras.applications.inception_v3 import InceptionV3
from keras.applications.vgg16 import VGG16
from keras.layers import Input, AveragePooling2D
from keras.models import Model
from keras.datasets import cifar10
from scipy.misc import imresize
import pickle
import tensorflow as tf
import keras.backend as K
import numpy as np

network='inception'  # Must be 'inception' or 'vgg'
dataset='cifar10'
batch_size=64

if network == 'vgg':
    size = (224, 224)
elif network == 'inception':
    size = (299, 299)
else:
    assert False, "network must be either 'inception' or 'vgg'"

def create_model():
    input_tensor = Input(shape=(size[0], size[1], 3))
    if network == 'inception':
        model = InceptionV3(input_tensor=input_tensor, include_top=False)
        x = model.output
        x = AveragePooling2D((8, 8), strides=(8, 8))(x)
        model = Model(model.input, x)
    elif network == 'vgg':
        model = VGG16(input_tensor=input_tensor, include_top=False)
        x = model.output
        x = AveragePooling2D((7, 7))(x)
        model = Model(model.input, x)
    else:
        assert False
    return model

def main():

    # Download and load cifar10 dataset
    (X_train, y_train), (_, _) = cifar10.load_data()

    # Reduce the dataset to the first 1000 entries, to save memory and computation time
    X_train = X_train[0:1000]
    y_train = y_train[0:1000]

    # Resize dataset images to comply with expected input image size
    X_train = [imresize(image, size) for image in X_train]
    X_train = np.array(X_train)

    # File name where to save bottlenecked features
    train_output_file = "{}_{}_{}.p".format(network, dataset, 'bottleneck_features_train')
    print("Saving to", train_output_file)

    with tf.Session() as sess:
        K.set_session(sess)
        K.set_learning_phase(1)
        model = create_model()
        # We skip pre-processing and bottleneck the features
        bottleneck_features_train = model.predict(X_train, batch_size=batch_size, verbose=1)
        data = {'features': bottleneck_features_train, 'labels': y_train}
        pickle.dump(data, open(train_output_file, 'wb'))

if __name__ == '__main__':
    main()

Upvotes: 1

Views: 1314

Answers (1)

Nassim Ben
Nassim Ben

Reputation: 11553

At prediction step your generator should only yield the input and not the targets. So only the X, not the y.

Does that help?

Upvotes: 1

Related Questions