Hamza Shamaseen
Hamza Shamaseen

Reputation: 25

TensorFlow image classification loss doesn't decrease

import tensorflow as tf
import matplotlib.pyplot as plt
import cv2
import os
import numpy as np
from tensorflow.keras.preprocessing.image import ImageDataGenerator
from tensorflow.keras.preprocessing import image
from tensorflow.keras.optimizers import Nadam
from tensorflow.keras.models import load_model

train = ImageDataGenerator(rescale=1 / 255)
validation = ImageDataGenerator(rescale=1 / 255)

train_dataset = train.flow_from_directory('raw-img/training', target_size=(200, 200), batch_size=3,
                                          class_mode='categorical')

validation_dataset = train.flow_from_directory('raw-img/validation', target_size=(200, 200), batch_size=3,
                                               class_mode='categorical')

model = tf.keras.models.Sequential([tf.keras.layers.Conv2D(16, (3, 3), activation='relu', input_shape=(200, 200, 3),padding='same'),
                                    tf.keras.layers.MaxPool2D(2, 2,padding='same'),
                                    #
                                    tf.keras.layers.Conv2D(32, (3, 3), activation='relu',padding='same'),
                                    tf.keras.layers.MaxPool2D(2, 2),
tf.keras.layers.Dropout(rate=0.6),
                                    #
                                    tf.keras.layers.Conv2D(64, (3, 3), activation='relu',padding='same'),
                                    tf.keras.layers.MaxPool2D(2, 2),
tf.keras.layers.Dropout(rate=0.6),
                                    #
                                    tf.keras.layers.Conv2D(128, (3, 3), activation='relu',padding='same'),
                                    tf.keras.layers.MaxPool2D(2, 2),
                                    #
                                    tf.keras.layers.Conv2D(128, (3, 3), activation='relu',padding='same'),
                                    tf.keras.layers.MaxPool2D(2, 2),
                                    #

                                    tf.keras.layers.Conv2D(256, (3, 3), activation='relu',padding='same'),
                                    tf.keras.layers.MaxPool2D(2, 2,),
                                    #
                                    tf.keras.layers.Flatten(),
                                    #
                                    tf.keras.layers.Dense(512, activation='relu'),

                                    tf.keras.layers.Dense(256, activation='relu'),
                                    tf.keras.layers.Dense(10, activation='sigmoid'),
])
print(model.summary())
model.compile(loss='binary_crossentropy', optimizer=Nadam(learning_rate=0.003), metrics['accuracy'])
model_fit = model.fit(train_dataset, epochs=70, batch_size=3, validation_data=validation_dataset,steps_per_epoch=len(train_dataset),validation_steps=len(validation_dataset))
loss, accuracy = model.evaluate(train_dataset)
print("Loss: ", loss)
print("Accuracy: ", accuracy)

Found 26179 images belonging to 10 classes. Found 8196 images belonging to 10 classes.

Epoch 1/70
2909/2909 [==============================] - 1005s 345ms/step - loss: 0.3292 - accuracy: 0.1805 - val_loss: 0.3533 - val_accuracy: 0.0000e+00
Epoch 2/70
2909/2909 [==============================] - 645s 222ms/step - loss: 0.3167 - accuracy: 0.1758 - val_loss: 0.3654 - val_accuracy: 0.0000e+00

...

Epoch 8/70
2909/2909 [==============================] - 445s 153ms/step - loss: 0.3160 - accuracy: 0.1835 - val_loss: 0.3666 - val_accuracy: 0.0000e+00
Epoch 9/70
2909/2909 [==============================] - ETA: 0s - loss: 0.3146 - accuracy: 0.1867

What the problem with this code? Accuracy stuck at 0.1800 and 0.1900 and loss in doesn't decrease.

Upvotes: 0

Views: 245

Answers (1)

Gerry P
Gerry P

Reputation: 8112

A couple of issues

  1. since your images are 200 X 200 you could use a larger batch size like say 32
  2. in the train = ImageDataGenerator(rescale=1 / 255) you might want to consider
    adding some image augmentation like horizontal_flip=True, etc. If you do add
    augmentation do not use the train in your code for the validation_data set, use
    validation
  3. in your model you have the code tf.keras.layers.Dense(10, activation='sigmoid')
    unless you are doing multi-label classification change the activation to "softmax'
  4. your model will likely over-fit. I would add at least one dropout layer to
    your model like tf.keras.layers.Dropout(.3)
  5. First do the above changes and look at the performance. If it starts to over-fit
    increase the dropout rate or reduce the number of nodes in the hidden layers
  6. If you are not satisfied with the accuracy you might get an improvement by
    using and adjustable learning rate. You can do this with the Keras callback
    ReduceLROnPlateau. Documentation is here. My suggest code is
rlronp=tf.keras.callbacks.ReduceLROnPlateau(monitor='val_loss', factor=.5,patience=1,verbose=1)
  1. I also recommend you use the Keras callback EarlyStopping. It will monitor
    the validation loss if it fails to reduce after 'patience' number of epochs.
    Documentation is here. set restore_best_weights=True so that is this
    callback activates it will load your model with the weights from the epoch with
    the lowest validation loss. My suggested code is
es=tf.keras.callbacks.EarlyStopping(monitor="val_loss",patience=4,verbose=1,
                                    restore_best_weights=True)
  1. if you use the callbacks then in model.fit set callbacks=[rlronp,es]

Upvotes: 1

Related Questions