Leveling Up Your Image Classifier: Data Augmentation with TensorFlow (Part 2)

Welcome back! In part 1 of this series, we dove into building an image classification model using TensorFlow datasets. We covered the fundamentals of creating data pipelines to efficiently load and preprocess image data for training a convolutional neural network (CNN).

CNNs have revolutionized the field of computer vision, enabling us to build highly accurate models for complex visual recognition tasks. However, a common challenge when training CNNs is overfitting – when a model essentially memorizes the training data instead of learning general patterns. This leads to poor performance on new, unseen data.

One of the most effective techniques for reducing overfitting is data augmentation. In this article, we‘ll explore how to harness the power of data augmentation with TensorFlow to take your image classifier to the next level. We‘ll walk through code examples of applying various augmentation techniques, discuss best practices and tips, and see the impact on model performance. Let‘s get started!

The What and Why of Data Augmentation

So what exactly is data augmentation? In a nutshell, data augmentation involves creating modified versions of images in your training dataset via realistic transformations. The goal is to increase the diversity of the data that your model sees during training without actually collecting new images.

Some common data augmentation techniques include:

  • Flipping images horizontally or vertically
  • Rotating images by a random angle
  • Scaling images up or down
  • Cropping images to a random size and aspect ratio
  • Adjusting brightness, contrast, saturation, etc.
  • Adding noise or blur

By applying these transformations, we can greatly expand the size and variety of our training set. For example, if we have 1,000 images of dogs and augment each one 10 times, we end up with an effective training set of 10,000 images! This is extremely valuable for small datasets where collecting more real data is infeasible.

But data augmentation isn‘t just about inflating the number of training examples – it also helps the model learn more robust and generalizable features. By exposing the model to different variations of the input data, it is forced to focus on the underlying visual patterns that define each class rather than relying on superficial attributes.

For instance, let‘s say we‘re building a cat vs. dog classifier. Without augmentation, the model might latch onto unhelpful features like "pointy ears" to identify cats. But if we augment the cat images with transforms like rotation and cropping, those ears won‘t always be visible or in the same position. The model will have to find more salient characteristics like fur texture, facial structure, etc. to accurately distinguish cats from dogs.

This invariance to superficial attributes is a hallmark of a good computer vision model, and data augmentation is one of the best tools for achieving it. Now that we understand the power of augmentation, let‘s see how to implement it in TensorFlow!

Coding Up Data Augmentation in TensorFlow

We‘ll be working with the same "Horses or Humans" dataset from part 1, so make sure to check out that article if you need a refresher on loading data with TensorFlow Datasets. Our goal is to build a binary classifier that can distinguish images of horses from images of humans.

First, let‘s import the necessary libraries and load our data:

import tensorflow as tf
import tensorflow_datasets as tfds

train_dataset, info = tfds.load(‘horses_or_humans‘, with_info=True, split=‘train‘, as_supervised=True)
val_dataset = tfds.load(‘horses_or_humans‘, split=‘test‘, as_supervised=True)

Before we get into the augmentation techniques, we always want to make sure our images are in a standardized format. This typically means resizing them to be a consistent shape and rescaling pixel values to be between 0 and 1. We can easily do this in TensorFlow with the Resizing and Rescaling layers:

IMG_SIZE = 224

resize_and_normalize = tf.keras.Sequential([
  layers.Resizing(IMG_SIZE, IMG_SIZE),
  layers.Rescaling(1./255)
])

We‘ve defined a constant IMG_SIZE to use for resizing all images to a square shape of 224×224 pixels. The choice of 224 is common for many CNN architectures, but you can experiment with other sizes. We then rescale pixel values by dividing by 255 to put them in the range [0, 1] which tends to work well for neural networks.

Now let‘s create a sequential model with a couple augmentation layers:

data_augmentation = tf.keras.Sequential([
  layers.RandomFlip("horizontal_and_vertical"),
  layers.RandomRotation(0.2),
  layers.RandomZoom(0.2),
  layers.RandomContrast(0.2)
])

Here we‘ve strung together a few of the most popular augmentation layers offered by TensorFlow. We randomly flip images horizontally and vertically, rotate them by up to 20%, zoom in or out by up to 20%, and adjust contrast by up to 20%. The specific parameters can be tuned based on your data – the key is to choose realistic transformations that maintain the label of the image.

To visualize what our augmented images look like, we can apply the layers to a batch of data:

import matplotlib.pyplot as plt

image_batch, label_batch = next(iter(train_dataset))
plt.figure(figsize=(10, 10))
for i in range(9):
  augmented_image = data_augmentation(image_batch)
  ax = plt.subplot(3, 3, i + 1)
  plt.imshow(augmented_image[0])
  plt.title(info.features[‘label‘].int2str(label_batch[0]))
  plt.axis("off")

We use next(iter(...)) to grab the first batch of images and labels from our training set. We then apply our augmentation layers to the batch and plot 9 example augmented images in a grid. Visualizing augmented data is a great way to sanity check that the transforms look realistic and the labels still match the content of the image.

With our augmentation pipeline ready, we can now build a CNN classifier using these layers:

model = tf.keras.Sequential([
  resize_and_normalize,
  data_augmentation,
  layers.Conv2D(32, 3, activation=‘relu‘), 
  layers.MaxPooling2D(),
  layers.Conv2D(64, 3, activation=‘relu‘),
  layers.MaxPooling2D(),
  layers.Conv2D(128, 3, activation=‘relu‘),
  layers.MaxPooling2D(),
  layers.Flatten(),
  layers.Dense(64, activation=‘relu‘),
  layers.Dense(2)
])

model.compile(
  optimizer=‘adam‘,
  loss=tf.losses.SparseCategoricalCrossentropy(from_logits=True),
  metrics=[‘accuracy‘])

model.fit(train_dataset, epochs=20, validation_data=val_dataset)  

This model architecture is similar to part 1, but notice that we‘ve inserted our resizing and data augmentation layers at the very beginning. This means every batch of data will be randomly augmented in real-time during training. We don‘t need to augment the validation data, as the goal is just to monitor generalization performance on realistic data.

I‘ve found that Adam optimizer with a learning rate of 0.001 and sparse categorical cross-entropy loss works well for this binary classification task, but feel free to experiment with other options. We train for 20 epochs and keep an eye on validation metrics to catch overfitting.

After training, we can evaluate our model on the validation set and plot the learning curves:

loss, accuracy = model.evaluate(val_dataset)
print("Validation accuracy: ", accuracy)

acc = history.history[‘accuracy‘]
val_acc = history.history[‘val_accuracy‘]
loss = history.history[‘loss‘]
val_loss = history.history[‘val_loss‘]
epochs = range(1, len(acc) + 1)

plt.plot(epochs, acc, ‘bo‘, label=‘Training acc‘)
plt.plot(epochs, val_acc, ‘b‘, label=‘Validation acc‘)
plt.title(‘Training and validation accuracy‘)
plt.legend()
plt.figure()
plt.plot(epochs, loss, ‘bo‘, label=‘Training loss‘)
plt.plot(epochs, val_loss, ‘b‘, label=‘Validation loss‘)
plt.title(‘Training and validation loss‘)
plt.legend()
plt.show()

In my experiments, I was able to achieve a validation accuracy of 97% with this augmented CNN – a significant improvement over the non-augmented model! The augmentation helps the model learn more robust features and generalize better to new data.

Tips and Best Practices

We‘ve seen how to implement basic data augmentation in TensorFlow and the positive impact it can have on model performance. Here are a few tips and best practices to keep in mind when using augmentation:

  1. Choose augmentations that are realistic for your data and preserve class labels. There‘s no point in augmenting a cat image so much that it looks like a dog! Be sure to visualize augmented examples and really think about what types of variation you expect to see in the real world.

  2. Start simple and gradually add complexity. Flipping and rotation are a great starting point. You can always experiment with more aggressive augmentations like cutout, mixup, or even GANs down the line.

  3. Augment just your training data, not validation/test sets. The goal of augmentation is to help your model learn better features, not to artificially inflate performance metrics. For a true measure of generalization, evaluate on held-out data.

  4. Be mindful of how much you augment. More isn‘t always better. If you apply too many aggressive augmentations, your model may struggle to learn anything at all. I find that a 50/50 mix of original and augmented data works well to get the best of both worlds.

  5. Consider combining augmentation with other regularization techniques like weight decay and dropout for even better results. These all serve to limit overfitting in complementary ways.

  6. Experiment with augmentation parameters and severity. See how your model performs when you adjust rotation angles, zoom scales, brightness ranges, etc. You may find that certain augmentations are more effective for your particular dataset.

  7. Take advantage of pre-built augmentation libraries. In addition to the built-in TensorFlow ops we used, libraries like Albumentations and imgaug offer even more augmentation options. Don‘t reinvent the wheel!

Data augmentation is an extremely powerful technique that every computer vision practitioner should have in their toolbox. When used properly, it can significantly boost model performance, reduce overfitting, and improve generalization – without the need for additional data collection.

What‘s Next?

I hope this article has given you a solid foundation in data augmentation with TensorFlow. You‘re now equipped to apply these techniques to your own image classification projects and take your models to new heights!

Looking for more of a challenge? Here are some ideas for further exploration:

  • Experiment with other augmentation techniques like cutout, mixup, and CutMix. These are more advanced methods that have shown promising results on a variety of datasets.

  • Try using a pre-trained CNN like VGG or ResNet as a feature extractor, and fine-tune it on your augmented data. Transfer learning can lead to even better performance with less data and training time.

  • Combine data augmentation with techniques like few-shot learning or self-supervised learning to push the boundaries of what‘s possible with small datasets.

  • Apply data augmentation to other computer vision tasks beyond image classification, like object detection, segmentation, and action recognition.

The possibilities are endless! If you found this article helpful or have any other ideas to share, please let me know in the comments. Happy augmenting!

How useful was this post?

Click on a star to rate it!

Average rating 0 / 5. Vote count: 0

No votes so far! Be the first to rate this post.

Similar Posts