1
votes

I'm making a convolutional network to predict 3 class of images, Cats, Dogs & People. I trained and trained it, but then when I pass a cat image to predict it always gives the wrong output. I tried other pictures of cats, but the result doesn't change. With people and dogs it has no problem, just with cats.

     cnn = Sequential()

    #------------------- Convolução e Pooling
    cnn.add(Conv2D(32, (3, 3), input_shape = (64, 64, 3), activation = 'relu'))
    cnn.add(Dropout(0.5))
    cnn.add(MaxPooling2D(pool_size = (2, 2)))

    cnn.add(Conv2D(32, (3, 3), activation = 'relu'))
    cnn.add(Dropout(0.5))
    cnn.add(MaxPooling2D(pool_size = (2, 2)))

    cnn.add(Conv2D(64, (3, 3), activation = 'relu'))
    cnn.add(MaxPooling2D(pool_size = (2, 2)))

    cnn.add(Conv2D(64, (3, 3), activation = 'relu'))
    cnn.add(Dropout(0.5))
    cnn.add(MaxPooling2D(pool_size = (2, 2)))

    #Full connection
    cnn.add(Flatten())
    cnn.add(Dense(units = 128, activation = 'relu'))
    cnn.add(Dense(units = 4, activation = 'softmax'))

    # Compiling the CNN
    cnn.compile(optimizer = OPTIMIZER, loss = 'categorical_crossentropy', metrics = ['accuracy'])

    filepath="LPT-{epoch:02d}-{loss:.4f}.h5"
    checkpoint = ModelCheckpoint(filepath, monitor='loss', verbose=1, save_best_only=True, mode='min')
    callbacks_list = [checkpoint]

12000 train images - 3000 test images

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

test_datagen = ImageDataGenerator(rescale = 1./255)

training_set = train_datagen.flow_from_directory('data/train',
                                                 target_size = tgt_size,
                                                 batch_size = batch_size,
                                                 class_mode = 'categorical')

test_set = test_datagen.flow_from_directory('data/test',
                                            target_size = tgt_size,
                                            batch_size = batch_size,
                                            class_mode = 'categorical')

cnn.fit_generator(training_set,
                  #steps_per_epoch = 12000,  
                  steps_per_epoch = nb_train_samples // batch_size,                                                   
                  epochs = EPOCHS,
                  verbose = VERBOSE,
                  validation_data = test_set,
                  validation_steps = nb_validation_samples // batch_size,
                  callbacks = callbacks_list)

My best training result:

loss: 0.6410 - acc: 0.7289 - val_loss: 0.6308 - val_acc: 0.7293

Class indices:

{'.ipynb_checkpoints': 0, 'cats': 1, 'dogs':2, 'person':3}

(I can't remove that ipynb folder)

Prediction:

pred1 = 'single_prediction/ct.jpg'
pred2 = 'single_prediction/ps.jpg'
pred3 = 'data/single_prediction/dg.jpg'

test_img = image.load_img(pred1, target_size = tgt_size)
test_img = image.img_to_array(test_img)
test_img = np.expand_dims(test_img, axis = 0)
pred = new_model.predict(test_img)
print(pred)

if pred[0][1] == 1:
        print('It is a cat!')
elif pred[0][2] == 1:
    print('It is a dog!')
elif pred[0][3] == 1:
    print('It is a Person!')

And the output for a cat image:

[[0.000000e+00 0.000000e+00 8.265931e-34 1.000000e+00]]

I already tried: Change the number of layers (added and removed), increase the epochs, decrease the batch... I also tried using np.argmax(). Can someone please give me a light here?

UPDATE: I removed the jupyter notebook's hidden folder with the command shutil.rmtree() and trained for about 40 epochs until it stopped improving. At last, I rescaled the prediction image and got it right.

test_img = image.img_to_array(test_img)/255

Thanks for all the help!

1
It looks like underfitting. So please consider to increase your model's performance first. You can do add more layers, increase the size of each layers, and remove dropout. Only when you find the overfitting happened, you can start to add dropout or limit your model's complexity.NormanZhu
You are not rescaling your images by division by 255, while the generator does this (you specified the rescale value).Dr. Snoopy
You said you have 3 classes, but your net have 4 nodes at the output. Is your probelm 4 class.?Sreeram TP
I added more layers and changed some, the val_acc is going well... Let's see!Newton
@MatiasValdenegro Where should I rescale?Newton

1 Answers

2
votes

The problem is with the ipynb checkpoints folder. This is a hidden folder. You need to delete it first. Then change your output dense layer to have 3 units (classes). Change this

cnn.add(Dense(units = 4, activation = 'softmax')) 

to

cnn.add(Dense(units = 3, activation = 'softmax'))