0
votes

I am trying to code a fruit image classifier with python, try to classify 7 fruits. I have 15077 images for train_set and 4204images for validation_set. I compiled the code for 10 epochs , the i got results like :

Train on 15077 samples, validate on 4204 samples Epoch 1/10 15077/15077 [==============================] - 264s 17ms/step - loss: 1.0652 - accuracy: 0.5325 - val_loss: 0.3722 - val_accuracy: 0.8428 Epoch 2/10 15077/15077 [==============================] - 256s 17ms/step - loss: 0.4236 - accuracy: 0.8405 - val_loss: 0.2910 - val_accuracy: 0.9034 Epoch 3/10 15077/15077 [==============================] - 499s 33ms/step - loss: 0.2682 - accuracy: 0.9107 - val_loss: 0.3614 - val_accuracy: 0.8830 Epoch 4/10 15077/15077 [==============================] - 243s 16ms/step - loss: 0.2022 - accuracy: 0.9381 - val_loss: 0.0985 - val_accuracy: 0.9724 Epoch 5/10 15077/15077 [==============================] - 245s 16ms/step - loss: 0.1500 - accuracy: 0.9548 - val_loss: 0.1258 - val_accuracy: 0.9536 Epoch 6/10 15077/15077 [==============================] - 253s 17ms/step - loss: 0.1509 - accuracy: 0.9529 - val_loss: 0.1831 - val_accuracy: 0.9317 Epoch 7/10 15077/15077 [==============================] - 245s 16ms/step - loss: 0.1020 - accuracy: 0.9678 - val_loss: 0.2164 - val_accuracy: 0.9391 Epoch 8/10 15077/15077 [==============================] - 255s 17ms/step - loss: 0.0668 - accuracy: 0.9816 - val_loss: 0.3004 - val_accuracy: 0.9229 Epoch 9/10 15077/15077 [==============================] - 243s 16ms/step - loss: 0.1081 - accuracy: 0.9704 - val_loss: 1.4997 - val_accuracy: 0.8639 Epoch 10/10 15077/15077 [==============================] - 240s 16ms/step - loss: 0.0765 - accuracy: 0.9784 - val_loss: 0.1763 - val_accuracy: 0.9424 Test loss: 0.17632227091173225 Test accuracy: 0.9424358010292053 i wonder that why accuracy is acting like sin wave ? I think it should increasing every epochs. Do you have any recommendation for modifying code ? Thanks for replying .

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import os
import cv2
import tensorflow as tf
import keras
from keras.models import Sequential
from keras.layers import Dense, Dropout, Flatten, Conv2D, MaxPooling2D
from keras.layers import LSTM, Input, TimeDistributed
from keras.models import Model
from keras.optimizers import RMSprop, SGD

# Import the backend
from keras import backend as K

dataDirTrain = "C:/Users/TCSEAKIN/Desktop/Py/AI-hack/AI/Training"
dataDirTest = "C:/Users/TCSEAKIN/Desktop/Py/AI-hack/AI/Test"
categories = ["Armut", "Cilek", "Elma_Kirmizi", "Elma_Yesil", "Mandalina", "Muz","Portakal"]


training_data = []
test_data = []

for category in categories:
    path = os.path.join(dataDirTrain, category)
    class_num = categories.index(category)
    for img in os.listdir(path):
        try:
            imgTrainArray = cv2.imread(os.path.join(path,img))
            newTrainArray = cv2.resize(imgTrainArray, (50, 50))
            training_data.append([newTrainArray, class_num])
        except Exception as e:
            pass


for category in categories:
    path = os.path.join(dataDirTest, category)
    class_num = categories.index(category)
    for img in os.listdir(path):
        try:
            imgTestArray = cv2.imread(os.path.join(path,img))
            newTestArray = cv2.resize(imgTestArray, (50, 50))
            test_data.append([newTestArray, class_num])
        except Exception as e:
            pass

X_train = []
x_test = []
y_train = []
y_test = []

for features, label in training_data:
    X_train.append(features)
    y_train.append(label)

for features, label in test_data:
    x_test.append(features)
    y_test.append(label)

X_train = np.array(X_train).reshape(-1, 50, 50, 3)
y_train = np.array(y_train).reshape(-1, 1)

x_test = np.array(x_test).reshape(-1, 50, 50, 3)
y_test = np.array(y_test).reshape(-1, 1)


X_train = X_train/255
x_test = x_test/255

from keras.utils import to_categorical

Y_train_one_hot = to_categorical(y_train)
Y_test_one_hot = to_categorical(y_test)

model_cnn = Sequential()
# First convolutional layer, note the specification of shape
model_cnn.add(Conv2D(64, kernel_size=(3, 3),activation='relu',input_shape=(50, 50, 3)))


model_cnn.add(Conv2D(128, (3, 3), activation='relu'))
model_cnn.add(MaxPooling2D(pool_size=(2, 2)))
model_cnn.add(Conv2D(256, (3, 3), activation='relu'))
model_cnn.add(MaxPooling2D(pool_size=(2, 2)))
model_cnn.add(Dropout(0.5))

model_cnn.add(Flatten())
model_cnn.add(Dense(128, activation='relu'))
model_cnn.add(Dropout(0.5))
model_cnn.add(Dense(64, activation='relu'))
model_cnn.add(Dropout(0.5))
model_cnn.add(Dense(7, activation='softmax'))

model_cnn.compile(loss="categorical_crossentropy",
              optimizer="adam",
              metrics=['accuracy'])

model_cnn.fit(X_train, Y_train_one_hot,
          batch_size=64,
          epochs=10,
          verbose=1,
          validation_data=(x_test, Y_test_one_hot))
score = model_cnn.evaluate(x_test, Y_test_one_hot, verbose=0)
print('Test loss:', score[0])
print('Test accuracy:', score[1])

model_cnn.save("C:/Users/TCSEAKIN/Desktop/Training3.py"
2

2 Answers

2
votes

I think training accuracy is already good. You can do couple of things to improve validation accuracy and overall performance.

  1. use ImageDataGenerator to augment images to get better model accuracies
  2. use lower learning rate or adaptive learning rate.
  3. Update two lines as shown below. Recently it was found that there are numerical instabilities introduced by softmax layer in the end of the model.

Replace these two line
from

model_cnn.add(Dense(7, activation='softmax'))

model_cnn.compile(loss="categorical_crossentropy",
              optimizer="adam",
              metrics=['accuracy'])

to

model_cnn.add(Dense(7))

model_cnn.compile(loss=tf.keras.losses.CategoricalCrossentropy(from_logits=True),
              optimizer="adam",
              metrics=['accuracy'])
  1. Try tuning some hyper parameters like changing batch_size from 64 to 32 which increases number of steps, try other optimizations techniques, increasing number of epochs etc.

Hope it helps.

0
votes

In fact it's a normal behavior. You can reduce your learning rate in order to decrease differences in accuracy between training epochs (Also, try other optimizers if you want)

Also, you should normalize your images in order to improve the capacity of your network to generalize knowledge. Here you can read more about normalization: https://machinelearningmastery.com/how-to-normalize-center-and-standardize-images-with-the-imagedatagenerator-in-keras/