conv-neural-networktensorflow2.0predictioninference

Tensorflow Inference on a Single Image & image_dataset_from_directory


I have trained a CNN and have a script that lets me perform inference on batches of images fed in using image_dataset_from_directory. The core of how I do that is using the following code:

import numpy as np
import os
import tensorflow as tf
from tensorflow.keras.preprocessing import image_dataset_from_directory
from keras.preprocessing import image
import cv2
from sklearn.metrics import classification_report
from sklearn.metrics import confusion_matrix

BATCH_SIZE = 32
IMG_SIZE = (96, 96)

validation_dataset = image_dataset_from_directory(validation_dir,                            batch_size=BATCH_SIZE,                              image_size=IMG_SIZE,                                            shuffle=False)

class_labels = np.concatenate([y for x, y in validation_dataset], axis=0)

paths = validation_dataset.file_paths
AUTOTUNE = tf.data.AUTOTUNE
validation_dataset = validation_dataset.prefetch(buffer_size=AUTOTUNE)

loaded_model = tf.keras.models.load_model('/Volumes/trained_models/classification/exported-models/mobilenet2_mu_classifier_V0.02')
predictions = loaded_model.predict(validation_dataset,batch_size=BATCH_SIZE).flatten()

# Apply a sigmoid since our model returns logits
probabilities = tf.nn.sigmoid(predictions)
predictions = tf.where(probabilities < 0.5, 0, 1)

What I would like to do now is modify this script to perform inference on single images that I load individually.

The code I have tried is:

import os
import math
import numpy as np
from PIL import Image
import tensorflow as tf
from tensorflow.keras.utils import img_to_array
from skimage import io

size = 96

# image_path, xmin, ymin, xmax and ymax come from a database query.
img = Image.open(image_path) 
img_crop = img.crop((xmin, ymin, xmax, ymax))
img_crop.resize((size,size))

model_path = '/Volumes/trained_models/classification/exported-models/mobilenet2_mu_classifier_V0.02'
loaded_model = tf.keras.models.load_model(model_path)
img_array = img_to_array(img_crop, data_format='channels_last')

try:
    prediction_logit = loaded_model.predict(img_array, batch_size=1, verbose=1)
except tf.errors.ValueError as e:
    print('TF value error')

However, I have been unable to get this to produce predictions. The try-except block does not throw an error, but the prediction_logit = loaded_model... line silently fails. I'm not sure where I've gone wrong, or why I'm able to get the above top code to produce predictions, but not this lower block. Any help would be appreciated!


Solution

  • So i am trying to learn TF and I stumbled upon this page - https://keras.io/examples/vision/image_classification_from_scratch/

    They have mentioned the exact way that you can load and run inference on a single image. In my case I was dealing with the multilabel classifier and the code block below helped me get what i wanted -

    # image_size - already defined in format(height, width) that all my 
    # images were transformed and trained on 
    
    img = keras.utils.load_img('drive/MyDrive/abcdef.jpg', target_size=image_size)
    img_array = keras.utils.img_to_array(img)
    img_array = tf.expand_dims(img_array, 0)  # Create batch axis
    
    img_predictions = model.predict(img_array)
    
    pred_label = class_names[np.argmax(np.round(img_predictions,2))]
    print(" Predicted label is :: "+ pred_label)
    
    #if you also want to display the image that was passed use the code below
    plt.imshow(img)