# Binary image classifier always predicting one class

I am trying to design a model for binary image classification, this is my first classifier and I am following an online tutorial but the model always predicts class 0

My dataset contains 3620 and 3651 images of each class respectively, I don't suppose the problem is due to an imbalanced dataset as the model is predicting only the class with lower number of sample in the dataset.

My code

from keras.preprocessing.image import ImageDataGenerator
from keras.models import Sequential
from keras.layers import Conv2D, MaxPooling2D
from keras.layers import Activation, Dropout, Flatten, Dense
from keras import backend as K

img_hieght, img_width = 150,150
train_data_dir = 'dataset/train'
#validation_data_dir = 'dataset/validation'

nb_train_samples = 3000
#nb_validation_samples = 500

epochs = 10
batch_size = 16

if K.image_data_format() == 'channels_first':
input_shape = (3, img_width, img_hieght)
else:
input_shape = (img_width, img_hieght, 3)

model = Sequential()

model.compile(loss = 'binary_crossentropy', optimizer = 'rmsprop', metrics = ['accuracy'])

train_datagen = ImageDataGenerator(
rescale = 1. /255,
shear_range = 0.2,
zoom_range = 0.2,
horizontal_flip = True)

train_generator = train_datagen.flow_from_directory(
train_data_dir,
target_size = (img_width,img_hieght),
batch_size = batch_size,
class_mode = 'binary')

model.fit_generator(train_generator,
steps_per_epoch = nb_train_samples//batch_size,
epochs = epochs)

model.save('classifier.h5')


I have tried checking the model summary as well, but couldn't detect anything notable

_________________________________________________________________
Layer (type)                 Output Shape              Param #
=================================================================
conv2d_1 (Conv2D)            (None, 148, 148, 32)      896
_________________________________________________________________
activation_1 (Activation)    (None, 148, 148, 32)      0
_________________________________________________________________
max_pooling2d_1 (MaxPooling2 (None, 74, 74, 32)        0
_________________________________________________________________
conv2d_2 (Conv2D)            (None, 72, 72, 32)        9248
_________________________________________________________________
activation_2 (Activation)    (None, 72, 72, 32)        0
_________________________________________________________________
max_pooling2d_2 (MaxPooling2 (None, 36, 36, 32)        0
_________________________________________________________________
conv2d_3 (Conv2D)            (None, 34, 34, 64)        18496
_________________________________________________________________
activation_3 (Activation)    (None, 34, 34, 64)        0
_________________________________________________________________
max_pooling2d_3 (MaxPooling2 (None, 17, 17, 64)        0
_________________________________________________________________
flatten_1 (Flatten)          (None, 18496)             0
_________________________________________________________________
dense_1 (Dense)              (None, 64)                1183808
_________________________________________________________________
activation_4 (Activation)    (None, 64)                0
_________________________________________________________________
dropout_1 (Dropout)          (None, 64)                0
_________________________________________________________________
dense_2 (Dense)              (None, 1)                 65
_________________________________________________________________
activation_5 (Activation)    (None, 1)                 0
=================================================================
Total params: 1,212,513
Trainable params: 1,212,513
Non-trainable params: 0
_________________________________________________________________
None



I have not used validation dataset, I am using only training data and testing the model manually using:

from keras.preprocessing import image
import numpy
import tensorflow as tf

categories = ['messi','ronaldo']
test_image= image.load_img('test4.jpeg', target_size = (150, 150))
test_image = image.img_to_array(test_image)
test_image = numpy.expand_dims(test_image, axis = 0)
test_image = test_image.reshape(-1,150, 150,3)

result = model.predict([test_image])

print(model.summary())


Please consider that I have only recently started working on ML, I am anticipating some serious silly fault in the code.

• Try adding more Conv2D layers. Also, normalize the images before training so that we don't encounter large numbers for the loss. – Shubham Panchal Feb 6 '20 at 0:29

imgen = ImageDataGenerator(rescale=1/255.)
testGene = imgen.flow_from_directory(<path to testing images>,
target_size=(150, 150,),
shuffle=False,
class_mode="input",
batch_size=batch_size,
save_to_dir=None
)

pred = model.predict_generator(testGene, steps=testGene.n/batch_size)


Testing folder should something like this

<path to testing images>/testing_folder/..test_img_1.jpg
..test_img_2.jpg
..
..


you should pass directory path up to <path to testing images>"

• I tried this method, but the variable 'pred' seems to be returning an empty list. – asiffarhankhan Feb 6 '20 at 4:35
• make sure inside the <path to testing images> there should be a folder,test images should be inside the folder..keras image processing library get the folder as class. – Rajith Thennakoon Feb 6 '20 at 4:37
• I had created a folder and added 4 sample images to it. updated the path in the code like you suggested, still no good. Also. I tried changing the 'save_to_dir' parameter in the generator to my test folder, but there's nothing saved. Maybe the generator is not created for some reason ? – asiffarhankhan Feb 6 '20 at 4:52
• when you run imgen.flow_from_directory() function,it should print out something like this Found 4 images belonging to 1 classes.. Run line by line and check for this message and let me know the result. – Rajith Thennakoon Feb 6 '20 at 4:57
• I got Found 0 images belonging to 0 classes. – asiffarhankhan Feb 6 '20 at 5:08