Last active
June 9, 2021 16:15
-
-
Save yongkangc/2c3edfbaa20e5210c369b36486fe78db to your computer and use it in GitHub Desktop.
transfer learning cnn tutorial.ipynb
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"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