1

I need advice. I got a very poor result(10% accuracy) when building a CNN model with Keras when only using a subset of CIFAR10 dataset (only use 10000 data, 1000 per class). How can I increase the accuracy? I try to change/increase the epoch, but the result is still the same. Here is my CNN architecture :

cnn = models.Sequential()
cnn.add(layers.Conv2D(25, (3, 3), input_shape=(32, 32, 3)))
cnn.add(layers.MaxPooling2D((2, 2)))
cnn.add(layers.Activation('relu'))
cnn.add(layers.Conv2D(50, (3, 3)))
cnn.add(layers.MaxPooling2D((2, 2)))
cnn.add(layers.Activation('relu'))
cnn.add(layers.Conv2D(100, (3, 3)))
cnn.add(layers.MaxPooling2D((2, 2)))
cnn.add(layers.Activation('relu'))
cnn.add(layers.Flatten())
cnn.add(layers.Dense(100))
cnn.add(layers.Activation('relu'))
cnn.add(layers.Dense(10))
cnn.add(layers.Activation('softmax'))

compile and fit:

EPOCHS = 200
BATCH_SIZE = 10
LEARNING_RATE = 0.1

cnn.compile(optimizer=tf.keras.optimizers.Adam(learning_rate=LEARNING_RATE),
            loss='binary_crossentropy',
            metrics=['accuracy'])

es = EarlyStopping(monitor='val_loss', mode='min', verbose=1)
mc = ModelCheckpoint(filepath=checkpoint_path, monitor='val_accuracy', mode='max', verbose=1, save_best_only=True)

history_cnn = cnn.fit(train_images, train_labels, epochs=EPOCHS, batch_size=BATCH_SIZE,
                validation_data=(test_images, test_labels),callbacks=[es, mc],verbose=0)

The data i use is CIFAR10, but i only take 1000 images per class so total data is only 10000. I use normalization for preprocessing the data.

thenoirlatte
  • 341
  • 3
  • 19

1 Answers1

1

First of all, the problem is the loss. Your dataset is a multi-class problem, not a binary and not multi-label one

As stated here:

The classes are completely mutually exclusive. There is no overlap between automobiles and trucks. "Automobile" includes sedans, SUVs, things of that sort. "Truck" includes only big trucks. Neither includes pickup trucks.

In this situation is suggested the use of the categorical crossentropy. Keep in mind that if your label are sparse (encoded with the number between 0 and 999) and not as one hot encoded vector ([0, 0, 0 ... 1, 0, 0]) you should use the sparse categorical crossentropy.

  • not sparse (labels encoded as vectors [0, 0, 1,....0])

    cnn.compile(optimizer=tf.keras.optimizers.Adam(learning_rate=LEARNING_RATE),
              loss='categorical_crossentropy',
              metrics=['accuracy'])
    
  • sparse (labels encoded as numbers in (0, ... 999))

    cnn.compile(optimizer=tf.keras.optimizers.Adam(learning_rate=LEARNING_RATE),
              loss='sparse_categorical_crossentropy',
              metrics=['accuracy'])
    

Also, the learning rate is quite high (0.1). I'll suggest you to start with something lower (0.001) for example.

this post is also relevant for your problem

Edit: my bad, for the number of filters it is a commong approach having an increasing number of filters

Nikaido
  • 4,443
  • 5
  • 30
  • 47
  • hi, thanks before, but after i tried (change the loss to 'categorical_crossentropy' and learning rate to 0.001), the loss is much lower than before, but the accuracy still 10% – thenoirlatte Oct 25 '20 at 12:54
  • @thenoirlatte did you try sparse_categorical_crossentropy? Maybe you have sparse labels – Nikaido Oct 25 '20 at 12:57
  • probably you have sparse labels, with 1000 classes it's quite heavy to keep the labels in that way in memory – Nikaido Oct 25 '20 at 12:59
  • 1
    my bad...I forgot to run it from the beginning, the accuracy is higher now (50%), I'll try to change to sparse_categorical_crossentropy and see the result – thenoirlatte Oct 25 '20 at 13:06