I am using Cat and Dog Dataset for Training a Model using Tensorflow Keras and the Files are Read using ImageDataGenerator.flow_from_directory.
Training and Validation Accuracy is Decent but when tried Predicting on Test Data, Model is predicting the Same Class for all the Images.
Code for Training is shown below:
import os, shutil
import tensorflow as tf
from tensorflow.keras.layers import Conv2D, MaxPooling2D, Flatten, Dropout, Dense
from tensorflow.keras.models import Sequential
from tensorflow.keras.optimizers import RMSprop
from tensorflow.keras.losses import binary_crossentropy
from tensorflow.keras.preprocessing import image
from tensorflow.keras.preprocessing.image import ImageDataGenerator
import numpy as np
import matplotlib.pyplot as plt
# Path to Training Directory
train_dir = 'Dogs_Vs_Cats_Small/train'
# Path to Validation Directory
validation_dir = 'Dogs_Vs_Cats_Small/validation'
#### Create the Convolutional Base
Max_Pool_Size = (2,2)
model = Sequential([
Conv2D(input_shape = (150, 150, 3), filters = 32, kernel_size = (3,3), activation = 'relu',
padding = 'valid', data_format = 'channels_last'),
MaxPooling2D(pool_size = Max_Pool_Size),
Conv2D(filters = 64, kernel_size = (3,3), activation = 'relu', padding = 'valid'),
MaxPooling2D(pool_size = Max_Pool_Size),
Conv2D(filters = 128, kernel_size = (3,3), activation = 'relu', padding = 'valid'),
MaxPooling2D(pool_size = Max_Pool_Size),
Conv2D(filters = 128, kernel_size = (3,3), activation = 'relu', padding = 'valid'),
MaxPooling2D(pool_size = Max_Pool_Size)
])
#### Define the Dense Layers on Top of Convolutional Base
model.add(Flatten())
model.add(Dense(units = 512, activation = 'relu'))
model.add(Dense(units = 1, activation = 'sigmoid'))
model.summary()
model.compile(optimizer = RMSprop(learning_rate = 0.001), loss = 'binary_crossentropy', metrics = 'acc')
Train_Gen = ImageDataGenerator(1./255)
Val_Gen = ImageDataGenerator(1./255)
Train_Generator = Train_Gen.flow_from_directory(train_dir, target_size = (150,150), batch_size = 20,
class_mode = 'binary')
Val_Generator = Val_Gen.flow_from_directory(validation_dir, target_size = (150, 150), class_mode = 'binary',
batch_size = 20)
batch_size = 20
target_size = (150,150)
No_Of_Training_Images = Train_Generator.classes.shape[0]
No_Of_Val_Images = Val_Generator.classes.shape[0]
steps_per_epoch = No_Of_Training_Images/batch_size
validation_steps = No_Of_Val_Images/batch_size
history = model.fit(x = Train_Generator, shuffle=True, epochs = 20,
steps_per_epoch = steps_per_epoch,
validation_data = Val_Generator
, validation_steps = validation_steps
)
Now, I Predict on the Test Data as shown below:
Test_Dir = 'Dogs_Vs_Cats_Very_Small/test'
Test_Generator = ImageDataGenerator(1./255).flow_from_directory(Test_Dir,
target_size = (150,150), batch_size = 1,
shuffle = False, class_mode = 'binary') # This outputs Found 17 images belonging to 2 classes.
No_Of_Samples = len(Test_Generator.filenames)
testPredictions = model.predict(Test_Generator, steps = No_Of_Samples)
predictedClassIndices=np.argmax(testPredictions,axis=1)
print(predictedClassIndices)
filenames = Test_Generator.filenames
for f in range(len(filenames)):
print(filenames[f],":",predictedClassIndices[f])
Output of the above Print Statement, i.e., Predicted Classes are shown below:
array([0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0])
cats/cat.1546.jpg : 0
cats/cat.1547.jpg : 0
cats/cat.1548.jpg : 0
cats/cat.1549.jpg : 0
cats/cat.1550.jpg : 0
cats/cat.1566.jpg : 0
cats/cat.1593.jpg : 0
cats/cat.1594.jpg : 0
dogs/dog.1514.jpg : 0
dogs/dog.1520.jpg : 0
dogs/dog.1525.jpg : 0
dogs/dog.1551.jpg : 0
dogs/dog.1555.jpg : 0
dogs/dog.1574.jpg : 0
dogs/dog.1594.jpg : 0
dogs/dog.1597.jpg : 0
dogs/dog.1599.jpg : 0
As seen above, all the Images are Predicted as Class = 0 i.e., Cats.
I've already look into this Stack Overflow Question and my Data is Balanced (1000 Cat Images and 1000 Dog Images) so, as per my understanding, Rebalancing my dataset or Adjusting class weights doesn't apply. I've tried "Increasing the time of training" as well.
EDIT: Content of testPredictions is shown below:
[[1.0473319e-05]
[9.8473930e-01]
[2.9069009e-01]
[5.0639841e-07]
[1.8511847e-01]
[6.0166395e-01]
[4.2568660e-01]
[4.6028453e-01]
[7.8800195e-01]
[8.5675471e-02]
[8.2654454e-02]
[7.2898394e-01]
[1.5504999e-01]
[8.2106847e-01]
[8.7003058e-01]
[9.9999285e-01]
[5.1210046e-01]]
Can someone help me to correct it.
Thank you all in advance.