How to save prediction values for the whole data in Keras I am using pre-trained VGG16 model to classify images located in the folder. Currently, I am able to classify only one single image. 


How can I modify the code to classify all the images in the folder
How can I save the prediction values for each image ?


Below is my code :

from keras.preprocessing.image import load_img
from keras.preprocessing.image import img_to_array
from keras.applications.imagenet_utils import decode_predictions
import matplotlib.pyplot as plt

filename = 'cat.jpg'
# load an image in PIL format
original = load_img(filename, target_size=(224, 224))
print('PIL image size',original.size)
plt.imshow(original)
plt.show()

# convert the PIL image to a numpy array
# IN PIL - image is in (width, height, channel)
# In Numpy - image is in (height, width, channel)
numpy_image = img_to_array(original)
plt.imshow(np.uint8(numpy_image))
plt.show()
print('numpy array size',numpy_image.shape)

# Convert the image / images into batch format
# expand_dims will add an extra dimension to the data at a particular axis
# We want the input matrix to the network to be of the form (batchsize, height, width, channels)
# Thus we add the extra dimension to the axis 0.
image_batch = np.expand_dims(numpy_image, axis=0)
print('image batch size', image_batch.shape)
plt.imshow(np.uint8(image_batch[0]))



# prepare the image for the VGG model
processed_image = vgg16.preprocess_input(image_batch.copy())

# get the predicted probabilities for each class
predictions = vgg_model.predict(processed_image)
print (predictions)

# convert the probabilities to class labels
# We will get top 5 predictions which is the default
#label = decode_predictions(predictions)


Thank you
First, you could always just wrap you code with a loop.

files = [file1, file2, ...]
predictions = []
for file in files:
    original = load_img(file, target_size=(224, 224))
    numpy_image = img_to_array(original)
    image_batch = np.expand_dims(numpy_image, axis=0)
    processed_image = vgg16.preprocess_input(image_batch)  # you dont need to copy :)      predictions_cur = vgg_model.predict(processed_image)
    print(predictions_cur)
    predictions.append(predictions_cur)
    #label = decode_predictions(predictions_cur)


Secondly, you could improve the efficiency of this code by using the tf.data api.
For example:

from tensorflow.data import Dataset

batch_size = 32
num_threads = 4
target_size=(224, 224)

def preprocess_image(file):
    # file is not a tensor, so we have to use functions that work on tensors
    img_string = tf.read_file(file)
    img = tf.image.decode_png(img_string)
    img = tf.image.resize_images(target_size)
    img = vgg16.preprocess_input(img)  # this function can handle tensors as well.
    return img

files = [file1, file2, ...]
dataset = Dataset.from_tensor_slices(tf.constant(files))
dataset = dataset.map(preprocess_image, num_threads)
dataset = dataset.batch(batch_size)
dataset = dataset.prefetch(1)  
predictions = vgg_model.predict(dataset, steps=len(files) // batch_size)
# You could decode the predictions from here :)


Explanation

Let me elaborate on each step :)  

dataset.from_tensor_slices(files) Will just build a dataset object, where the samples it will use are your files. 

dataset.map(preprocess_image, num_threads)
This indicates to preprocess each sample before we use it.
This will also be made in num_threads parallel calls, which will haste the process in case we batch samples together for prediction.

dataset = dataset.batch(batch_size)
This will batch samples together for prediction. This is useful to make predictions in parallel and haste the process.  

dataset.prefetch(1)
This will prefatch the next batch while the previous one is being predicted upon. So this will also make the process faster because you save time this way.  

and finally predictions = vgg_model.predict(dataset, steps=len(files) // batch_size)
This will predict over the all the files we've provided to the dataset above.
Do notice that we indicate that the number of steps is len(files) // batch_size so if len(files) isn't a multiply of batch_size, some images will not be predicted upon. If you want all the images to be predicted upon, you can use a batch_size that divides len(files), or just use batch_size = 1.