1
$\begingroup$

I am training a CNN model with about 20.000 images with two classes each 10.000 images. The size of the images vary between 50*50 pixel and 1000x500 pixels. I am resizing all images to the average size of all images, which is 350x150 pixels. Then training a CNN with this architecture:

import cv2
import os
import numpy as np
from keras.models import Sequential
from keras.layers import Dense
from keras.layers import Dropout
from keras.layers import Flatten
from keras.constraints import maxnorm
from keras.optimizers import SGD
from keras.layers.convolutional import Convolution2D
from keras.layers.convolutional import MaxPooling2D
from keras.utils import np_utils
from sklearn.model_selection import train_test_split
import random
import matplotlib.pyplot as plt

data = []
labels = []

imagePaths = sorted(list(my_images))
random.seed(42)
random.shuffle(imagePaths)
# loop over the  images
for imagePath in imagePaths:
    image = cv2.imread(imagePath)
    image = cv2.resize(image, (350, 150))
    data.append(image)
    # extract the class label from the image path and update the
    # labels list
    label = imagePath.split(os.path.sep)[-2].split('/')[-1]
    if label == 'pos':
        label = 1
    elif label == 'neg':
        label = 0
    labels.append(label)

# scale the raw pixel intensities to the range [0, 1]
data = np.array(data, dtype="float") / 255.0
labels = np.array(labels)

# partition the data into training and testing splits using 75% of
# the data for training and the remaining 25% for testing
(trainX, testX, trainY, testY) = train_test_split(data, labels, test_size=0.25, random_state=42)
unique, counts = np.unique(trainY, return_counts=True)
print(dict(zip(unique, counts)))

y_train = np_utils.to_categorical(trainY)
y_test = np_utils.to_categorical(testY)
num_classes = 2

# # # Create the model
model = Sequential()
model.add(Convolution2D(32, 3, 3, input_shape=(150, 350, 3), activation='relu', border_mode='same'))
model.add(Dropout(0.2))
model.add(Convolution2D(32, 3, 3, activation='relu', border_mode='same'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Convolution2D(64, 3, 3, activation='relu', border_mode='same'))
model.add(Dropout(0.2))
model.add(Convolution2D(64, 3, 3, activation='relu', border_mode='same'))
model.add(MaxPooling2D(pool_size=(2, 2)))
model.add(Flatten())
model.add(Dropout(0.2))
model.add(Dense(1024, activation='relu', W_constraint=maxnorm(3)))
model.add(Dropout(0.2))
model.add(Dense(512, activation='relu', W_constraint=maxnorm(3)))
model.add(Dropout(0.2))
model.add(Dense(num_classes, activation='softmax'))
# Compile model
epochs = 25
lrate = 0.01
decay = lrate / epochs
sgd = SGD(lr=lrate, momentum=0.9, decay=decay, nesterov=False)
model.compile(loss='categorical_crossentropy', optimizer=sgd, metrics=['accuracy'])

I am getting an accuracy of 95 % which is really good and I am using it as production model. However I am wondering whether I can improve the accuracy since the number of images seems to be very high and the classification problem separable: example images

Is there any chance to improve the model and to squeeze out a bit more from the prediction?

$\endgroup$

1 Answer 1

2
$\begingroup$

95% is very good, I'm not sure if improving that result would not alter the result in production: Keeping an error margin might be helpful to avoid overfitting, but it may not be your case.

Nevertheless, here are some tips to improve your model even more:

  • Apply the AdamW algorithm instead of SGD. AdamW is an optimizer that reduces the learning rate progressively with iterations. I've already improved models by 20% using this optimizer.

https://www.fast.ai/posts/2018-07-02-adam-weight-decay.html

  • Fine-tune your hyperparameters & structure thanks to a genetic algorithm. This solution requires a lot of patience, as it explores many different model configurations, but you will eventually reach better results. Therefore, you could rent a powerful GPU in a cloud for a few hours to do this task (=few dollars).

https://sainivedh.medium.com/optimization-of-cnn-architecture-using-genetic-algorithm-for-image-classification-5c48f25dac9c

$\endgroup$
1
  • 1
    $\begingroup$ Thanks a lot for your suggestions, I will do some experiments (hardware is not a problem). 95% is indeed very good but critical in some cases were I have only small number of samples (10 objects) and this needs manual checks. $\endgroup$
    – honeymoon
    Sep 20, 2022 at 8:12

Your Answer

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.