How to use Resnet for image classification in Pytorch

This recipe helps you use Resnet for image classification in Pytorch

Recipe Objective

How to use Resnet for image classification in Pytorch?

The resnet are nothing but the residual networks which are made for deep neural networks training making the training easy of neural networks. These are easy for optimization and can gain accuracy from considerably increased depth. The dataset that we are going to use are an Image dataset which consist of images of ants and bees. The dataset is divided into two parts training and validation. In which there are 120 training images of the ants and bees in the training data and 75 validation images present into the validation data.

PyTorch vs Tensorflow - Which One Should You Choose For Your Next Deep Learning Project ?

Step 1 - Import library

from __future__ import print_function, division
import torch
import torch.nn as nn
import torch.optim as optim
from torch.optim import lr_scheduler
import numpy as np
import torchvision from torchvision
import datasets, models, transforms
import matplotlib.pyplot as plt
import time
import os
import copy
plt.ion() # This is the interactive mode

Step 2 - Load the data

transforming_hymen_data = {
'train_data': transforms.Compose([
                                 transforms.RandomResizedCrop(224),
                                 transforms.RandomHorizontalFlip(),
                                 transforms.ToTensor(),
                                 transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225]) ]),
'validation_data': transforms.Compose([
    transforms.Resize(256),
    transforms.CenterCrop(224),
    transforms.ToTensor(),
    transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225])
]),
}
directory_data = '/content/drive/MyDrive/Data sets/Pytorch_Exercise_50_hymenoptera_data'
datasets_images = {x: datasets.ImageFolder(os.path.join(directory_data, x),
                                           transforming_hymen_data[x])
                   for x in ['train_data', 'validation_data']}
loaders_data = {x: torch.utils.data.DataLoader(datasets_images[x], batch_size=4, shuffle=True, num_workers=4)
               for x in ['train_data', 'validation_data']}
sizes_datasets = {x: len(datasets_images[x]) for x in ['train_data', 'validation_data']}
class_names = datasets_images['train_data'].classes
device = torch.device("cuda:0" if torch.cuda.is_available() else "cpu")

Here in the above we are loading our data, in the first we are transforming our data which is nothing but Data augmentation and normalization for training dataset and only normalization for validation dataset, and for that we are defining some the parameters such as RandomResizedCrop, normalize, RandomHorizontalFlip, etc and all these parameters we are mentioning under compose. The parameters are defined for both the training and validation dataset. Then we are loading our data and storing it into variable called "directory_data". After that we are loading our images which are present in the data into a variable called "datasets_images", then using dataloaders for loading data, checking the sizes or shape of our datasets i.e train_data and validation_data then classes which are present in our datasets then we are defining the device on which we have to run our model.

Step 3 - Visualizing our data

def visualize_data(input, title=None):
    input = input.numpy().transpose((1, 2, 0))
    mean = np.array([0.485, 0.456, 0.406])
    std = np.array([0.229, 0.224, 0.225])
    input = std * input + mean
    input = np.clip(input, 0, 1)
    plt.imshow(input)
    if title is not None:
       plt.title(title)
    plt.pause(0.001) ## Here we are pausing a bit so that plots are updated
inputs_data, classes = next(iter(loaders_data['train_data']))
## This is the code for getting a batch of training data
out = torchvision.utils.make_grid(inputs_data)
## Here we are making a grid from batch
visualize_data(out, title=[class_names[x] for x in classes])

Here are we are visualizing our data which consist of images, the visualization is done because to understand data augmentation.

Step 4 - Training the model

def model_training(res_model, criterion, optimizer, scheduler, number_epochs=25):
    since = time.time()
    best_resmodel_wts = copy.deepcopy(res_model.state_dict())
    best_accuracy = 0.0
    for epochs in range(number_epochs):
        print('Epoch {}/{}'.format(epochs, number_epochs - 1))
        print('-' * 10)
        for phase in ['train_data', 'validation_data']: ## Here each epoch is having a training and validation phase
            if phase == 'train_data':
               res_model.train() ## Here we are setting our model to training mode
            else:
               res_model.eval() ## Here we are setting our model to evaluate mode

            running_loss = 0.0
            running_corrects = 0

            for inputs, labels in loaders_data[phase]: ## Iterating over data.
                inputs = inputs.to(device)
                labels = labels.to(device)

                optimizer.zero_grad() ## here we are making the gradients to zero

                with torch.set_grad_enabled(phase == 'train_data'): ## forwarding and then tracking the history if only in train
                     outputs = res_model(inputs)
                     _, preds = torch.max(outputs, 1)
                     loss = criterion(outputs, labels)

                     if phase == 'train': # backward and then optimizing only if it is in training phase
                         loss.backward()
                         optimizer.step()

                running_loss += loss.item() * inputs.size(0)
                running_corrects += torch.sum(preds == labels.data)
            if phase == 'train':
                scheduler.step()

             epoch_loss = running_loss / sizes_datasets[phase]
             epoch_acc = running_corrects.double() / sizes_datasets[phase]

             print('{} Loss: {:.4f} Acc: {:.4f}'.format(phase, epoch_loss, epoch_acc))

             if phase == 'val' and epoch_acc > best_acc: ## deep copy the model
                 best_accuracy = epoch_acc
                 best_resmodel_wts = copy.deepcopy(res_model.state_dict())

         print()

     time_elapsed = time.time() - since
     print('Training complete in {:.0f}m {:.0f}s'.format(time_elapsed // 60, time_elapsed % 60))
     print('Best val Acc: {:4f}'.format(best_accuracy))

     # load best model weights
     res_model.load_state_dict(best_resmodel_wts)
     return res_model

Step 5 - Visualizing our predictions

def model_visualization(res_model, num_images=6):
    was_training = res_model.training
    res_model.eval()
    images_so_far = 0
    fig = plt.figure()
    with torch.no_grad():
        for i, (inputs, labels) in enumerate(loaders_data['validation_data']):
            inputs = inputs.to(device)
            labels = labels.to(device)
            outputs = res_model(inputs)
            _, preds = torch.max(outputs, 1)
        for j in range(inputs.size()[0]):
            images_so_far += 1
            ax = plt.subplot(num_images//2, 2, images_so_far)
            ax.axis('off')
            ax.set_title('predicted: {}'.format(class_names[preds[j]]))
            visualize_data(inputs.cpu().data[j])

            if images_so_far == num_images:
               res_model.train(mode=was_training)
               return res_model.train(mode=was_training)

Step 6 - Finetunning the convet

finetune_model = models.resnet18(pretrained=True)
num_ftrs = finetune_model.fc.in_features
finetune_model.fc = nn.Linear(num_ftrs, 2)
finetune_model = finetune_model.to(device)
criterion = nn.CrossEntropyLoss()
finetune_optim = optim.SGD(finetune_model.parameters(), lr=0.001, momentum=0.9)

Here in the above we are finetunning the convet in which the size of each output sample is set to 2 and then alternatively it can be generalized to nn.Linear(num_ftrs, len(class_names)). In the finetune_optim we are observing that all the parameters are being optimized. At last deccaying the LR by a factor of 0.1 at an every 7 epochs.

Step 7 - Training and evaluation

finetune_model = model_training(finetune_model, criterion, finetune_optim, exp_lr_scheduler, number_epochs=25)

Epoch 0/24
----------
train_data Loss: 0.7878 Acc: 0.4180
validation_data Loss: 0.8192 Acc: 0.4706

Epoch 1/24
----------
train_data Loss: 0.7921 Acc: 0.3934
validation_data Loss: 0.8287 Acc: 0.4641

Epoch 2/24
----------
train_data Loss: 0.7782 Acc: 0.4344
validation_data Loss: 0.8385 Acc: 0.4706

Epoch 3/24
----------
train_data Loss: 0.7935 Acc: 0.4221
validation_data Loss: 0.8349 Acc: 0.4379

Epoch 4/24
----------
train_data Loss: 0.8029 Acc: 0.3770
validation_data Loss: 0.8396 Acc: 0.4641

Epoch 5/24
----------
train_data Loss: 0.7802 Acc: 0.4262
validation_data Loss: 0.7846 Acc: 0.5033

Epoch 6/24
----------
train_data Loss: 0.7805 Acc: 0.4508
validation_data Loss: 0.7927 Acc: 0.4902

Epoch 7/24
----------
train_data Loss: 0.7976 Acc: 0.3852
validation_data Loss: 0.8078 Acc: 0.4967

Epoch 8/24
----------
train_data Loss: 0.7740 Acc: 0.4385
validation_data Loss: 0.8175 Acc: 0.4837

Epoch 9/24
----------
train_data Loss: 0.7597 Acc: 0.4426
validation_data Loss: 0.8121 Acc: 0.4641

Epoch 10/24
----------
train_data Loss: 0.7910 Acc: 0.4426
validation_data Loss: 0.7881 Acc: 0.4641

Epoch 11/24
----------
train_data Loss: 0.7650 Acc: 0.4590
validation_data Loss: 0.8069 Acc: 0.4902

Epoch 12/24
----------
train_data Loss: 0.7776 Acc: 0.3934
validation_data Loss: 0.8194 Acc: 0.4641

Epoch 13/24
----------
train_data Loss: 0.7966 Acc: 0.3893
validation_data Loss: 0.8287 Acc: 0.4902

Epoch 14/24
----------
train_data Loss: 0.7817 Acc: 0.4139
validation_data Loss: 0.8161 Acc: 0.4641

Epoch 15/24
----------
train_data Loss: 0.7571 Acc: 0.4467
validation_data Loss: 0.8001 Acc: 0.4902

Epoch 16/24
----------
train_data Loss: 0.7642 Acc: 0.4795
validation_data Loss: 0.7982 Acc: 0.5163

Epoch 17/24
----------
train_data Loss: 0.7627 Acc: 0.4713
validation_data Loss: 0.8273 Acc: 0.4967

Epoch 18/24
----------
train_data Loss: 0.7718 Acc: 0.4631
validation_data Loss: 0.8144 Acc: 0.4902

Epoch 19/24
----------
train_data Loss: 0.7780 Acc: 0.3852
validation_data Loss: 0.7904 Acc: 0.4837

Epoch 20/24
----------
train_data Loss: 0.7849 Acc: 0.4713
validation_data Loss: 0.8213 Acc: 0.4771

Epoch 21/24
----------
train_data Loss: 0.7891 Acc: 0.4139
validation_data Loss: 0.8145 Acc: 0.4510

Epoch 22/24
----------
train_data Loss: 0.7923 Acc: 0.3934
validation_data Loss: 0.8298 Acc: 0.4575

Epoch 23/24
----------
train_data Loss: 0.7861 Acc: 0.4180
validation_data Loss: 0.8187 Acc: 0.4706

Epoch 24/24
----------
train_data Loss: 0.7950 Acc: 0.4303
validation_data Loss: 0.8257 Acc: 0.4444

Training complete in 15m 41s
Best val Acc: 0.000000

Step 8 - Visualizing the final results

model_visualization(finetune_model)

What Users are saying..

profile image

Ed Godalle

Director Data Analytics at EY / EY Tech
linkedin profile url

I am the Director of Data Analytics with over 10+ years of IT experience. I have a background in SQL, Python, and Big Data working with Accenture, IBM, and Infosys. I am looking to enhance my skills... Read More

Relevant Projects

Build a Multi ClassText Classification Model using Naive Bayes
Implement the Naive Bayes Algorithm to build a multi class text classification model in Python.

PyCaret Project to Build and Deploy an ML App using Streamlit
In this PyCaret Project, you will build a customer segmentation model with PyCaret and deploy the machine learning application using Streamlit.

Recommender System Machine Learning Project for Beginners-3
Content Based Recommender System Project - Building a Content-Based Product Recommender App with Streamlit

Loan Eligibility Prediction in Python using H2O.ai
In this loan prediction project you will build predictive models in Python using H2O.ai to predict if an applicant is able to repay the loan or not.

Langchain Project for Customer Support App in Python
In this LLM Project, you will learn how to enhance customer support interactions through Large Language Models (LLMs), enabling intelligent, context-aware responses. This Langchain project aims to seamlessly integrate LLM technology with databases, PDF knowledge bases, and audio processing agents to create a comprehensive customer support application.

Build a Text Generator Model using Amazon SageMaker
In this Deep Learning Project, you will train a Text Generator Model on Amazon Reviews Dataset using LSTM Algorithm in PyTorch and deploy it on Amazon SageMaker.

MLOps using Azure Devops to Deploy a Classification Model
In this MLOps Azure project, you will learn how to deploy a classification machine learning model to predict the customer's license status on Azure through scalable CI/CD ML pipelines.

Topic modelling using Kmeans clustering to group customer reviews
In this Kmeans clustering machine learning project, you will perform topic modelling in order to group customer reviews based on recurring patterns.

Build CI/CD Pipeline for Machine Learning Projects using Jenkins
In this project, you will learn how to create a CI/CD pipeline for a search engine application using Jenkins.

End-to-End ML Model Monitoring using Airflow and Docker
In this MLOps Project, you will learn to build an end to end pipeline to monitor any changes in the predictive power of model or degradation of data.