Skip to content

Instantly share code, notes, and snippets.

@yongkangc
Last active June 9, 2021 16:15
Show Gist options
  • Save yongkangc/2c3edfbaa20e5210c369b36486fe78db to your computer and use it in GitHub Desktop.
Save yongkangc/2c3edfbaa20e5210c369b36486fe78db to your computer and use it in GitHub Desktop.
transfer learning cnn tutorial.ipynb
Display the source blob
Display the rendered blob
Raw
{
"nbformat": 4,
"nbformat_minor": 0,
"metadata": {
"accelerator": "GPU",
"colab": {
"name": "transfer learning cnn tutorial.ipynb",
"provenance": [],
"collapsed_sections": [],
"include_colab_link": true
},
"kernelspec": {
"display_name": "Python 3",
"name": "python3"
},
"language_info": {
"name": "python"
},
"widgets": {
"application/vnd.jupyter.widget-state+json": {
"77a6d1191b034c61a904fb11bd9e370f": {
"model_module": "@jupyter-widgets/controls",
"model_name": "HBoxModel",
"state": {
"_view_name": "HBoxView",
"_dom_classes": [],
"_model_name": "HBoxModel",
"_view_module": "@jupyter-widgets/controls",
"_model_module_version": "1.5.0",
"_view_count": null,
"_view_module_version": "1.5.0",
"box_style": "",
"layout": "IPY_MODEL_a07d0aec8dab4cbcadc4b76f942eab2b",
"_model_module": "@jupyter-widgets/controls",
"children": [
"IPY_MODEL_51297ef3fe5c4f5189bc3a2e232f45e4",
"IPY_MODEL_7c9e8994a3454cffa30fff59afb89bfa"
]
}
},
"a07d0aec8dab4cbcadc4b76f942eab2b": {
"model_module": "@jupyter-widgets/base",
"model_name": "LayoutModel",
"state": {
"_view_name": "LayoutView",
"grid_template_rows": null,
"right": null,
"justify_content": null,
"_view_module": "@jupyter-widgets/base",
"overflow": null,
"_model_module_version": "1.2.0",
"_view_count": null,
"flex_flow": null,
"width": null,
"min_width": null,
"border": null,
"align_items": null,
"bottom": null,
"_model_module": "@jupyter-widgets/base",
"top": null,
"grid_column": null,
"overflow_y": null,
"overflow_x": null,
"grid_auto_flow": null,
"grid_area": null,
"grid_template_columns": null,
"flex": null,
"_model_name": "LayoutModel",
"justify_items": null,
"grid_row": null,
"max_height": null,
"align_content": null,
"visibility": null,
"align_self": null,
"height": null,
"min_height": null,
"padding": null,
"grid_auto_rows": null,
"grid_gap": null,
"max_width": null,
"order": null,
"_view_module_version": "1.2.0",
"grid_template_areas": null,
"object_position": null,
"object_fit": null,
"grid_auto_columns": null,
"margin": null,
"display": null,
"left": null
}
},
"51297ef3fe5c4f5189bc3a2e232f45e4": {
"model_module": "@jupyter-widgets/controls",
"model_name": "FloatProgressModel",
"state": {
"_view_name": "ProgressView",
"style": "IPY_MODEL_5dc62900703e40e290721bd120a68e23",
"_dom_classes": [],
"description": "100%",
"_model_name": "FloatProgressModel",
"bar_style": "success",
"max": 553507836,
"_view_module": "@jupyter-widgets/controls",
"_model_module_version": "1.5.0",
"value": 553507836,
"_view_count": null,
"_view_module_version": "1.5.0",
"orientation": "horizontal",
"min": 0,
"description_tooltip": null,
"_model_module": "@jupyter-widgets/controls",
"layout": "IPY_MODEL_78feae83110f4338b4c051a2b10fcaa1"
}
},
"7c9e8994a3454cffa30fff59afb89bfa": {
"model_module": "@jupyter-widgets/controls",
"model_name": "HTMLModel",
"state": {
"_view_name": "HTMLView",
"style": "IPY_MODEL_8e1486498f1c4feba052179e02ed2864",
"_dom_classes": [],
"description": "",
"_model_name": "HTMLModel",
"placeholder": "​",
"_view_module": "@jupyter-widgets/controls",
"_model_module_version": "1.5.0",
"value": " 528M/528M [00:03<00:00, 166MB/s]",
"_view_count": null,
"_view_module_version": "1.5.0",
"description_tooltip": null,
"_model_module": "@jupyter-widgets/controls",
"layout": "IPY_MODEL_e0b12e0abf654ccd973027b841c08a01"
}
},
"5dc62900703e40e290721bd120a68e23": {
"model_module": "@jupyter-widgets/controls",
"model_name": "ProgressStyleModel",
"state": {
"_view_name": "StyleView",
"_model_name": "ProgressStyleModel",
"description_width": "initial",
"_view_module": "@jupyter-widgets/base",
"_model_module_version": "1.5.0",
"_view_count": null,
"_view_module_version": "1.2.0",
"bar_color": null,
"_model_module": "@jupyter-widgets/controls"
}
},
"78feae83110f4338b4c051a2b10fcaa1": {
"model_module": "@jupyter-widgets/base",
"model_name": "LayoutModel",
"state": {
"_view_name": "LayoutView",
"grid_template_rows": null,
"right": null,
"justify_content": null,
"_view_module": "@jupyter-widgets/base",
"overflow": null,
"_model_module_version": "1.2.0",
"_view_count": null,
"flex_flow": null,
"width": null,
"min_width": null,
"border": null,
"align_items": null,
"bottom": null,
"_model_module": "@jupyter-widgets/base",
"top": null,
"grid_column": null,
"overflow_y": null,
"overflow_x": null,
"grid_auto_flow": null,
"grid_area": null,
"grid_template_columns": null,
"flex": null,
"_model_name": "LayoutModel",
"justify_items": null,
"grid_row": null,
"max_height": null,
"align_content": null,
"visibility": null,
"align_self": null,
"height": null,
"min_height": null,
"padding": null,
"grid_auto_rows": null,
"grid_gap": null,
"max_width": null,
"order": null,
"_view_module_version": "1.2.0",
"grid_template_areas": null,
"object_position": null,
"object_fit": null,
"grid_auto_columns": null,
"margin": null,
"display": null,
"left": null
}
},
"8e1486498f1c4feba052179e02ed2864": {
"model_module": "@jupyter-widgets/controls",
"model_name": "DescriptionStyleModel",
"state": {
"_view_name": "StyleView",
"_model_name": "DescriptionStyleModel",
"description_width": "",
"_view_module": "@jupyter-widgets/base",
"_model_module_version": "1.5.0",
"_view_count": null,
"_view_module_version": "1.2.0",
"_model_module": "@jupyter-widgets/controls"
}
},
"e0b12e0abf654ccd973027b841c08a01": {
"model_module": "@jupyter-widgets/base",
"model_name": "LayoutModel",
"state": {
"_view_name": "LayoutView",
"grid_template_rows": null,
"right": null,
"justify_content": null,
"_view_module": "@jupyter-widgets/base",
"overflow": null,
"_model_module_version": "1.2.0",
"_view_count": null,
"flex_flow": null,
"width": null,
"min_width": null,
"border": null,
"align_items": null,
"bottom": null,
"_model_module": "@jupyter-widgets/base",
"top": null,
"grid_column": null,
"overflow_y": null,
"overflow_x": null,
"grid_auto_flow": null,
"grid_area": null,
"grid_template_columns": null,
"flex": null,
"_model_name": "LayoutModel",
"justify_items": null,
"grid_row": null,
"max_height": null,
"align_content": null,
"visibility": null,
"align_self": null,
"height": null,
"min_height": null,
"padding": null,
"grid_auto_rows": null,
"grid_gap": null,
"max_width": null,
"order": null,
"_view_module_version": "1.2.0",
"grid_template_areas": null,
"object_position": null,
"object_fit": null,
"grid_auto_columns": null,
"margin": null,
"display": null,
"left": null
}
}
}
}
},
"cells": [
{
"cell_type": "markdown",
"metadata": {
"id": "view-in-github",
"colab_type": "text"
},
"source": [
"<a href=\"https://colab.research.google.com/gist/ExtremelySunnyYK/2c3edfbaa20e5210c369b36486fe78db/transfer-learning-cnn-tutorial.ipynb\" target=\"_parent\"><img src=\"https://colab.research.google.com/assets/colab-badge.svg\" alt=\"Open In Colab\"/></a>"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "xX0gpUz6KDA-"
},
"source": [
"# Classify vehicles on emergency or non-emergency"
]
},
{
"cell_type": "code",
"metadata": {
"id": "q9Asqcq9krix"
},
"source": [
"# importing the libraries\n",
"import pandas as pd\n",
"import numpy as np\n",
"from tqdm import tqdm\n",
"\n",
"# for reading and displaying images\n",
"from skimage.io import imread\n",
"from skimage.transform import resize\n",
"import matplotlib.pyplot as plt\n",
"%matplotlib inline\n",
"\n",
"# for creating validation set\n",
"from sklearn.model_selection import train_test_split\n",
"\n",
"# for evaluating the model\n",
"from sklearn.metrics import accuracy_score\n",
"\n",
"# PyTorch libraries and modules\n",
"import torch\n",
"from torch.autograd import Variable\n",
"from torch.nn import Linear, ReLU, CrossEntropyLoss, Sequential, Conv2d, MaxPool2d, Module, Softmax, BatchNorm2d, Dropout\n",
"from torch.optim import Adam, SGD\n",
"\n",
"# torchvision for pre-trained models\n",
"from torchvision import models"
],
"execution_count": 1,
"outputs": []
},
{
"cell_type": "code",
"metadata": {
"colab": {
"base_uri": "https://localhost:8080/"
},
"id": "8ysn4Cahkx1Y",
"outputId": "5d4ffacb-0dcc-44b2-84fb-9d4149c325de"
},
"source": [
"!unzip /content/emergency_vs_non-emergency_dataset.zip"
],
"execution_count": 3,
"outputs": [
{
"output_type": "stream",
"text": [
"Archive: /content/emergency_vs_non-emergency_dataset.zip\n",
" End-of-central-directory signature not found. Either this file is not\n",
" a zipfile, or it constitutes one disk of a multi-part archive. In the\n",
" latter case the central directory and zipfile comment will be found on\n",
" the last disk(s) of this archive.\n",
"unzip: cannot find zipfile directory in one of /content/emergency_vs_non-emergency_dataset.zip or\n",
" /content/emergency_vs_non-emergency_dataset.zip.zip, and cannot find /content/emergency_vs_non-emergency_dataset.zip.ZIP, period.\n"
],
"name": "stdout"
}
]
},
{
"cell_type": "code",
"metadata": {
"id": "V-qcKCApkyVM"
},
"source": [
"# loading dataset\n",
"train = pd.read_csv('/content/emergency_vs_non-emergency_dataset/emergency_train.csv')\n",
"train.head()"
],
"execution_count": null,
"outputs": []
},
{
"cell_type": "markdown",
"metadata": {
"id": "25xJBlRAKdlj"
},
"source": [
"There are two columns in the .csv file:\n",
"\n",
"1. image_names: It represents the name of all the images in the dataset\n",
"2. emergency_or_no: It specifies whether that particular image belongs to the emergency or non-emergency class. 0 means that the image is a non-emergency vehicle and 1 represents an emergency vehicle"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "pxkHO6qlNHBN"
},
"source": [
"# Image Processing"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "hLrpOWp6LcY0"
},
"source": [
"There are 1,646 images in the dataset and they have been reshaped to (224,224,3) since VGG16 requires all the images in this particular shape. Let’s now visualize a few images from the dataset:"
]
},
{
"cell_type": "code",
"metadata": {
"id": "nEpkzsqjky0K",
"colab": {
"base_uri": "https://localhost:8080/",
"height": 244
},
"outputId": "fe387dff-dac2-4d98-f82c-44e14835d2b6"
},
"source": [
"# loading training images\n",
"train_img = []\n",
"for img_name in tqdm(train['image_names']):\n",
" # defining the image path\n",
" image_path = '/content/emergency_vs_non-emergency_dataset/images/' + img_name\n",
" # reading the image\n",
" img = imread(image_path)\n",
" # normalizing the pixel values\n",
" img = img/255\n",
" # print(img.shape)\n",
" # resizing the image to (224,224,3)\n",
" img = resize(img, output_shape=(224,224,3), mode='constant', anti_aliasing=True)\n",
" # converting the type of pixel to float 32\n",
" img = img.astype('float32')\n",
" # appending the image into the list\n",
" train_img.append(img)\n",
"\n",
"# converting the list to numpy array\n",
"train_x = np.array(train_img)\n",
"train_x.shape"
],
"execution_count": 5,
"outputs": [
{
"output_type": "error",
"ename": "NameError",
"evalue": "ignored",
"traceback": [
"\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
"\u001b[0;31mNameError\u001b[0m Traceback (most recent call last)",
"\u001b[0;32m<ipython-input-5-c55da8405885>\u001b[0m in \u001b[0;36m<module>\u001b[0;34m()\u001b[0m\n\u001b[1;32m 1\u001b[0m \u001b[0;31m# loading training images\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 2\u001b[0m \u001b[0mtrain_img\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;34m[\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 3\u001b[0;31m \u001b[0;32mfor\u001b[0m \u001b[0mimg_name\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mtqdm\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mtrain\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m'image_names'\u001b[0m\u001b[0;34m]\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 4\u001b[0m \u001b[0;31m# defining the image path\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 5\u001b[0m \u001b[0mimage_path\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;34m'/content/emergency_vs_non-emergency_dataset/images/'\u001b[0m \u001b[0;34m+\u001b[0m \u001b[0mimg_name\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
"\u001b[0;31mNameError\u001b[0m: name 'train' is not defined"
]
}
]
},
{
"cell_type": "code",
"metadata": {
"id": "tbWm96nrk0aO"
},
"source": [
"# Exploring the data\n",
"index = 10\n",
"plt.imshow(train_x[index])\n",
"if (train['emergency_or_not'][index] == 1):\n",
" print('It is an Emergency vehicle')\n",
"else:\n",
" print('It is a Non-Emergency vehicle')"
],
"execution_count": null,
"outputs": []
},
{
"cell_type": "markdown",
"metadata": {
"id": "clJi83ZlMIcN"
},
"source": [
"This is a police car and hence has a label of Emergency vehicle. Now store the target in a separate variable:"
]
},
{
"cell_type": "code",
"metadata": {
"id": "XOeETxzbk0e2"
},
"source": [
"# defining the target\n",
"train_y = train['emergency_or_not'].values"
],
"execution_count": null,
"outputs": []
},
{
"cell_type": "code",
"metadata": {
"id": "QOsSJwvbk0iH",
"colab": {
"base_uri": "https://localhost:8080/"
},
"outputId": "098f804e-fe82-4220-9c79-17b485b15b18"
},
"source": [
"# create validation set\n",
"train_x, val_x, train_y, val_y = train_test_split(train_x, train_y, test_size = 0.1, random_state = 13, stratify=train_y)\n",
"(train_x.shape, train_y.shape), (val_x.shape, val_y.shape)"
],
"execution_count": null,
"outputs": [
{
"output_type": "execute_result",
"data": {
"text/plain": [
"(((1481, 224, 224, 3), (1481,)), ((165, 224, 224, 3), (165,)))"
]
},
"metadata": {
"tags": []
},
"execution_count": 10
}
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "qdU3AaQpMo8v"
},
"source": [
"1,481 images in the training set and remaining 165 images in the validation set are converted into torch format:"
]
},
{
"cell_type": "code",
"metadata": {
"id": "5p421gVHk0k5",
"colab": {
"base_uri": "https://localhost:8080/"
},
"outputId": "6dd47c1a-6b58-46bd-bbd6-bcbe1c9befea"
},
"source": [
"# converting training images into torch format\n",
"train_x = train_x.reshape(1481, 3, 224, 224)\n",
"train_x = torch.from_numpy(train_x)\n",
"\n",
"# converting the target into torch format\n",
"train_y = train_y.astype(int)\n",
"train_y = torch.from_numpy(train_y)\n",
"\n",
"# shape of training data\n",
"train_x.shape, train_y.shape"
],
"execution_count": null,
"outputs": [
{
"output_type": "execute_result",
"data": {
"text/plain": [
"(torch.Size([1481, 3, 224, 224]), torch.Size([1481]))"
]
},
"metadata": {
"tags": []
},
"execution_count": 11
}
]
},
{
"cell_type": "code",
"metadata": {
"id": "3xOAvB1Jk0tw",
"colab": {
"base_uri": "https://localhost:8080/"
},
"outputId": "3d367c64-8719-4f30-a091-0c8ad51902bd"
},
"source": [
"# converting validation images into torch format\n",
"val_x = val_x.reshape(165, 3, 224, 224)\n",
"val_x = torch.from_numpy(val_x)\n",
"\n",
"# converting the target into torch format\n",
"val_y = val_y.astype(int)\n",
"val_y = torch.from_numpy(val_y)\n",
"\n",
"# shape of validation data\n",
"val_x.shape, val_y.shape"
],
"execution_count": null,
"outputs": [
{
"output_type": "execute_result",
"data": {
"text/plain": [
"(torch.Size([165, 3, 224, 224]), torch.Size([165]))"
]
},
"metadata": {
"tags": []
},
"execution_count": 12
}
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "5-r44wayMxrX"
},
"source": [
"# Vanilla CNN"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "5xLnz2WeNTrm"
},
"source": [
"Usually used as a benchmark"
]
},
{
"cell_type": "code",
"metadata": {
"id": "R9Y9kfHUk0wn"
},
"source": [
"class Net(Module): \n",
" def __init__(self):\n",
" super(Net, self).__init__()\n",
"\n",
" self.cnn_layers = Sequential(\n",
" # Defining a 2D convolution layer\n",
" Conv2d(3, 4, kernel_size=3, stride=1, padding=1),\n",
" BatchNorm2d(4),\n",
" ReLU(inplace=True),\n",
" MaxPool2d(kernel_size=2, stride=2),\n",
" # Defining another 2D convolution layer\n",
" Conv2d(4, 8, kernel_size=3, stride=1, padding=1),\n",
" BatchNorm2d(8),\n",
" ReLU(inplace=True),\n",
" MaxPool2d(kernel_size=2, stride=2),\n",
" )\n",
"\n",
" self.linear_layers = Sequential(\n",
" Linear(8 * 56 * 56, 2)\n",
" )\n",
"\n",
" # Defining the forward pass \n",
" def forward(self, x):\n",
" x = self.cnn_layers(x)\n",
" x = x.view(x.size(0), -1)\n",
" x = self.linear_layers(x)\n",
" return x"
],
"execution_count": null,
"outputs": []
},
{
"cell_type": "code",
"metadata": {
"id": "oBO_WAZsk0y2",
"colab": {
"base_uri": "https://localhost:8080/"
},
"outputId": "003160d9-3855-47fc-d496-28fe9e56acf7"
},
"source": [
"# defining the model\n",
"model = Net()\n",
"# defining the optimizer\n",
"optimizer = Adam(model.parameters(), lr=0.0001)\n",
"# defining the loss function\n",
"criterion = CrossEntropyLoss()\n",
"# checking if GPU is available\n",
"if torch.cuda.is_available():\n",
" model = model.cuda()\n",
" criterion = criterion.cuda()\n",
"\n",
"print(model)"
],
"execution_count": null,
"outputs": [
{
"output_type": "stream",
"text": [
"Net(\n",
" (cnn_layers): Sequential(\n",
" (0): Conv2d(3, 4, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))\n",
" (1): BatchNorm2d(4, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
" (2): ReLU(inplace=True)\n",
" (3): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)\n",
" (4): Conv2d(4, 8, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))\n",
" (5): BatchNorm2d(8, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\n",
" (6): ReLU(inplace=True)\n",
" (7): MaxPool2d(kernel_size=2, stride=2, padding=0, dilation=1, ceil_mode=False)\n",
" )\n",
" (linear_layers): Sequential(\n",
" (0): Linear(in_features=25088, out_features=2, bias=True)\n",
" )\n",
")\n"
],
"name": "stdout"
}
]
},
{
"cell_type": "code",
"metadata": {
"id": "FGCWVK-vky5o",
"colab": {
"base_uri": "https://localhost:8080/"
},
"outputId": "dfbec851-0691-489e-d6b1-184fb273ecdc"
},
"source": [
"# batch size of the model\n",
"batch_size = 128\n",
"\n",
"# number of epochs to train the model\n",
"n_epochs = 15\n",
"\n",
"for epoch in range(1, n_epochs+1):\n",
"\n",
" # keep track of training and validation loss\n",
" train_loss = 0.0\n",
" \n",
" permutation = torch.randperm(train_x.size()[0])\n",
"\n",
" training_loss = []\n",
" for i in tqdm(range(0,train_x.size()[0], batch_size)):\n",
"\n",
" indices = permutation[i:i+batch_size]\n",
" batch_x, batch_y = train_x[indices], train_y[indices]\n",
" \n",
" if torch.cuda.is_available():\n",
" batch_x, batch_y = batch_x.cuda(), batch_y.cuda()\n",
" \n",
" optimizer.zero_grad()\n",
" # in case you wanted a semi-full example\n",
" outputs = model(batch_x)\n",
" loss = criterion(outputs,batch_y)\n",
"\n",
" training_loss.append(loss.item())\n",
" loss.backward()\n",
" optimizer.step()\n",
" \n",
" training_loss = np.average(training_loss)\n",
" print('epoch: \\t', epoch, '\\t training loss: \\t', training_loss)"
],
"execution_count": null,
"outputs": [
{
"output_type": "stream",
"text": [
"100%|██████████| 12/12 [00:00<00:00, 12.19it/s]\n",
" 17%|█▋ | 2/12 [00:00<00:00, 19.26it/s]"
],
"name": "stderr"
},
{
"output_type": "stream",
"text": [
"epoch: \t 1 \t training loss: \t 0.8101396163304647\n"
],
"name": "stdout"
},
{
"output_type": "stream",
"text": [
"100%|██████████| 12/12 [00:00<00:00, 18.35it/s]\n",
" 17%|█▋ | 2/12 [00:00<00:00, 19.20it/s]"
],
"name": "stderr"
},
{
"output_type": "stream",
"text": [
"epoch: \t 2 \t training loss: \t 0.6502994944651922\n"
],
"name": "stdout"
},
{
"output_type": "stream",
"text": [
"100%|██████████| 12/12 [00:00<00:00, 18.30it/s]\n",
" 17%|█▋ | 2/12 [00:00<00:00, 19.07it/s]"
],
"name": "stderr"
},
{
"output_type": "stream",
"text": [
"epoch: \t 3 \t training loss: \t 0.6039342532555262\n"
],
"name": "stdout"
},
{
"output_type": "stream",
"text": [
"100%|██████████| 12/12 [00:00<00:00, 18.10it/s]\n",
" 17%|█▋ | 2/12 [00:00<00:00, 19.17it/s]"
],
"name": "stderr"
},
{
"output_type": "stream",
"text": [
"epoch: \t 4 \t training loss: \t 0.5880758116642634\n"
],
"name": "stdout"
},
{
"output_type": "stream",
"text": [
"100%|██████████| 12/12 [00:00<00:00, 18.25it/s]\n",
" 17%|█▋ | 2/12 [00:00<00:00, 19.44it/s]"
],
"name": "stderr"
},
{
"output_type": "stream",
"text": [
"epoch: \t 5 \t training loss: \t 0.5575701668858528\n"
],
"name": "stdout"
},
{
"output_type": "stream",
"text": [
"100%|██████████| 12/12 [00:00<00:00, 18.20it/s]\n",
" 17%|█▋ | 2/12 [00:00<00:00, 19.20it/s]"
],
"name": "stderr"
},
{
"output_type": "stream",
"text": [
"epoch: \t 6 \t training loss: \t 0.539302279551824\n"
],
"name": "stdout"
},
{
"output_type": "stream",
"text": [
"100%|██████████| 12/12 [00:00<00:00, 18.14it/s]\n",
" 17%|█▋ | 2/12 [00:00<00:00, 18.90it/s]"
],
"name": "stderr"
},
{
"output_type": "stream",
"text": [
"epoch: \t 7 \t training loss: \t 0.5262438108523687\n"
],
"name": "stdout"
},
{
"output_type": "stream",
"text": [
"100%|██████████| 12/12 [00:00<00:00, 18.22it/s]\n",
" 17%|█▋ | 2/12 [00:00<00:00, 19.05it/s]"
],
"name": "stderr"
},
{
"output_type": "stream",
"text": [
"epoch: \t 8 \t training loss: \t 0.5014186675349871\n"
],
"name": "stdout"
},
{
"output_type": "stream",
"text": [
"100%|██████████| 12/12 [00:00<00:00, 18.14it/s]\n",
" 17%|█▋ | 2/12 [00:00<00:00, 18.48it/s]"
],
"name": "stderr"
},
{
"output_type": "stream",
"text": [
"epoch: \t 9 \t training loss: \t 0.4785558332999547\n"
],
"name": "stdout"
},
{
"output_type": "stream",
"text": [
"100%|██████████| 12/12 [00:00<00:00, 18.19it/s]\n",
" 17%|█▋ | 2/12 [00:00<00:00, 18.91it/s]"
],
"name": "stderr"
},
{
"output_type": "stream",
"text": [
"epoch: \t 10 \t training loss: \t 0.46593211591243744\n"
],
"name": "stdout"
},
{
"output_type": "stream",
"text": [
"100%|██████████| 12/12 [00:00<00:00, 18.20it/s]\n",
" 17%|█▋ | 2/12 [00:00<00:00, 19.17it/s]"
],
"name": "stderr"
},
{
"output_type": "stream",
"text": [
"epoch: \t 11 \t training loss: \t 0.44710880517959595\n"
],
"name": "stdout"
},
{
"output_type": "stream",
"text": [
"100%|██████████| 12/12 [00:00<00:00, 18.25it/s]\n",
" 17%|█▋ | 2/12 [00:00<00:00, 19.16it/s]"
],
"name": "stderr"
},
{
"output_type": "stream",
"text": [
"epoch: \t 12 \t training loss: \t 0.4318452949325244\n"
],
"name": "stdout"
},
{
"output_type": "stream",
"text": [
"100%|██████████| 12/12 [00:00<00:00, 18.11it/s]\n",
" 17%|█▋ | 2/12 [00:00<00:00, 19.09it/s]"
],
"name": "stderr"
},
{
"output_type": "stream",
"text": [
"epoch: \t 13 \t training loss: \t 0.4182896812756856\n"
],
"name": "stdout"
},
{
"output_type": "stream",
"text": [
"100%|██████████| 12/12 [00:00<00:00, 18.19it/s]\n",
" 17%|█▋ | 2/12 [00:00<00:00, 19.42it/s]"
],
"name": "stderr"
},
{
"output_type": "stream",
"text": [
"epoch: \t 14 \t training loss: \t 0.4100518450140953\n"
],
"name": "stdout"
},
{
"output_type": "stream",
"text": [
"100%|██████████| 12/12 [00:00<00:00, 18.28it/s]"
],
"name": "stderr"
},
{
"output_type": "stream",
"text": [
"epoch: \t 15 \t training loss: \t 0.3807670896251996\n"
],
"name": "stdout"
},
{
"output_type": "stream",
"text": [
"\n"
],
"name": "stderr"
}
]
},
{
"cell_type": "code",
"metadata": {
"id": "x5L0mTtjky8d",
"colab": {
"base_uri": "https://localhost:8080/"
},
"outputId": "44de07b2-d464-48f4-f078-da95a786619b"
},
"source": [
"# prediction for training set\n",
"prediction = []\n",
"target = []\n",
"permutation = torch.randperm(train_x.size()[0])\n",
"for i in tqdm(range(0,train_x.size()[0], batch_size)):\n",
" indices = permutation[i:i+batch_size]\n",
" batch_x, batch_y = train_x[indices], train_y[indices]\n",
"\n",
" if torch.cuda.is_available():\n",
" batch_x, batch_y = batch_x.cuda(), batch_y.cuda()\n",
"\n",
" with torch.no_grad():\n",
" output = model(batch_x.cuda())\n",
"\n",
" softmax = torch.exp(output).cpu()\n",
" prob = list(softmax.numpy())\n",
" predictions = np.argmax(prob, axis=1)\n",
" prediction.append(predictions)\n",
" target.append(batch_y)\n",
" \n",
"# training accuracy\n",
"accuracy = []\n",
"for i in range(len(prediction)):\n",
" accuracy.append(accuracy_score(target[i].cpu().data.numpy(),prediction[i]))\n",
" \n",
"print('training accuracy: \\t', np.average(accuracy))"
],
"execution_count": null,
"outputs": [
{
"output_type": "stream",
"text": [
"100%|██████████| 12/12 [00:00<00:00, 22.71it/s]"
],
"name": "stderr"
},
{
"output_type": "stream",
"text": [
"training accuracy: \t 0.8792094748858448\n"
],
"name": "stdout"
},
{
"output_type": "stream",
"text": [
"\n"
],
"name": "stderr"
}
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "eHTB5WagNiOP"
},
"source": [
"We got a training accuracy of around 87% which is a good score. Let’s now check the validation accuracy:"
]
},
{
"cell_type": "code",
"metadata": {
"id": "fFvJOoqBoeUs",
"colab": {
"base_uri": "https://localhost:8080/"
},
"outputId": "5e3c3338-8247-46f7-a5fc-93cdf464e1ed"
},
"source": [
"# prediction for validation set\n",
"prediction_val = []\n",
"target_val = []\n",
"permutation = torch.randperm(val_x.size()[0])\n",
"for i in tqdm(range(0,val_x.size()[0], batch_size)):\n",
" indices = permutation[i:i+batch_size]\n",
" batch_x, batch_y = val_x[indices], val_y[indices]\n",
"\n",
" if torch.cuda.is_available():\n",
" batch_x, batch_y = batch_x.cuda(), batch_y.cuda()\n",
"\n",
" with torch.no_grad():\n",
" output = model(batch_x.cuda())\n",
"\n",
" softmax = torch.exp(output).cpu()\n",
" prob = list(softmax.numpy())\n",
" predictions = np.argmax(prob, axis=1)\n",
" prediction_val.append(predictions)\n",
" target_val.append(batch_y)\n",
" \n",
"# validation accuracy\n",
"accuracy_val = []\n",
"for i in range(len(prediction_val)):\n",
" accuracy_val.append(accuracy_score(target_val[i].cpu().data.numpy(),prediction_val[i]))\n",
" \n",
"print('validation accuracy: \\t', np.average(accuracy_val))"
],
"execution_count": null,
"outputs": [
{
"output_type": "stream",
"text": [
"100%|██████████| 2/2 [00:00<00:00, 33.40it/s]"
],
"name": "stderr"
},
{
"output_type": "stream",
"text": [
"validation accuracy: \t 0.7125211148648649\n"
],
"name": "stdout"
},
{
"output_type": "stream",
"text": [
"\n"
],
"name": "stderr"
}
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "jFuUgfx5Nlrd"
},
"source": [
"The validation accuracy comes out to be 70% which pales in comparison. This serves as a benchmark. Next, use transfer learning to solve this problem. "
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "cPZceSJWOBhn"
},
"source": [
"# Transfer Learning"
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "Sk3LLFzXOHkC"
},
"source": [
"The steps to train the model using transfer learning:\n",
"\n",
"1. First, we will load the weights of the pre-trained model – VGG16 in our case\n",
"2. Then we will fine tune the model as per the problem at hand\n",
"3. Next, we will use these pre-trained weights and extract features for our images\n",
"4. Finally, we will train the fine tuned model using the extracted features\n",
"\n"
]
},
{
"cell_type": "code",
"metadata": {
"id": "1XHBXsxXoeaG",
"colab": {
"base_uri": "https://localhost:8080/",
"height": 83,
"referenced_widgets": [
"77a6d1191b034c61a904fb11bd9e370f",
"a07d0aec8dab4cbcadc4b76f942eab2b",
"51297ef3fe5c4f5189bc3a2e232f45e4",
"7c9e8994a3454cffa30fff59afb89bfa",
"5dc62900703e40e290721bd120a68e23",
"78feae83110f4338b4c051a2b10fcaa1",
"8e1486498f1c4feba052179e02ed2864",
"e0b12e0abf654ccd973027b841c08a01"
]
},
"outputId": "a60e66ce-c7f6-43b9-f71f-a88beeab7cb6"
},
"source": [
"# loading the pretrained model\n",
"model = models.vgg16_bn(pretrained=True)"
],
"execution_count": null,
"outputs": [
{
"output_type": "stream",
"text": [
"Downloading: \"https://download.pytorch.org/models/vgg16_bn-6c64b313.pth\" to /root/.cache/torch/hub/checkpoints/vgg16_bn-6c64b313.pth\n"
],
"name": "stderr"
},
{
"output_type": "display_data",
"data": {
"application/vnd.jupyter.widget-view+json": {
"model_id": "77a6d1191b034c61a904fb11bd9e370f",
"version_minor": 0,
"version_major": 2
},
"text/plain": [
"HBox(children=(FloatProgress(value=0.0, max=553507836.0), HTML(value='')))"
]
},
"metadata": {
"tags": []
}
},
{
"output_type": "stream",
"text": [
"\n"
],
"name": "stdout"
}
]
},
{
"cell_type": "code",
"metadata": {
"id": "F7J34APKoeed"
},
"source": [
"# Freeze model weights\n",
"for param in model.parameters():\n",
" param.requires_grad = False"
],
"execution_count": null,
"outputs": []
},
{
"cell_type": "markdown",
"metadata": {
"id": "cwcxznU_Q3vl"
},
"source": [
"There are 2 classes to predict and VGG16 is trained on ImageNet which has 1000 classes, there is a need to update the final layer as per the specific problem."
]
},
{
"cell_type": "code",
"metadata": {
"id": "ZyInTfOdoekD"
},
"source": [
"# Add on classifier\n",
"model.classifier[6] = Sequential(\n",
" Linear(4096, 2))\n",
"for param in model.classifier[6].parameters():\n",
" param.requires_grad = True"
],
"execution_count": null,
"outputs": []
},
{
"cell_type": "markdown",
"metadata": {
"id": "pSj8GpEERokO"
},
"source": [
"To train the last layer, the requires_grad for the layer have to be set as True. Let’s set the training to GPU."
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "E10RcZuTC36i"
},
"source": [
"Let’s set the training to GPU."
]
},
{
"cell_type": "code",
"metadata": {
"id": "HL4iPx8tC1qG"
},
"source": [
"if torch.cuda.is_available():\n",
" model = model.cuda()\n",
" criterion = criterion.cuda()"
],
"execution_count": null,
"outputs": []
},
{
"cell_type": "code",
"metadata": {
"id": "F3QWu-tHoem2",
"colab": {
"base_uri": "https://localhost:8080/"
},
"outputId": "5ae5d7c2-8d9f-4e9c-a248-66ce4b101618"
},
"source": [
"# batch_size\n",
"batch_size = 128\n",
"\n",
"# extracting features for train data\n",
"data_x = []\n",
"label_x = []\n",
"\n",
"inputs,labels = train_x, train_y\n",
"\n",
"for i in tqdm(range(int(train_x.shape[0]/batch_size)+1)):\n",
" input_data = inputs[i*batch_size:(i+1)*batch_size]\n",
" label_data = labels[i*batch_size:(i+1)*batch_size]\n",
" input_data , label_data = Variable(input_data.cuda()),Variable(label_data.cuda())\n",
" x = model.features(input_data.cuda())\n",
" data_x.extend(x.data.cpu().numpy())\n",
" label_x.extend(label_data.data.cpu().numpy())"
],
"execution_count": null,
"outputs": [
{
"output_type": "stream",
"text": [
"100%|██████████| 12/12 [00:07<00:00, 1.69it/s]\n"
],
"name": "stderr"
}
]
},
{
"cell_type": "code",
"metadata": {
"id": "42t4yNW8oeph",
"colab": {
"base_uri": "https://localhost:8080/"
},
"outputId": "49a53b72-66cc-4531-8c02-06d93cf9936b"
},
"source": [
"# extracting features for validation data\n",
"data_y = []\n",
"label_y = []\n",
"\n",
"inputs,labels = val_x, val_y\n",
"\n",
"for i in tqdm(range(int(val_x.shape[0]/batch_size)+1)):\n",
" input_data = inputs[i*batch_size:(i+1)*batch_size]\n",
" label_data = labels[i*batch_size:(i+1)*batch_size]\n",
" input_data , label_data = Variable(input_data.cuda()),Variable(label_data.cuda())\n",
" x = model.features(input_data.cuda())\n",
" data_y.extend(x.data.cpu().numpy())\n",
" label_y.extend(label_data.data.cpu().numpy())"
],
"execution_count": null,
"outputs": [
{
"output_type": "stream",
"text": [
"100%|██████████| 2/2 [00:00<00:00, 2.47it/s]\n"
],
"name": "stderr"
}
]
},
{
"cell_type": "code",
"metadata": {
"id": "37cUDBFtsEwV"
},
"source": [
"# converting the features into torch format\n",
"x_train = torch.from_numpy(np.array(data_x))\n",
"x_train = x_train.view(x_train.size(0), -1)\n",
"y_train = torch.from_numpy(np.array(label_x))\n",
"x_val = torch.from_numpy(np.array(data_y))\n",
"x_val = x_val.view(x_val.size(0), -1)\n",
"y_val = torch.from_numpy(np.array(label_y))"
],
"execution_count": null,
"outputs": []
},
{
"cell_type": "code",
"metadata": {
"id": "Lotl7LKgsFyN"
},
"source": [
"import torch.optim as optim\n",
"\n",
"# specify loss function\n",
"criterion = CrossEntropyLoss()\n",
"\n",
"# specify optimizer and learning rate\n",
"optimizer = optim.Adam(model.classifier[6].parameters(), lr=0.0005)"
],
"execution_count": null,
"outputs": []
},
{
"cell_type": "code",
"metadata": {
"id": "CReZdJDDsG38",
"colab": {
"base_uri": "https://localhost:8080/"
},
"outputId": "5393b61a-a20b-46b8-dca1-e14bbd8be9fc"
},
"source": [
"# batch size\n",
"batch_size = 128\n",
"\n",
"# number of epochs to train the model\n",
"n_epochs = 30\n",
"\n",
"for epoch in tqdm(range(1, n_epochs+1)):\n",
"\n",
" # keep track of training and validation loss\n",
" train_loss = 0.0\n",
" \n",
" permutation = torch.randperm(x_train.size()[0])\n",
"\n",
" training_loss = []\n",
" for i in range(0,x_train.size()[0], batch_size):\n",
"\n",
" indices = permutation[i:i+batch_size]\n",
" batch_x, batch_y = x_train[indices], y_train[indices]\n",
" \n",
" if torch.cuda.is_available():\n",
" batch_x, batch_y = batch_x.cuda(), batch_y.cuda()\n",
" \n",
" optimizer.zero_grad()\n",
" # in case you wanted a semi-full example\n",
" outputs = model.classifier(batch_x)\n",
" loss = criterion(outputs,batch_y)\n",
"\n",
" training_loss.append(loss.item())\n",
" loss.backward()\n",
" optimizer.step()\n",
" \n",
" training_loss = np.average(training_loss)\n",
" print('epoch: \\t', epoch, '\\t training loss: \\t', training_loss)"
],
"execution_count": null,
"outputs": [
{
"output_type": "stream",
"text": [
" 7%|▋ | 2/30 [00:00<00:04, 6.09it/s]"
],
"name": "stderr"
},
{
"output_type": "stream",
"text": [
"epoch: \t 1 \t training loss: \t 0.634782001376152\n",
"epoch: \t 2 \t training loss: \t 0.5196206942200661\n"
],
"name": "stdout"
},
{
"output_type": "stream",
"text": [
" 13%|█▎ | 4/30 [00:00<00:04, 6.08it/s]"
],
"name": "stderr"
},
{
"output_type": "stream",
"text": [
"epoch: \t 3 \t training loss: \t 0.47351022561391193\n",
"epoch: \t 4 \t training loss: \t 0.453992818792661\n"
],
"name": "stdout"
},
{
"output_type": "stream",
"text": [
" 20%|██ | 6/30 [00:00<00:03, 6.12it/s]"
],
"name": "stderr"
},
{
"output_type": "stream",
"text": [
"epoch: \t 5 \t training loss: \t 0.436656358341376\n",
"epoch: \t 6 \t training loss: \t 0.4325019096334775\n"
],
"name": "stdout"
},
{
"output_type": "stream",
"text": [
" 27%|██▋ | 8/30 [00:01<00:03, 6.14it/s]"
],
"name": "stderr"
},
{
"output_type": "stream",
"text": [
"epoch: \t 7 \t training loss: \t 0.42470891028642654\n",
"epoch: \t 8 \t training loss: \t 0.4138946359356244\n"
],
"name": "stdout"
},
{
"output_type": "stream",
"text": [
" 33%|███▎ | 10/30 [00:01<00:03, 6.05it/s]"
],
"name": "stderr"
},
{
"output_type": "stream",
"text": [
"epoch: \t 9 \t training loss: \t 0.4068816229701042\n",
"epoch: \t 10 \t training loss: \t 0.39944549401601154\n"
],
"name": "stdout"
},
{
"output_type": "stream",
"text": [
" 40%|████ | 12/30 [00:01<00:02, 6.13it/s]"
],
"name": "stderr"
},
{
"output_type": "stream",
"text": [
"epoch: \t 11 \t training loss: \t 0.398816242814064\n",
"epoch: \t 12 \t training loss: \t 0.39193615317344666\n"
],
"name": "stdout"
},
{
"output_type": "stream",
"text": [
" 47%|████▋ | 14/30 [00:02<00:02, 6.12it/s]"
],
"name": "stderr"
},
{
"output_type": "stream",
"text": [
"epoch: \t 13 \t training loss: \t 0.39300836126009625\n",
"epoch: \t 14 \t training loss: \t 0.3807535544037819\n"
],
"name": "stdout"
},
{
"output_type": "stream",
"text": [
" 53%|█████▎ | 16/30 [00:02<00:02, 6.08it/s]"
],
"name": "stderr"
},
{
"output_type": "stream",
"text": [
"epoch: \t 15 \t training loss: \t 0.3876273309191068\n",
"epoch: \t 16 \t training loss: \t 0.365109587709109\n"
],
"name": "stdout"
},
{
"output_type": "stream",
"text": [
" 60%|██████ | 18/30 [00:02<00:01, 6.08it/s]"
],
"name": "stderr"
},
{
"output_type": "stream",
"text": [
"epoch: \t 17 \t training loss: \t 0.38077934583028156\n",
"epoch: \t 18 \t training loss: \t 0.3648728628953298\n"
],
"name": "stdout"
},
{
"output_type": "stream",
"text": [
" 67%|██████▋ | 20/30 [00:03<00:01, 6.13it/s]"
],
"name": "stderr"
},
{
"output_type": "stream",
"text": [
"epoch: \t 19 \t training loss: \t 0.37697024643421173\n",
"epoch: \t 20 \t training loss: \t 0.37384723375240964\n"
],
"name": "stdout"
},
{
"output_type": "stream",
"text": [
" 73%|███████▎ | 22/30 [00:03<00:01, 6.14it/s]"
],
"name": "stderr"
},
{
"output_type": "stream",
"text": [
"epoch: \t 21 \t training loss: \t 0.35718678931395215\n",
"epoch: \t 22 \t training loss: \t 0.365610308945179\n"
],
"name": "stdout"
},
{
"output_type": "stream",
"text": [
" 80%|████████ | 24/30 [00:03<00:00, 6.14it/s]"
],
"name": "stderr"
},
{
"output_type": "stream",
"text": [
"epoch: \t 23 \t training loss: \t 0.3694082275032997\n",
"epoch: \t 24 \t training loss: \t 0.3612728814284007\n"
],
"name": "stdout"
},
{
"output_type": "stream",
"text": [
" 87%|████████▋ | 26/30 [00:04<00:00, 6.12it/s]"
],
"name": "stderr"
},
{
"output_type": "stream",
"text": [
"epoch: \t 25 \t training loss: \t 0.3561461269855499\n",
"epoch: \t 26 \t training loss: \t 0.3564560264348984\n"
],
"name": "stdout"
},
{
"output_type": "stream",
"text": [
" 93%|█████████▎| 28/30 [00:04<00:00, 6.14it/s]"
],
"name": "stderr"
},
{
"output_type": "stream",
"text": [
"epoch: \t 27 \t training loss: \t 0.3482185825705528\n",
"epoch: \t 28 \t training loss: \t 0.3575662299990654\n"
],
"name": "stdout"
},
{
"output_type": "stream",
"text": [
"100%|██████████| 30/30 [00:04<00:00, 6.10it/s]"
],
"name": "stderr"
},
{
"output_type": "stream",
"text": [
"epoch: \t 29 \t training loss: \t 0.34120848526557285\n",
"epoch: \t 30 \t training loss: \t 0.3652077565590541\n"
],
"name": "stdout"
},
{
"output_type": "stream",
"text": [
"\n"
],
"name": "stderr"
}
]
},
{
"cell_type": "code",
"metadata": {
"id": "L3BKx2YLsIFs",
"colab": {
"base_uri": "https://localhost:8080/"
},
"outputId": "7d2d1dee-821b-4f73-bea4-2dd81cbb7881"
},
"source": [
"# prediction for training set\n",
"prediction = []\n",
"target = []\n",
"permutation = torch.randperm(x_train.size()[0])\n",
"for i in tqdm(range(0,x_train.size()[0], batch_size)):\n",
" indices = permutation[i:i+batch_size]\n",
" batch_x, batch_y = x_train[indices], y_train[indices]\n",
"\n",
" if torch.cuda.is_available():\n",
" batch_x, batch_y = batch_x.cuda(), batch_y.cuda()\n",
"\n",
" with torch.no_grad():\n",
" output = model.classifier(batch_x.cuda())\n",
"\n",
" softmax = torch.exp(output).cpu()\n",
" prob = list(softmax.numpy())\n",
" predictions = np.argmax(prob, axis=1)\n",
" prediction.append(predictions)\n",
" target.append(batch_y)\n",
" \n",
"# training accuracy\n",
"accuracy = []\n",
"for i in range(len(prediction)):\n",
" accuracy.append(accuracy_score(target[i].cpu().data.numpy(),prediction[i]))\n",
" \n",
"print('training accuracy: \\t', np.average(accuracy))"
],
"execution_count": null,
"outputs": [
{
"output_type": "stream",
"text": [
"100%|██████████| 12/12 [00:00<00:00, 75.58it/s]\n"
],
"name": "stderr"
},
{
"output_type": "stream",
"text": [
"training accuracy: \t 0.8552903824200913\n"
],
"name": "stdout"
}
]
},
{
"cell_type": "code",
"metadata": {
"id": "or7jk0jTw9rB",
"colab": {
"base_uri": "https://localhost:8080/"
},
"outputId": "0664f4e0-08f0-46e4-dcd9-f728fab9869c"
},
"source": [
"# prediction for validation set\n",
"prediction_val = []\n",
"target_val = []\n",
"permutation = torch.randperm(x_val.size()[0])\n",
"for i in tqdm(range(0,x_val.size()[0], batch_size)):\n",
" indices = permutation[i:i+batch_size]\n",
" batch_x, batch_y = x_val[indices], y_val[indices]\n",
"\n",
" if torch.cuda.is_available():\n",
" batch_x, batch_y = batch_x.cuda(), batch_y.cuda()\n",
"\n",
" with torch.no_grad():\n",
" output = model.classifier(batch_x.cuda())\n",
"\n",
" softmax = torch.exp(output).cpu()\n",
" prob = list(softmax.numpy())\n",
" predictions = np.argmax(prob, axis=1)\n",
" prediction_val.append(predictions)\n",
" target_val.append(batch_y)\n",
" \n",
"# validation accuracy\n",
"accuracy_val = []\n",
"for i in range(len(prediction_val)):\n",
" accuracy_val.append(accuracy_score(target_val[i].cpu().data.numpy(),prediction_val[i]))\n",
" \n",
"print('validation accuracy: \\t', np.average(accuracy_val))"
],
"execution_count": null,
"outputs": [
{
"output_type": "stream",
"text": [
"100%|██████████| 2/2 [00:00<00:00, 88.82it/s]"
],
"name": "stderr"
},
{
"output_type": "stream",
"text": [
"validation accuracy: \t 0.8017314189189189\n"
],
"name": "stdout"
},
{
"output_type": "stream",
"text": [
"\n"
],
"name": "stderr"
}
]
},
{
"cell_type": "markdown",
"metadata": {
"id": "yQUPe4glSaxd"
},
"source": [
"Validation accuracy performed much better than vanilla CNN. Moreover, the training and validation accuracies for VGG16 is much in sync so the model is well generalized. "
]
},
{
"cell_type": "code",
"metadata": {
"id": "o9FVjnXUHMbB"
},
"source": [
""
],
"execution_count": null,
"outputs": []
}
]
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment