Transfer Learning with PyTorch
By: Dario Radečić
Tags: Programming, Deep Learning, Python, Data Science, Machine Learning

Dataset download and basic preparation

Let’s start with imports. Here we have the usual suspects like Numpy, Pandas, and Matplotlib, but also our favorite deep learning library — Pytorch — followed by everything it has to offer.

import os

import numpy as np

import pandas as pd

import matplotlib.pyplot as plt

from datetime import datetime import torch

import torch.nn as nn

import torch.nn.functional as F

from torch.utils.data import DataLoader

from torchvision.utils import make_grid

from torchvision import models, transforms, datasets

We’re writing this code in Colab, or Colab Pro to be more precise, so we’ll utilize the power of GPUs for training. If you don’t know what Colab is, or wondering is it worth it to upgrade to the Pro version, feel free to check these articles:

Because we’re training on the GPU and that might not be the case for you, we need a robust way for handling this. Here’s a standard approach:

device = torch.device(‘cuda:0’ if torch.cuda.is_available() else ‘cpu’)

device >>> device(type=’cuda’, index=0)

It should say something like type=’cpu’ if you are training on the CPU, but as Colab is free there's no need to ever do so.

Now onto the dataset. We’ll be using Dog or Cat dataset for this purpose. It has a plethora of images of various sizes, something which we'll handle down the road. Right now we need to download and unzip it. Here’s how:

After a minute or so, depending on your internet speed, the dataset is ready to use. Now we can declare it as a data directory — not required but will save us a bit time down the road.

DIR_DATA = ‘/content/data/dogscats/’

Data Preparation

The first part of the first part is now done. Next, we have to apply some transformations to training and validation subsets, and then load the transformed data with DataLoaders. Here are the transformations we applied:

Random rotation

Random horizontal flip

Resizing to 224x224 — required for pre-trained architectures

Conversion to Tensor

Normalization

Here’s the code:

train_transforms = transforms.Compose([

transforms.RandomRotation(10),

transforms.RandomHorizontalFlip(p=0.5),

transforms.Resize(224),

transforms.CenterCrop((224, 224)),

transforms.ToTensor(),

transforms.Normalize(

mean=[0.485, 0.456, 0.406],

std=[0.229, 0.224, 0.225]

)

]) valid_transforms = transforms.Compose([

transforms.Resize(224),

transforms.CenterCrop((224, 224)),

transforms.ToTensor(),

transforms.Normalize(

mean=[0.485, 0.456, 0.406],

std=[0.229, 0.224, 0.225]

)

])

Now we load the data with DataLoaders. This step is also straightforward and something you are probably familiar with:

train_data = datasets.ImageFolder(os.path.join(DIR_DATA, ‘train’), transform=train_transforms)

valid_data = datasets.ImageFolder(os.path.join(DIR_DATA, ‘valid’), transform=valid_transforms) torch.manual_seed(42)

train_loader = DataLoader(train_data, batch_size=64, shuffle=True)

valid_loader = DataLoader(valid_data, batch_size=64, shuffle=False) class_names = train_data.classes

class_names >>> ['cats', 'dogs']

If we were now to inverse-normalize a single batch and visualize it, we’d get this:

A quick look at the image above indicates our transformation work as expected.

The data preparation part is now done and in the next section, we’ll declare a custom CNN architecture, train it, and evaluate the performance.