Reputation: 59
I'm using Tensorflow v2.4.1 to try and train a CNN. Here is a (simplified) version of my training:
train_datagen = ImageDataGenerator(
rescale=1./255,
zca_epsilon=1e-06,
rotation_range=20,
width_shift_range=.2,
height_shift_range=.2,
shear_range=0.2,
zoom_range=.2,
fill_mode='nearest',
cval=0., # value used for fill_mode = "constant")
train_generator = train_datagen.flow_from_directory(
data_dir + '/train',
target_size=(256,256),
batch_size=64,
class_mode='categorical'
)
model.fit(train_generator)
Now, I am trying to write some code that will test the model on a similarly structured directory of images, one-by-one. I'm doing this like so:
class_list = ['a','b','c','d']
count_total = 0
count_right = 0
for c in class_list:
test_dir = data_dir + '/test/', + c + '/'
for imagepath in os.listdir(test_dir):
image = cv2.imread(test_dir+imagepath)
image_from_array = Image.fromarray(image, "RGB")
size_image = image_from_array.resize((256,256))
p = np.expand_dims(size_image, 0)
img = tf.cast(p, tf.float32)/255
pred = class_list[np.argmax(model.predict(img))]
count_total += 1
if pred == c:
count_right += 1
acc = count_right/count_total
My accuracy(acc
) is coming out to be 0.20. However, I think this is a problem with the code, rather than the proper accuracy, because if I run the below code:
test_datagen = ImageDataGenerator(rescale=1./255)
test_generator = test_datagen.flow_from_directory(
data_dir + '/test',
target_size=(256,256),
batch_size=64,
class_mode='categorical'
)
model.evaluate(test_generator)
Then model.evaluate()
reports an accuracy of 0.53
So what is wrong with the code that predicts images one-by-one?
Upvotes: 0
Views: 38
Reputation: 11651
Opencv loads images by default in BGR while TensorFlow uses RGB. The images you are predicting are significantly different from the one you trained the network with, resulting in a loss of accuracy.
After loading your image with opencv, you should convert it to RGB, or use pillow directly to load the image in RGB.
Converting from BGR to RGB in opencv:
img_bgr = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
Reading the image directly with Pillow in RGB
img = Image.open("/path/to/the/image")
Upvotes: 1