pythontensorflowconv-neural-networkimage-recognition

TensorFlow Prediction for each image in a folder


I created a model in TF, it recognizes one image, but when I try to make predictions for multiple images in a folder, I get an error.

import tensorflow as tf
import os
import cv2
import imghdr
import numpy as np
gpus = tf.config.experimental.list_physical_devices('GPU')
for gpu in gpus:
tf.config.experimental.set_memory_growth(gpu, True)
data_dir = 'dataset'
image_exts = \['jpeg','jpg', 'bmp', 'png'\]
for image_class in os.listdir(data_dir):
for image in os.listdir(os.path.join(data_dir, image_class)):
image_path = os.path.join(data_dir, image_class, image)
try:
img = cv2.imread(image_path)
tip = imghdr.what(image_path)
if tip not in image_exts:
print('Image not in ext list {}'.format(image_path))
os.remove(image_path)
except Exception as e:
print('Issue with image {}'.format(image_path))

data = tf.keras.utils.image_dataset_from_directory('dataset')
data_iterator = data.as_numpy_iterator()
batch = data_iterator.next()
data = data.map(lambda x,y: (x/255, y))
data.as_numpy_iterator().next()
train_size = int(len(data)\*.7)
val_size = int(len(data)\*.2)
test_size = int(len(data)\*.1)
train = data.take(train_size)
val = data.skip(train_size).take(val_size)
test = data.skip(train_size+val_size).take(test_size)
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Conv2D, MaxPooling2D, Dense, Flatten, Dropout
model = Sequential()
model.add(Conv2D(16, (3,3), 1, activation='relu', input_shape=(256,256,3)))
model.add(MaxPooling2D())
model.add(Conv2D(32, (3,3), 1, activation='relu'))
model.add(MaxPooling2D())
model.add(Conv2D(16, (3,3), 1, activation='relu'))
model.add(MaxPooling2D())
model.add(Flatten())
model.add(Dense(256, activation='relu'))
model.add(Dense(1, activation='sigmoid'))
model.compile('adam', loss=tf.losses.BinaryCrossentropy(), metrics=\['accuracy'\])
logdir='logs'
tensorboard_callback = tf.keras.callbacks.TensorBoard(log_dir=logdir)
hist = model.fit(train, epochs=10, validation_data=val, callbacks=\[tensorboard_callback\])
import os
import cv2

folder_path = "test"
for dirs,folder,files in os.walk(folder_path):
for file in files:
print((file))
img = cv2.imread(file)
resize = tf.image.resize(img, (256,256))
yhat = model.predict(np.expand_dims(resize/255, 0))
if yhat \> 0.5:
print(f'Predicted class is Sneakers ')
else:
print(f'Predicted class is Flats')

Error: ValueError Traceback (most recent call last) Input In [21], in <cell line: 5>() 7 print((file)) 8 img = cv2.imread(file) ----> 9 resize = tf.image.resize(img, (256,256)) 10 yhat = model.predict(np.expand_dims(resize/255, 0)) 11 if yhat > 0.5:

File ~\AppData\Roaming\Python\Python39\site-packages\tensorflow\python\util\traceback_utils.py:153, in filter_traceback..error_handler(*args, **kwargs) 151 except Exception as e: 152 filtered_tb = _process_traceback_frames(e.traceback) --> 153 raise e.with_traceback(filtered_tb) from None 154 finally: 155 del filtered_tb

File ~\AppData\Roaming\Python\Python39\site-packages\tensorflow\python\framework\constant_op.py:102, in convert_to_eager_tensor(value, ctx, dtype) 100 dtype = dtypes.as_dtype(dtype).as_datatype_enum 101 ctx.ensure_initialized() --> 102 return ops.EagerTensor(value, ctx.device_name, dtype)

ValueError: Attempt to convert a value (None) with an unsupported type (<class 'NoneType'>) to a Tensor.


Solution

  • ValueError: Attempt to convert a value (None) with an unsupported type (<class 'NoneType'>) to a Tensor

    Here issue is not with TensorFlow. It is with opencv. Two possible sources of issue:

    1. wrong file path or file name is not appropriate (improper extension, or not an image file)
    2. improper build of opencv-python

    Solution:

    1. Check file name, path and file content
    2. Uninstall and reinstall opencv-python (if no issues with image file or path)
    3. Try matplotlib as follows (if no issues with image file or path):
    from matplotlib import pyplot as plt
    
    # continue iterating over files
    # read with matplotlib
    img = plt.imread(file)
    # your model expects BGR (cv2 version)
    # plt reads as RGB
    # change channel order
    img = img[...,::-1]
    # continue with your code
    resize = tf.image.resize(img, (256,256))