I'm doing a simple binary classification using this dataset

import os

train_dir = "/tmp/Dataset/TrainingandValidation"
fire = os.path.join(train_dir, 'fire')
nofire = os.path.join(train_dir, 'nofire')

test_dir = "/tmp/Dataset/Testing/"
tfire = os.path.join(test_dir, 'fire')
tnofire = os.path.join(test_dir, 'nofire')

from tensorflow.keras.preprocessing.image import ImageDataGenerator

test_data = ImageDataGenerator(rescale=1.0/255.)
train_data = ImageDataGenerator (rescale= 1.0/255.)

train_images = train_data.flow_from_directory (train_dir,
                                               batch_size= 20,
test_images = test_data.flow_from_directory(test_dir,
                                            target_size = (150,150))

import tensorflow as tf

model = tf.keras.Sequential ([
                              tf.keras.layers.Conv2D (16, (3,3), activation='relu', input_shape =(150,150,3)),
                              tf.keras.layers.Conv2D (32, (3,3), activation='relu'),
                              tf.keras.layers.Conv2D (64, (3,3), activation='relu'),
                              tf.keras.layers.Dense(512, activation='relu'),
                              tf.keras.layers.Dense(1, activation= 'sigmoid')



from tensorflow.keras.optimizers import RMSprop
model.compile(optimizer= RMSprop (lr=0.001), 
              loss = 'binary_crossentropy',

from tensorflow.keras.callbacks import Callback

class myCallback(tf.keras.callbacks.Callback):
  def on_epoch_end(self, epoch, logs={}):
      print("\nReached 94% val_accuracy")
      self.model.stop_training = True
callbacks = myCallback()

history = model.fit(train_images,
          steps_per_epoch= 76, 
          validation_steps= 19,
          callbacks= [callbacks])

import numpy as np

# uploading images to predict 
from google.colab import files
from keras.preprocessing import image


for fn in uploaded.keys():
  # predicting images
  path='/content/' + fn
  img=image.load_img(path, target_size=(150, 150))
  x= x/255.0

  x=np.expand_dims(x, axis=0)
  images = np.vstack([x])
  classes = model.predict(images, batch_size=1)
  if classes[0]>0:
    print(fn + " fire")
    print(fn + " no fire")

The model is getting well as below :

Epoch 14/15
76/76 [==============================] - 3s 40ms/step - loss: 0.0524 - accuracy: 0.9812 - val_loss: 0.2918 - val_accuracy: 0.9474

Reached 94% val_accuracy

Although it might look it's overfitting or so, when I upload images to predict them the model almost always predict 1 (fire), even if I ask it to predict training images!

I tried adding a dropout layer before the last layer but not much better. I feel like there's something wrong with the preprocessing of the images?

  • $\begingroup$ You should not use a sigmoid activation at the output layer when the preceding layers have ReLU activation. Sigmoid would output values close to 1 if the inputs are large positive numbers. On the other hand, ReLU always outputs positive numbers ( except some other variants ). So, the sigmoids input will always come from the output of a ReLU function multiplied by the weights. This will lead to unstable training as the sigmoid will always output extreme values like 0 and 1. $\endgroup$ Apr 9, 2021 at 6:48
  • $\begingroup$ I suggest you convert the binary classification problem to a multi-class classification problem.Transform the binary labels to one-hot labels and add a softmax function at the last Dense layer $\endgroup$ Apr 9, 2021 at 6:49
  • $\begingroup$ Thank you a lot @ShubhamPanchal that worked. Although I did binary classification using similar CNN structure to the above on cats and dogs dataset and worked well. Multi class worked well enough here. $\endgroup$ Apr 9, 2021 at 11:41


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Browse other questions tagged or ask your own question.