Enhance Your ML Experimentation Workflow with Real-Time Plots
In the previous article of this series, I demonstrated how to use DVC's VS Code extension to transform our IDE into an experimentation platform, allowing us to directly run and evaluate ML experiments. I also mentioned that the extension offers useful plotting functionalities, which enable us to visualize and evaluate the performance of our experiments using interactive plots. To make it even better, the extension also offers live plotting of certain metrics during the training phase. You can get a sneak peek of this feature in the following figure.
This article will demonstrate how to enhance the previously-introduced experimentation workflow by monitoring model performance and evaluating experiments with interactive plots, all within VS Code. To achieve this, we'll tackle a binary image classification problem. First, we will provide an overview of transfer learning in computer vision and share some details about the selected dataset.
Problem definition and methodology
Image classification is one of the most popular tasks in the field of computer vision. For our example, we will use the cat vs dog classification problem, which has been widely used in the research community to benchmark different Deep Learning models. As you might have guessed, the goal of the project is to classify an input image as either a cat or a dog.
To achieve high accuracy even with limited training data, we will leverage transfer learning to speed up the training process. Transfer learning is a powerful deep learning technique that has recently gained significant popularity, especially in various domains of computer vision. With the vast amount of data available on the internet, transfer learning allows us to leverage existing knowledge from one domain/problem and apply it to a different one.
One of the approaches to using Transfer Learning for computer vision is based on the idea of feature extraction. First, a model is trained on a large and general dataset (for example, the ImageNet dataset). This model serves as a generic model of "vision". Then, we can use the learned feature maps of such a model without having to start the training of a custom network from scratch
For our use case, we will utilize a pre-trained model (ResNet50) to extract relevant features for our binary classification problem. The approach consists of a few steps:
- Obtain a pre-trained model, i.e., a saved network that was previously trained on a large dataset. You can find some examples here.
- Use the feature maps learned by the selected network to extract meaningful features from images that the network was not trained on.
- Add a new classifier on top of the pre-trained network. The classifier will be trained from scratch since the classification component of the pre-trained model is specific to its original task.
We will show how to do all of this in the following sections. However, please bear in mind that this is not a tutorial on transfer learning. If you would like to learn more about the theory and implementation, please refer to this article or this tutorial.
Getting the data
By using the following snippet, we can download the cats vs. dogs dataset. The original dataset contained 12500 images of each class. However, for our project, we will be using a smaller, filtered dataset that contains 1000 training images and 500 validation images per class. The additional benefit of downloading the filtered dataset via TensorFlow is that it does not contain some corrupted images that were present in the original dataset (please see here for more information).
import os
import tensorflow as tf
import shutil
DATA_URL = "https://storage.googleapis.com/mledu-datasets/cats_and_dogs_filtered.zip"
DATA_PATH = "data/raw"
path_to_zip = tf.keras.utils.get_file(
"cats_and_dogs.zip", origin=DATA_URL, extract=True
)
download_path = os.path.join(os.path.dirname(path_to_zip), "cats_and_dogs_filtered")
train_dir_from = os.path.join(download_path, "train")
validation_dir_from = os.path.join(download_path, "validation")
train_dir_to = os.path.join(DATA_PATH, "train")
validation_dir_to = os.path.join(DATA_PATH, "validation")
shutil.move(train_dir_from, train_dir_to)
shutil.move(validation_dir_from, validation_dir_to)
The following tree presents the structure of the directories containing the downloaded images: