FastAI in R: How to Train Deep Learning Models with FastAI

[This article was first published on Tag: r - Appsilon | Enterprise R Shiny Dashboards, and kindly contributed to R-bloggers]. (You can report issue about the content on this page here)
Want to share your content on R-bloggers? click here if you have a blog, or here if you don't.

It seems like it’s getting easier and easier to get into deep learning, at least as a practitioner. Packages like FastAI are available to masses for both Python and R, and in some simple scenarios they seem to provide a no-brainer solution for training deep learning models with as few lines of code as possible.

Today we’ll dive into FastAI in R, and you’ll learn how to train an image classification model from scratch. Well, not from scratch, but with a pretrained network available in FastAI, which yields high accuracy with only a few training epochs. But first, we’ll go over FastAI in general, so you can know what it can and what it can’t do.

This repository we prepared contains three examples of how FastAI can be leveraged from the perspective of an R user, with various degrees of involvement of Python code. You can find a brief presentation of the methods in our Fast AI in R blogpost. Here we will explain the steps in some more detail.

Looking to build a custom Deep Learning Model on top of an existing architecture? Look no further than Transfer Learning.

Table of contents:


What is FastAI and Why Should You Care?

FastAI is an open-source library for deep learning that makes it easy to train highly-accurate neural network models. Needless to say, it moves the barrier of entry for practitioners even lower, which is a good thing. The library is built on top of PyTorch and provides a suite of high-level API functions for building and evaluating models in no time.

Since FastAI is built on top of PyTorch, it has native Python support. But what about R? Well, there’s a wrapper package we’ll go over shortly, and it can do anything the Python version can since it mainly executes Python code below the surface.

So, what can you do with FastAI? The library has a range of tools that make it easy to work with images, text, tabular data, time series, audio, GANs, and much more. There are also convenient functions built in for downloading various datasets, so you don’t have to search the web and preprocess the data manually. Neat!

Who’s Behind FastAI?

The founder of FastAI, Jeremy Howard, needs no introduction. He’s made significant contributions to the field of deep learning, was CEO of Kaggle for a time, and is currently a faculty member at the University of San Francisco and the University of the Witwatersrand in South Africa.

Howard co-founded FastAI with Rachel Thomas, who is also a founding director of the Center for Applied Data Ethics at the University of San Francisco. She was selected by Forbes magazine as one of the 20 most incredible women in artificial intelligence.

In short, this means FastAI has more than solid foundations, and you can expect the library to be built and documented well.

Want to learn more about FastAI? Here are some useful links:

FastAI in R – How to Install FastAI

Note: As of April 2023, we had trouble installing the R version of FastAI on Apple Silicon Macbooks. The procedure you’re about to see works on any Intel Mac or Windows/Linux PC but isn’t guaranteed to work on M1/M2 devices.

Installing the R version of FastAI is a bit more manual and tedious than the Python version. In Python, one pip-install command is enough, but for R, it’s a different story. You first have to install Miniconda, then the reticulate package, create a virtual environment, and then install FastAI from GitHub.

You don’t need to worry since we’ll guide you through every step.

Install Miniconda and Create a Virtual Environment

Miniconda is a lightweight version of Anaconda Python distribution, which is a popular package and environment manager for Python. As it turns out, you need to install Miniconda first if you want to use a FastAI wrapper in R.

But even before Miniconda, you have to install R’s reticulate package. It provides an interface between R and Python, allowing you to integrate code written in both languages on the same project. If you’re a data scientist using both R and Python, reticulate is the package you should consider learning.

The following code snippet uses the R console to install reticulate, and then uses the package to install Miniconda on your system:

install.pakcages("reticulate")

reticulate::install_miniconda()

Here’s the output you should see:

Image 1 - Installing Miniconda with Reticulate

Image 1 – Installing Miniconda with Reticulate

Once installed, you can create a new virtual environment. We’ve named ours r-reticulate, but feel free to be a bit more creative:

reticulate::conda_create("r-reticulate")
Image 2 - Creating a virtual environment with Reticulate

Image 2 – Creating a virtual environment with Reticulate

Want to learn more about R and Python integration with Reticulate? We have just the article for you.

You now have both reticulate and a virtual environment configured, so the next step is to install FastAI.

Install and Configure FastAI in R

The recommended way to install FastAI in R is by getting it straight from the GitHub repo. Doing so requires an additional R package – devtools. Here’s the R shell command to install that package first, and then to install FastAI from a repo:

install.packages("devtools")

devtools::install_github("eagerai/fastai")

You should see something similar to this in the console output:

Image 3 - Installing the R package from GitHub with devtools

Image 3 – Installing the R package from GitHub with devtools

You’d think that’s all, but you’d be wrong. The R wrapper package might be installed, but that doesn’t mean the underlying Python library and its dependencies are installed and configured correctly.

Run these two commands to activate the previously configured r-reticulate virtual environment and to install Python dependencies for FastAI:

reticulate::use_condaenv("r-reticulate", required = TRUE)
fastai::install_fastai(gpu = FALSE, cuda_version = "11.6", overwrite = FALSE)

The last command will pull a good amount of Python libraries, as shown in the following image:

Image 4 - Installing FastAI Python dependencies

Image 4 – Installing FastAI Python dependencies

Sit back because this will take a couple of minutes. Done? Great, join us in the following section.

How to Train an Image Classification Model with FastAI in R

The difficult part of this article was installing FastAI in R. That’s over, which means you can now fully enjoy the high-level API functions FastAI has to offer.

We’ll start by downloading and exploring a dataset for image classification.

Data Gathering and Exploration

The process of data gathering typically boils down to searching the web for adequate pre-made datasets at best or creating the dataset from scratch at worst. Depending on the problem you’re trying to solve, this step can typically take from minutes to months or even years in some domain-specific problems.

Luckily for us, that’s not the case with FastAI. There are dozens of built-in convenience functions that will download the data for you, and even automatically set the appropriate directory structure.

But first, the library imports. Stick these two at the top of your R script:

library(magrittr)
library(fastai)

We’ll use the Oxford-IIT Pet Dataset which has 37 categories of pet images with roughly 200 images for each class. It may seem this is not enough for deep learning, and indeed, a model trained from scratch on this data will likely generalize poorly.

The good news is – FastAI allows us to leverage transfer learning without breaking a sweat.

But first, let’s download the dataset. The following code snippet downloads the Oxford-IIT Pet dataset:

# Download data
URLs_PETS()

If the function call doesn’t work for you, download and extract the .tgz file from this download link. Either way, you’re ready to move on to the next step.

Now you have to define paths to the dataset, image, and annotation folders. The built-in get_image_files() function automatically scans the image directory and ensures they are formatted correctly. If there are no errors, the function returns all of the images in an array.

The following code snippet defines paths to all folders, loads the images, and prints the contents of the first one:

# Folder paths
path <- "/Users/dradecic/Desktop/oxford-iiit-pet"
path_anno <- "/Users/dradecic/Desktop/oxford-iiit-pet/annotations"
path_img <- "/Users/dradecic/Desktop/oxford-iiit-pet/images"
fnames <- get_image_files(path_img)

# One example
fnames[1]

Here’s what you should see in the R console:

Image 5 - Path to a single image

Image 5 – Path to a single image

We’re on the right track, and the next step is to load these images with the DataLoader class. This one will load all of the JPG files in batches of 10, and resize them to a square size of 460×460 pixels. It also uses the ImageNet normalization values for red, green, and blue image channels.

Finally, the code snippet plots one batch of images with their respective class names so we can see what we’re dealing with:

# DataLoader
dls = ImageDataLoaders_from_name_re(
  path = path,
  fnames = fnames,
  pat = "(.+)_\\d+.jpg$",
  item_tfms = Resize(size = 460),
  bs = 10,
  batch_tfms = list(Normalize_from_stats(imagenet_stats()))
)

dls %>%
  show_batch()

The images in the batch are random, but expect to see something similar to this:

Image 6 - A random batch of images

Image 6 – A random batch of images

The dataset is now loaded correctly, which means we can proceed to model training.

A Custom Pretrained Neural Network Architecture

A big part of why FastAI in R works so great on a small dataset is transfer learning. Put simply, this technique leverages models trained on large, generic datasets, where especially the initial layers of the model learn to recognise patterns common in almost all image data (such as edges, corners, gradients of color etc.). This valuable knowledge serves as a foundation to learning specifics of a new (so called “downstream”) task. Apparently, for many cases which fall close to the standard problems solved by computer vision, even small datasets are enough to finetune the model to a given task..

There are numerous pre-built architectures you can use, many implemented directly in FastAI, and even more available when using packages like timm.

If you’re into graphs, the following one describes the structure of one of the simplest choices the ResNet-18 architecture:

Image 7 - ResNet-18 architecture (Credits- www.researchgate.net)

Image 7 – ResNet-18 architecture (Credits- www.researchgate.net)

The following code snippet instantiates a cnn_learner, which takes in a DataLoader, model architecture, and a list of metrics you want to keep track of while training:

# Model architecture
learn = cnn_learner(dls = dls, arch = resnet18(), metrics = list(accuracy, error_rate()))

Once you run the above code snippet, you should see the download progress bar in the R console. This just means R is downloading the ResNet-18 network:

Image 8 - Downloading a ResNet-18 model

Image 8 – Downloading a ResNet-18 model

Once done, you can proceed with model training. Let’s do that next.

Training a Model with FastAI in R

We don’t need to train the model for long since it leverages a pretrained architecture. A couple of epochs should be enough. The following code snippet trains the model on our custom dataset for 5 epochs:

# Fit
learn %>%
  fit_one_cycle(n_epoch = 5)

Depending on your hardware, this might take a while, from seconds per epoch to minutes. You’ll see the R console output updated with each epoch, and it will look similar to this after the training finishes:

Image 9 - FastAI in R training progress

Image 9 – FastAI in R training progress

In addition, you’ll see your metrics on training and validation sets plotted automatically in the Charts panel of RStudio. Here’s what it looks like on our end:

Image 10 - Training and validation metrics during training

Image 10 – Training and validation metrics during training

You can see why we say the metrics are hit and miss. Both training and validation loss are decreasing, but accuracy and error rates seem static over time. The accuracy is reported to be only around 3%, which is far from the truth, as you’ll see in the following section.

Evaluating Model Predictions

The easiest and also visually most appealing way to evaluate a classification algorithm is through a confusion matrix. It’s an NxN matrix that shows correct classification on the top-left to bottom-right diagonal, false positives in the upper triangle, and false negatives on the bottom triangle.

The following code snippet calculates the confusion matrix and plots it using the highcharter R package. Install it if you don’t have it already (install.packages("highcharter")):

# Confusion matrix
library(highcharter)

cm <- learn %>%
  get_confusion_matrix()

hchart(cm, label = TRUE) %>%
  hc_yAxis(title = list(text = "Actual")) %>%
  hc_xAxis(title = list(text = "Predicted"), labels = list(rotation = - 90))

This is the resulting visualization:

Image 11 - Confusion matrix

Image 11 – Confusion matrix

This one is a bit difficult to look at due to 37 classes, but the main diagonal looks great. There are some misclassifications, but overall nothing we should worry about. After all, we’ve trained the model on one of the simplest architectures for only 5 epochs!

FastAI in R also has a convenient function that allows you to visualize top losses, or instances your model had the hardest time predicting. Here’s how to use it:

# Top losses
interp = ClassificationInterpretation_from_learner(learn = learn)
interp %>%
  plot_top_losses(k = 9, figsize = c(15, 11))

And this is what it outputs in our case:

Image 12 - Top losses of our classification model

Image 12 – Top losses of our classification model

In the example of the first image, the model predicted the class of newfoundland while the actual class was american_pit_bull_terrier.

And that’s how easy it is to use FastAI in R to train highly-accurate image classification models. Let’s make a short recap next.


Summing up FastAI in R

If you’re working on a deep learning problem that has to do with tabular data, time series, image classification, NLP, and even GANs, here is some good news for you – You don’t have to start from scratch. Libraries like FastAI do all the heavy lifting for you and provide a plethora of convenience functions for training and evaluating deep learning models. The best thing – FastAI is available for both Python and R, so you won’t have to change tech stacks in order to use it.

Today you’ve learned how to train an image classification model with FastAI and transfer learning, and it took us maybe 15 lines of code to train a highly-accurate model on a stupidly small dataset. That’s the power of libraries such as FastAI, so make sure to leverage it in your next machine learning project.

Would you like to see another example of FastAI in R? Please let us know in the comment section below, or reach out on Twitter – @appsilon. We’d love to hear from you.

FastAI for detecting Solar Panels from Orthophotos? We did the research, you do the reading.

The post appeared first on appsilon.com/blog/.

To leave a comment for the author, please follow the link and comment on their blog: Tag: r - Appsilon | Enterprise R Shiny Dashboards.

R-bloggers.com offers daily e-mail updates about R news and tutorials about learning R and many other topics. Click here if you're looking to post or find an R/data-science job.
Want to share your content on R-bloggers? click here if you have a blog, or here if you don't.

Never miss an update!
Subscribe to R-bloggers to receive
e-mails with the latest R posts.
(You will not see this message again.)

Click here to close (This popup will not appear again)