Tensorflow CIFAR-100 Series (5)

Data augmentation

Posted by Omar Mohamed on April 19, 2019

Recently by the same author:


Ultimate Image Classification

Scene recognition walkthrough


Omar Mohamed

Machine learning / Software developer

You may find interesting:


Tensorflow CIFAR-100 Series (7)

ResNets


Tensorflow CIFAR-100 Series (7)

ResNets

In part_4 we trained our depth-wise convolution model. But in this tutorial we will build upon part_2 again because we only care about increasing accuracy. So we will be adding data augmentation to our normal CNN model.

Data Augmentation

Like we discussed before, CIFAR-100 contains few images per class which makes training a model that generalies harder, so data augmentation can really be helpful to increase our generalizatoin. One of the best libraries out there for image augmentation is imgaug it takes a batch of images and begin to augment them as you specify. Here are some examples:

image

Here you can find a list of all possible augmentations.

Implementation

After installing the library and importing it, only a few lines will be added to our part_2 implementation. We will be augmenting the training batches randomly before they go into the model.

seq = iaa.SomeOf((0, None), [
    iaa.Crop(px=(0, 12)),  # crop images from each side by 0 to 8px (randomly chosen)
    iaa.Fliplr(0.5),  # horizontally flip 50% of the images
    iaa.CoarseDropout((0.0, 0.20), size_percent=(0.02, 0.25), per_channel=0.5),
    # Drop 0 to 20% of all pixels by converting them to black pixels
], random_order=True)

Here we initialized our augmentation parameters. We will be using them randomly and in any combination. Cropping from the sides, flip left and right ,and dropping parts of the image. Of course you can add as many more as you want.

And we will add one line in our training function to augment the batch:

    # method to train one epoch of train data
    def train_epoch(dataset, labels, batch_size):
        data_size = dataset.shape[0]
        global step
        for offset in range(0, data_size, batch_size):
            batch_data = dataset[offset:(offset + batch_size), :]
			
			# notice this line
            batch_data = seq.augment_images(batch_data)

            batch_labels = labels[offset:(offset + batch_size)]
            # train on batch and get accuracy and loss
            feed_dict = {tf_inputs: batch_data, tf_labels: batch_labels, fully_connected_keep_prob: 0.5,
                         conv_keep_prob: train_conv_keep_prob, is_training_ph: True}

            _, l, predictions, lr = session.run(
                [optimize, tf_loss, tf_predictions, learning_rate], feed_dict=feed_dict)

            # print results on mini-batch every 5 iteration
            if (step % 25 == 0):
                print('Learning rate at step %d: %.14f' % (step, lr))
                print('DropBlock keep probability at step %d: %.14f' % (step, train_conv_keep_prob))
                print('Minibatch loss at step %d: %f' % (step, l))
                batch_train_accuracy, _ = accuracy(np.argmax(predictions, axis=1), batch_labels)
                print('Minibatch accuracy: %.1f%%' % batch_train_accuracy)
                # save data for plotting
                training_batch_loss.append(l)
                training_batch_loss_iteration.append(step)
                training_batch_accuracy.append(batch_train_accuracy)
                training_batch_accuracy_iteration.append(step)
            step = step + 1

Results

Training set accuracy:

image image

Test set accuracy:

image image

Final training set accuracy: 97.5%
Final training set loss: 0.1332
Final test set accuracy: 65.3%
Final test set loss: 1.3090

So a simple idea like data augmentation can really increase our accuracy by a large margin like you see here.

If you want to check the full state of the project until now click here to go the repository.
See you in part 6.