Upload 2 files
Browse files- Transfer_Learning.ipynb +425 -0
- readme.md +83 -0
Transfer_Learning.ipynb
ADDED
|
@@ -0,0 +1,425 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
{
|
| 2 |
+
"nbformat": 4,
|
| 3 |
+
"nbformat_minor": 0,
|
| 4 |
+
"metadata": {
|
| 5 |
+
"colab": {
|
| 6 |
+
"provenance": []
|
| 7 |
+
},
|
| 8 |
+
"kernelspec": {
|
| 9 |
+
"name": "python3",
|
| 10 |
+
"display_name": "Python 3"
|
| 11 |
+
},
|
| 12 |
+
"language_info": {
|
| 13 |
+
"name": "python"
|
| 14 |
+
}
|
| 15 |
+
},
|
| 16 |
+
"cells": [
|
| 17 |
+
{
|
| 18 |
+
"cell_type": "code",
|
| 19 |
+
"execution_count": 1,
|
| 20 |
+
"metadata": {
|
| 21 |
+
"colab": {
|
| 22 |
+
"base_uri": "https://localhost:8080/"
|
| 23 |
+
},
|
| 24 |
+
"id": "DLfuYXOZRLSc",
|
| 25 |
+
"outputId": "7bb39bd1-b77c-4b73-a2cc-504307f87a5e"
|
| 26 |
+
},
|
| 27 |
+
"outputs": [
|
| 28 |
+
{
|
| 29 |
+
"output_type": "stream",
|
| 30 |
+
"name": "stdout",
|
| 31 |
+
"text": [
|
| 32 |
+
"Libraries imported successfully!\n"
|
| 33 |
+
]
|
| 34 |
+
}
|
| 35 |
+
],
|
| 36 |
+
"source": [
|
| 37 |
+
"# ============================================================\n",
|
| 38 |
+
"# Transfer Learning using ResNet on CIFAR-10\n",
|
| 39 |
+
"# ============================================================\n",
|
| 40 |
+
"# Description : Pretend CIFAR-10 categories are Bengali\n",
|
| 41 |
+
"# celebrities β same transfer learning concept\n",
|
| 42 |
+
"# Model : ResNet18 pretrained on ImageNet\n",
|
| 43 |
+
"# Author : Fatima\n",
|
| 44 |
+
"# ============================================================\n",
|
| 45 |
+
"\n",
|
| 46 |
+
"# ββ Import Required Libraries ββββββββββββββββββββββββββββββββ\n",
|
| 47 |
+
"import torch # PyTorch\n",
|
| 48 |
+
"import torch.nn as nn # neural network\n",
|
| 49 |
+
"import torchvision.models as models # pretrained models\n",
|
| 50 |
+
"import torchvision.transforms as transforms # image transforms\n",
|
| 51 |
+
"from torchvision.datasets import CIFAR10 # practice dataset\n",
|
| 52 |
+
"from torch.utils.data import DataLoader # data feeding\n",
|
| 53 |
+
"import matplotlib.pyplot as plt # visualization\n",
|
| 54 |
+
"\n",
|
| 55 |
+
"print(\"Libraries imported successfully!\")"
|
| 56 |
+
]
|
| 57 |
+
},
|
| 58 |
+
{
|
| 59 |
+
"cell_type": "code",
|
| 60 |
+
"source": [
|
| 61 |
+
"# ββ Step 2: Load Pretrained ResNet18 ββββββββββββββββββββββββ\n",
|
| 62 |
+
"# ResNet18 = pretrained on ImageNet (1000 categories)\n",
|
| 63 |
+
"# already knows edges, shapes, textures, face patterns\n",
|
| 64 |
+
"# we borrow this knowledge for our celebrity task\n",
|
| 65 |
+
"\n",
|
| 66 |
+
"print(\"Loading pretrained ResNet18...\")\n",
|
| 67 |
+
"\n",
|
| 68 |
+
"# weights=DEFAULT loads the pretrained ImageNet weights\n",
|
| 69 |
+
"model = models.resnet18(weights=models.ResNet18_Weights.DEFAULT)\n",
|
| 70 |
+
"\n",
|
| 71 |
+
"# look at the final layer before we change it\n",
|
| 72 |
+
"print(\"\\nOriginal final layer:\")\n",
|
| 73 |
+
"print(model.fc)\n",
|
| 74 |
+
"\n",
|
| 75 |
+
"# ββ Step 3: Replace Final Layer βββββββββββββββββββββββββββββ\n",
|
| 76 |
+
"# original final layer β Linear(512, 1000) = 1000 categories\n",
|
| 77 |
+
"# we replace it β Linear(512, 10) = 10 celebrities\n",
|
| 78 |
+
"# (in real project β Linear(512, 250) = 250 Bengali celebs)\n",
|
| 79 |
+
"\n",
|
| 80 |
+
"num_celebrities = 10 # pretending 10 CIFAR categories = 10 celebrities\n",
|
| 81 |
+
"\n",
|
| 82 |
+
"model.fc = nn.Linear(512, num_celebrities)\n",
|
| 83 |
+
"\n",
|
| 84 |
+
"print(\"\\nModified final layer:\")\n",
|
| 85 |
+
"print(model.fc)\n",
|
| 86 |
+
"\n",
|
| 87 |
+
"print(\"\\nResNet18 ready for celebrity recognition! β
\")"
|
| 88 |
+
],
|
| 89 |
+
"metadata": {
|
| 90 |
+
"colab": {
|
| 91 |
+
"base_uri": "https://localhost:8080/"
|
| 92 |
+
},
|
| 93 |
+
"id": "yk6ClSQrRwz9",
|
| 94 |
+
"outputId": "bcf48079-0cc7-4798-adf6-14abc7bdbd69"
|
| 95 |
+
},
|
| 96 |
+
"execution_count": 2,
|
| 97 |
+
"outputs": [
|
| 98 |
+
{
|
| 99 |
+
"output_type": "stream",
|
| 100 |
+
"name": "stdout",
|
| 101 |
+
"text": [
|
| 102 |
+
"Loading pretrained ResNet18...\n",
|
| 103 |
+
"Downloading: \"https://download.pytorch.org/models/resnet18-f37072fd.pth\" to /root/.cache/torch/hub/checkpoints/resnet18-f37072fd.pth\n"
|
| 104 |
+
]
|
| 105 |
+
},
|
| 106 |
+
{
|
| 107 |
+
"output_type": "stream",
|
| 108 |
+
"name": "stderr",
|
| 109 |
+
"text": [
|
| 110 |
+
"100%|ββββββββββ| 44.7M/44.7M [00:00<00:00, 344MB/s]"
|
| 111 |
+
]
|
| 112 |
+
},
|
| 113 |
+
{
|
| 114 |
+
"output_type": "stream",
|
| 115 |
+
"name": "stdout",
|
| 116 |
+
"text": [
|
| 117 |
+
"\n",
|
| 118 |
+
"Original final layer:\n",
|
| 119 |
+
"Linear(in_features=512, out_features=1000, bias=True)\n",
|
| 120 |
+
"\n",
|
| 121 |
+
"Modified final layer:\n",
|
| 122 |
+
"Linear(in_features=512, out_features=10, bias=True)\n",
|
| 123 |
+
"\n",
|
| 124 |
+
"ResNet18 ready for celebrity recognition! β
\n"
|
| 125 |
+
]
|
| 126 |
+
},
|
| 127 |
+
{
|
| 128 |
+
"output_type": "stream",
|
| 129 |
+
"name": "stderr",
|
| 130 |
+
"text": [
|
| 131 |
+
"\n"
|
| 132 |
+
]
|
| 133 |
+
}
|
| 134 |
+
]
|
| 135 |
+
},
|
| 136 |
+
{
|
| 137 |
+
"cell_type": "code",
|
| 138 |
+
"source": [
|
| 139 |
+
"# ββ Step 3: Load CIFAR-10 Dataset βββββββββββββββββββββββββββ\n",
|
| 140 |
+
"# CIFAR-10 = 60,000 images, 10 categories\n",
|
| 141 |
+
"# we pretend each category = one Bengali celebrity\n",
|
| 142 |
+
"# ResNet expects images of size 224x224\n",
|
| 143 |
+
"# so we resize CIFAR-10 images from 32x32 to 224x224\n",
|
| 144 |
+
"\n",
|
| 145 |
+
"print(\"Loading CIFAR-10 dataset...\")\n",
|
| 146 |
+
"\n",
|
| 147 |
+
"# define image transformations\n",
|
| 148 |
+
"transform = transforms.Compose([\n",
|
| 149 |
+
" # resize to 224x224 (ResNet expected input size)\n",
|
| 150 |
+
" transforms.Resize((224, 224)),\n",
|
| 151 |
+
" # convert image to PyTorch tensor\n",
|
| 152 |
+
" transforms.ToTensor(),\n",
|
| 153 |
+
" # normalize using ImageNet mean and std\n",
|
| 154 |
+
" # because ResNet was trained with these values\n",
|
| 155 |
+
" transforms.Normalize(\n",
|
| 156 |
+
" mean=[0.485, 0.456, 0.406],\n",
|
| 157 |
+
" std=[0.229, 0.224, 0.225]\n",
|
| 158 |
+
" )\n",
|
| 159 |
+
"])\n",
|
| 160 |
+
"\n",
|
| 161 |
+
"# load training data\n",
|
| 162 |
+
"train_dataset = CIFAR10(\n",
|
| 163 |
+
" root=\"./data\", # where to save dataset\n",
|
| 164 |
+
" train=True, # training set\n",
|
| 165 |
+
" download=True, # download if not present\n",
|
| 166 |
+
" transform=transform # apply transformations\n",
|
| 167 |
+
")\n",
|
| 168 |
+
"\n",
|
| 169 |
+
"# load test data\n",
|
| 170 |
+
"test_dataset = CIFAR10(\n",
|
| 171 |
+
" root=\"./data\",\n",
|
| 172 |
+
" train=False, # test set\n",
|
| 173 |
+
" download=True,\n",
|
| 174 |
+
" transform=transform\n",
|
| 175 |
+
")\n",
|
| 176 |
+
"\n",
|
| 177 |
+
"# create dataloaders\n",
|
| 178 |
+
"train_loader = DataLoader(\n",
|
| 179 |
+
" train_dataset,\n",
|
| 180 |
+
" batch_size=32, # 32 images at a time\n",
|
| 181 |
+
" shuffle=True # randomize each epoch\n",
|
| 182 |
+
")\n",
|
| 183 |
+
"\n",
|
| 184 |
+
"test_loader = DataLoader(\n",
|
| 185 |
+
" test_dataset,\n",
|
| 186 |
+
" batch_size=32,\n",
|
| 187 |
+
" shuffle=False # no need to shuffle test data\n",
|
| 188 |
+
")\n",
|
| 189 |
+
"\n",
|
| 190 |
+
"print(f\"Training images : {len(train_dataset)}\")\n",
|
| 191 |
+
"print(f\"Test images : {len(test_dataset)}\")\n",
|
| 192 |
+
"print(f\"Training batches: {len(train_loader)}\")\n",
|
| 193 |
+
"print(\"Dataset ready! β
\")"
|
| 194 |
+
],
|
| 195 |
+
"metadata": {
|
| 196 |
+
"colab": {
|
| 197 |
+
"base_uri": "https://localhost:8080/"
|
| 198 |
+
},
|
| 199 |
+
"id": "BtdWc1VLShty",
|
| 200 |
+
"outputId": "4e5d120c-d273-46bc-99c0-dbfb4c2c154f"
|
| 201 |
+
},
|
| 202 |
+
"execution_count": 3,
|
| 203 |
+
"outputs": [
|
| 204 |
+
{
|
| 205 |
+
"output_type": "stream",
|
| 206 |
+
"name": "stdout",
|
| 207 |
+
"text": [
|
| 208 |
+
"Loading CIFAR-10 dataset...\n"
|
| 209 |
+
]
|
| 210 |
+
},
|
| 211 |
+
{
|
| 212 |
+
"output_type": "stream",
|
| 213 |
+
"name": "stderr",
|
| 214 |
+
"text": [
|
| 215 |
+
"100%|ββββββββββ| 170M/170M [41:04<00:00, 69.2kB/s]\n"
|
| 216 |
+
]
|
| 217 |
+
},
|
| 218 |
+
{
|
| 219 |
+
"output_type": "stream",
|
| 220 |
+
"name": "stdout",
|
| 221 |
+
"text": [
|
| 222 |
+
"Training images : 50000\n",
|
| 223 |
+
"Test images : 10000\n",
|
| 224 |
+
"Training batches: 1563\n",
|
| 225 |
+
"Dataset ready! β
\n"
|
| 226 |
+
]
|
| 227 |
+
}
|
| 228 |
+
]
|
| 229 |
+
},
|
| 230 |
+
{
|
| 231 |
+
"cell_type": "code",
|
| 232 |
+
"source": [
|
| 233 |
+
"# ββ Step 4: Training Loop (Fast Version) ββββββββββββββββββββ\n",
|
| 234 |
+
"# use only 500 images instead of 50,000\n",
|
| 235 |
+
"# so it runs fast on CPU\n",
|
| 236 |
+
"# concept is exactly the same!\n",
|
| 237 |
+
"\n",
|
| 238 |
+
"from torch.utils.data import Subset\n",
|
| 239 |
+
"\n",
|
| 240 |
+
"# take only first 500 training images\n",
|
| 241 |
+
"small_train = Subset(train_dataset, range(500))\n",
|
| 242 |
+
"small_loader = DataLoader(small_train,\n",
|
| 243 |
+
" batch_size=32,\n",
|
| 244 |
+
" shuffle=True)\n",
|
| 245 |
+
"\n",
|
| 246 |
+
"# setup\n",
|
| 247 |
+
"device = torch.device(\"cpu\")\n",
|
| 248 |
+
"print(f\"Using device: {device}\")\n",
|
| 249 |
+
"model = model.to(device)\n",
|
| 250 |
+
"\n",
|
| 251 |
+
"# loss and optimizer\n",
|
| 252 |
+
"loss_fn = nn.CrossEntropyLoss()\n",
|
| 253 |
+
"optimizer = torch.optim.Adam(model.parameters(), lr=0.001)\n",
|
| 254 |
+
"\n",
|
| 255 |
+
"print(f\"Training on 500 images ({len(small_loader)} batches)\")\n",
|
| 256 |
+
"print(\"Starting training...\\n\")\n",
|
| 257 |
+
"\n",
|
| 258 |
+
"for epoch in range(2):\n",
|
| 259 |
+
"\n",
|
| 260 |
+
" total_loss = 0\n",
|
| 261 |
+
" correct = 0\n",
|
| 262 |
+
" total = 0\n",
|
| 263 |
+
"\n",
|
| 264 |
+
" for batch_idx, (images, labels) in enumerate(small_loader):\n",
|
| 265 |
+
"\n",
|
| 266 |
+
" images = images.to(device)\n",
|
| 267 |
+
" labels = labels.to(device)\n",
|
| 268 |
+
"\n",
|
| 269 |
+
" # Step 1: forward pass\n",
|
| 270 |
+
" predictions = model(images)\n",
|
| 271 |
+
"\n",
|
| 272 |
+
" # Step 2: calculate loss\n",
|
| 273 |
+
" loss = loss_fn(predictions, labels)\n",
|
| 274 |
+
"\n",
|
| 275 |
+
" # Step 3: backpropagation\n",
|
| 276 |
+
" loss.backward()\n",
|
| 277 |
+
"\n",
|
| 278 |
+
" # Step 4: update weights\n",
|
| 279 |
+
" optimizer.step()\n",
|
| 280 |
+
"\n",
|
| 281 |
+
" # Step 5: reset gradients\n",
|
| 282 |
+
" optimizer.zero_grad()\n",
|
| 283 |
+
"\n",
|
| 284 |
+
" total_loss += loss.item()\n",
|
| 285 |
+
" _, predicted = torch.max(predictions, 1)\n",
|
| 286 |
+
" correct += (predicted == labels).sum().item()\n",
|
| 287 |
+
" total += labels.size(0)\n",
|
| 288 |
+
"\n",
|
| 289 |
+
" print(f\"Epoch {epoch+1} | Batch {batch_idx+1}/{len(small_loader)} | Loss: {round(loss.item(), 4)}\")\n",
|
| 290 |
+
"\n",
|
| 291 |
+
" accuracy = round((correct / total) * 100, 2)\n",
|
| 292 |
+
" avg_loss = round(total_loss / len(small_loader), 4)\n",
|
| 293 |
+
" print(f\"\\nEpoch {epoch+1} Summary:\")\n",
|
| 294 |
+
" print(f\" Average Loss : {avg_loss}\")\n",
|
| 295 |
+
" print(f\" Accuracy : {accuracy}%\\n\")\n",
|
| 296 |
+
"\n",
|
| 297 |
+
"print(\"Training complete! β
\")"
|
| 298 |
+
],
|
| 299 |
+
"metadata": {
|
| 300 |
+
"colab": {
|
| 301 |
+
"base_uri": "https://localhost:8080/"
|
| 302 |
+
},
|
| 303 |
+
"id": "jTWccloycRsU",
|
| 304 |
+
"outputId": "c2cfce1a-9ee0-4c57-f833-3ebbefc49007"
|
| 305 |
+
},
|
| 306 |
+
"execution_count": 7,
|
| 307 |
+
"outputs": [
|
| 308 |
+
{
|
| 309 |
+
"output_type": "stream",
|
| 310 |
+
"name": "stdout",
|
| 311 |
+
"text": [
|
| 312 |
+
"Using device: cpu\n",
|
| 313 |
+
"Training on 500 images (16 batches)\n",
|
| 314 |
+
"Starting training...\n",
|
| 315 |
+
"\n",
|
| 316 |
+
"Epoch 1 | Batch 1/16 | Loss: 0.7116\n",
|
| 317 |
+
"Epoch 1 | Batch 2/16 | Loss: 1.3489\n",
|
| 318 |
+
"Epoch 1 | Batch 3/16 | Loss: 1.1916\n",
|
| 319 |
+
"Epoch 1 | Batch 4/16 | Loss: 1.2354\n",
|
| 320 |
+
"Epoch 1 | Batch 5/16 | Loss: 1.4737\n",
|
| 321 |
+
"Epoch 1 | Batch 6/16 | Loss: 1.1769\n",
|
| 322 |
+
"Epoch 1 | Batch 7/16 | Loss: 1.4508\n",
|
| 323 |
+
"Epoch 1 | Batch 8/16 | Loss: 1.3606\n",
|
| 324 |
+
"Epoch 1 | Batch 9/16 | Loss: 1.7716\n",
|
| 325 |
+
"Epoch 1 | Batch 10/16 | Loss: 1.4312\n",
|
| 326 |
+
"Epoch 1 | Batch 11/16 | Loss: 1.4026\n",
|
| 327 |
+
"Epoch 1 | Batch 12/16 | Loss: 0.9197\n",
|
| 328 |
+
"Epoch 1 | Batch 13/16 | Loss: 2.539\n",
|
| 329 |
+
"Epoch 1 | Batch 14/16 | Loss: 1.0783\n",
|
| 330 |
+
"Epoch 1 | Batch 15/16 | Loss: 1.2675\n",
|
| 331 |
+
"Epoch 1 | Batch 16/16 | Loss: 1.628\n",
|
| 332 |
+
"\n",
|
| 333 |
+
"Epoch 1 Summary:\n",
|
| 334 |
+
" Average Loss : 1.3742\n",
|
| 335 |
+
" Accuracy : 57.4%\n",
|
| 336 |
+
"\n",
|
| 337 |
+
"Epoch 2 | Batch 1/16 | Loss: 0.9406\n",
|
| 338 |
+
"Epoch 2 | Batch 2/16 | Loss: 0.6462\n",
|
| 339 |
+
"Epoch 2 | Batch 3/16 | Loss: 0.4644\n",
|
| 340 |
+
"Epoch 2 | Batch 4/16 | Loss: 0.9182\n",
|
| 341 |
+
"Epoch 2 | Batch 5/16 | Loss: 0.9893\n",
|
| 342 |
+
"Epoch 2 | Batch 6/16 | Loss: 0.7247\n",
|
| 343 |
+
"Epoch 2 | Batch 7/16 | Loss: 0.8304\n",
|
| 344 |
+
"Epoch 2 | Batch 8/16 | Loss: 0.9865\n",
|
| 345 |
+
"Epoch 2 | Batch 9/16 | Loss: 0.7683\n",
|
| 346 |
+
"Epoch 2 | Batch 10/16 | Loss: 0.5611\n",
|
| 347 |
+
"Epoch 2 | Batch 11/16 | Loss: 0.8494\n",
|
| 348 |
+
"Epoch 2 | Batch 12/16 | Loss: 0.9649\n",
|
| 349 |
+
"Epoch 2 | Batch 13/16 | Loss: 0.7664\n",
|
| 350 |
+
"Epoch 2 | Batch 14/16 | Loss: 1.0289\n",
|
| 351 |
+
"Epoch 2 | Batch 15/16 | Loss: 0.7901\n",
|
| 352 |
+
"Epoch 2 | Batch 16/16 | Loss: 1.2206\n",
|
| 353 |
+
"\n",
|
| 354 |
+
"Epoch 2 Summary:\n",
|
| 355 |
+
" Average Loss : 0.8406\n",
|
| 356 |
+
" Accuracy : 69.8%\n",
|
| 357 |
+
"\n",
|
| 358 |
+
"Training complete! β
\n"
|
| 359 |
+
]
|
| 360 |
+
}
|
| 361 |
+
]
|
| 362 |
+
},
|
| 363 |
+
{
|
| 364 |
+
"cell_type": "code",
|
| 365 |
+
"source": [
|
| 366 |
+
"# ββ Step 5: Evaluate on Test Data βββββββββββββββββββββββββββ\n",
|
| 367 |
+
"# test the model on images it has NEVER seen before\n",
|
| 368 |
+
"# this tells us if model truly learned or just memorized\n",
|
| 369 |
+
"\n",
|
| 370 |
+
"from torch.utils.data import Subset\n",
|
| 371 |
+
"\n",
|
| 372 |
+
"# take 200 test images\n",
|
| 373 |
+
"small_test = Subset(test_dataset, range(200))\n",
|
| 374 |
+
"small_test_loader = DataLoader(small_test,\n",
|
| 375 |
+
" batch_size=32,\n",
|
| 376 |
+
" shuffle=False)\n",
|
| 377 |
+
"\n",
|
| 378 |
+
"# switch model to evaluation mode\n",
|
| 379 |
+
"# turns off dropout and batch normalization\n",
|
| 380 |
+
"model.eval()\n",
|
| 381 |
+
"\n",
|
| 382 |
+
"correct = 0\n",
|
| 383 |
+
"total = 0\n",
|
| 384 |
+
"\n",
|
| 385 |
+
"# torch.no_grad() = don't calculate gradients\n",
|
| 386 |
+
"# we're just testing, not training\n",
|
| 387 |
+
"with torch.no_grad():\n",
|
| 388 |
+
" for images, labels in small_test_loader:\n",
|
| 389 |
+
"\n",
|
| 390 |
+
" images = images.to(device)\n",
|
| 391 |
+
" labels = labels.to(device)\n",
|
| 392 |
+
"\n",
|
| 393 |
+
" # forward pass only\n",
|
| 394 |
+
" predictions = model(images)\n",
|
| 395 |
+
"\n",
|
| 396 |
+
" # get predicted class\n",
|
| 397 |
+
" _, predicted = torch.max(predictions, 1)\n",
|
| 398 |
+
" correct += (predicted == labels).sum().item()\n",
|
| 399 |
+
" total += labels.size(0)\n",
|
| 400 |
+
"\n",
|
| 401 |
+
"accuracy = round((correct / total) * 100, 2)\n",
|
| 402 |
+
"print(f\"Test Accuracy: {accuracy}%\")\n",
|
| 403 |
+
"print(f\"Correct: {correct}/{total}\")"
|
| 404 |
+
],
|
| 405 |
+
"metadata": {
|
| 406 |
+
"colab": {
|
| 407 |
+
"base_uri": "https://localhost:8080/"
|
| 408 |
+
},
|
| 409 |
+
"id": "UFj9_RLzlSFA",
|
| 410 |
+
"outputId": "933ecf45-afc5-41a6-d90c-410dd5eed1f5"
|
| 411 |
+
},
|
| 412 |
+
"execution_count": 8,
|
| 413 |
+
"outputs": [
|
| 414 |
+
{
|
| 415 |
+
"output_type": "stream",
|
| 416 |
+
"name": "stdout",
|
| 417 |
+
"text": [
|
| 418 |
+
"Test Accuracy: 52.0%\n",
|
| 419 |
+
"Correct: 104/200\n"
|
| 420 |
+
]
|
| 421 |
+
}
|
| 422 |
+
]
|
| 423 |
+
}
|
| 424 |
+
]
|
| 425 |
+
}
|
readme.md
ADDED
|
@@ -0,0 +1,83 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Transfer Learning using ResNet for Celebrity Recognition
|
| 2 |
+
|
| 3 |
+
## Description
|
| 4 |
+
This project demonstrates transfer learning using a pretrained ResNet18 model. The final layer is modified to recognize 10 categories (simulating Bengali celebrities) instead of the original 1000 ImageNet categories. The model is trained on the CIFAR-10 dataset as a practice dataset β the same concept applies directly to the Bengali Celebrity Multimodal Dataset project.
|
| 5 |
+
|
| 6 |
+
## What is Transfer Learning?
|
| 7 |
+
Transfer learning means borrowing a pretrained model that already knows edges, shapes, textures and face patterns from millions of images. We only replace the final layer to match our task. This saves months of training time and gives better results.
|
| 8 |
+
|
| 9 |
+
## Pipeline
|
| 10 |
+
```
|
| 11 |
+
Load Pretrained ResNet18 β Replace Final Layer (1000 β 10) β
|
| 12 |
+
Train on CIFAR-10 β Evaluate on Test Data
|
| 13 |
+
```
|
| 14 |
+
|
| 15 |
+
## Model Architecture
|
| 16 |
+
```
|
| 17 |
+
ResNet18 (pretrained on ImageNet)
|
| 18 |
+
β
|
| 19 |
+
βββ Conv layers 1-50 β already learned edges, shapes, patterns
|
| 20 |
+
β BORROWED from ImageNet training β
|
| 21 |
+
β
|
| 22 |
+
βββ Final layer β REPLACED
|
| 23 |
+
Original : Linear(512, 1000) β 1000 ImageNet categories
|
| 24 |
+
Modified : Linear(512, 10) β 10 celebrities
|
| 25 |
+
|
| 26 |
+
```
|
| 27 |
+
|
| 28 |
+
## Results
|
| 29 |
+
```
|
| 30 |
+
Training Accuracy : 69.8% (after 2 epochs, 500 images)
|
| 31 |
+
Test Accuracy : 52.0% (on 200 unseen images)
|
| 32 |
+
Random Guessing : 10.0% (10 categories)
|
| 33 |
+
|
| 34 |
+
Transfer learning is 5x better than random guessing!
|
| 35 |
+
```
|
| 36 |
+
|
| 37 |
+
## Two Types of Transfer Learning
|
| 38 |
+
- **Feature Extraction** β freeze all layers, train only final layer β good for small datasets
|
| 39 |
+
- **Fine Tuning** β train all layers, pretrained weights = starting point β good for large datasets (used in Bengali celebrity project)
|
| 40 |
+
|
| 41 |
+
## Project Connection
|
| 42 |
+
This project directly simulates the Bengali Celebrity Multimodal Dataset pipeline:
|
| 43 |
+
|
| 44 |
+
- **CIFAR-10 categories** β simulates Bengali celebrities
|
| 45 |
+
- **ResNet18 pretrained** β borrows face pattern knowledge
|
| 46 |
+
- **Final layer modified** β Linear(512, 250) for 250 Bengali celebrities
|
| 47 |
+
- **Training loop** β same loop used for real celebrity recognition
|
| 48 |
+
|
| 49 |
+
## Tech Stack
|
| 50 |
+
- Python
|
| 51 |
+
- PyTorch
|
| 52 |
+
- TorchVision
|
| 53 |
+
- ResNet18 (pretrained)
|
| 54 |
+
- CIFAR-10 Dataset
|
| 55 |
+
- Google Colab
|
| 56 |
+
|
| 57 |
+
## How to Run
|
| 58 |
+
1. Open notebook in Google Colab
|
| 59 |
+
2. Run all cells in order
|
| 60 |
+
3. Model downloads automatically
|
| 61 |
+
4. CIFAR-10 dataset downloads automatically
|
| 62 |
+
5. Training starts and shows accuracy per epoch
|
| 63 |
+
|
| 64 |
+
## Requirements
|
| 65 |
+
```
|
| 66 |
+
pip install torch
|
| 67 |
+
pip install torchvision
|
| 68 |
+
```
|
| 69 |
+
|
| 70 |
+
## Key PyTorch Concepts Used
|
| 71 |
+
- `models.resnet18(weights=DEFAULT)` β load pretrained model
|
| 72 |
+
- `model.fc = nn.Linear(512, 10)` β replace final layer
|
| 73 |
+
- `nn.CrossEntropyLoss()` β loss for classification
|
| 74 |
+
- `torch.optim.Adam()` β optimizer for fine tuning
|
| 75 |
+
- `model.eval()` β switch to evaluation mode
|
| 76 |
+
- `torch.no_grad()` β disable gradient during testing
|
| 77 |
+
|
| 78 |
+
## Author
|
| 79 |
+
Fatima Noor
|
| 80 |
+
## Related Projects
|
| 81 |
+
- [face-detection-scrfd](https://github.com/fatima-noor-ai/face-detection-scrfd) β Face detection on images
|
| 82 |
+
- [video-face-detection-scrfd](https://github.com/fatima-noor-ai/video-face-detection-scrfd) β Face detection on videos
|
| 83 |
+
- [audio-processing-mel-spectrogram](https://github.com/fatima-noor-ai/audio-processing-mel-spectrogram) β Audio processing
|