Develop and Deploy an Image Classifier App Using Fastai
This article was published as a part of the Data Science Blogathon.
Fastai is a popular open-source library used for learning and practicing machine learning and deep learning. Jeremy Howard and Rachel Thomas founded fast.ai with the objective of making deep learning more accessible. All the exhaustive resources such as courses, software, and research papers available in fast.ai are completely free.
In August 2020, fastai_v2 was released that promises to be much faster, and more flexible to implement deep learning frameworks. The 2020 fastai course combines the core concepts of both machine learning and deep learning. It also teaches the user about the important aspects of model production and deployment. In this article, I will discuss the techniques taught in the initial three lessons of the fast.ai beginner course, about building a quick and simple image classification model. Along with building the model, you will also learn how to easily develop a web application for the model and deploy it for production.
This article will follow the top-down approach that Jeremy follows for teaching in his courses. You will first learn about training an image classifier. Later, the details about the model used for classification will be explained. The prerequisite for understanding this article is knowledge of Python, as fastai is written in Python and built on PyTorch. It is recommended to run this code in Google Colab or Gradient, as GPU access is required. Also, fastai can be easily installed on these two platforms.
Install, Import, and Load Dataset
!pip install -Uqq fastbook import fastbook fastbook.setup_book() from fastbook import * from fastai.vision.widgets import *
Install fastai and import the necessary libraries. If you are using Colab then you will have to provide access to your Google Drive to save the files and images. You can download any image dataset from sources such as Kaggle and Bing image search. Fast.ai also has a huge collection of images. I have used a set of chest X-ray images from https://github.com/ieee8023/covid-chestxray-dataset in this article.
path = Path ('/content/gdrive/My Drive/Covid19images')
Save the path of your dataset location in the Path() object. If you are using the fast.ai dataset then you can use the following code:
path = untar_data(URLs.PETS)/'images'
This downloads and extracts the images from the fastai PETS dataset collection.
Check the image path and display a few sample images from the dataset. I have used the Python Imaging Library (PIL) for this.
path.ls from PIL import Image img = Image.open(path'/train/covid/1-s2.0-S1684118220300682-main.pdf-002-a2.png') print(img.shape) img.to_thumb(128,128)
In this image classification problem, I will be training the model to classify the X-ray images into COVID or No COVID classes. The preprocessed dataset has been placed in separate COVID and No COVID folders (Credit: Christian Tutivén Gálvez).
If you are using the fast.ai dataset then use the following function to group the images based on the name of the pet:
def is_cat(x): return x.isupper()
PETS is a collection of cat and dog images. Cat images are labeled with the first letter in uppercase so that it’s easy to categorize them.
Image transformation is a key step in training a model for images. It is also referred to as data augmentation. To avoid overfitting the model image transformation is a must. There are different ways to transform images such as resizing, cropping, squishing, and padding. However, squishing and padding robs the original information from the images and adds additional pixels respectively. Hence, randomly resizing the images yields good results.
In this method as shown in the below example, random areas of each image are sampled during every epoch. This enables the model to learn more details of every image, yielding better accuracy. Another important point to remember is, always transform only the training images, and do not modify the validation images. This is handled by default in the fastai library.
item_tfms=Resize(128, ResizeMethod.Squish)) item_tfms=Resize(128, ResizeMethod.Pad, pad_mode='zeros') item_tfms=RandomResizedCrop(128, min_scale=0.3) - 30% of the image area is zoomed by specifying 0.3
Fastai library provides a standard set of augmentations through the aug_transforms function. It can be applied in batch if the image size is uniform, which will save a lot of training time.
tfms = aug_transforms(do_flip = True, flip_vert = False, mult=2.0)
DataLoaders class in fastai is very handy to store various objects used for training and validating a model. If you want to customize the objects to be used during training, then you can use the DataBlock class in conjunction with the DataLoaders.
data= ImageDataLoaders.from_folder(path,train = "train", valid_pct=0.2, item_tfms=Resize(128), batch_tfms=tfms, bs = 30, num_workers = 4)
If you have the image labels defined in a metafile, then DataBlock can be used to divide the images and labels into two different blocks as shown in the below code snippet. Use the defined datablock with the dataloaders function to access the images.
Data = DataBlock( blocks=(ImageBlock, CategoryBlock), get_items=get_image_files, splitter=RandomSplitter(valid_pct=0.2, seed=42), get_y=parent_label, item_tfms=Resize(128)) dls = Data.dataloaders(path)
For training this image dataset a pre-trained CNN model is used. This approach is known as transfer learning. Jeremy recommends using pre-trained models for faster training and better accuracy. This is especially applicable to computer vision problems.
learn = cnn_learner(data, resnet34, metrics=error_rate) learn.fine_tune(4)
ResNet34 architecture is used and the result validated on the error rate. As a pre-trained model is used for training, a fine-tune method is used rather than fitting the model.
You can run more epochs and see how the model performs. Choose the right number of epochs to avoid overfitting. Instead of error_rate, you can try accuracy (accuracy=1-error rate) for validating the model performance. Both are used to validate the output of the model. In this example, 20% of the data is reserved for validation. So the model will train only on 80% of the data. This is a very crucial step to check the performance of any machine learning model. You can also run this model by changing the ResNet layers (options are 18, 50, 101, and 152). This again might result in overfitting, unless you have a large dataset that will yield accurate results.
Validate Model Performance
Model performance can be validated in different ways. One of the popular methods is using the confusion matrix. Diagonal values of the matrix indicate correct predictions for each class, whereas other cell values indicate a number of wrong predictions.
interp = ClassificationInterpretation.from_learner(learn) interp.plot_confusion_matrix()
Fastai provides a useful function to see the wrong predictions based on the highest loss rate. The output of this function indicates the predicted label, target label, loss rate, and the probability value for each image. High probability indicates a high confidence level by the model. It varies between 0 and 1. A high loss rate indicates how bad the model performance is.
interp.plot_top_losses(5, nrows=1, figsize = (25,5))
Another awesome Fastai function, ImageClassifierCleaner (a GUI) helps to clean the faulty images by deleting them or renaming their labels. This greatly helps in data preprocessing resulting in improved model accuracy. Jeremy suggests running this function after doing basic training on the images, as this gives an idea of the kind of anomalies in the dataset.
from fastai.vision.widgets import * cleaner = ImageClassifierCleaner(learn) cleaner
Save and Deploy Model
Once you have trained the model and satisfied with the outcome, its time to deploy the model. For deploying the model into production you need to save your model architecture and the parameters it’s trained on. For this, the export method is used. The exported model is saved as a PKL file, which is a file created by pickle (a Python module).
Create an inference learner from the exported file that can be used to deploy your model as an application. The inference learner predicts the output for new images one at a time. The prediction returns three parameters: the predicted category, index of the predicted category, and the probabilities of each category.
learn_inf = load_learner(path/'export.pkl') learn_inf.predict("img")
(‘noCovid’, tensor(1), tensor([5.4443e-05, 9.9995e-01])) – prediction
There are several ways to create a web application for deploying your model. One of the simplest methods is to create the required objects for your application in Jupyter notebook using IPython widgets, which are GUI components.
from fastai.vision.widgets import * btn_upload = widgets.FileUpload() out_pl = widgets.Output() lbl_pred = widgets.Label()
Once you design your application elements, use Voila that runs Jupyter notebooks like a web application to deploy your model. It removes all the cell inputs, and only shows the model output. To view your notebook as a Voilà web application, replace the word “notebooks” in your browser’s URL with: “voila/render”. Voila has to be installed and executed in the same notebook that contains your trained model and the IPython widgets.
!pip install voila !jupyter serverextension enable voila --sys-prefix
That’s it, you have built and deployed a cool image classifier application using fastai library in under eight steps! This is just the tip of the iceberg that I have shown in this article. There are many more fastai components for various deep learning use cases related to NLP and computer vision that you can explore. Below are links for the fast.ai learning resources, and my git repo that has the code and images for the image classifier explained in this article. Happy Learning!
Covid19 X-ray image classifier – Contains the complete code and dataset discussed in the article
https://github.com/fastai/fastbook – Covers all the lessons taught in the fast.ai course
https://docs.fast.ai/ – Covers complete fastai API documentation
https://forums.fast.ai/ – Fast.ai community forum