diff --git a/ml_model/notebooks/notebook[4].ipynb b/ml_model/notebooks/notebook[4].ipynb index 5460d14..53b1140 100644 --- a/ml_model/notebooks/notebook[4].ipynb +++ b/ml_model/notebooks/notebook[4].ipynb @@ -2,7 +2,7 @@ "cells": [ { "cell_type": "code", - "execution_count": 2, + "execution_count": 46, "metadata": {}, "outputs": [], "source": [ @@ -21,7 +21,7 @@ }, { "cell_type": "code", - "execution_count": 4, + "execution_count": 47, "metadata": {}, "outputs": [ { @@ -375,7 +375,7 @@ }, { "cell_type": "code", - "execution_count": 6, + "execution_count": 48, "metadata": {}, "outputs": [], "source": [ @@ -385,7 +385,7 @@ }, { "cell_type": "code", - "execution_count": 5, + "execution_count": 49, "metadata": {}, "outputs": [], "source": [ @@ -397,7 +397,7 @@ }, { "cell_type": "code", - "execution_count": 7, + "execution_count": 50, "metadata": {}, "outputs": [], "source": [ @@ -408,7 +408,196 @@ }, { "cell_type": "code", - "execution_count": 33, + "execution_count": 16, + "metadata": {}, + "outputs": [], + "source": [ + "import torch\n", + "import torch.nn as nn\n", + "import torch.optim as optim\n", + "from torch.optim import lr_scheduler\n", + "import torch.nn.functional as F\n", + "from tqdm import tqdm\n", + "\n", + "# Define the Spatial Attention Module\n", + "class SpatialAttention(nn.Module):\n", + " def __init__(self, in_channels):\n", + " super(SpatialAttention, self).__init__()\n", + " self.conv1 = nn.Conv2d(in_channels, 1, kernel_size=1) # Reduce channels to 1\n", + " self.conv2 = nn.Conv2d(1, 1, kernel_size=3, padding=1) # Learn spatial weights\n", + " self.sigmoid = nn.Sigmoid() # Normalize attention map to [0, 1]\n", + "\n", + " def forward(self, x):\n", + " attn = self.conv1(x) # Reduce channel dimension\n", + " attn = self.conv2(attn) # Learn spatial relationships\n", + " attn = self.sigmoid(attn) # Normalize\n", + " return x * attn # Apply attention\n", + "\n", + "# Define the Custom CNN with integrated Spatial Attention\n", + "class CustomCNNWithAttention(nn.Module):\n", + " def __init__(self, num_classes=6):\n", + " super(CustomCNNWithAttention, self).__init__()\n", + " # 1st Convolutional Block\n", + " self.conv1 = nn.Conv2d(3, 16, kernel_size=3, padding=1)\n", + " self.bn1 = nn.BatchNorm2d(16)\n", + " self.pool1 = nn.MaxPool2d(kernel_size=2, stride=2)\n", + "\n", + " # 2nd Convolutional Block\n", + " self.conv2 = nn.Conv2d(16, 32, kernel_size=3, padding=1)\n", + " self.bn2 = nn.BatchNorm2d(32)\n", + " self.pool2 = nn.MaxPool2d(kernel_size=2, stride=2)\n", + "\n", + " # 3rd Convolutional Block\n", + " self.conv3 = nn.Conv2d(32, 64, kernel_size=3, padding=1)\n", + " self.bn3 = nn.BatchNorm2d(64)\n", + " self.pool3 = nn.MaxPool2d(kernel_size=2, stride=2)\n", + "\n", + " # 4th Convolutional Block\n", + " self.conv4 = nn.Conv2d(64, 128, kernel_size=3, padding=1)\n", + " self.bn4 = nn.BatchNorm2d(128)\n", + " self.pool4 = nn.MaxPool2d(kernel_size=2, stride=2)\n", + "\n", + " # Attention Module\n", + " self.attention = SpatialAttention(in_channels=128)\n", + "\n", + " # Global Average Pooling\n", + " self.global_avg_pool = nn.AdaptiveAvgPool2d((1, 1))\n", + " \n", + " # Fully Connected Layers\n", + " self.fc1 = nn.Linear(128, 512)\n", + " self.fc2 = nn.Linear(512, num_classes) # Output for `num_classes` classes\n", + "\n", + " # Dropout for Regularization\n", + " self.dropout = nn.Dropout(0.5)\n", + "\n", + " def forward(self, x):\n", + " # 1st Convolutional Block\n", + " x = self.pool1(F.relu(self.bn1(self.conv1(x))))\n", + " \n", + " # 2nd Convolutional Block\n", + " x = self.pool2(F.relu(self.bn2(self.conv2(x))))\n", + " \n", + " # 3rd Convolutional Block\n", + " x = self.pool3(F.relu(self.bn3(self.conv3(x))))\n", + "\n", + " # 4th Convolutional Block\n", + " x = self.pool4(F.relu(self.bn4(self.conv4(x))))\n", + "\n", + " # Apply Attention Mechanism\n", + " x = self.attention(x)\n", + "\n", + " # Global Average Pooling\n", + " x = self.global_avg_pool(x)\n", + " \n", + " # Flatten the output\n", + " x = torch.flatten(x, 1)\n", + " \n", + " # Fully Connected Layers\n", + " x = F.relu(self.fc1(x))\n", + " x = self.dropout(x)\n", + " x = self.fc2(x)\n", + " \n", + " return x\n", + "\n", + "# Train and Validation Function\n", + "def train_model(model, train_loader, val_loader, criterion, optimizer, scheduler, num_epochs=20, device=\"cuda\" if torch.cuda.is_available() else \"cpu\"):\n", + " model = model.to(device)\n", + " best_acc = 0.0\n", + "\n", + " for epoch in range(num_epochs):\n", + " print(f\"Epoch {epoch + 1}/{num_epochs}\")\n", + " print(\"-\" * 30)\n", + "\n", + " # Training Phase\n", + " model.train()\n", + " running_loss = 0.0\n", + " running_corrects = 0\n", + " total_train = 0\n", + "\n", + " for inputs, labels in tqdm(train_loader, desc=\"Training\"):\n", + " inputs = inputs.to(device)\n", + " labels = labels.to(device).long() # Ensure labels are of type torch.long\n", + "\n", + " # Zero the parameter gradients\n", + " optimizer.zero_grad()\n", + "\n", + " # Forward Pass\n", + " outputs = model(inputs)\n", + " loss = criterion(outputs, labels)\n", + " _, preds = torch.max(outputs, 1)\n", + "\n", + " # Backward Pass and Optimization\n", + " loss.backward()\n", + " optimizer.step()\n", + "\n", + " # Track statistics\n", + " running_loss += loss.item() * inputs.size(0)\n", + " running_corrects += torch.sum(preds == labels.data)\n", + " total_train += labels.size(0)\n", + "\n", + " # Adjust learning rate\n", + " scheduler.step()\n", + "\n", + " epoch_loss = running_loss / total_train\n", + " epoch_acc = running_corrects.double() / total_train\n", + "\n", + " print(f\"Training Loss: {epoch_loss:.4f} Acc: {epoch_acc:.4f}\")\n", + "\n", + " # Validation Phase\n", + " model.eval()\n", + " running_loss = 0.0\n", + " running_corrects = 0\n", + " total_val = 0\n", + "\n", + " with torch.no_grad():\n", + " for inputs, labels in tqdm(val_loader, desc=\"Validation\"):\n", + " inputs = inputs.to(device)\n", + " labels = labels.to(device).long() # Ensure labels are of type torch.long\n", + "\n", + " # Forward Pass\n", + " outputs = model(inputs)\n", + " loss = criterion(outputs, labels)\n", + " _, preds = torch.max(outputs, 1)\n", + "\n", + " # Track statistics\n", + " running_loss += loss.item() * inputs.size(0)\n", + " running_corrects += torch.sum(preds == labels.data)\n", + " total_val += labels.size(0)\n", + "\n", + " epoch_val_loss = running_loss / total_val\n", + " epoch_val_acc = running_corrects.double() / total_val\n", + "\n", + " print(f\"Validation Loss: {epoch_val_loss:.4f} Acc: {epoch_val_acc:.4f}\")\n", + "\n", + " # Save the best model\n", + " if epoch_val_acc > best_acc:\n", + " best_acc = epoch_val_acc\n", + " torch.save(model, \"customcnnwithAttention_full.pth\")\n", + "\n", + "\n", + " print(f\"Training complete. Best Validation Acc: {best_acc:.4f}\")\n", + "\n", + "\n", + " \n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "metadata": {}, + "outputs": [], + "source": [ + "model_deepercnn = CustomCNNWithAttention(num_classes=6)\n", + "criterion = nn.CrossEntropyLoss()\n", + "\n", + "optimizer_deepercnn = optim.Adam(model_deepercnn.parameters(), lr=0.001)\n", + "scheduler_deepercnn = lr_scheduler.StepLR(optimizer_deepercnn, step_size=7, gamma=0.1)\n" + ] + }, + { + "cell_type": "code", + "execution_count": 19, "metadata": {}, "outputs": [ { @@ -423,28 +612,28 @@ "name": "stderr", "output_type": "stream", "text": [ - "Training: 100%|██████████| 516/516 [01:14<00:00, 6.96it/s]\n" + "Training: 100%|██████████| 516/516 [05:05<00:00, 1.69it/s]\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ - "Training Loss: 0.8376 Acc: 0.6717\n" + "Training Loss: 0.8360 Acc: 0.6724\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ - "Validation: 100%|██████████| 31/31 [00:03<00:00, 8.47it/s]\n" + "Validation: 100%|██████████| 31/31 [00:21<00:00, 1.42it/s]\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ - "Validation Loss: 0.5899 Acc: 0.7810\n", + "Validation Loss: 0.6254 Acc: 0.7727\n", "Epoch 2/20\n", "------------------------------\n" ] @@ -453,28 +642,28 @@ "name": "stderr", "output_type": "stream", "text": [ - "Training: 100%|██████████| 516/516 [02:04<00:00, 4.15it/s]\n" + "Training: 100%|██████████| 516/516 [05:39<00:00, 1.52it/s]\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ - "Training Loss: 0.4635 Acc: 0.8398\n" + "Training Loss: 0.4946 Acc: 0.8168\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ - "Validation: 100%|██████████| 31/31 [00:03<00:00, 8.43it/s]\n" + "Validation: 100%|██████████| 31/31 [00:22<00:00, 1.39it/s]\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ - "Validation Loss: 1.0286 Acc: 0.6694\n", + "Validation Loss: 0.2939 Acc: 0.9008\n", "Epoch 3/20\n", "------------------------------\n" ] @@ -483,28 +672,28 @@ "name": "stderr", "output_type": "stream", "text": [ - "Training: 100%|██████████| 516/516 [01:06<00:00, 7.74it/s]\n" + "Training: 100%|██████████| 516/516 [05:50<00:00, 1.47it/s]\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ - "Training Loss: 0.3725 Acc: 0.8760\n" + "Training Loss: 0.3618 Acc: 0.8777\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ - "Validation: 100%|██████████| 31/31 [00:03<00:00, 8.92it/s]\n" + "Validation: 100%|██████████| 31/31 [00:20<00:00, 1.50it/s]\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ - "Validation Loss: 0.3632 Acc: 0.8430\n", + "Validation Loss: 0.2257 Acc: 0.9174\n", "Epoch 4/20\n", "------------------------------\n" ] @@ -513,28 +702,28 @@ "name": "stderr", "output_type": "stream", "text": [ - "Training: 100%|██████████| 516/516 [01:06<00:00, 7.72it/s]\n" + "Training: 100%|██████████| 516/516 [05:17<00:00, 1.62it/s]\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ - "Training Loss: 0.2876 Acc: 0.8991\n" + "Training Loss: 0.2992 Acc: 0.8947\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ - "Validation: 100%|██████████| 31/31 [00:03<00:00, 8.84it/s]\n" + "Validation: 100%|██████████| 31/31 [00:15<00:00, 1.98it/s]\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ - "Validation Loss: 0.1987 Acc: 0.9421\n", + "Validation Loss: 0.4048 Acc: 0.8595\n", "Epoch 5/20\n", "------------------------------\n" ] @@ -543,28 +732,28 @@ "name": "stderr", "output_type": "stream", "text": [ - "Training: 100%|██████████| 516/516 [01:23<00:00, 6.19it/s]\n" + "Training: 100%|██████████| 516/516 [02:36<00:00, 3.30it/s]\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ - "Training Loss: 0.2244 Acc: 0.9204\n" + "Training Loss: 0.2199 Acc: 0.9274\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ - "Validation: 100%|██████████| 31/31 [00:07<00:00, 4.28it/s]\n" + "Validation: 100%|██████████| 31/31 [00:06<00:00, 4.54it/s]\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ - "Validation Loss: 0.1300 Acc: 0.9628\n", + "Validation Loss: 0.1676 Acc: 0.9463\n", "Epoch 6/20\n", "------------------------------\n" ] @@ -573,28 +762,28 @@ "name": "stderr", "output_type": "stream", "text": [ - "Training: 100%|██████████| 516/516 [02:13<00:00, 3.87it/s]\n" + "Training: 100%|██████████| 516/516 [01:57<00:00, 4.37it/s]\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ - "Training Loss: 0.1765 Acc: 0.9364\n" + "Training Loss: 0.2032 Acc: 0.9304\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ - "Validation: 100%|██████████| 31/31 [00:07<00:00, 4.39it/s]\n" + "Validation: 100%|██████████| 31/31 [00:05<00:00, 5.74it/s]\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ - "Validation Loss: 0.1446 Acc: 0.9545\n", + "Validation Loss: 0.1988 Acc: 0.9256\n", "Epoch 7/20\n", "------------------------------\n" ] @@ -603,28 +792,28 @@ "name": "stderr", "output_type": "stream", "text": [ - "Training: 100%|██████████| 516/516 [01:12<00:00, 7.09it/s]\n" + "Training: 100%|██████████| 516/516 [01:48<00:00, 4.76it/s]\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ - "Training Loss: 0.1840 Acc: 0.9369\n" + "Training Loss: 0.1855 Acc: 0.9367\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ - "Validation: 100%|██████████| 31/31 [00:03<00:00, 8.91it/s]\n" + "Validation: 100%|██████████| 31/31 [00:06<00:00, 5.02it/s]\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ - "Validation Loss: 0.1111 Acc: 0.9504\n", + "Validation Loss: 0.1505 Acc: 0.9380\n", "Epoch 8/20\n", "------------------------------\n" ] @@ -633,28 +822,28 @@ "name": "stderr", "output_type": "stream", "text": [ - "Training: 100%|██████████| 516/516 [01:04<00:00, 7.97it/s]\n" + "Training: 100%|██████████| 516/516 [01:53<00:00, 4.53it/s]\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ - "Training Loss: 0.0949 Acc: 0.9709\n" + "Training Loss: 0.0934 Acc: 0.9719\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ - "Validation: 100%|██████████| 31/31 [00:05<00:00, 5.61it/s]\n" + "Validation: 100%|██████████| 31/31 [00:05<00:00, 5.75it/s]\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ - "Validation Loss: 0.0643 Acc: 0.9793\n", + "Validation Loss: 0.0882 Acc: 0.9793\n", "Epoch 9/20\n", "------------------------------\n" ] @@ -663,28 +852,28 @@ "name": "stderr", "output_type": "stream", "text": [ - "Training: 100%|██████████| 516/516 [02:06<00:00, 4.09it/s]\n" + "Training: 100%|██████████| 516/516 [01:57<00:00, 4.40it/s]\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ - "Training Loss: 0.0734 Acc: 0.9757\n" + "Training Loss: 0.0813 Acc: 0.9760\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ - "Validation: 100%|██████████| 31/31 [00:07<00:00, 4.06it/s]\n" + "Validation: 100%|██████████| 31/31 [00:06<00:00, 5.05it/s]\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ - "Validation Loss: 0.0670 Acc: 0.9752\n", + "Validation Loss: 0.0824 Acc: 0.9752\n", "Epoch 10/20\n", "------------------------------\n" ] @@ -693,28 +882,28 @@ "name": "stderr", "output_type": "stream", "text": [ - "Training: 100%|██████████| 516/516 [02:15<00:00, 3.81it/s]\n" + "Training: 100%|██████████| 516/516 [01:53<00:00, 4.56it/s]\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ - "Training Loss: 0.0596 Acc: 0.9791\n" + "Training Loss: 0.0719 Acc: 0.9777\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ - "Validation: 100%|██████████| 31/31 [00:07<00:00, 3.97it/s]\n" + "Validation: 100%|██████████| 31/31 [00:03<00:00, 7.94it/s]\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ - "Validation Loss: 0.0590 Acc: 0.9752\n", + "Validation Loss: 0.0950 Acc: 0.9752\n", "Epoch 11/20\n", "------------------------------\n" ] @@ -723,28 +912,28 @@ "name": "stderr", "output_type": "stream", "text": [ - "Training: 100%|██████████| 516/516 [01:17<00:00, 6.69it/s]\n" + "Training: 100%|██████████| 516/516 [01:12<00:00, 7.11it/s]\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ - "Training Loss: 0.0617 Acc: 0.9811\n" + "Training Loss: 0.0635 Acc: 0.9801\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ - "Validation: 100%|██████████| 31/31 [00:03<00:00, 8.75it/s]\n" + "Validation: 100%|██████████| 31/31 [00:03<00:00, 9.15it/s]\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ - "Validation Loss: 0.0857 Acc: 0.9628\n", + "Validation Loss: 0.0710 Acc: 0.9752\n", "Epoch 12/20\n", "------------------------------\n" ] @@ -753,28 +942,28 @@ "name": "stderr", "output_type": "stream", "text": [ - "Training: 100%|██████████| 516/516 [01:05<00:00, 7.89it/s]\n" + "Training: 100%|██████████| 516/516 [01:16<00:00, 6.77it/s]\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ - "Training Loss: 0.0572 Acc: 0.9813\n" + "Training Loss: 0.0640 Acc: 0.9801\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ - "Validation: 100%|██████████| 31/31 [00:03<00:00, 8.77it/s]\n" + "Validation: 100%|██████████| 31/31 [00:03<00:00, 8.58it/s]\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ - "Validation Loss: 0.0622 Acc: 0.9752\n", + "Validation Loss: 0.0865 Acc: 0.9793\n", "Epoch 13/20\n", "------------------------------\n" ] @@ -783,28 +972,28 @@ "name": "stderr", "output_type": "stream", "text": [ - "Training: 100%|██████████| 516/516 [01:09<00:00, 7.38it/s]\n" + "Training: 100%|██████████| 516/516 [01:32<00:00, 5.59it/s]\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ - "Training Loss: 0.0581 Acc: 0.9808\n" + "Training Loss: 0.0533 Acc: 0.9837\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ - "Validation: 100%|██████████| 31/31 [00:08<00:00, 3.86it/s]\n" + "Validation: 100%|██████████| 31/31 [00:04<00:00, 6.58it/s]\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ - "Validation Loss: 0.0446 Acc: 0.9835\n", + "Validation Loss: 0.0667 Acc: 0.9752\n", "Epoch 14/20\n", "------------------------------\n" ] @@ -813,28 +1002,28 @@ "name": "stderr", "output_type": "stream", "text": [ - "Training: 100%|██████████| 516/516 [01:15<00:00, 6.80it/s]\n" + "Training: 100%|██████████| 516/516 [01:38<00:00, 5.22it/s]\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ - "Training Loss: 0.0536 Acc: 0.9842\n" + "Training Loss: 0.0523 Acc: 0.9840\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ - "Validation: 100%|██████████| 31/31 [00:03<00:00, 8.89it/s]\n" + "Validation: 100%|██████████| 31/31 [00:04<00:00, 6.80it/s]\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ - "Validation Loss: 0.0394 Acc: 0.9835\n", + "Validation Loss: 0.0704 Acc: 0.9793\n", "Epoch 15/20\n", "------------------------------\n" ] @@ -843,28 +1032,28 @@ "name": "stderr", "output_type": "stream", "text": [ - "Training: 100%|██████████| 516/516 [01:03<00:00, 8.07it/s]\n" + "Training: 100%|██████████| 516/516 [01:33<00:00, 5.54it/s]\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ - "Training Loss: 0.0398 Acc: 0.9874\n" + "Training Loss: 0.0432 Acc: 0.9876\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ - "Validation: 100%|██████████| 31/31 [00:03<00:00, 8.96it/s]\n" + "Validation: 100%|██████████| 31/31 [00:04<00:00, 6.82it/s]\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ - "Validation Loss: 0.0329 Acc: 0.9876\n", + "Validation Loss: 0.0670 Acc: 0.9793\n", "Epoch 16/20\n", "------------------------------\n" ] @@ -873,28 +1062,28 @@ "name": "stderr", "output_type": "stream", "text": [ - "Training: 100%|██████████| 516/516 [01:04<00:00, 7.95it/s]\n" + "Training: 100%|██████████| 516/516 [01:34<00:00, 5.48it/s]\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ - "Training Loss: 0.0419 Acc: 0.9871\n" + "Training Loss: 0.0459 Acc: 0.9830\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ - "Validation: 100%|██████████| 31/31 [00:03<00:00, 8.94it/s]\n" + "Validation: 100%|██████████| 31/31 [00:04<00:00, 7.13it/s]\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ - "Validation Loss: 0.0393 Acc: 0.9876\n", + "Validation Loss: 0.0663 Acc: 0.9752\n", "Epoch 17/20\n", "------------------------------\n" ] @@ -903,28 +1092,28 @@ "name": "stderr", "output_type": "stream", "text": [ - "Training: 100%|██████████| 516/516 [01:04<00:00, 8.04it/s]\n" + "Training: 100%|██████████| 516/516 [01:33<00:00, 5.52it/s]\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ - "Training Loss: 0.0380 Acc: 0.9888\n" + "Training Loss: 0.0412 Acc: 0.9871\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ - "Validation: 100%|██████████| 31/31 [00:03<00:00, 8.93it/s]\n" + "Validation: 100%|██████████| 31/31 [00:04<00:00, 7.10it/s]\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ - "Validation Loss: 0.0362 Acc: 0.9793\n", + "Validation Loss: 0.0779 Acc: 0.9793\n", "Epoch 18/20\n", "------------------------------\n" ] @@ -933,28 +1122,28 @@ "name": "stderr", "output_type": "stream", "text": [ - "Training: 100%|██████████| 516/516 [01:04<00:00, 8.04it/s]\n" + "Training: 100%|██████████| 516/516 [01:28<00:00, 5.83it/s]\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ - "Training Loss: 0.0353 Acc: 0.9888\n" + "Training Loss: 0.0432 Acc: 0.9859\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ - "Validation: 100%|██████████| 31/31 [00:03<00:00, 8.88it/s]\n" + "Validation: 100%|██████████| 31/31 [00:04<00:00, 7.35it/s]\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ - "Validation Loss: 0.0415 Acc: 0.9793\n", + "Validation Loss: 0.0831 Acc: 0.9793\n", "Epoch 19/20\n", "------------------------------\n" ] @@ -963,28 +1152,28 @@ "name": "stderr", "output_type": "stream", "text": [ - "Training: 100%|██████████| 516/516 [01:05<00:00, 7.86it/s]\n" + "Training: 100%|██████████| 516/516 [01:43<00:00, 5.00it/s]\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ - "Training Loss: 0.0372 Acc: 0.9876\n" + "Training Loss: 0.0388 Acc: 0.9874\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ - "Validation: 100%|██████████| 31/31 [00:03<00:00, 8.68it/s]\n" + "Validation: 100%|██████████| 31/31 [00:05<00:00, 5.94it/s]\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ - "Validation Loss: 0.0347 Acc: 0.9835\n", + "Validation Loss: 0.0580 Acc: 0.9793\n", "Epoch 20/20\n", "------------------------------\n" ] @@ -993,29 +1182,29 @@ "name": "stderr", "output_type": "stream", "text": [ - "Training: 100%|██████████| 516/516 [01:03<00:00, 8.09it/s]\n" + "Training: 100%|██████████| 516/516 [01:34<00:00, 5.45it/s]\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ - "Training Loss: 0.0330 Acc: 0.9908\n" + "Training Loss: 0.0392 Acc: 0.9886\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ - "Validation: 100%|██████████| 31/31 [00:03<00:00, 8.83it/s]" + "Validation: 100%|██████████| 31/31 [00:04<00:00, 7.56it/s]" ] }, { "name": "stdout", "output_type": "stream", "text": [ - "Validation Loss: 0.0374 Acc: 0.9876\n", - "Training complete. Best Validation Acc: 0.9876\n" + "Validation Loss: 0.0535 Acc: 0.9793\n", + "Training complete. Best Validation Acc: 0.9793\n" ] }, { @@ -1027,339 +1216,159 @@ } ], "source": [ - "import torch\n", - "import torch.nn as nn\n", - "import torch.optim as optim\n", - "from torch.optim import lr_scheduler\n", - "import torch.nn.functional as F\n", - "from tqdm import tqdm\n", + " # Train the model\n", + "train_model(model_deepercnn, train_loader, val_loader, criterion, optimizer_deepercnn, scheduler_deepercnn, num_epochs=20)" + ] + }, + { + "cell_type": "code", + "execution_count": 58, + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "C:\\Users\\Shravya H Jain\\AppData\\Local\\Temp\\ipykernel_22584\\4239124031.py:39: FutureWarning: You are using `torch.load` with `weights_only=False` (the current default value), which uses the default pickle module implicitly. It is possible to construct malicious pickle data which will execute arbitrary code during unpickling (See https://github.com/pytorch/pytorch/blob/main/SECURITY.md#untrusted-models for more details). In a future release, the default value for `weights_only` will be flipped to `True`. This limits the functions that could be executed during unpickling. Arbitrary objects will no longer be allowed to be loaded via this mode unless they are explicitly allowlisted by the user via `torch.serialization.add_safe_globals`. We recommend you start setting `weights_only=True` for any use case where you don't have full control of the loaded file. Please open an issue on GitHub for any issues related to this experimental feature.\n", + " model = torch.load(\"customcnnwithAttention_full.pth\")\n", + "Testing: 100%|██████████| 61/61 [00:07<00:00, 8.13it/s]\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Test Accuracy: 0.9794\n" + ] + }, + { + "data": { + "text/plain": [ + "tensor(0.9794, device='cuda:0', dtype=torch.float64)" + ] + }, + "execution_count": 58, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "def test_model(model, test_loader, device=\"cuda\" if torch.cuda.is_available() else \"cpu\"):\n", + " \"\"\"\n", + " Test the trained model on a test dataset.\n", "\n", - "# Define the Spatial Attention Module\n", - "class SpatialAttention(nn.Module):\n", - " def __init__(self, in_channels):\n", - " super(SpatialAttention, self).__init__()\n", - " self.conv1 = nn.Conv2d(in_channels, 1, kernel_size=1) # Reduce channels to 1\n", - " self.conv2 = nn.Conv2d(1, 1, kernel_size=3, padding=1) # Learn spatial weights\n", - " self.sigmoid = nn.Sigmoid() # Normalize attention map to [0, 1]\n", + " Args:\n", + " model (torch.nn.Module): Trained model.\n", + " test_loader (torch.utils.data.DataLoader): DataLoader for the test dataset.\n", + " device (str): Device to perform testing on (e.g., 'cuda' or 'cpu').\n", + " \n", + " Returns:\n", + " float: Test accuracy.\n", + " \"\"\"\n", + " model = model.to(device)\n", + " model.eval() # Set model to evaluation mode\n", + " running_corrects = 0\n", + " total_test = 0\n", "\n", - " def forward(self, x):\n", - " attn = self.conv1(x) # Reduce channel dimension\n", - " attn = self.conv2(attn) # Learn spatial relationships\n", - " attn = self.sigmoid(attn) # Normalize\n", - " return x * attn # Apply attention\n", + " with torch.no_grad():\n", + " for inputs, labels in tqdm(test_loader, desc=\"Testing\"):\n", + " inputs = inputs.to(device)\n", + " labels = labels.to(device).long() # Ensure labels are of type torch.long\n", "\n", - "# Define the Custom CNN with integrated Spatial Attention\n", - "class CustomCNNWithAttention(nn.Module):\n", - " def __init__(self, num_classes=6):\n", - " super(CustomCNNWithAttention, self).__init__()\n", - " # 1st Convolutional Block\n", - " self.conv1 = nn.Conv2d(3, 16, kernel_size=3, padding=1)\n", - " self.bn1 = nn.BatchNorm2d(16)\n", - " self.pool1 = nn.MaxPool2d(kernel_size=2, stride=2)\n", + " # Forward pass\n", + " outputs = model(inputs)\n", + " _, preds = torch.max(outputs, 1)\n", "\n", - " # 2nd Convolutional Block\n", - " self.conv2 = nn.Conv2d(16, 32, kernel_size=3, padding=1)\n", - " self.bn2 = nn.BatchNorm2d(32)\n", - " self.pool2 = nn.MaxPool2d(kernel_size=2, stride=2)\n", + " # Track statistics\n", + " running_corrects += torch.sum(preds == labels.data)\n", + " total_test += labels.size(0)\n", "\n", - " # 3rd Convolutional Block\n", - " self.conv3 = nn.Conv2d(32, 64, kernel_size=3, padding=1)\n", - " self.bn3 = nn.BatchNorm2d(64)\n", - " self.pool3 = nn.MaxPool2d(kernel_size=2, stride=2)\n", - "\n", - " # 4th Convolutional Block\n", - " self.conv4 = nn.Conv2d(64, 128, kernel_size=3, padding=1)\n", - " self.bn4 = nn.BatchNorm2d(128)\n", - " self.pool4 = nn.MaxPool2d(kernel_size=2, stride=2)\n", - "\n", - " # Attention Module\n", - " self.attention = SpatialAttention(in_channels=128)\n", - "\n", - " # Global Average Pooling\n", - " self.global_avg_pool = nn.AdaptiveAvgPool2d((1, 1))\n", - " \n", - " # Fully Connected Layers\n", - " self.fc1 = nn.Linear(128, 512)\n", - " self.fc2 = nn.Linear(512, num_classes) # Output for `num_classes` classes\n", - "\n", - " # Dropout for Regularization\n", - " self.dropout = nn.Dropout(0.5)\n", - "\n", - " def forward(self, x):\n", - " # 1st Convolutional Block\n", - " x = self.pool1(F.relu(self.bn1(self.conv1(x))))\n", - " \n", - " # 2nd Convolutional Block\n", - " x = self.pool2(F.relu(self.bn2(self.conv2(x))))\n", - " \n", - " # 3rd Convolutional Block\n", - " x = self.pool3(F.relu(self.bn3(self.conv3(x))))\n", - "\n", - " # 4th Convolutional Block\n", - " x = self.pool4(F.relu(self.bn4(self.conv4(x))))\n", - "\n", - " # Apply Attention Mechanism\n", - " x = self.attention(x)\n", - "\n", - " # Global Average Pooling\n", - " x = self.global_avg_pool(x)\n", - " \n", - " # Flatten the output\n", - " x = torch.flatten(x, 1)\n", - " \n", - " # Fully Connected Layers\n", - " x = F.relu(self.fc1(x))\n", - " x = self.dropout(x)\n", - " x = self.fc2(x)\n", - " \n", - " return x\n", - "\n", - "# Train and Validation Function\n", - "def train_model(model, train_loader, val_loader, criterion, optimizer, scheduler, num_epochs=20, device=\"cuda\" if torch.cuda.is_available() else \"cpu\"):\n", - " model = model.to(device)\n", - " best_acc = 0.0\n", - "\n", - " for epoch in range(num_epochs):\n", - " print(f\"Epoch {epoch + 1}/{num_epochs}\")\n", - " print(\"-\" * 30)\n", - "\n", - " # Training Phase\n", - " model.train()\n", - " running_loss = 0.0\n", - " running_corrects = 0\n", - " total_train = 0\n", - "\n", - " for inputs, labels in tqdm(train_loader, desc=\"Training\"):\n", - " inputs = inputs.to(device)\n", - " labels = labels.to(device).long() # Ensure labels are of type torch.long\n", - "\n", - " # Zero the parameter gradients\n", - " optimizer.zero_grad()\n", - "\n", - " # Forward Pass\n", - " outputs = model(inputs)\n", - " loss = criterion(outputs, labels)\n", - " _, preds = torch.max(outputs, 1)\n", - "\n", - " # Backward Pass and Optimization\n", - " loss.backward()\n", - " optimizer.step()\n", - "\n", - " # Track statistics\n", - " running_loss += loss.item() * inputs.size(0)\n", - " running_corrects += torch.sum(preds == labels.data)\n", - " total_train += labels.size(0)\n", - "\n", - " # Adjust learning rate\n", - " scheduler.step()\n", - "\n", - " epoch_loss = running_loss / total_train\n", - " epoch_acc = running_corrects.double() / total_train\n", - "\n", - " print(f\"Training Loss: {epoch_loss:.4f} Acc: {epoch_acc:.4f}\")\n", - "\n", - " # Validation Phase\n", - " model.eval()\n", - " running_loss = 0.0\n", - " running_corrects = 0\n", - " total_val = 0\n", - "\n", - " with torch.no_grad():\n", - " for inputs, labels in tqdm(val_loader, desc=\"Validation\"):\n", - " inputs = inputs.to(device)\n", - " labels = labels.to(device).long() # Ensure labels are of type torch.long\n", - "\n", - " # Forward Pass\n", - " outputs = model(inputs)\n", - " loss = criterion(outputs, labels)\n", - " _, preds = torch.max(outputs, 1)\n", - "\n", - " # Track statistics\n", - " running_loss += loss.item() * inputs.size(0)\n", - " running_corrects += torch.sum(preds == labels.data)\n", - " total_val += labels.size(0)\n", - "\n", - " epoch_val_loss = running_loss / total_val\n", - " epoch_val_acc = running_corrects.double() / total_val\n", - "\n", - " print(f\"Validation Loss: {epoch_val_loss:.4f} Acc: {epoch_val_acc:.4f}\")\n", - "\n", - " # Save the best model\n", - " if epoch_val_acc > best_acc:\n", - " best_acc = epoch_val_acc\n", - " torch.save(model.state_dict(), \"customcnnwithAttention.pth\")\n", - "\n", - " print(f\"Training complete. Best Validation Acc: {best_acc:.4f}\")\n", - "\n", - "# Example Usage\n", - "if __name__ == \"__main__\":\n", - " # Assuming train_loader and val_loader are defined\n", - " model_deepercnn = CustomCNNWithAttention(num_classes=6)\n", - " criterion = nn.CrossEntropyLoss()\n", + " test_acc = running_corrects.double() / total_test\n", + " print(f\"Test Accuracy: {test_acc:.4f}\")\n", + " return test_acc\n", "\n", - " optimizer_deepercnn = optim.Adam(model_deepercnn.parameters(), lr=0.001)\n", - " scheduler_deepercnn = lr_scheduler.StepLR(optimizer_deepercnn, step_size=7, gamma=0.1)\n", "\n", - " # Train the model\n", - " train_model(model_deepercnn, train_loader, val_loader, criterion, optimizer_deepercnn, scheduler_deepercnn, num_epochs=20)\n" + "# Example usage:\n", + "# Assuming `test_loader` is your DataLoader for the test dataset.\n", + "# Load the trained model:\n", + "model = torch.load(\"customcnnwithAttention_full.pth\")\n", + "test_model(model, test_loader)\n" ] }, { "cell_type": "code", - "execution_count": 8, + "execution_count": 60, "metadata": {}, - "outputs": [ - { - "ename": "ModuleNotFoundError", - "evalue": "No module named 'seaborn'", - "output_type": "error", - "traceback": [ - "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m", - "\u001b[1;31mModuleNotFoundError\u001b[0m Traceback (most recent call last)", - "Cell \u001b[1;32mIn[8], line 3\u001b[0m\n\u001b[0;32m 1\u001b[0m \u001b[38;5;28;01mimport\u001b[39;00m \u001b[38;5;21;01mmatplotlib\u001b[39;00m\u001b[38;5;21;01m.\u001b[39;00m\u001b[38;5;21;01mpyplot\u001b[39;00m \u001b[38;5;28;01mas\u001b[39;00m \u001b[38;5;21;01mplt\u001b[39;00m\n\u001b[0;32m 2\u001b[0m \u001b[38;5;28;01mfrom\u001b[39;00m \u001b[38;5;21;01msklearn\u001b[39;00m\u001b[38;5;21;01m.\u001b[39;00m\u001b[38;5;21;01mmetrics\u001b[39;00m \u001b[38;5;28;01mimport\u001b[39;00m roc_curve, auc, precision_recall_curve, confusion_matrix, classification_report\n\u001b[1;32m----> 3\u001b[0m \u001b[38;5;28;01mimport\u001b[39;00m \u001b[38;5;21;01mseaborn\u001b[39;00m \u001b[38;5;28;01mas\u001b[39;00m \u001b[38;5;21;01msns\u001b[39;00m\n\u001b[0;32m 4\u001b[0m \u001b[38;5;28;01mimport\u001b[39;00m \u001b[38;5;21;01mnumpy\u001b[39;00m \u001b[38;5;28;01mas\u001b[39;00m \u001b[38;5;21;01mnp\u001b[39;00m\n\u001b[0;32m 6\u001b[0m \u001b[38;5;66;03m# Function to plot ROC-AUC Curve\u001b[39;00m\n", - "\u001b[1;31mModuleNotFoundError\u001b[0m: No module named 'seaborn'" - ] - } - ], + "outputs": [], "source": [ "import matplotlib.pyplot as plt\n", - "from sklearn.metrics import roc_curve, auc, precision_recall_curve, confusion_matrix, classification_report\n", - "import seaborn as sns\n", - "import numpy as np\n", + "from sklearn.metrics import roc_curve, auc, accuracy_score\n", + "import torch\n", + "from tqdm import tqdm\n", "\n", - "# Function to plot ROC-AUC Curve\n", - "def plot_roc_curve(model, test_loader, device=\"cuda\" if torch.cuda.is_available() else \"cpu\"):\n", + "# Testing Function\n", + "def test_model1(model, test_loader, device=\"cuda\" if torch.cuda.is_available() else \"cpu\", num_classes=6):\n", + " model = model.to(device)\n", " model.eval()\n", - " y_true = []\n", - " y_scores = []\n", + " true_labels = []\n", + " predicted_labels = []\n", + " predicted_probs = []\n", + " batch_accuracies = []\n", "\n", " with torch.no_grad():\n", - " for inputs, labels in test_loader:\n", + " for inputs, labels in tqdm(test_loader, desc=\"Testing\"):\n", " inputs = inputs.to(device)\n", - " labels = labels.to(device).long()\n", + " labels = labels.to(device).long() # Ensure labels are of type torch.long\n", "\n", - " # Forward pass\n", + " # Forward Pass\n", " outputs = model(inputs)\n", - " probs = torch.softmax(outputs, dim=1) # Get probabilities\n", - "\n", - " y_true.extend(labels.cpu().numpy())\n", - " y_scores.extend(probs.cpu().numpy())\n", - "\n", - " y_true = np.array(y_true)\n", - " y_scores = np.array(y_scores)\n", - "\n", - " # Compute ROC curve and ROC area for each class\n", - " for i in range(y_scores.shape[1]):\n", - " fpr, tpr, _ = roc_curve(y_true == i, y_scores[:, i])\n", - " roc_auc = auc(fpr, tpr)\n", - "\n", - " plt.plot(fpr, tpr, label=f'Class {i} (area = {roc_auc:.2f})')\n", - "\n", - " plt.plot([0, 1], [0, 1], color='navy', linestyle='--')\n", - " plt.xlabel('False Positive Rate')\n", - " plt.ylabel('True Positive Rate')\n", - " plt.title('Receiver Operating Characteristic (ROC)')\n", - " plt.legend(loc=\"lower right\")\n", - " plt.show()\n", + " _, preds = torch.max(outputs, 1) # Predicted labels\n", + " probs = torch.softmax(outputs, dim=1) # Probabilities\n", "\n", - "# Function to plot training and validation metrics\n", - "def plot_training_curves(history):\n", - " epochs = range(1, len(history['train_loss']) + 1)\n", + " # Save true and predicted labels\n", + " true_labels.extend(labels.cpu().numpy())\n", + " predicted_labels.extend(preds.cpu().numpy())\n", + " predicted_probs.extend(probs.cpu().numpy())\n", "\n", - " # Loss Curves\n", - " plt.figure(figsize=(12, 6))\n", - " plt.plot(epochs, history['train_loss'], label='Training Loss')\n", - " plt.plot(epochs, history['val_loss'], label='Validation Loss')\n", - " plt.title('Training and Validation Loss')\n", - " plt.xlabel('Epochs')\n", - " plt.ylabel('Loss')\n", - " plt.legend()\n", - " plt.show()\n", + " # Calculate batch accuracy\n", + " batch_accuracy = accuracy_score(labels.cpu().numpy(), preds.cpu().numpy())\n", + " batch_accuracies.append(batch_accuracy)\n", "\n", - " # Accuracy Curves\n", - " plt.figure(figsize=(12, 6))\n", - " plt.plot(epochs, history['train_acc'], label='Training Accuracy')\n", - " plt.plot(epochs, history['val_acc'], label='Validation Accuracy')\n", - " plt.title('Training and Validation Accuracy')\n", - " plt.xlabel('Epochs')\n", - " plt.ylabel('Accuracy')\n", + " # Plot Accuracy Curve\n", + " plt.figure(figsize=(8, 6))\n", + " plt.plot(batch_accuracies, label=\"Accuracy per Batch\", color=\"blue\")\n", + " plt.xlabel(\"Batch Index\")\n", + " plt.ylabel(\"Accuracy\")\n", + " plt.title(\"Accuracy Curve\")\n", " plt.legend()\n", " plt.show()\n", "\n", - "# Testing Function with Metrics\n", - "def test_model_with_metrics(model, test_loader, criterion, device=\"cuda\" if torch.cuda.is_available() else \"cpu\"):\n", - " model.eval()\n", - " running_loss = 0.0\n", - " running_corrects = 0\n", - " total_test = 0\n", - " y_true = []\n", - " y_pred = []\n", - "\n", - " with torch.no_grad():\n", - " for inputs, labels in tqdm(test_loader, desc=\"Testing\"):\n", - " inputs = inputs.to(device)\n", - " labels = labels.to(device).long()\n", - "\n", - " # Forward pass\n", - " outputs = model(inputs)\n", - " loss = criterion(outputs, labels)\n", - " _, preds = torch.max(outputs, 1)\n", - "\n", - " running_loss += loss.item() * inputs.size(0)\n", - " running_corrects += torch.sum(preds == labels.data)\n", - " total_test += labels.size(0)\n", - "\n", - " y_true.extend(labels.cpu().numpy())\n", - " y_pred.extend(preds.cpu().numpy())\n", - "\n", - " test_loss = running_loss / total_test\n", - " test_acc = running_corrects.double() / total_test\n", - "\n", - " print(f\"Test Loss: {test_loss:.4f} Acc: {test_acc:.4f}\")\n", + " # Convert labels and probabilities to numpy arrays for ROC\n", + " true_labels = torch.tensor(true_labels).numpy()\n", + " predicted_probs = torch.tensor(predicted_probs).numpy()\n", "\n", - " # Confusion Matrix\n", - " cm = confusion_matrix(y_true, y_pred)\n", + " # Plot ROC Curve for each class\n", " plt.figure(figsize=(10, 8))\n", - " sns.heatmap(cm, annot=True, fmt='d', cmap='Blues', xticklabels=range(model.fc2.out_features), yticklabels=range(model.fc2.out_features))\n", - " plt.xlabel('Predicted Labels')\n", - " plt.ylabel('True Labels')\n", - " plt.title('Confusion Matrix')\n", - " plt.show()\n", - "\n", - " # Classification Report\n", - " print(\"Classification Report:\")\n", - " print(classification_report(y_true, y_pred))\n", - "\n", - " return test_loss, test_acc\n", - "\n", - "# Example Usage for Testing and Visualization\n", - "if __name__ == \"__main__\":\n", - " # Assuming test_loader is defined\n", - " model_deepercnn = CustomCNNWithAttention(num_classes=6)\n", - " model_deepercnn.load_state_dict(torch.load(\"customcnnwithAttention.pth\")) # Load trained model\n", - " model_deepercnn = model_deepercnn.to(\"cuda\" if torch.cuda.is_available() else \"cpu\")\n", - "\n", - " criterion = nn.CrossEntropyLoss()\n", - "\n", - " # Test the model and plot metrics\n", - " test_loss, test_acc = test_model_with_metrics(model_deepercnn, test_loader, criterion)\n", + " for i in range(num_classes):\n", + " fpr, tpr, _ = roc_curve(true_labels == i, predicted_probs[:, i])\n", + " roc_auc = auc(fpr, tpr)\n", + " plt.plot(fpr, tpr, label=f\"Class {i} (AUC = {roc_auc:.2f})\")\n", "\n", - " # Plot ROC-AUC Curve\n", - " plot_roc_curve(model_deepercnn, test_loader)\n", + " plt.plot([0, 1], [0, 1], \"k--\", label=\"Random Guess\")\n", + " plt.xlabel(\"False Positive Rate\")\n", + " plt.ylabel(\"True Positive Rate\")\n", + " plt.title(\"ROC Curve\")\n", + " plt.legend(loc=\"lower right\")\n", + " plt.show()\n", "\n", - " # Plot Training and Validation Metrics (assuming you have saved the history)\n", - " history = {\n", - " \"train_loss\": [0.8, 0.6, 0.4],\n", - " \"val_loss\": [0.9, 0.7, 0.5],\n", - " \"train_acc\": [0.7, 0.8, 0.9],\n", - " \"val_acc\": [0.6, 0.75, 0.85],\n", - " }\n", - " plot_training_curves(history)\n" + " # Calculate overall accuracy\n", + " overall_accuracy = accuracy_score(true_labels, predicted_labels)\n", + " print(f\"Overall Test Accuracy: {overall_accuracy:.4f}\")\n" ] }, { "cell_type": "code", - "execution_count": 9, + "execution_count": 20, "metadata": {}, "outputs": [ { @@ -1367,72 +1376,1803 @@ "output_type": "stream", "text": [ "Epoch 1/20\n", - "------------------------------\n" + "----------\n" ] }, { "name": "stderr", "output_type": "stream", "text": [ - "Training: 13%|█▎ | 69/516 [00:13<01:29, 4.99it/s]\n" + "Training: 100%|██████████| 516/516 [02:11<00:00, 3.93it/s]\n" ] }, { - "ename": "KeyboardInterrupt", - "evalue": "", - "output_type": "error", - "traceback": [ - "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m", - "\u001b[1;31mKeyboardInterrupt\u001b[0m Traceback (most recent call last)", - "Cell \u001b[1;32mIn[9], line 175\u001b[0m\n\u001b[0;32m 172\u001b[0m scheduler_deepercnn \u001b[38;5;241m=\u001b[39m lr_scheduler\u001b[38;5;241m.\u001b[39mStepLR(optimizer_deepercnn, step_size\u001b[38;5;241m=\u001b[39m\u001b[38;5;241m7\u001b[39m, gamma\u001b[38;5;241m=\u001b[39m\u001b[38;5;241m0.1\u001b[39m)\n\u001b[0;32m 174\u001b[0m \u001b[38;5;66;03m# Train the model\u001b[39;00m\n\u001b[1;32m--> 175\u001b[0m \u001b[43mtrain_model\u001b[49m\u001b[43m(\u001b[49m\u001b[43mmodel_deepercnn\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mtrain_loader\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mval_loader\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mcriterion\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43moptimizer_deepercnn\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mscheduler_deepercnn\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mnum_epochs\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[38;5;241;43m20\u001b[39;49m\u001b[43m)\u001b[49m\n", - "Cell \u001b[1;32mIn[9], line 103\u001b[0m, in \u001b[0;36mtrain_model\u001b[1;34m(model, train_loader, val_loader, criterion, optimizer, scheduler, num_epochs, device)\u001b[0m\n\u001b[0;32m 100\u001b[0m running_corrects \u001b[38;5;241m=\u001b[39m \u001b[38;5;241m0\u001b[39m\n\u001b[0;32m 101\u001b[0m total_train \u001b[38;5;241m=\u001b[39m \u001b[38;5;241m0\u001b[39m\n\u001b[1;32m--> 103\u001b[0m \u001b[43m\u001b[49m\u001b[38;5;28;43;01mfor\u001b[39;49;00m\u001b[43m \u001b[49m\u001b[43minputs\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mlabels\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;129;43;01min\u001b[39;49;00m\u001b[43m \u001b[49m\u001b[43mtqdm\u001b[49m\u001b[43m(\u001b[49m\u001b[43mtrain_loader\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mdesc\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[38;5;124;43mTraining\u001b[39;49m\u001b[38;5;124;43m\"\u001b[39;49m\u001b[43m)\u001b[49m\u001b[43m:\u001b[49m\n\u001b[0;32m 104\u001b[0m \u001b[43m \u001b[49m\u001b[43minputs\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43m \u001b[49m\u001b[43minputs\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mto\u001b[49m\u001b[43m(\u001b[49m\u001b[43mdevice\u001b[49m\u001b[43m)\u001b[49m\n\u001b[0;32m 105\u001b[0m \u001b[43m \u001b[49m\u001b[43mlabels\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43m \u001b[49m\u001b[43mlabels\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mto\u001b[49m\u001b[43m(\u001b[49m\u001b[43mdevice\u001b[49m\u001b[43m)\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mlong\u001b[49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;66;43;03m# Ensure labels are of type torch.long\u001b[39;49;00m\n", - "File \u001b[1;32mc:\\Users\\Shravya H Jain\\Desktop\\micro-classify-main\\Micro-Classify\\.venv\\Lib\\site-packages\\tqdm\\std.py:1181\u001b[0m, in \u001b[0;36mtqdm.__iter__\u001b[1;34m(self)\u001b[0m\n\u001b[0;32m 1178\u001b[0m time \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_time\n\u001b[0;32m 1180\u001b[0m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[1;32m-> 1181\u001b[0m \u001b[43m \u001b[49m\u001b[38;5;28;43;01mfor\u001b[39;49;00m\u001b[43m \u001b[49m\u001b[43mobj\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;129;43;01min\u001b[39;49;00m\u001b[43m \u001b[49m\u001b[43miterable\u001b[49m\u001b[43m:\u001b[49m\n\u001b[0;32m 1182\u001b[0m \u001b[43m \u001b[49m\u001b[38;5;28;43;01myield\u001b[39;49;00m\u001b[43m \u001b[49m\u001b[43mobj\u001b[49m\n\u001b[0;32m 1183\u001b[0m \u001b[43m \u001b[49m\u001b[38;5;66;43;03m# Update and possibly print the progressbar.\u001b[39;49;00m\n\u001b[0;32m 1184\u001b[0m \u001b[43m \u001b[49m\u001b[38;5;66;43;03m# Note: does not call self.update(1) for speed optimisation.\u001b[39;49;00m\n", - "File \u001b[1;32mc:\\Users\\Shravya H Jain\\Desktop\\micro-classify-main\\Micro-Classify\\.venv\\Lib\\site-packages\\torch\\utils\\data\\dataloader.py:701\u001b[0m, in \u001b[0;36m_BaseDataLoaderIter.__next__\u001b[1;34m(self)\u001b[0m\n\u001b[0;32m 698\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_sampler_iter \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m:\n\u001b[0;32m 699\u001b[0m \u001b[38;5;66;03m# TODO(https://github.com/pytorch/pytorch/issues/76750)\u001b[39;00m\n\u001b[0;32m 700\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_reset() \u001b[38;5;66;03m# type: ignore[call-arg]\u001b[39;00m\n\u001b[1;32m--> 701\u001b[0m data \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m_next_data\u001b[49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\n\u001b[0;32m 702\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_num_yielded \u001b[38;5;241m+\u001b[39m\u001b[38;5;241m=\u001b[39m \u001b[38;5;241m1\u001b[39m\n\u001b[0;32m 703\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m (\n\u001b[0;32m 704\u001b[0m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_dataset_kind \u001b[38;5;241m==\u001b[39m _DatasetKind\u001b[38;5;241m.\u001b[39mIterable\n\u001b[0;32m 705\u001b[0m \u001b[38;5;129;01mand\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_IterableDataset_len_called \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m\n\u001b[0;32m 706\u001b[0m \u001b[38;5;129;01mand\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_num_yielded \u001b[38;5;241m>\u001b[39m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_IterableDataset_len_called\n\u001b[0;32m 707\u001b[0m ):\n", - "File \u001b[1;32mc:\\Users\\Shravya H Jain\\Desktop\\micro-classify-main\\Micro-Classify\\.venv\\Lib\\site-packages\\torch\\utils\\data\\dataloader.py:757\u001b[0m, in \u001b[0;36m_SingleProcessDataLoaderIter._next_data\u001b[1;34m(self)\u001b[0m\n\u001b[0;32m 755\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21m_next_data\u001b[39m(\u001b[38;5;28mself\u001b[39m):\n\u001b[0;32m 756\u001b[0m index \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_next_index() \u001b[38;5;66;03m# may raise StopIteration\u001b[39;00m\n\u001b[1;32m--> 757\u001b[0m data \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m_dataset_fetcher\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mfetch\u001b[49m\u001b[43m(\u001b[49m\u001b[43mindex\u001b[49m\u001b[43m)\u001b[49m \u001b[38;5;66;03m# may raise StopIteration\u001b[39;00m\n\u001b[0;32m 758\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_pin_memory:\n\u001b[0;32m 759\u001b[0m data \u001b[38;5;241m=\u001b[39m _utils\u001b[38;5;241m.\u001b[39mpin_memory\u001b[38;5;241m.\u001b[39mpin_memory(data, \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39m_pin_memory_device)\n", - "File \u001b[1;32mc:\\Users\\Shravya H Jain\\Desktop\\micro-classify-main\\Micro-Classify\\.venv\\Lib\\site-packages\\torch\\utils\\data\\_utils\\fetch.py:50\u001b[0m, in \u001b[0;36m_MapDatasetFetcher.fetch\u001b[1;34m(self, possibly_batched_index)\u001b[0m\n\u001b[0;32m 48\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mauto_collation:\n\u001b[0;32m 49\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28mhasattr\u001b[39m(\u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mdataset, \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124m__getitems__\u001b[39m\u001b[38;5;124m\"\u001b[39m) \u001b[38;5;129;01mand\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mdataset\u001b[38;5;241m.\u001b[39m__getitems__:\n\u001b[1;32m---> 50\u001b[0m data \u001b[38;5;241m=\u001b[39m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mdataset\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43m__getitems__\u001b[49m\u001b[43m(\u001b[49m\u001b[43mpossibly_batched_index\u001b[49m\u001b[43m)\u001b[49m\n\u001b[0;32m 51\u001b[0m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[0;32m 52\u001b[0m data \u001b[38;5;241m=\u001b[39m [\u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mdataset[idx] \u001b[38;5;28;01mfor\u001b[39;00m idx \u001b[38;5;129;01min\u001b[39;00m possibly_batched_index]\n", - "File \u001b[1;32mc:\\Users\\Shravya H Jain\\Desktop\\micro-classify-main\\Micro-Classify\\.venv\\Lib\\site-packages\\torch\\utils\\data\\dataset.py:420\u001b[0m, in \u001b[0;36mSubset.__getitems__\u001b[1;34m(self, indices)\u001b[0m\n\u001b[0;32m 418\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mdataset\u001b[38;5;241m.\u001b[39m__getitems__([\u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mindices[idx] \u001b[38;5;28;01mfor\u001b[39;00m idx \u001b[38;5;129;01min\u001b[39;00m indices]) \u001b[38;5;66;03m# type: ignore[attr-defined]\u001b[39;00m\n\u001b[0;32m 419\u001b[0m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[1;32m--> 420\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m [\u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mdataset\u001b[49m\u001b[43m[\u001b[49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mindices\u001b[49m\u001b[43m[\u001b[49m\u001b[43midx\u001b[49m\u001b[43m]\u001b[49m\u001b[43m]\u001b[49m \u001b[38;5;28;01mfor\u001b[39;00m idx \u001b[38;5;129;01min\u001b[39;00m indices]\n", - "Cell \u001b[1;32mIn[4], line 187\u001b[0m, in \u001b[0;36mCustomImageDataset.__getitem__\u001b[1;34m(self, idx)\u001b[0m\n\u001b[0;32m 185\u001b[0m \u001b[38;5;28;01mdef\u001b[39;00m \u001b[38;5;21m__getitem__\u001b[39m(\u001b[38;5;28mself\u001b[39m, idx):\n\u001b[0;32m 186\u001b[0m img_path \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mimage_paths[idx]\n\u001b[1;32m--> 187\u001b[0m image \u001b[38;5;241m=\u001b[39m \u001b[43mImage\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mopen\u001b[49m\u001b[43m(\u001b[49m\u001b[43mimg_path\u001b[49m\u001b[43m)\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mconvert\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;124;43m'\u001b[39;49m\u001b[38;5;124;43mRGB\u001b[39;49m\u001b[38;5;124;43m'\u001b[39;49m\u001b[43m)\u001b[49m\n\u001b[0;32m 189\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mtransform:\n\u001b[0;32m 190\u001b[0m image \u001b[38;5;241m=\u001b[39m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mtransform(image)\n", - "File \u001b[1;32mc:\\Users\\Shravya H Jain\\Desktop\\micro-classify-main\\Micro-Classify\\.venv\\Lib\\site-packages\\PIL\\Image.py:995\u001b[0m, in \u001b[0;36mImage.convert\u001b[1;34m(self, mode, matrix, dither, palette, colors)\u001b[0m\n\u001b[0;32m 992\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m mode \u001b[38;5;129;01min\u001b[39;00m (\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mBGR;15\u001b[39m\u001b[38;5;124m\"\u001b[39m, \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mBGR;16\u001b[39m\u001b[38;5;124m\"\u001b[39m, \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mBGR;24\u001b[39m\u001b[38;5;124m\"\u001b[39m):\n\u001b[0;32m 993\u001b[0m deprecate(mode, \u001b[38;5;241m12\u001b[39m)\n\u001b[1;32m--> 995\u001b[0m \u001b[38;5;28;43mself\u001b[39;49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mload\u001b[49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\n\u001b[0;32m 997\u001b[0m has_transparency \u001b[38;5;241m=\u001b[39m \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mtransparency\u001b[39m\u001b[38;5;124m\"\u001b[39m \u001b[38;5;129;01min\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39minfo\n\u001b[0;32m 998\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m mode \u001b[38;5;129;01mand\u001b[39;00m \u001b[38;5;28mself\u001b[39m\u001b[38;5;241m.\u001b[39mmode \u001b[38;5;241m==\u001b[39m \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mP\u001b[39m\u001b[38;5;124m\"\u001b[39m:\n\u001b[0;32m 999\u001b[0m \u001b[38;5;66;03m# determine default mode\u001b[39;00m\n", - "File \u001b[1;32mc:\\Users\\Shravya H Jain\\Desktop\\micro-classify-main\\Micro-Classify\\.venv\\Lib\\site-packages\\PIL\\ImageFile.py:293\u001b[0m, in \u001b[0;36mImageFile.load\u001b[1;34m(self)\u001b[0m\n\u001b[0;32m 290\u001b[0m \u001b[38;5;28;01mraise\u001b[39;00m \u001b[38;5;167;01mOSError\u001b[39;00m(msg)\n\u001b[0;32m 292\u001b[0m b \u001b[38;5;241m=\u001b[39m b \u001b[38;5;241m+\u001b[39m s\n\u001b[1;32m--> 293\u001b[0m n, err_code \u001b[38;5;241m=\u001b[39m \u001b[43mdecoder\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43mdecode\u001b[49m\u001b[43m(\u001b[49m\u001b[43mb\u001b[49m\u001b[43m)\u001b[49m\n\u001b[0;32m 294\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m n \u001b[38;5;241m<\u001b[39m \u001b[38;5;241m0\u001b[39m:\n\u001b[0;32m 295\u001b[0m \u001b[38;5;28;01mbreak\u001b[39;00m\n", - "\u001b[1;31mKeyboardInterrupt\u001b[0m: " + "name": "stdout", + "output_type": "stream", + "text": [ + "Training Loss: 1.5772 Acc: 0.3286\n" ] - } - ], - "source": [ - "import torch\n", - "import torch.nn as nn\n", - "import torch.optim as optim\n", - "from torch.optim import lr_scheduler\n", - "import torch.nn.functional as F\n", - "from tqdm import tqdm\n", - "\n", - "# Define the Spatial Attention Module\n", - "class SpatialAttention(nn.Module):\n", - " def __init__(self, in_channels):\n", - " super(SpatialAttention, self).__init__()\n", - " self.conv1 = nn.Conv2d(in_channels, 1, kernel_size=1) # Reduce channels to 1\n", - " self.conv2 = nn.Conv2d(1, 1, kernel_size=3, padding=1) # Learn spatial weights\n", - " self.sigmoid = nn.Sigmoid() # Normalize attention map to [0, 1]\n", - "\n", - " def forward(self, x):\n", - " attn = self.conv1(x) # Reduce channel dimension\n", - " attn = self.conv2(attn) # Learn spatial relationships\n", - " attn = self.sigmoid(attn) # Normalize\n", - " return x * attn # Apply attention\n", - "\n", - "# Define the Custom CNN with integrated Spatial Attention\n", - "class CustomCNNWithAttention(nn.Module):\n", - " def __init__(self, num_classes=6):\n", - " super(CustomCNNWithAttention, self).__init__()\n", - " # 1st Convolutional Block\n", - " self.conv1 = nn.Conv2d(3, 16, kernel_size=3, padding=1)\n", - " self.bn1 = nn.BatchNorm2d(16)\n", - " self.pool1 = nn.MaxPool2d(kernel_size=2, stride=2)\n", - "\n", - " # 2nd Convolutional Block\n", - " self.conv2 = nn.Conv2d(16, 32, kernel_size=3, padding=1)\n", - " self.bn2 = nn.BatchNorm2d(32)\n", - " self.pool2 = nn.MaxPool2d(kernel_size=2, stride=2)\n", + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "Validation: 100%|██████████| 31/31 [00:06<00:00, 5.08it/s]\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Validation Loss: 1.4002 Acc: 0.4298\n", + "Model saved as best_model.pth\n", + "Epoch 2/20\n", + "----------\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "Training: 100%|██████████| 516/516 [02:10<00:00, 3.96it/s]\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Training Loss: 1.1618 Acc: 0.5380\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "Validation: 100%|██████████| 31/31 [00:06<00:00, 4.71it/s]\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Validation Loss: 1.3031 Acc: 0.5000\n", + "Model saved as best_model.pth\n", + "Epoch 3/20\n", + "----------\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "Training: 100%|██████████| 516/516 [02:15<00:00, 3.82it/s]\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Training Loss: 0.8467 Acc: 0.6598\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "Validation: 100%|██████████| 31/31 [00:07<00:00, 3.91it/s]\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Validation Loss: 0.8997 Acc: 0.6116\n", + "Model saved as best_model.pth\n", + "Epoch 4/20\n", + "----------\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "Training: 100%|██████████| 516/516 [02:12<00:00, 3.90it/s]\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Training Loss: 0.7024 Acc: 0.7091\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "Validation: 100%|██████████| 31/31 [00:06<00:00, 5.01it/s]\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Validation Loss: 0.7495 Acc: 0.6860\n", + "Model saved as best_model.pth\n", + "Epoch 5/20\n", + "----------\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "Training: 100%|██████████| 516/516 [02:13<00:00, 3.86it/s]\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Training Loss: 0.6140 Acc: 0.7503\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "Validation: 100%|██████████| 31/31 [00:06<00:00, 5.06it/s]\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Validation Loss: 0.6653 Acc: 0.7314\n", + "Model saved as best_model.pth\n", + "Epoch 6/20\n", + "----------\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "Training: 100%|██████████| 516/516 [02:08<00:00, 4.02it/s]\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Training Loss: 0.5315 Acc: 0.7945\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "Validation: 100%|██████████| 31/31 [00:06<00:00, 4.57it/s]\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Validation Loss: 0.4132 Acc: 0.8760\n", + "Model saved as best_model.pth\n", + "Epoch 7/20\n", + "----------\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "Training: 100%|██████████| 516/516 [02:13<00:00, 3.86it/s]\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Training Loss: 0.5120 Acc: 0.8098\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "Validation: 100%|██████████| 31/31 [00:06<00:00, 5.00it/s]\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Validation Loss: 0.4936 Acc: 0.8058\n", + "Epoch 8/20\n", + "----------\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "Training: 100%|██████████| 516/516 [04:16<00:00, 2.01it/s]\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Training Loss: 0.3988 Acc: 0.8624\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "Validation: 100%|██████████| 31/31 [00:18<00:00, 1.71it/s]\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Validation Loss: 0.3807 Acc: 0.8719\n", + "Model saved as best_model.pth\n", + "Epoch 9/20\n", + "----------\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "Training: 100%|██████████| 516/516 [03:13<00:00, 2.67it/s]\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Training Loss: 0.3567 Acc: 0.8772\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "Validation: 100%|██████████| 31/31 [00:06<00:00, 4.60it/s]\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Validation Loss: 0.3503 Acc: 0.8719\n", + "Model saved as best_model.pth\n", + "Epoch 10/20\n", + "----------\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "Training: 100%|██████████| 516/516 [02:21<00:00, 3.63it/s]\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Training Loss: 0.3394 Acc: 0.8784\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "Validation: 100%|██████████| 31/31 [00:14<00:00, 2.11it/s]\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Validation Loss: 0.3364 Acc: 0.8926\n", + "Model saved as best_model.pth\n", + "Epoch 11/20\n", + "----------\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "Training: 100%|██████████| 516/516 [04:03<00:00, 2.12it/s]\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Training Loss: 0.3140 Acc: 0.8889\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "Validation: 100%|██████████| 31/31 [00:15<00:00, 2.00it/s]\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Validation Loss: 0.2976 Acc: 0.9050\n", + "Model saved as best_model.pth\n", + "Epoch 12/20\n", + "----------\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "Training: 100%|██████████| 516/516 [04:43<00:00, 1.82it/s]\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Training Loss: 0.2982 Acc: 0.8918\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "Validation: 100%|██████████| 31/31 [00:16<00:00, 1.94it/s]\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Validation Loss: 0.3157 Acc: 0.8884\n", + "Epoch 13/20\n", + "----------\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "Training: 100%|██████████| 516/516 [04:32<00:00, 1.89it/s]\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Training Loss: 0.2928 Acc: 0.9012\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "Validation: 100%|██████████| 31/31 [00:15<00:00, 2.00it/s]\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Validation Loss: 0.2750 Acc: 0.9091\n", + "Model saved as best_model.pth\n", + "Epoch 14/20\n", + "----------\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "Training: 100%|██████████| 516/516 [04:44<00:00, 1.81it/s]\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Training Loss: 0.2697 Acc: 0.9073\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "Validation: 100%|██████████| 31/31 [00:15<00:00, 2.00it/s]\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Validation Loss: 0.2789 Acc: 0.8926\n", + "Epoch 15/20\n", + "----------\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "Training: 100%|██████████| 516/516 [03:52<00:00, 2.22it/s]\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Training Loss: 0.2515 Acc: 0.9141\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "Validation: 100%|██████████| 31/31 [00:07<00:00, 4.24it/s]\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Validation Loss: 0.2557 Acc: 0.9050\n", + "Model saved as best_model.pth\n", + "Epoch 16/20\n", + "----------\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "Training: 100%|██████████| 516/516 [01:59<00:00, 4.33it/s]\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Training Loss: 0.2584 Acc: 0.9095\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "Validation: 100%|██████████| 31/31 [00:07<00:00, 4.42it/s]\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Validation Loss: 0.2396 Acc: 0.9174\n", + "Model saved as best_model.pth\n", + "Epoch 17/20\n", + "----------\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "Training: 100%|██████████| 516/516 [02:10<00:00, 3.95it/s]\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Training Loss: 0.2526 Acc: 0.9146\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "Validation: 100%|██████████| 31/31 [00:06<00:00, 4.95it/s]\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Validation Loss: 0.2637 Acc: 0.9174\n", + "Epoch 18/20\n", + "----------\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "Training: 100%|██████████| 516/516 [04:17<00:00, 2.01it/s]\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Training Loss: 0.2504 Acc: 0.9151\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "Validation: 100%|██████████| 31/31 [00:18<00:00, 1.66it/s]\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Validation Loss: 0.2693 Acc: 0.9091\n", + "Epoch 19/20\n", + "----------\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "Training: 100%|██████████| 516/516 [05:26<00:00, 1.58it/s]\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Training Loss: 0.2484 Acc: 0.9146\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "Validation: 100%|██████████| 31/31 [00:16<00:00, 1.83it/s]\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Validation Loss: 0.2797 Acc: 0.9132\n", + "Epoch 20/20\n", + "----------\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "Training: 100%|██████████| 516/516 [03:47<00:00, 2.27it/s]\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Training Loss: 0.2437 Acc: 0.9214\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "Validation: 100%|██████████| 31/31 [00:10<00:00, 3.04it/s]" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Validation Loss: 0.2719 Acc: 0.9091\n", + "Training complete.\n", + "Best Validation Loss: 0.2396\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\n" + ] + } + ], + "source": [ + "import torch\n", + "import torch.nn as nn\n", + "import torch.optim as optim\n", + "import torch.nn.functional as F\n", + "from torch.optim import lr_scheduler\n", + "from tqdm import tqdm\n", + "\n", + "# Model Definition: CustomCNNWithLSTM\n", + "class CustomCNNWithLSTM(nn.Module):\n", + " def __init__(self, num_classes=6, lstm_hidden_size=128, lstm_num_layers=2):\n", + " super(CustomCNNWithLSTM, self).__init__()\n", + " self.conv1 = nn.Conv2d(3, 16, kernel_size=3, padding=1)\n", + " self.bn1 = nn.BatchNorm2d(16)\n", + " self.pool1 = nn.MaxPool2d(kernel_size=2, stride=2)\n", + "\n", + " self.conv2 = nn.Conv2d(16, 32, kernel_size=3, padding=1)\n", + " self.bn2 = nn.BatchNorm2d(32)\n", + " self.pool2 = nn.MaxPool2d(kernel_size=2, stride=2)\n", + "\n", + " self.conv3 = nn.Conv2d(32, 64, kernel_size=3, padding=1)\n", + " self.bn3 = nn.BatchNorm2d(64)\n", + " self.pool3 = nn.MaxPool2d(kernel_size=2, stride=2)\n", + "\n", + " self.conv4 = nn.Conv2d(64, 128, kernel_size=3, padding=1)\n", + " self.bn4 = nn.BatchNorm2d(128)\n", + " self.pool4 = nn.MaxPool2d(kernel_size=2, stride=2)\n", + "\n", + " # Dynamically compute the LSTM input size\n", + " self.lstm_input_size = 128 # Channels after CNN\n", + " self.flatten = nn.Flatten(start_dim=2)\n", + "\n", + " self.lstm = nn.LSTM(\n", + " input_size=self.lstm_input_size,\n", + " hidden_size=lstm_hidden_size,\n", + " num_layers=lstm_num_layers,\n", + " batch_first=True,\n", + " bidirectional=True\n", + " )\n", + "\n", + " self.fc1 = nn.Linear(lstm_hidden_size * 2, 512)\n", + " self.fc2 = nn.Linear(512, num_classes)\n", + " self.dropout = nn.Dropout(0.5)\n", + "\n", + " def forward(self, x):\n", + " # Pass through CNN\n", + " x = self.pool1(F.relu(self.bn1(self.conv1(x))))\n", + " x = self.pool2(F.relu(self.bn2(self.conv2(x))))\n", + " x = self.pool3(F.relu(self.bn3(self.conv3(x))))\n", + " x = self.pool4(F.relu(self.bn4(self.conv4(x))))\n", + "\n", + " # Flatten for LSTM input\n", + " batch_size, channels, height, width = x.shape\n", + " x = x.view(batch_size, channels, -1).permute(0, 2, 1)\n", + "\n", + " # Pass through LSTM\n", + " lstm_out, _ = self.lstm(x)\n", + " x = lstm_out[:, -1, :]\n", + "\n", + " # Pass through fully connected layers\n", + " x = F.relu(self.fc1(x))\n", + " x = self.dropout(x)\n", + " x = self.fc2(x)\n", + " return x\n", + "\n", + "\n", + "# Training function\n", + "def train_model(model, train_loader, val_loader, criterion, optimizer, scheduler, num_epochs, device):\n", + " model.to(device)\n", + " best_loss = float('inf')\n", + "\n", + " for epoch in range(num_epochs):\n", + " print(f\"Epoch {epoch + 1}/{num_epochs}\")\n", + " print(\"-\" * 10)\n", + "\n", + " # Training Phase\n", + " model.train()\n", + " train_loss = 0.0\n", + " train_corrects = 0\n", + "\n", + " # Use tqdm for training progress bar\n", + " for inputs, labels in tqdm(train_loader, desc=\"Training\", ncols=100, dynamic_ncols=True):\n", + " inputs, labels = inputs.to(device), labels.to(device, dtype=torch.long)\n", + "\n", + " optimizer.zero_grad()\n", + " outputs = model(inputs)\n", + " loss = criterion(outputs, labels)\n", + " loss.backward()\n", + " optimizer.step()\n", + "\n", + " train_loss += loss.item() * inputs.size(0)\n", + " _, preds = torch.max(outputs, 1)\n", + " train_corrects += torch.sum(preds == labels.data)\n", + "\n", + " scheduler.step()\n", + " epoch_loss = train_loss / len(train_loader.dataset)\n", + " epoch_acc = train_corrects.double() / len(train_loader.dataset)\n", + "\n", + " print(f\"Training Loss: {epoch_loss:.4f} Acc: {epoch_acc:.4f}\")\n", + "\n", + " # Validation Phase\n", + " model.eval()\n", + " val_loss = 0.0\n", + " val_corrects = 0\n", + "\n", + " # Use tqdm for validation progress bar\n", + " with torch.no_grad():\n", + " for inputs, labels in tqdm(val_loader, desc=\"Validation\", ncols=100, dynamic_ncols=True):\n", + " inputs, labels = inputs.to(device), labels.to(device, dtype=torch.long)\n", + " outputs = model(inputs)\n", + " loss = criterion(outputs, labels)\n", + "\n", + " val_loss += loss.item() * inputs.size(0)\n", + " _, preds = torch.max(outputs, 1)\n", + " val_corrects += torch.sum(preds == labels.data)\n", + "\n", + " epoch_val_loss = val_loss / len(val_loader.dataset)\n", + " epoch_val_acc = val_corrects.double() / len(val_loader.dataset)\n", + "\n", + " print(f\"Validation Loss: {epoch_val_loss:.4f} Acc: {epoch_val_acc:.4f}\")\n", + "\n", + " # Save the best model\n", + " if epoch_val_loss < best_loss:\n", + " best_loss = epoch_val_loss\n", + " torch.save(model.state_dict(), \"best_model.pth\")\n", + " print(\"Model saved as best_model.pth\")\n", + "\n", + " print(\"Training complete.\")\n", + " print(f\"Best Validation Loss: {best_loss:.4f}\")\n", + "\n", + "\n", + "# Example Usage\n", + "if __name__ == \"__main__\":\n", + " # Define the DataLoader instances (train_loader and val_loader) with your data\n", + "\n", + " num_classes = 6\n", + " model_cnn_lstm = CustomCNNWithLSTM(num_classes=num_classes)\n", + " criterion = nn.CrossEntropyLoss()\n", + " optimizer = optim.Adam(model_cnn_lstm.parameters(), lr=0.0001)\n", + " scheduler = lr_scheduler.StepLR(optimizer, step_size=7, gamma=0.1)\n", + "\n", + " device = 'cuda' if torch.cuda.is_available() else 'cpu'\n", + "\n", + " # Train the model (replace train_loader and val_loader with your actual data loaders)\n", + " train_model(\n", + " model_cnn_lstm,\n", + " train_loader, # Your DataLoader for training data\n", + " val_loader, # Your DataLoader for validation data\n", + " criterion,\n", + " optimizer,\n", + " scheduler,\n", + " num_epochs=20,\n", + " device=device\n", + " )\n" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "metadata": {}, + "outputs": [], + "source": [ + "import torch\n", + "import torch.nn.functional as F\n", + "from tqdm import tqdm\n", + "\n", + "# Testing function\n", + "def test_model(model, test_loader, criterion, device):\n", + " model.to(device)\n", + " model.eval() # Set the model to evaluation mode\n", + "\n", + " test_loss = 0.0\n", + " test_corrects = 0\n", + " total_samples = 0\n", + "\n", + " # Disable gradient computation during inference\n", + " with torch.no_grad():\n", + " # Loop through the test data\n", + " for inputs, labels in tqdm(test_loader, desc=\"Testing\", ncols=100, dynamic_ncols=True):\n", + " inputs, labels = inputs.to(device), labels.to(device, dtype=torch.long)\n", + "\n", + " # Forward pass\n", + " outputs = model(inputs)\n", + " loss = criterion(outputs, labels)\n", + "\n", + " # Accumulate loss and accuracy\n", + " test_loss += loss.item() * inputs.size(0)\n", + " _, preds = torch.max(outputs, 1)\n", + " test_corrects += torch.sum(preds == labels.data)\n", + " total_samples += inputs.size(0)\n", + "\n", + " # Compute final average loss and accuracy\n", + " test_loss /= total_samples\n", + " test_acc = test_corrects.double() / total_samples\n", + "\n", + " # Print the results\n", + " print(f\"Test Loss: {test_loss:.4f} Acc: {test_acc:.4f}\")\n", + " return test_loss, test_acc\n" + ] + }, + { + "cell_type": "code", + "execution_count": 39, + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "C:\\Users\\Shravya H Jain\\AppData\\Local\\Temp\\ipykernel_22584\\3287528403.py:66: FutureWarning: You are using `torch.load` with `weights_only=False` (the current default value), which uses the default pickle module implicitly. It is possible to construct malicious pickle data which will execute arbitrary code during unpickling (See https://github.com/pytorch/pytorch/blob/main/SECURITY.md#untrusted-models for more details). In a future release, the default value for `weights_only` will be flipped to `True`. This limits the functions that could be executed during unpickling. Arbitrary objects will no longer be allowed to be loaded via this mode unless they are explicitly allowlisted by the user via `torch.serialization.add_safe_globals`. We recommend you start setting `weights_only=True` for any use case where you don't have full control of the loaded file. Please open an issue on GitHub for any issues related to this experimental feature.\n", + " model_deepercnn.load_state_dict(torch.load(\"customcnnwithAttention.pth\"))\n", + "Testing: 100%|██████████| 61/61 [00:08<00:00, 6.85it/s]\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Test Loss: 0.0887 Test Acc: 0.9733\n", + "\n", + "Classification Report:\n", + " precision recall f1-score support\n", + "\n", + " Class 0 0.96 0.93 0.95 84\n", + " Class 1 0.92 0.96 0.94 80\n", + " Class 2 1.00 1.00 1.00 80\n", + " Class 3 1.00 0.96 0.98 84\n", + " Class 4 1.00 1.00 1.00 78\n", + " Class 5 0.96 0.99 0.98 80\n", + "\n", + " accuracy 0.97 486\n", + " macro avg 0.97 0.97 0.97 486\n", + "weighted avg 0.97 0.97 0.97 486\n", + "\n", + "\n", + "Confusion Matrix:\n", + "[[78 6 0 0 0 0]\n", + " [ 3 77 0 0 0 0]\n", + " [ 0 0 80 0 0 0]\n", + " [ 0 0 0 81 0 3]\n", + " [ 0 0 0 0 78 0]\n", + " [ 0 1 0 0 0 79]]\n" + ] + }, + { + "data": { + "image/png": "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1WFIkqpUqaLg4GBFlNHvfV9fX4WGlmx79OjRGjNmTJnczx4kk2UsJCREx44dk5+fnyxu9j1Iubm5Cg0N1bFjx2S1Wl0dTrlC3zmPvnMefec8+s557tx3hmHo7NmzCgkJcXUoNt7e3jpy5Ijy8/PLpH3DMErlE1eqSkpSzZo15enpqezs7BL7s7OzFRwcbFpMJJNlzMPDQ3Xr1nV1GL/JarW63Q+I8oK+cx595zz6znn0nfPcte/cpSL5S97e3vL29nZ1GKpSpYqio6O1atUqPfLII5KkoqIirVq1Sn379jXtPiSTAAAA16mUlBT16NFDrVq10m233abXX39d58+f11NPPWXaPUgmAQAArlN/+tOf9N///lejRo1SVlaWWrRooWXLlpWalPNHkExWYF5eXho9evRVx1rg6ug759F3zqPvnEffOY++K//69u1r6mvtX7MY7jifHgAAAOUCi5YDAADAaSSTAAAAcBrJJAAAAJxGMgkAwP8wjcB5RUVFrg4BLkIyid/FDwjn8YvJefy9c05xvxUVFennn392cTTlS1FRkSwWi3788Uf98MMPrg6nXCkqKpKHh4cOHDigtWvXujocXGMkk/hNxT8g9u/fr/79++uJJ57Q2LFjtWvXLleH5vaKfzFlZWXp5MmTrg6nXCn+e3f48GG9/PLLev755/X222+7Oiy398v/vyYlJemhhx5SSkqKsrKyXB1aueDh4aGjR4+qZcuWmjx5so4ePerqkMqF4r936enpuuWWW7R3715Xh4RrjGQSv8nDw0N79+7VbbfdpqNHj8rLy0tvvfWWnn/+eU2ZMsXV4bktwzBsfRcaGqrExET9+OOPrg6rXCj+xbRz507ddddd+uqrr/Tdd9+pX79+evHFF10dntv6db/l5OSoRYsW+sc//qFXXnnF1eGVG1999ZV++OEHrVixQjNmzFBmZqarQ3JrxX/vduzYodatW+vZZ5/Vc8895+qwcI2xziSuyjAMFRYWqk+fPioqKtK7774r6fIXxL/44ovas2ePHnnkEQ0bNszFkbqnkydP6rHHHpOvr6927dqlqKgozZ07VzVr1nR1aG4vMzNTDzzwgDp16qRJkyZJkhYsWKA+ffpo1apVatasmYsjdE9Hjx7V/fffry5duig1NVWS9MYbb2jXrl168803WXTaDt99951SU1MVHR2tCRMmqGfP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zBmdOHFCt99+u+1YpUqV1KpVq1Kvuoulp6fL09NT99xzj91xHzx4UBcuXNADDzxQYn9+fr5atmwpSdq7d2+JOCQpJibG7nsU++CDDzRlyhQdOnRI586d088//yyr1VrinHr16umGG24ocZ+ioiLt379ffn5+OnTokJ555hn17t3bds7PP/8sf39/h+MBgD+KZBKAadq0aaNp06apSpUqCgkJUaVKJX/E+Pj4lPh87tw5RUdHa+7cuaXaqlWrllMxVK1a1eFrzp07J0n6/PPPSyRx0uVxoGbZsGGDEhMTNXbsWLVr107+/v6aP3++Xn31VYdjnTFjRqnk1tPT07RYAcBeJJMATOPj46OGDRvaff4tt9yiDz74QLVr1y5VnStWp04dffPNN7r77rslXa7Abd26VbfccssVz2/WrJmKior05ZdfKi4urtTx4spoYWGhbV+TJk3k5eWlzMzMq1Y0o6KibJOJim3cuPH3H/IX1q9fr7CwMA0fPty2LyMjo9R5mZmZOn78uEJCQmz38fDwUKNGjRQUFKSQkBAdPnxYiYmJDt0fAMoCE3AAuExiYqJq1qypzp0766uvvtKRI0e0du1a9e/fX99//70k6YUXXtArr7yiRYsWad++fXr++ed/c43I+vXrq0ePHnr66ae1aNEiW5sffvihJCksLEwWi0VLlizRf//7X507d05+fn4aNGiQkpOT9d577+nQoUPatm2bpk6dapvU0qdPHx04cECDBw/W/v37NW/ePM2ePduh542IiFBmZqbmz5+vQ4cOacqUKVecTOTt7a0ePXpox44d+uqrr9S/f3916dJFwcHBkqSxY8cqNTVVU6ZM0XfffaedO3dq1qxZeu211xyKBwDMQDIJwGWqVaumdevWqV69eoqPj1dUVJSeeeYZXbp0yVapHDhwoLp166YePXooJiZGfn5+evTRR3+z3WnTpumxxx7T888/r8aNG6t37946f/68JOmGG27Q2LFj9eKLLyooKEh9+/aVJL300ksaOXKkUlNTFRUVpfbt2+vzzz9XgwYNJF0ex/jJJ59o0aJFuvnmmzV9+nS9/PLLDj1vp06dlJycrL59+6pFixZav369Ro4cWeq8hg0bKj4+Xg899JDatm2r5s2bl1j6p1evXvrHP/6hWbNmqVmzZrrnnns0e/ZsW6wAcC1ZjKuNYgcAAAB+B5VJAAAAOI1kEgAAAE4jmQQAAIDTSCYBAADgNJJJAAAAOI1kEgAAAE4jmQQAAIDTSCYBAADgNJJJAAAAOI1kEgAAAE4jmQQAAIDTSCYBAADgtP8DvgX/TQjhavQAAAAASUVORK5CYII=", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "import torch\n", + "import numpy as np\n", + "import matplotlib.pyplot as plt\n", + "from sklearn.metrics import classification_report, confusion_matrix\n", + "\n", + "# Test Function\n", + "def test_model(model, test_loader, criterion, device=\"cuda\" if torch.cuda.is_available() else \"cpu\"):\n", + " model = model.to(device)\n", + " model.eval()\n", + "\n", + " running_loss = 0.0\n", + " running_corrects = 0\n", + " total_test = 0\n", + " all_preds = []\n", + " all_labels = []\n", + "\n", + " with torch.no_grad():\n", + " for inputs, labels in tqdm(test_loader, desc=\"Testing\"):\n", + " inputs = inputs.to(device)\n", + " labels = labels.to(device).long() # Ensure labels are of type torch.long\n", + "\n", + " # Forward Pass\n", + " outputs = model(inputs)\n", + " loss = criterion(outputs, labels)\n", + " _, preds = torch.max(outputs, 1)\n", + "\n", + " # Track statistics\n", + " running_loss += loss.item() * inputs.size(0)\n", + " running_corrects += torch.sum(preds == labels.data)\n", + " total_test += labels.size(0)\n", + "\n", + " all_preds.extend(preds.cpu().numpy())\n", + " all_labels.extend(labels.cpu().numpy())\n", + "\n", + " test_loss = running_loss / total_test\n", + " test_acc = running_corrects.double() / total_test\n", + "\n", + " print(f\"Test Loss: {test_loss:.4f} Test Acc: {test_acc:.4f}\")\n", + "\n", + " # Classification Report\n", + " print(\"\\nClassification Report:\")\n", + " print(classification_report(all_labels, all_preds, target_names=[f\"Class {i}\" for i in range(6)]))\n", + "\n", + " # Confusion Matrix\n", + " cm = confusion_matrix(all_labels, all_preds)\n", + " print(\"\\nConfusion Matrix:\")\n", + " print(cm)\n", + "\n", + " # Plot Confusion Matrix\n", + " plt.figure(figsize=(8, 6))\n", + " plt.imshow(cm, interpolation='nearest', cmap=plt.cm.Blues)\n", + " plt.title(\"Confusion Matrix\")\n", + " plt.colorbar()\n", + " tick_marks = np.arange(6)\n", + " plt.xticks(tick_marks, [f\"Class {i}\" for i in range(6)], rotation=45)\n", + " plt.yticks(tick_marks, [f\"Class {i}\" for i in range(6)])\n", + " plt.ylabel('True label')\n", + " plt.xlabel('Predicted label')\n", + " plt.tight_layout()\n", + " plt.show()\n", + "\n", + "# Example Usage\n", + "if __name__ == \"__main__\":\n", + " # Assuming test_loader is defined\n", + " model_deepercnn = CustomCNNWithAttention(num_classes=6)\n", + " model_deepercnn.load_state_dict(torch.load(\"customcnnwithAttention.pth\"))\n", + " model_deepercnn.eval()\n", + "\n", + " criterion = nn.CrossEntropyLoss()\n", + "\n", + " # Test the model\n", + " test_model(model_deepercnn, test_loader, criterion)\n" + ] + }, + { + "cell_type": "code", + "execution_count": 37, + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "C:\\Users\\Shravya H Jain\\AppData\\Local\\Temp\\ipykernel_22584\\66978296.py:37: FutureWarning: You are using `torch.load` with `weights_only=False` (the current default value), which uses the default pickle module implicitly. It is possible to construct malicious pickle data which will execute arbitrary code during unpickling (See https://github.com/pytorch/pytorch/blob/main/SECURITY.md#untrusted-models for more details). In a future release, the default value for `weights_only` will be flipped to `True`. This limits the functions that could be executed during unpickling. Arbitrary objects will no longer be allowed to be loaded via this mode unless they are explicitly allowlisted by the user via `torch.serialization.add_safe_globals`. We recommend you start setting `weights_only=True` for any use case where you don't have full control of the loaded file. Please open an issue on GitHub for any issues related to this experimental feature.\n", + " model_deepercnn.load_state_dict(torch.load(\"customcnnwithAttention.pth\"))\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Classification Report:\n", + " precision recall f1-score support\n", + "\n", + " 0 0.9630 0.9286 0.9455 84\n", + " 1 0.9059 0.9625 0.9333 80\n", + " 2 1.0000 1.0000 1.0000 80\n", + " 3 1.0000 0.9762 0.9880 84\n", + " 4 1.0000 1.0000 1.0000 78\n", + " 5 0.9750 0.9750 0.9750 80\n", + "\n", + " accuracy 0.9733 486\n", + " macro avg 0.9740 0.9737 0.9736 486\n", + "weighted avg 0.9740 0.9733 0.9734 486\n", + "\n", + "Confusion Matrix:\n", + "[[78 6 0 0 0 0]\n", + " [ 3 77 0 0 0 0]\n", + " [ 0 0 80 0 0 0]\n", + " [ 0 0 0 82 0 2]\n", + " [ 0 0 0 0 78 0]\n", + " [ 0 2 0 0 0 78]]\n" + ] + } + ], + "source": [ + "from sklearn.metrics import classification_report, confusion_matrix\n", + "import torch\n", + "\n", + "def test_model(model, test_loader, device=\"cuda\" if torch.cuda.is_available() else \"cpu\"):\n", + " model = model.to(device)\n", + " model.eval()\n", + " \n", + " all_preds = []\n", + " all_targets = []\n", + "\n", + " with torch.no_grad():\n", + " for inputs, labels in test_loader:\n", + " inputs = inputs.to(device)\n", + " labels = labels.to(device).long() # Ensure labels are of type torch.long\n", + "\n", + " # Forward pass\n", + " outputs = model(inputs)\n", + " _, preds = torch.max(outputs, 1)\n", + "\n", + " # Collect predictions and targets\n", + " all_preds.extend(preds.cpu().numpy())\n", + " all_targets.extend(labels.cpu().numpy())\n", + " \n", + " # Generate Classification Report\n", + " print(\"Classification Report:\")\n", + " print(classification_report(all_targets, all_preds, digits=4))\n", + "\n", + " # Generate Confusion Matrix\n", + " print(\"Confusion Matrix:\")\n", + " print(confusion_matrix(all_targets, all_preds))\n", + "\n", + "# Example Usage\n", + "# Assuming test_loader is defined\n", + "if __name__ == \"__main__\":\n", + " # Load the trained model weights\n", + " model_deepercnn = CustomCNNWithAttention(num_classes=6)\n", + " model_deepercnn.load_state_dict(torch.load(\"customcnnwithAttention.pth\"))\n", + "\n", + " # Evaluate the model on test data\n", + " test_model(model_deepercnn, test_loader)\n" + ] + }, + { + "cell_type": "code", + "execution_count": 25, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Epoch 1/20, Train Loss: 0.9637, Train Acc: 0.6081\n", + "Validation Loss: 1.6030, Validation Acc: 0.4990\n", + "Epoch 2/20, Train Loss: 0.6486, Train Acc: 0.7564\n", + "Validation Loss: 0.4759, Validation Acc: 0.8289\n", + "Epoch 3/20, Train Loss: 0.4112, Train Acc: 0.8551\n", + "Validation Loss: 0.3839, Validation Acc: 0.8732\n", + "Epoch 4/20, Train Loss: 0.3462, Train Acc: 0.8814\n", + "Validation Loss: 0.9806, Validation Acc: 0.7155\n", + "Epoch 5/20, Train Loss: 0.3261, Train Acc: 0.8866\n", + "Validation Loss: 0.5992, Validation Acc: 0.8216\n", + "Epoch 6/20, Train Loss: 0.2721, Train Acc: 0.9033\n", + "Validation Loss: 0.2847, Validation Acc: 0.9113\n", + "Epoch 7/20, Train Loss: 0.2255, Train Acc: 0.9268\n", + "Validation Loss: 0.2577, Validation Acc: 0.9186\n", + "Epoch 8/20, Train Loss: 0.2269, Train Acc: 0.9301\n", + "Validation Loss: 0.1997, Validation Acc: 0.9423\n", + "Epoch 9/20, Train Loss: 0.1701, Train Acc: 0.9469\n", + "Validation Loss: 0.2421, Validation Acc: 0.9258\n", + "Epoch 10/20, Train Loss: 0.1698, Train Acc: 0.9461\n", + "Validation Loss: 0.2228, Validation Acc: 0.9381\n", + "Epoch 11/20, Train Loss: 0.1469, Train Acc: 0.9559\n", + "Validation Loss: 0.2490, Validation Acc: 0.9361\n", + "Epoch 12/20, Train Loss: 0.1271, Train Acc: 0.9585\n", + "Validation Loss: 0.2432, Validation Acc: 0.9165\n", + "Epoch 13/20, Train Loss: 0.1548, Train Acc: 0.9502\n", + "Validation Loss: 0.3115, Validation Acc: 0.9134\n", + "Epoch 14/20, Train Loss: 0.1170, Train Acc: 0.9611\n", + "Validation Loss: 0.2114, Validation Acc: 0.9351\n", + "Epoch 15/20, Train Loss: 0.1296, Train Acc: 0.9593\n", + "Validation Loss: 0.1878, Validation Acc: 0.9412\n", + "Epoch 16/20, Train Loss: 0.1133, Train Acc: 0.9652\n", + "Validation Loss: 0.2685, Validation Acc: 0.9175\n", + "Epoch 17/20, Train Loss: 0.0965, Train Acc: 0.9701\n", + "Validation Loss: 0.1411, Validation Acc: 0.9619\n", + "Epoch 18/20, Train Loss: 0.1571, Train Acc: 0.9490\n", + "Validation Loss: 0.1995, Validation Acc: 0.9412\n", + "Epoch 19/20, Train Loss: 0.1037, Train Acc: 0.9714\n", + "Validation Loss: 0.1628, Validation Acc: 0.9526\n", + "Epoch 20/20, Train Loss: 0.0828, Train Acc: 0.9734\n", + "Validation Loss: 0.1624, Validation Acc: 0.9495\n", + "Model saved!\n" + ] + } + ], + "source": [ + "# %% Imports\n", + "import os\n", + "import numpy as np\n", + "import torch\n", + "import torch.nn as nn\n", + "import torch.optim as optim\n", + "import torch.nn.functional as F\n", + "from torch.utils.data import Dataset, DataLoader\n", + "from torchvision import transforms\n", + "from sklearn.preprocessing import LabelEncoder\n", + "from sklearn.metrics import accuracy_score\n", + "from PIL import Image\n", + "\n", + "# %% Attention Mechanism\n", + "class Attention(nn.Module):\n", + " def __init__(self, hidden_size):\n", + " super(Attention, self).__init__()\n", + " self.attention = nn.Linear(hidden_size * 2, 1)\n", + "\n", + " def forward(self, lstm_output):\n", + " attention_weights = torch.softmax(self.attention(lstm_output), dim=1)\n", + " context_vector = torch.sum(attention_weights * lstm_output, dim=1)\n", + " return context_vector\n", + "\n", + "# %% CNN with LSTM and Attention\n", + "class CustomCNNWithLSTM(nn.Module):\n", + " def __init__(self, num_classes=6, lstm_hidden_size=256, lstm_num_layers=2):\n", + " super(CustomCNNWithLSTM, self).__init__()\n", + " # CNN Layers\n", + " self.conv1 = nn.Conv2d(3, 32, kernel_size=3, padding=1)\n", + " self.bn1 = nn.BatchNorm2d(32)\n", + " self.pool1 = nn.MaxPool2d(kernel_size=2, stride=2)\n", + "\n", + " self.conv2 = nn.Conv2d(32, 64, kernel_size=3, padding=1)\n", + " self.bn2 = nn.BatchNorm2d(64)\n", + " self.pool2 = nn.MaxPool2d(kernel_size=2, stride=2)\n", + "\n", + " self.conv3 = nn.Conv2d(64, 128, kernel_size=3, padding=1)\n", + " self.bn3 = nn.BatchNorm2d(128)\n", + " self.pool3 = nn.MaxPool2d(kernel_size=2, stride=2)\n", + "\n", + " self.conv4 = nn.Conv2d(128, 256, kernel_size=3, padding=1)\n", + " self.bn4 = nn.BatchNorm2d(256)\n", + " self.pool4 = nn.MaxPool2d(kernel_size=2, stride=2)\n", + "\n", + " # LSTM Layers\n", + " self.lstm = nn.LSTM(\n", + " input_size=256,\n", + " hidden_size=lstm_hidden_size,\n", + " num_layers=lstm_num_layers,\n", + " batch_first=True,\n", + " bidirectional=True\n", + " )\n", + "\n", + " # Attention Layer\n", + " self.attention = Attention(lstm_hidden_size)\n", + "\n", + " # Fully Connected Layers\n", + " self.fc1 = nn.Linear(lstm_hidden_size * 2, 512)\n", + " self.fc2 = nn.Linear(512, num_classes)\n", + " self.dropout = nn.Dropout(0.5)\n", + "\n", + " def forward(self, x):\n", + " x = self.pool1(F.relu(self.bn1(self.conv1(x))))\n", + " x = self.pool2(F.relu(self.bn2(self.conv2(x))))\n", + " x = self.pool3(F.relu(self.bn3(self.conv3(x))))\n", + " x = self.pool4(F.relu(self.bn4(self.conv4(x))))\n", + "\n", + " # Flatten for LSTM\n", + " batch_size, channels, height, width = x.size()\n", + " x = x.view(batch_size, channels, -1).permute(0, 2, 1)\n", + "\n", + " # LSTM + Attention\n", + " lstm_out, _ = self.lstm(x)\n", + " x = self.attention(lstm_out)\n", + "\n", + " # Fully Connected Layers\n", + " x = F.relu(self.fc1(x))\n", + " x = self.dropout(x)\n", + " x = self.fc2(x)\n", + " return x\n", + "\n", + "# %% Custom Dataset\n", + "class CustomImageDataset(Dataset):\n", + " def __init__(self, base_dir, subfolders, transform=None, label_encoder=None):\n", + " self.image_paths = []\n", + " self.labels = []\n", + " for subfolder in subfolders:\n", + " folder_path = os.path.join(base_dir, subfolder)\n", + " for img_name in os.listdir(folder_path):\n", + " if img_name.lower().endswith(('.png', '.jpg', '.jpeg')):\n", + " self.image_paths.append(os.path.join(folder_path, img_name))\n", + " self.labels.append(subfolder)\n", + " if label_encoder:\n", + " self.label_encoder = label_encoder\n", + " self.labels = self.label_encoder.transform(self.labels)\n", + " self.transform = transform\n", + "\n", + " def __len__(self):\n", + " return len(self.image_paths)\n", + "\n", + " def __getitem__(self, idx):\n", + " image = Image.open(self.image_paths[idx]).convert(\"RGB\")\n", + " label = self.labels[idx]\n", + " if self.transform:\n", + " image = self.transform(image)\n", + " return image, label\n", + "\n", + "# %% Data Transformations\n", + "transform = transforms.Compose([\n", + " transforms.Resize((224, 224)),\n", + " transforms.RandomHorizontalFlip(),\n", + " transforms.ColorJitter(brightness=0.2, contrast=0.2),\n", + " transforms.ToTensor(),\n", + " transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225])\n", + "])\n", + "\n", + "# %% Dataset Preparation\n", + "base_dir = \"DIAT-uSAT_dataset\"\n", + "subfolders = [\"3_long_blade_rotor\", \"3_short_blade_rotor\", \"Bird\", \"Bird+mini-helicopter\", \"drone\", \"rc_plane\"]\n", + "\n", + "label_encoder = LabelEncoder()\n", + "label_encoder.fit(subfolders)\n", + "\n", + "train_dataset = CustomImageDataset(base_dir, subfolders, transform, label_encoder)\n", + "train_size = int(0.8 * len(train_dataset))\n", + "val_size = len(train_dataset) - train_size\n", + "train_dataset, val_dataset = torch.utils.data.random_split(train_dataset, [train_size, val_size])\n", + "\n", + "# %% Data Loaders\n", + "batch_size = 32\n", + "train_loader = DataLoader(train_dataset, batch_size=batch_size, shuffle=True)\n", + "val_loader = DataLoader(val_dataset, batch_size=batch_size, shuffle=False)\n", + "\n", + "# %% Model, Loss, Optimizer\n", + "device = torch.device(\"cuda\" if torch.cuda.is_available() else \"cpu\")\n", + "model = CustomCNNWithLSTM(num_classes=len(subfolders)).to(device)\n", + "criterion = nn.CrossEntropyLoss()\n", + "optimizer = optim.Adam(model.parameters(), lr=0.001)\n", + "\n", + "# %% Training Function\n", + "def train_model(model, train_loader, val_loader, criterion, optimizer, num_epochs=20):\n", + " for epoch in range(num_epochs):\n", + " model.train()\n", + " train_loss = 0.0\n", + " train_preds, train_labels = [], []\n", + "\n", + " for images, labels in train_loader:\n", + " images, labels = images.to(device), labels.to(device).long() # Ensure labels are of type long\n", + "\n", + " outputs = model(images)\n", + "\n", + " # Ensure outputs and labels have correct shapes\n", + " assert outputs.shape[1] == len(subfolders), \"Output classes don't match the number of labels\"\n", + "\n", + " loss = criterion(outputs, labels) # Labels should be of type long\n", + "\n", + " optimizer.zero_grad() # Clear previous gradients\n", + " loss.backward() # Compute gradients\n", + " optimizer.step() # Update model parameters\n", + "\n", + " train_loss += loss.item()\n", + " train_preds.extend(torch.argmax(outputs, dim=1).cpu().numpy()) # Get predicted class labels\n", + " train_labels.extend(labels.cpu().numpy()) # Get true class labels\n", + "\n", + " train_acc = accuracy_score(train_labels, train_preds)\n", + " print(f\"Epoch {epoch+1}/{num_epochs}, Train Loss: {train_loss/len(train_loader):.4f}, Train Acc: {train_acc:.4f}\")\n", + "\n", + " # Validation\n", + " model.eval()\n", + " val_loss = 0.0\n", + " val_preds, val_labels = [], []\n", + " with torch.no_grad():\n", + " for images, labels in val_loader:\n", + " images, labels = images.to(device), labels.to(device).long()\n", + "\n", + " outputs = model(images)\n", + " loss = criterion(outputs, labels)\n", + "\n", + " val_loss += loss.item()\n", + " val_preds.extend(torch.argmax(outputs, dim=1).cpu().numpy())\n", + " val_labels.extend(labels.cpu().numpy())\n", + "\n", + " val_acc = accuracy_score(val_labels, val_preds)\n", + " print(f\"Validation Loss: {val_loss/len(val_loader):.4f}, Validation Acc: {val_acc:.4f}\")\n", + "\n", + "# %% Train Model\n", + "train_model(model, train_loader, val_loader, criterion, optimizer, num_epochs=20)\n", + "\n", + "# %% Save Model\n", + "torch.save(model.state_dict(), \"custom_cnn_lstm_model.pth\")\n", + "print(\"Model saved!\")\n" + ] + }, + { + "cell_type": "code", + "execution_count": 26, + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "C:\\Users\\Shravya H Jain\\AppData\\Local\\Temp\\ipykernel_22584\\3379055925.py:8: FutureWarning: You are using `torch.load` with `weights_only=False` (the current default value), which uses the default pickle module implicitly. It is possible to construct malicious pickle data which will execute arbitrary code during unpickling (See https://github.com/pytorch/pytorch/blob/main/SECURITY.md#untrusted-models for more details). In a future release, the default value for `weights_only` will be flipped to `True`. This limits the functions that could be executed during unpickling. Arbitrary objects will no longer be allowed to be loaded via this mode unless they are explicitly allowlisted by the user via `torch.serialization.add_safe_globals`. We recommend you start setting `weights_only=True` for any use case where you don't have full control of the loaded file. Please open an issue on GitHub for any issues related to this experimental feature.\n", + " model = torch.load(model_path, map_location=device) # Load the complete model onto the appropriate device\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Model has been converted to ONNX and saved at customcnnwithAttention_full.onnx\n" + ] + } + ], + "source": [ + "import torch\n", + "\n", + "# Path to the saved complete model file\n", + "model_path = \"customcnnwithAttention_full.pth\"\n", + "\n", + "# Load the complete model (architecture + weights)\n", + "device = torch.device(\"cuda\" if torch.cuda.is_available() else \"cpu\") # Select device dynamically\n", + "model = torch.load(model_path, map_location=device) # Load the complete model onto the appropriate device\n", + "model.eval() # Set the model to evaluation mode\n", + "\n", + "# Define a dummy input on the same device as the model\n", + "dummy_input = torch.randn(1, 3, 224, 224).to(device) # Batch size = 1, 3 channels, 224x224 resolution\n", + "\n", + "# Path to save the ONNX model\n", + "onnx_file_path = \"customcnnwithAttention_full.onnx\"\n", + "\n", + "# Export the model to ONNX format\n", + "torch.onnx.export(\n", + " model,\n", + " dummy_input,\n", + " onnx_file_path,\n", + " export_params=True,\n", + " opset_version=11,\n", + " do_constant_folding=True,\n", + " input_names=['input'],\n", + " output_names=['output'],\n", + " dynamic_axes={\n", + " 'input': {0: 'batch_size'},\n", + " 'output': {0: 'batch_size'}\n", + " }\n", + ")\n", + "\n", + "print(f\"Model has been converted to ONNX and saved at {onnx_file_path}\")\n" + ] + }, + { + "cell_type": "code", + "execution_count": 34, + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "Testing: 100%|██████████| 61/61 [00:09<00:00, 6.49it/s]" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Test Loss: 0.1089\n", + "Test Accuracy: 0.9691\n", + "Sample Predictions: [4, 5, 4, 3, 0, 1, 3, 2, 3, 0]\n", + "Sample Labels: [4, 5, 4, 3, 0, 1, 3, 2, 3, 0]\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\n" + ] + } + ], + "source": [ + "import torch\n", + "from tqdm import tqdm\n", + "\n", + "def test_model(model, test_loader, criterion, device=\"cuda\" if torch.cuda.is_available() else \"cpu\"):\n", + " \"\"\"\n", + " Test the trained model on the test dataset.\n", + " \n", + " Args:\n", + " model (nn.Module): Trained PyTorch model.\n", + " test_loader (DataLoader): DataLoader for the test dataset.\n", + " criterion (nn.Module): Loss function.\n", + " device (str): Device to run the testing on (default: \"cuda\" if available).\n", + " \n", + " Returns:\n", + " dict: Dictionary containing test loss and accuracy.\n", + " \"\"\"\n", + " model.eval() # Set the model to evaluation mode\n", + " running_loss = 0.0\n", + " running_corrects = 0\n", + " total_samples = 0\n", + "\n", + " all_preds = []\n", + " all_labels = []\n", + "\n", + " with torch.no_grad(): # No gradient calculation for testing\n", + " for inputs, labels in tqdm(test_loader, desc=\"Testing\"):\n", + " inputs = inputs.to(device)\n", + " labels = labels.to(device).long()\n", + "\n", + " # Forward pass\n", + " outputs = model(inputs)\n", + " loss = criterion(outputs, labels)\n", + " \n", + " # Collect test metrics\n", + " running_loss += loss.item() * inputs.size(0)\n", + " _, preds = torch.max(outputs, 1)\n", + " running_corrects += torch.sum(preds == labels)\n", + " total_samples += labels.size(0)\n", + "\n", + " # Store predictions and labels for further analysis if needed\n", + " all_preds.extend(preds.cpu().numpy())\n", + " all_labels.extend(labels.cpu().numpy())\n", + "\n", + " # Calculate overall loss and accuracy\n", + " test_loss = running_loss / total_samples\n", + " test_accuracy = running_corrects.double() / total_samples\n", + "\n", + " print(f\"Test Loss: {test_loss:.4f}\")\n", + " print(f\"Test Accuracy: {test_accuracy:.4f}\")\n", + "\n", + " return {\n", + " \"test_loss\": test_loss,\n", + " \"test_accuracy\": test_accuracy.item(),\n", + " \"all_preds\": all_preds,\n", + " \"all_labels\": all_labels,\n", + " }\n", + "\n", + "# Example Usage\n", + "criterion = nn.CrossEntropyLoss() # Define the same criterion used during training\n", + "device = \"cuda\" if torch.cuda.is_available() else \"cpu\"\n", + "\n", + "test_results = test_model(model, test_loader, criterion, device=device)\n", + "\n", + "# Optional: Print predictions and labels for a sanity check\n", + "print(\"Sample Predictions:\", test_results[\"all_preds\"][:10])\n", + "print(\"Sample Labels:\", test_results[\"all_labels\"][:10])\n" + ] + }, + { + "cell_type": "code", + "execution_count": 40, + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "Testing: 100%|██████████| 61/61 [00:09<00:00, 6.56it/s]\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Test Loss: 0.1099\n", + "Test Accuracy: 0.9733\n" + ] + }, + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAwIAAAKlCAYAAAB40ltaAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjkuMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8hTgPZAAAACXBIWXMAAA9hAAAPYQGoP6dpAACexElEQVR4nOzdd1iTV/sH8G9ACCgbRXAgKgqo4MKBuBfiqHtXUbGtW4uiYl3gwK2t1lG1iqu2zr61dVQUByLiAHGh4sBWQEVAWQEhvz/8mRpBTTThScj3817PdcHJM+7nNC/mzn3OeURSqVQKIiIiIiLSKXpCB0BERERERMWPiQARERERkQ5iIkBEREREpIOYCBARERER6SAmAkREREREOoiJABERERGRDmIiQERERESkg5gIEBERERHpICYCREREREQ6iIkAERF91J07d9CxY0eYm5tDJBLh4MGDKj3/gwcPIBKJsHXrVpWeV5u1bt0arVu3FjoMIirBmAgQEWmJ+Ph4fPPNN6hWrRqMjIxgZmYGT09PfP/998jOzlbrtX18fBAbG4sFCxZg+/btcHd3V+v1itOwYcMgEolgZmZWZD/euXMHIpEIIpEIy5YtU/r8jx8/xty5cxEdHa2CaImIVKeU0AEQEdHH/fnnn+jbty/EYjGGDh2KOnXqIDc3F2fPnoW/vz+uX7+On376SS3Xzs7ORkREBL777juMGzdOLdeoUqUKsrOzYWBgoJbzf0ypUqWQlZWFP/74A/369ZN7befOnTAyMkJOTs4nnfvx48cIDAyEg4MD6tWrp/Bxx44d+6TrEREpiokAEZGGu3//PgYMGIAqVargxIkTsLOzk702duxY3L17F3/++afarv/06VMAgIWFhdquIRKJYGRkpLbzf4xYLIanpyd++eWXQonArl270KVLF+zbt69YYsnKykLp0qVhaGhYLNcjIt3FoUFERBpuyZIlyMjIwObNm+WSgDccHR0xceJE2e+vXr3CvHnzUL16dYjFYjg4OGDGjBmQSCRyxzk4OKBr1644e/YsGjduDCMjI1SrVg3btm2T7TN37lxUqVIFAODv7w+RSAQHBwcAr4fUvPn5bXPnzoVIJJJr+/vvv9G8eXNYWFjAxMQETk5OmDFjhuz1980ROHHiBFq0aIEyZcrAwsIC3bt3x82bN4u83t27dzFs2DBYWFjA3Nwcw4cPR1ZW1vs79h2DBg3C4cOHkZaWJmuLiorCnTt3MGjQoEL7P3/+HFOmTIGrqytMTExgZmYGb29vxMTEyPYJCwtDo0aNAADDhw+XDTF6c5+tW7dGnTp1cOnSJbRs2RKlS5eW9cu7cwR8fHxgZGRU6P69vLxgaWmJx48fK3yvREQAEwEiIo33xx9/oFq1amjWrJlC+48cORKzZ89GgwYNsHLlSrRq1QrBwcEYMGBAoX3v3r2LPn36oEOHDli+fDksLS0xbNgwXL9+HQDQq1cvrFy5EgAwcOBAbN++HatWrVIq/uvXr6Nr166QSCQICgrC8uXL8cUXXyA8PPyDxx0/fhxeXl548uQJ5s6dCz8/P5w7dw6enp548OBBof379euHly9fIjg4GP369cPWrVsRGBiocJy9evWCSCTC/v37ZW27du2Cs7MzGjRoUGj/e/fu4eDBg+jatStWrFgBf39/xMbGolWrVrIP5S4uLggKCgIAfP3119i+fTu2b9+Oli1bys6TkpICb29v1KtXD6tWrUKbNm2KjO/7779HuXLl4OPjg/z8fADAhg0bcOzYMaxevRoVKlRQ+F6JiAAAUiIi0ljp6elSANLu3bsrtH90dLQUgHTkyJFy7VOmTJECkJ44cULWVqVKFSkA6enTp2VtT548kYrFYunkyZNlbffv35cCkC5dulTunD4+PtIqVaoUimHOnDnSt/95WblypRSA9OnTp++N+801tmzZImurV6+e1MbGRpqSkiJri4mJkerp6UmHDh1a6HojRoyQO2fPnj2l1tbW773m2/dRpkwZqVQqlfbp00farl07qVQqlebn50ttbW2lgYGBRfZBTk6OND8/v9B9iMViaVBQkKwtKiqq0L290apVKykA6fr164t8rVWrVnJtR48elQKQzp8/X3rv3j2piYmJtEePHh+9RyKiorAiQESkwV68eAEAMDU1VWj/v/76CwDg5+cn1z558mQAKDSXoFatWmjRooXs93LlysHJyQn37t375Jjf9WZuwe+//46CggKFjklMTER0dDSGDRsGKysrWbubmxs6dOggu8+3jRo1Su73Fi1aICUlRdaHihg0aBDCwsKQlJSEEydOICkpqchhQcDreQV6eq//Gc3Pz0dKSops2NPly5cVvqZYLMbw4cMV2rdjx4745ptvEBQUhF69esHIyAgbNmxQ+FpE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REREpDbqHhqkKDs7u0LPz3JxcZEtGf/muUzJycly+yQnJyv1TCutqgh88cUXsodvvevdZUGFtmnTJmRnZxf5mpWVVTFHo7jo6Oj3vlaxYsXiC4SIiIhIR3l6ehZ6FtPt27dlC+BUrVoVtra2CA0NRb169QAAL168kD1/S1FalQiYmprC1NRU6DAUoq0fmh0dHYUOgYiIiEgQmvLQr2+//RbNmjXDwoUL0a9fP1y4cAE//fQTfvrpJwCv45w0aRLmz5+PGjVqoGrVqpg1axYqVKiAHj16KHwdrUoEiIiIiIhKukaNGuHAgQMICAhAUFAQqlatilWrVsktpT916lRkZmbi66+/RlpaGpo3b44jR47IJhorgqsGUYnFVYNUh6sGqQ5XDSIi+jAhVw1ynn5Uree/tchLredXllZNFiYiIiIiItXg0CAiIiIiIgB6epoxR6C4sCJARERERKSDWBEgIiIiIoJya/2XBEwEiIiIiIigOcuHFhcODSIiIiIi0kGsCBARERERQfeGBrEiQERERESkg1gRICIiIiIC5wgQEREREZEOYEWAiIiIiAisCBARERERkQ5gRYCIiIiICLq3ahATASIiIiIicGgQERERERHpAFYEiIiIiIige0ODWBEgIiIiItJBrAgQEREREYFzBIiIiIiISAewIkBEREREBM4RICIiIiIiHcCKABERERERdG+OABMBIiIiIiJwaBAREREREekAVgSIiIiIiKB7Q4NYESAiIiIi0kGsCBARERERQffmCDARoBLL2FBf6BBKjNS/ZwkdQolh2fRboUMoEVLPrxQ6BCIircdEgIiIiIgInCNAREREREQ6gBUBIiIiIiJwjgARERERkU7i0CAiIiIiIirxWBEgIiIiIoLuDQ1iRYCIiIiISAexIkBEREREBM4RICIiIiIiHcCKABERERERWBEgIiIiIiIdwIoAERERERF0b9UgJgJERERERODQICIiIiIi0gGsCBARERERQfeGBrEiQERERESkg1gRICIiIiIC5wgQEREREZEOYCJARERERITXcwTUuSlq7ty5EIlEcpuzs7Ps9ZycHIwdOxbW1tYwMTFB7969kZycrPT9MhEgIiIiItIwtWvXRmJiomw7e/as7LVvv/0Wf/zxB/bs2YNTp07h8ePH6NWrl9LX4BwBIiIiIiIAemqeIyCRSCCRSOTa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CJcuXcLFixfRtm1bdO/eHdevXwcAfPvtt/jjjz+wZ88enDp1Co8fP0avXr2Uvl+RVCqVKn0UkRbIeSV0BESkLpaNxgkdQomRGrVG6BBKDElegdAhlAjmxsJ9T701KkGt5x/oVh4SiUSuTSwWQywWf/RYKysrLF26FH369EG5cuWwa9cu9OnTBwBw69YtuLi4ICIiAk2bNlU4HlYEiIiIiIgAiEQitW7BwcEwNzeX24KDgz8YU35+Pnbv3o3MzEx4eHjg0qVLyMvLQ/v27WX7ODs7w97eHhEREUrdL1cNIiIiIiIqBgEBAfDz85Nre181IDY2Fh4eHsjJyYGJiQkOHDiAWrVqITo6GoaGhrCwsJDbv3z58khKSlIqHiYCREREREQA1L14qKLDgADAyckJ0dHRSE9Px969e+Hj44NTp06pNB4mAkREREREGsbQ0BCOjo4AgIYNGyIqKgrff/89+vfvj9zcXKSlpclVBZKTk2Fra6vUNThHgIiIiIgIrx8ops7tcxQUFEAikaBhw4YwMDBAaGio7LW4uDgkJCTAw8NDqXOyIkBEREREpEECAgLg7e0Ne3t7vHz5Ert27UJYWBiOHj0Kc3Nz+Pr6ws/PD1ZWVjAzM8P48ePh4eGh1IpBABMBIiIiIiIA6p8joKgnT55g6NChSExMhLm5Odzc3HD06FF06NABALBy5Uro6emhd+/ekEgk8PLywtq1a5W+Dp8jQCUWnyNAVHLxOQKqw+cIqA6fI6AaQj5HYNflf9R6/kENKqn1/MriHAEiIiIiIh3EoUFERERERHj9QDFdwooAEREREZEOYkWAiIiIiAi69w25rt0vERERERGBFQEiIiIiIgCcI0BERERERDqAFQEiIiIiImjOA8WKCxMBIiIiIiJwaBAREREREekAVgSIiEjrpEatETqEEsOy5QyhQygxUk8vFDoE+ky69g25rt0vERERERGBFQEiIiIiIgCcI0BERERERDqAFQEiIiIiIuje8qGsCBARERER6SBWBIiIiIiIAOjYFAEmAkREREREAKCnY4ODODSIiIiIiEgHsSJARERERATdGxrEigARERERkQ5iRYCIiIiICICIcwSIiIiIiKikY0WAiIiIiAicI0BERERERDqAFQEiIiIiIujecwSYCBARERERgUODiIiIiIhIB7AiQEREREQEVgSIiIiIiEgH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Fi1aFF8wRERERELTrYIAEwFd5ujoKHQIRERERCQQJgJERERERNC5ggAfKEZEREREpItYESAiIiIigu49R4CJABERERERdG/5UA4NIiIiIiLSQawIEBERERFB94YGsSJARERERKSDmAgQEREREekgJgJERERERDqIcwSIiIiIiMA5AkREREREpANYESAiIiIigu49R4CJABERERERODSIiIiIiIh0ACsCRERERESAjg0MYkWAiIiIiEgnsSJARERERAToXEmAFQEiIiIiIh3EigAREREREXRv+VBWBIiIiIiIdBArAkRERERE0L3nCDARICIiIiKCzs0V5tAgIiIiIiJdxIoAERERERGgcyUBVgSIiIiIiHQQEwEiIiIiIrxePlSd/1PWjz/+CAcHBxgZGaFJkya4cOGCSu+XiQARERERkYb59ddf4efnhzlz5uDy5cuoW7cuvLy88OTJE5Vdg4kAERERERFeLx+qzk0ZK1aswFdffYXhw4ejVq1aWL9+PUqXLo2ff/5ZZffLRICIiIiIqBhIJBK8ePFCbpNIJIX2y83NxaVLl9C+fXtZm56eHtq3b4+IiAiVxcNVg6jEMtKCd7dEIkFwcDACAgIgFouFDkdrsR9Vh32pOuxL1dCmfsy+uFLoED5Im/pSKOr+7DB3fjACAwPl2ubMmYO5c+fKtT179gz5+fkoX768XHv58uVx69YtlcUjkkqlUpWdjYiU8uLFC5ibmyM9PR1mZmZCh6O12I+qw75UHfalarAfVYd9KTyJRFKoAiAWiwslZo8fP0bFihVx7tw5eHh4yNqnTp2KU6dOITIyUiXxaMF3pkRERERE2q+oD/1FKVu2LPT19ZGcnCzXnpycDFtbW5XFwzkCREREREQaxNDQEA0bNkRoaKisraCgAKGhoXIVgs/FigARERERkYbx8/ODj48P3N3d0bhxY6xatQqZmZkYPny4yq7BRIBIQGKxGHPmzOGkrc/EflQd9qXqsC9Vg/2oOuxL7dK/f388ffoUs2fPRlJSEurVq4cjR44UmkD8OThZmIiIiIhIB3GOABERERGRDmIiQERERESkg5gIEBERERHpICYCREREREQ6iIkAEREREZEOYiJAVIzy8/Nx+vRppKWlCR0KEamYVCpFQkICcnJyhA6lRHj16hWOHz+ODRs24OXLlwCAx48fIyMjQ+DIiEoO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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Sample Predictions: [4, 5, 4, 3, 0, 1, 3, 2, 3, 0]\n", + "Sample Labels: [4, 5, 4, 3, 0, 1, 3, 2, 3, 0]\n" + ] + } + ], + "source": [ + "import torch\n", + "from tqdm import tqdm\n", + "from sklearn.metrics import confusion_matrix\n", + "import seaborn as sns\n", + "import matplotlib.pyplot as plt\n", + "\n", + "def test_model(model, test_loader, criterion, device=\"cuda\" if torch.cuda.is_available() else \"cpu\"):\n", + " \"\"\"\n", + " Test the trained model on the test dataset.\n", + " \n", + " Args:\n", + " model (nn.Module): Trained PyTorch model.\n", + " test_loader (DataLoader): DataLoader for the test dataset.\n", + " criterion (nn.Module): Loss function.\n", + " device (str): Device to run the testing on (default: \"cuda\" if available).\n", + " \n", + " Returns:\n", + " dict: Dictionary containing test loss, accuracy, confusion matrix, predictions, and labels.\n", + " \"\"\"\n", + " model.eval() # Set the model to evaluation mode\n", + " running_loss = 0.0\n", + " running_corrects = 0\n", + " total_samples = 0\n", + "\n", + " all_preds = []\n", + " all_labels = []\n", + "\n", + " with torch.no_grad(): # No gradient calculation for testing\n", + " for inputs, labels in tqdm(test_loader, desc=\"Testing\"):\n", + " inputs = inputs.to(device)\n", + " labels = labels.to(device).long()\n", + "\n", + " # Forward pass\n", + " outputs = model(inputs)\n", + " loss = criterion(outputs, labels)\n", + " \n", + " # Collect test metrics\n", + " running_loss += loss.item() * inputs.size(0)\n", + " _, preds = torch.max(outputs, 1)\n", + " running_corrects += torch.sum(preds == labels)\n", + " total_samples += labels.size(0)\n", + "\n", + " # Store predictions and labels for further analysis if needed\n", + " all_preds.extend(preds.cpu().numpy())\n", + " all_labels.extend(labels.cpu().numpy())\n", + "\n", + " # Calculate overall loss and accuracy\n", + " test_loss = running_loss / total_samples\n", + " test_accuracy = running_corrects.double() / total_samples\n", + "\n", + " print(f\"Test Loss: {test_loss:.4f}\")\n", + " print(f\"Test Accuracy: {test_accuracy:.4f}\")\n", + "\n", + " # Calculate confusion matrix\n", + " cm = confusion_matrix(all_labels, all_preds)\n", + "\n", + " # Plot confusion matrix using Seaborn\n", + " plt.figure(figsize=(8, 6))\n", + " sns.heatmap(cm, annot=True, fmt='g', cmap='Blues', xticklabels=[\"3_long_blade_rotor\", \"3_short_blade_rotor\", \"Bird\", \"Bird+mini-helicopter\", \"drone\", \"rc_plane\"], yticklabels=[\"3_long_blade_rotor\", \"3_short_blade_rotor\", \"Bird\", \"Bird+mini-helicopter\", \"drone\", \"rc_plane\"])\n", + " plt.xlabel('Predicted Labels')\n", + " plt.ylabel('True Labels')\n", + " plt.title('Confusion Matrix')\n", + " plt.show()\n", + "\n", + " return {\n", + " \"test_loss\": test_loss,\n", + " \"test_accuracy\": test_accuracy.item(),\n", + " \"confusion_matrix\": cm,\n", + " \"all_preds\": all_preds,\n", + " \"all_labels\": all_labels,\n", + " }\n", + "\n", + "# Example Usage\n", + "criterion = nn.CrossEntropyLoss() # Define the same criterion used during training\n", + "device = \"cuda\" if torch.cuda.is_available() else \"cpu\"\n", + "\n", + "test_results = test_model(model, test_loader, criterion, device=device)\n", + "\n", + "# Optional: Print predictions and labels for a sanity check\n", + "print(\"Sample Predictions:\", test_results[\"all_preds\"][:10])\n", + "print(\"Sample Labels:\", test_results[\"all_labels\"][:10])\n" + ] + }, + { + "cell_type": "code", + "execution_count": 43, + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "Testing: 100%|██████████| 61/61 [00:09<00:00, 6.29it/s]\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Test Loss: 0.0684\n", + "Test Accuracy: 0.9794\n" + ] + }, + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAwIAAAKlCAYAAAB40ltaAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjkuMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8hTgPZAAAACXBIWXMAAA9hAAAPYQGoP6dpAACWpUlEQVR4nOzdZ3hUVff38d8kpEEaBELoLRB6DUpAitJRpAmiKF2pgoYmKiWhBOkCCggIAUFuEUFFKdJ7h1BEpIMSek0CISR5XvAwf8dQEpjkZDLfz32d60727DlnzXaAWbP23seUmJiYKAAAAAB2xcHoAAAAAACkPRIBAAAAwA6RCAAAAAB2iEQAAAAAsEMkAgAAAIAdIhEAAAAA7BCJAAAAAGCHSAQAAAAAO0QiAAAAANghEgEAwFMdO3ZM9erVk5eXl0wmk5YuXWrV858+fVomk0lz5syx6nltWa1atVSrVi2jwwCQgZEIAICNOHHihLp06aLChQvL1dVVnp6eqlatmr744gvduXMnVa/drl07HTx4UCNGjNC8efMUGBiYqtdLS+3bt5fJZJKnp+cjx/HYsWMymUwymUwaO3Zsis9//vx5DR06VPv377dCtABgPZmMDgAA8HS//vqrWrZsKRcXF7Vt21alS5fWvXv3tHnzZvXr10+HDx/W119/nSrXvnPnjrZt26ZPP/1UPXv2TJVrFChQQHfu3JGTk1OqnP9pMmXKpJiYGP3yyy9q1aqVxWPz58+Xq6ur7t69+0znPn/+vEJCQlSwYEGVL18+2c9btWrVM10PAJKLRAAA0rlTp06pdevWKlCggNauXatcuXKZH+vRo4eOHz+uX3/9NdWuf/nyZUmSt7d3ql3DZDLJ1dU11c7/NC4uLqpWrZq+++67JInAggUL9Oqrr2rx4sVpEktMTIwyZ84sZ2fnNLkeAPvF1CAASOdGjx6tqKgozZo1yyIJeMjf31+9e/c2/37//n0NGzZMRYoUkYuLiwoWLKhPPvlEsbGxFs8rWLCgXnvtNW3evFkvvPCCXF1dVbhwYc2dO9fcZ+jQoSpQoIAkqV+/fjKZTCpYsKCkB1NqHv78b0OHDpXJZLJo+/333/XSSy/J29tb7u7uCggI0CeffGJ+/HFrBNauXavq1asrS5Ys8vb2VpMmTXTkyJFHXu/48eNq3769vL295eXlpQ4dOigmJubxA/sfb7/9tpYvX64bN26Y23bt2qVjx47p7bffTtL/2rVr6tu3r8qUKSN3d3d5enqqYcOGioiIMPdZv369KleuLEnq0KGDeYrRw9dZq1YtlS5dWnv27FGNGjWUOXNm87j8d41Au3bt5OrqmuT1169fX1mzZtX58+eT/VoBQCIRAIB075dfflHhwoVVtWrVZPXv3LmzBg8erIoVK2rChAmqWbOmwsLC1Lp16yR9jx8/rjfeeEN169bVuHHjlDVrVrVv316HDx+WJDVv3lwTJkyQJL311luaN2+eJk6cmKL4Dx8+rNdee02xsbEKDQ3VuHHj9Prrr2vLli1PfN7q1atVv359Xbp0SUOHDlVwcLC2bt2qatWq6fTp00n6t2rVSrdv31ZYWJhatWqlOXPmKCQkJNlxNm/eXCaTST/++KO5bcGCBSpevLgqVqyYpP/Jkye1dOlSvfbaaxo/frz69eungwcPqmbNmuYP5SVKlFBoaKgk6f3339e8efM0b9481ahRw3yeq1evqmHDhipfvrwmTpyol19++ZHxffHFF8qRI4fatWun+Ph4SdL06dO1atUqTZ48Wblz5072awUASVIiACDdunnzZqKkxCZNmiSr//79+xMlJXbu3NmivW/fvomSEteuXWtuK1CgQKKkxI0bN5rbLl26lOji4pLYp08fc9upU6cSJSWOGTPG4pzt2rVLLFCgQJIYhgwZkvjvf14mTJiQKCnx8uXLj4374TVmz55tbitfvnyir69v4tWrV81tERERiQ4ODolt27ZNcr2OHTtanLNZs2aJPj4+j73mv19HlixZEhMTExPfeOONxNq1aycmJiYmxsfHJ/r5+SWGhIQ8cgzu3r2bGB8fn+R1uLi4JIaGhprbdu3aleS1PVSzZs1ESYnTpk175GM1a9a0aFu5cmWipMThw4cnnjx5MtHd3T2xadOmT32NAPAoVAQAIB27deuWJMnDwyNZ/X/77TdJUnBwsEV7nz59JCnJWoKSJUuqevXq5t9z5MihgIAAnTx58plj/q+Hawt++uknJSQkJOs5kZGR2r9/v9q3b69s2bKZ28uWLau6deuaX+e/de3a1eL36tWr6+rVq+YxTI63335b69ev14ULF7R27VpduHDhkdOCpAfrChwcHvwzGh8fr6tXr5qnPe3duzfZ13RxcVGHDh2S1bdevXrq0qWLQkND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ubm5qWzZsurZs6d5kTvsF4kAkMZy5MihzZs3KyAgwKL96NGjqlq1qq5evWpQZLandOnSmjZtml566SWL9k2bNun999/XkSNHDIoM9mzevHmaNm2aTp06pW3btqlAgQKaOHGiChUqpCZNmhgdHuxMjhw5tHXr1iS7BgES9xEA0tz9+/f1559/Jmn/888/lZCQYEBEtuvEiRPy9vZO0u7l5WWxPzaQVqZOnarg4GA1atRIN27cME9P8/b2trjnBZBW3nnnHc2aNcvoMJBOsUYASGMdOnRQp06ddOLECb3wwguSHuznPGrUKHXo0MHg6GxL5cqVFRwcrHnz5ilnzpySpIsXL6pfv37msQXS0uTJkzVjxgw1bdpUo0aNMrcHBgaqb9++BkYGe3X//n198803Wr16tSpVqqQsWbJYPD5+/HiDIkN6QCIApLGxY8fKz89P48aNU2RkpCQpV65c6tevn/r06WNwdLblm2++UbNmzZQ/f37ly5dPknTu3DkVLVpUS5cuNTY42KVTp06pQoUKSdpdXFwUHR1tQESwd4cOHVLFihUlSX/99ZfFYw83VoD9Yo0AYKBbt25JenDDFzybxMRE/f777+bpViVKlFCdOnX4Bw6GKFmypMLCwtSkSRN5eHgoIiJChQsX1uTJkzV79mzt3bvX6BABwIyKAGAgEoDnZzKZVK9ePdWrV8/oUAAFBwerR48eunv3rhITE7Vz50599913CgsL08yZM40ODwAsUBEADPDDDz/o+++/19mzZ3Xv3j2Lx/jGMGWio6O1YcOGR45lr169DIoK9mz+/PkaOnSoTpw4IUnKnTu3QkJC1KlTJ4MjAwBLJAJAGps0aZI+/fRTtW/fXl9//bU6dOigEydOaNeuXerRo4dGjBhhdIg2Y9++fWrUqJFiYmIUHR2tbNmy6cqVK8qcObN8fX118uRJo0OEHYuJiVFUVJR8fX2NDgUAHontQ4E09tVXX+nrr7/W5MmT5ezsrP79++v3339Xr169dPPmTaPDsykfffSRGjdurOvXr8vNzU3bt2/XmTNnVKlSJY0dO9bo8GDnHiakAJBekQgAaezs2bOqWrWqJMnNzU23b9+WJL377rv67rvvjAzN5uzfv199+vSRg4ODHB0dFRsbq3z58mn06NH65JNPjA4PdujixYt69913lTt3bmXKlEmOjo4WBwCkJywW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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "image/png": "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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "ename": "ValueError", + "evalue": "multiclass format is not supported", + "output_type": "error", + "traceback": [ + "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[1;31mValueError\u001b[0m Traceback (most recent call last)", + "Cell \u001b[1;32mIn[43], line 116\u001b[0m\n\u001b[0;32m 113\u001b[0m criterion \u001b[38;5;241m=\u001b[39m nn\u001b[38;5;241m.\u001b[39mCrossEntropyLoss() \u001b[38;5;66;03m# Define the same criterion used during training\u001b[39;00m\n\u001b[0;32m 114\u001b[0m device \u001b[38;5;241m=\u001b[39m \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mcuda\u001b[39m\u001b[38;5;124m\"\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m torch\u001b[38;5;241m.\u001b[39mcuda\u001b[38;5;241m.\u001b[39mis_available() \u001b[38;5;28;01melse\u001b[39;00m \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mcpu\u001b[39m\u001b[38;5;124m\"\u001b[39m\n\u001b[1;32m--> 116\u001b[0m test_results \u001b[38;5;241m=\u001b[39m \u001b[43mtest_model\u001b[49m\u001b[43m(\u001b[49m\u001b[43mmodel\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mtest_loader\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mcriterion\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mdevice\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mdevice\u001b[49m\u001b[43m)\u001b[49m\n\u001b[0;32m 118\u001b[0m \u001b[38;5;66;03m# Optional: Print predictions and labels for a sanity check\u001b[39;00m\n\u001b[0;32m 119\u001b[0m \u001b[38;5;28mprint\u001b[39m(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mSample Predictions:\u001b[39m\u001b[38;5;124m\"\u001b[39m, test_results[\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mall_preds\u001b[39m\u001b[38;5;124m\"\u001b[39m][:\u001b[38;5;241m10\u001b[39m])\n", + "Cell \u001b[1;32mIn[43], line 83\u001b[0m, in \u001b[0;36mtest_model\u001b[1;34m(model, test_loader, criterion, device)\u001b[0m\n\u001b[0;32m 80\u001b[0m plt\u001b[38;5;241m.\u001b[39mshow()\n\u001b[0;32m 82\u001b[0m \u001b[38;5;66;03m# Precision-Recall Curve (Precision vs Recall)\u001b[39;00m\n\u001b[1;32m---> 83\u001b[0m precision, recall, _ \u001b[38;5;241m=\u001b[39m \u001b[43mprecision_recall_curve\u001b[49m\u001b[43m(\u001b[49m\u001b[43mall_labels\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mnp\u001b[49m\u001b[38;5;241;43m.\u001b[39;49m\u001b[43marray\u001b[49m\u001b[43m(\u001b[49m\u001b[43mall_probs\u001b[49m\u001b[43m)\u001b[49m\u001b[43m[\u001b[49m\u001b[43m:\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;241;43m1\u001b[39;49m\u001b[43m]\u001b[49m\u001b[43m)\u001b[49m\n\u001b[0;32m 85\u001b[0m plt\u001b[38;5;241m.\u001b[39mfigure(figsize\u001b[38;5;241m=\u001b[39m(\u001b[38;5;241m8\u001b[39m, \u001b[38;5;241m6\u001b[39m))\n\u001b[0;32m 86\u001b[0m plt\u001b[38;5;241m.\u001b[39mplot(recall, precision, color\u001b[38;5;241m=\u001b[39m\u001b[38;5;124m'\u001b[39m\u001b[38;5;124mb\u001b[39m\u001b[38;5;124m'\u001b[39m)\n", + "File \u001b[1;32mc:\\Users\\Shravya H Jain\\Desktop\\micro-classify-main\\Micro-Classify\\.venv\\Lib\\site-packages\\sklearn\\utils\\_param_validation.py:213\u001b[0m, in \u001b[0;36mvalidate_params..decorator..wrapper\u001b[1;34m(*args, **kwargs)\u001b[0m\n\u001b[0;32m 207\u001b[0m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[0;32m 208\u001b[0m \u001b[38;5;28;01mwith\u001b[39;00m config_context(\n\u001b[0;32m 209\u001b[0m skip_parameter_validation\u001b[38;5;241m=\u001b[39m(\n\u001b[0;32m 210\u001b[0m prefer_skip_nested_validation \u001b[38;5;129;01mor\u001b[39;00m global_skip_validation\n\u001b[0;32m 211\u001b[0m )\n\u001b[0;32m 212\u001b[0m ):\n\u001b[1;32m--> 213\u001b[0m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[43mfunc\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[43margs\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[38;5;241;43m*\u001b[39;49m\u001b[43mkwargs\u001b[49m\u001b[43m)\u001b[49m\n\u001b[0;32m 214\u001b[0m \u001b[38;5;28;01mexcept\u001b[39;00m InvalidParameterError \u001b[38;5;28;01mas\u001b[39;00m e:\n\u001b[0;32m 215\u001b[0m \u001b[38;5;66;03m# When the function is just a wrapper around an estimator, we allow\u001b[39;00m\n\u001b[0;32m 216\u001b[0m \u001b[38;5;66;03m# the function to delegate validation to the estimator, but we replace\u001b[39;00m\n\u001b[0;32m 217\u001b[0m \u001b[38;5;66;03m# the name of the estimator by the name of the function in the error\u001b[39;00m\n\u001b[0;32m 218\u001b[0m \u001b[38;5;66;03m# message to avoid confusion.\u001b[39;00m\n\u001b[0;32m 219\u001b[0m msg \u001b[38;5;241m=\u001b[39m re\u001b[38;5;241m.\u001b[39msub(\n\u001b[0;32m 220\u001b[0m \u001b[38;5;124mr\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mparameter of \u001b[39m\u001b[38;5;124m\\\u001b[39m\u001b[38;5;124mw+ must be\u001b[39m\u001b[38;5;124m\"\u001b[39m,\n\u001b[0;32m 221\u001b[0m \u001b[38;5;124mf\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mparameter of \u001b[39m\u001b[38;5;132;01m{\u001b[39;00mfunc\u001b[38;5;241m.\u001b[39m\u001b[38;5;18m__qualname__\u001b[39m\u001b[38;5;132;01m}\u001b[39;00m\u001b[38;5;124m must be\u001b[39m\u001b[38;5;124m\"\u001b[39m,\n\u001b[0;32m 222\u001b[0m \u001b[38;5;28mstr\u001b[39m(e),\n\u001b[0;32m 223\u001b[0m )\n", + "File \u001b[1;32mc:\\Users\\Shravya H Jain\\Desktop\\micro-classify-main\\Micro-Classify\\.venv\\Lib\\site-packages\\sklearn\\metrics\\_ranking.py:1002\u001b[0m, in \u001b[0;36mprecision_recall_curve\u001b[1;34m(y_true, y_score, pos_label, sample_weight, drop_intermediate, probas_pred)\u001b[0m\n\u001b[0;32m 993\u001b[0m warnings\u001b[38;5;241m.\u001b[39mwarn(\n\u001b[0;32m 994\u001b[0m (\n\u001b[0;32m 995\u001b[0m \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mprobas_pred was deprecated in version 1.5 and will be removed in 1.7.\u001b[39m\u001b[38;5;124m\"\u001b[39m\n\u001b[1;32m (...)\u001b[0m\n\u001b[0;32m 998\u001b[0m \u001b[38;5;167;01mFutureWarning\u001b[39;00m,\n\u001b[0;32m 999\u001b[0m )\n\u001b[0;32m 1000\u001b[0m y_score \u001b[38;5;241m=\u001b[39m probas_pred\n\u001b[1;32m-> 1002\u001b[0m fps, tps, thresholds \u001b[38;5;241m=\u001b[39m \u001b[43m_binary_clf_curve\u001b[49m\u001b[43m(\u001b[49m\n\u001b[0;32m 1003\u001b[0m \u001b[43m \u001b[49m\u001b[43my_true\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43my_score\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mpos_label\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43mpos_label\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43msample_weight\u001b[49m\u001b[38;5;241;43m=\u001b[39;49m\u001b[43msample_weight\u001b[49m\n\u001b[0;32m 1004\u001b[0m \u001b[43m\u001b[49m\u001b[43m)\u001b[49m\n\u001b[0;32m 1006\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m drop_intermediate \u001b[38;5;129;01mand\u001b[39;00m \u001b[38;5;28mlen\u001b[39m(fps) \u001b[38;5;241m>\u001b[39m \u001b[38;5;241m2\u001b[39m:\n\u001b[0;32m 1007\u001b[0m \u001b[38;5;66;03m# Drop thresholds corresponding to points where true positives (tps)\u001b[39;00m\n\u001b[0;32m 1008\u001b[0m \u001b[38;5;66;03m# do not change from the previous or subsequent point. This will keep\u001b[39;00m\n\u001b[0;32m 1009\u001b[0m \u001b[38;5;66;03m# only the first and last point for each tps value. All points\u001b[39;00m\n\u001b[0;32m 1010\u001b[0m \u001b[38;5;66;03m# with the same tps value have the same recall and thus x coordinate.\u001b[39;00m\n\u001b[0;32m 1011\u001b[0m \u001b[38;5;66;03m# They appear as a vertical line on the plot.\u001b[39;00m\n\u001b[0;32m 1012\u001b[0m optimal_idxs \u001b[38;5;241m=\u001b[39m np\u001b[38;5;241m.\u001b[39mwhere(\n\u001b[0;32m 1013\u001b[0m np\u001b[38;5;241m.\u001b[39mconcatenate(\n\u001b[0;32m 1014\u001b[0m [[\u001b[38;5;28;01mTrue\u001b[39;00m], np\u001b[38;5;241m.\u001b[39mlogical_or(np\u001b[38;5;241m.\u001b[39mdiff(tps[:\u001b[38;5;241m-\u001b[39m\u001b[38;5;241m1\u001b[39m]), np\u001b[38;5;241m.\u001b[39mdiff(tps[\u001b[38;5;241m1\u001b[39m:])), [\u001b[38;5;28;01mTrue\u001b[39;00m]]\n\u001b[0;32m 1015\u001b[0m )\n\u001b[0;32m 1016\u001b[0m )[\u001b[38;5;241m0\u001b[39m]\n", + "File \u001b[1;32mc:\\Users\\Shravya H Jain\\Desktop\\micro-classify-main\\Micro-Classify\\.venv\\Lib\\site-packages\\sklearn\\metrics\\_ranking.py:817\u001b[0m, in \u001b[0;36m_binary_clf_curve\u001b[1;34m(y_true, y_score, pos_label, sample_weight)\u001b[0m\n\u001b[0;32m 815\u001b[0m y_type \u001b[38;5;241m=\u001b[39m type_of_target(y_true, input_name\u001b[38;5;241m=\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;124my_true\u001b[39m\u001b[38;5;124m\"\u001b[39m)\n\u001b[0;32m 816\u001b[0m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m (y_type \u001b[38;5;241m==\u001b[39m \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mbinary\u001b[39m\u001b[38;5;124m\"\u001b[39m \u001b[38;5;129;01mor\u001b[39;00m (y_type \u001b[38;5;241m==\u001b[39m \u001b[38;5;124m\"\u001b[39m\u001b[38;5;124mmulticlass\u001b[39m\u001b[38;5;124m\"\u001b[39m \u001b[38;5;129;01mand\u001b[39;00m pos_label \u001b[38;5;129;01mis\u001b[39;00m \u001b[38;5;129;01mnot\u001b[39;00m \u001b[38;5;28;01mNone\u001b[39;00m)):\n\u001b[1;32m--> 817\u001b[0m \u001b[38;5;28;01mraise\u001b[39;00m \u001b[38;5;167;01mValueError\u001b[39;00m(\u001b[38;5;124m\"\u001b[39m\u001b[38;5;132;01m{0}\u001b[39;00m\u001b[38;5;124m format is not supported\u001b[39m\u001b[38;5;124m\"\u001b[39m\u001b[38;5;241m.\u001b[39mformat(y_type))\n\u001b[0;32m 819\u001b[0m check_consistent_length(y_true, y_score, sample_weight)\n\u001b[0;32m 820\u001b[0m y_true \u001b[38;5;241m=\u001b[39m column_or_1d(y_true)\n", + "\u001b[1;31mValueError\u001b[0m: multiclass format is not supported" + ] + } + ], + "source": [ + "import torch\n", + "from sklearn.metrics import roc_curve, auc, precision_recall_curve, accuracy_score\n", + "import matplotlib.pyplot as plt\n", + "from tqdm import tqdm\n", + "import seaborn as sns\n", + "import numpy as np\n", + "from sklearn.metrics import confusion_matrix\n", + "\n", + "def test_model(model, test_loader, criterion, device=\"cuda\" if torch.cuda.is_available() else \"cpu\"):\n", + " \"\"\"\n", + " Test the trained model on the test dataset.\n", + " \n", + " Args:\n", + " model (nn.Module): Trained PyTorch model.\n", + " test_loader (DataLoader): DataLoader for the test dataset.\n", + " criterion (nn.Module): Loss function.\n", + " device (str): Device to run the testing on (default: \"cuda\" if available).\n", + " \n", + " Returns:\n", + " dict: Dictionary containing test loss, accuracy, confusion matrix, predictions, and labels.\n", + " \"\"\"\n", + " model.eval() # Set the model to evaluation mode\n", + " running_loss = 0.0\n", + " running_corrects = 0\n", + " total_samples = 0\n", + "\n", + " all_preds = []\n", + " all_labels = []\n", + " all_probs = []\n", + "\n", + " with torch.no_grad(): # No gradient calculation for testing\n", + " for inputs, labels in tqdm(test_loader, desc=\"Testing\"):\n", + " inputs = inputs.to(device)\n", + " labels = labels.to(device).long()\n", + "\n", + " # Forward pass\n", + " outputs = model(inputs)\n", + " loss = criterion(outputs, labels)\n", + " \n", + " # Collect test metrics\n", + " running_loss += loss.item() * inputs.size(0)\n", + " _, preds = torch.max(outputs, 1)\n", + " running_corrects += torch.sum(preds == labels)\n", + " total_samples += labels.size(0)\n", + "\n", + " # Store predictions, labels, and probabilities for further analysis if needed\n", + " all_preds.extend(preds.cpu().numpy())\n", + " all_labels.extend(labels.cpu().numpy())\n", + " all_probs.extend(F.softmax(outputs, dim=1).cpu().numpy())\n", + "\n", + " # Calculate overall loss and accuracy\n", + " test_loss = running_loss / total_samples\n", + " test_accuracy = running_corrects.double() / total_samples\n", + "\n", + " print(f\"Test Loss: {test_loss:.4f}\")\n", + " print(f\"Test Accuracy: {test_accuracy:.4f}\")\n", + "\n", + " # Calculate confusion matrix\n", + " cm = confusion_matrix(all_labels, all_preds)\n", + "\n", + " # Plot confusion matrix using Seaborn\n", + " plt.figure(figsize=(8, 6))\n", + " sns.heatmap(cm, annot=True, fmt='g', cmap='Blues', xticklabels=[\"3_long_blade_rotor\", \"3_short_blade_rotor\", \"Bird\", \"Bird+mini-helicopter\", \"drone\", \"rc_plane\"], yticklabels=[\"3_long_blade_rotor\", \"3_short_blade_rotor\", \"Bird\", \"Bird+mini-helicopter\", \"drone\", \"rc_plane\"])\n", + " plt.xlabel('Predicted Labels')\n", + " plt.ylabel('True Labels')\n", + " plt.title('Confusion Matrix')\n", + " plt.show()\n", + "\n", + " # ROC Curve (One-vs-Rest)\n", + " fpr, tpr, _ = roc_curve(all_labels, np.array(all_probs)[:, 1], pos_label=1)\n", + " roc_auc = auc(fpr, tpr)\n", + " \n", + " plt.figure(figsize=(8, 6))\n", + " plt.plot(fpr, tpr, color='b', label=f'ROC curve (area = {roc_auc:.2f})')\n", + " plt.plot([0, 1], [0, 1], color='gray', linestyle='--')\n", + " plt.xlabel('False Positive Rate')\n", + " plt.ylabel('True Positive Rate')\n", + " plt.title('ROC Curve')\n", + " plt.legend(loc='lower right')\n", + " plt.show()\n", + "\n", + " # Precision-Recall Curve (Precision vs Recall)\n", + " precision, recall, _ = precision_recall_curve(all_labels, np.array(all_probs)[:, 1])\n", + " \n", + " plt.figure(figsize=(8, 6))\n", + " plt.plot(recall, precision, color='b')\n", + " plt.xlabel('Recall')\n", + " plt.ylabel('Precision')\n", + " plt.title('Precision-Recall Curve')\n", + " plt.show()\n", + "\n", + " # Accuracy Curve (Accuracy vs Epochs)\n", + " accuracy_curve = [accuracy_score(all_labels, all_preds)]\n", + " \n", + " plt.figure(figsize=(8, 6))\n", + " plt.plot(accuracy_curve, color='b', label=\"Accuracy\")\n", + " plt.xlabel('Epochs')\n", + " plt.ylabel('Accuracy')\n", + " plt.title('Accuracy Curve')\n", + " plt.legend(loc='best')\n", + " plt.show()\n", + "\n", + " return {\n", + " \"test_loss\": test_loss,\n", + " \"test_accuracy\": test_accuracy.item(),\n", + " \"confusion_matrix\": cm,\n", + " \"all_preds\": all_preds,\n", + " \"all_labels\": all_labels,\n", + " \"roc_auc\": roc_auc,\n", + " }\n", + "\n", + "# Example Usage\n", + "criterion = nn.CrossEntropyLoss() # Define the same criterion used during training\n", + "device = \"cuda\" if torch.cuda.is_available() else \"cpu\"\n", + "\n", + "test_results = test_model(model, test_loader, criterion, device=device)\n", + "\n", + "# Optional: Print predictions and labels for a sanity check\n", + "print(\"Sample Predictions:\", test_results[\"all_preds\"][:10])\n", + "print(\"Sample Labels:\", test_results[\"all_labels\"][:10])\n" + ] + }, + { + "cell_type": "code", + "execution_count": 77, + "metadata": {}, + "outputs": [], + "source": [ + "import torch\n", + "import torch.nn as nn\n", + "import torch.optim as optim\n", + "from torch.optim import lr_scheduler\n", + "import torch.nn.functional as F\n", + "from torch.utils.data import DataLoader, random_split\n", + "from tqdm import tqdm\n", + "from sklearn.metrics import confusion_matrix, roc_curve, auc\n", + "import seaborn as sns\n", + "import matplotlib.pyplot as plt\n", + "from torchvision import transforms\n", + "from sklearn.metrics import accuracy_score\n", + "# Define the transformations for the dataset\n", + "transform = transforms.Compose([\n", + " transforms.Resize((224, 224)),\n", + " transforms.RandomHorizontalFlip(),\n", + " transforms.ColorJitter(brightness=0.2, contrast=0.2),\n", + " transforms.ToTensor(),\n", + " transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]) # Normalize with ImageNet stats\n", + "])\n", + "# Define the Spatial Attention Module\n", + "class SpatialAttention(nn.Module):\n", + " def __init__(self, in_channels):\n", + " super(SpatialAttention, self).__init__()\n", + " self.conv1 = nn.Conv2d(in_channels, 1, kernel_size=1)\n", + " self.conv2 = nn.Conv2d(1, 1, kernel_size=3, padding=1)\n", + " self.sigmoid = nn.Sigmoid()\n", + "\n", + " def forward(self, x):\n", + " attn = self.conv1(x)\n", + " attn = self.conv2(attn)\n", + " attn = self.sigmoid(attn)\n", + " return x * attn\n", + "\n", + "# Define the Custom CNN with integrated Spatial Attention\n", + "class CustomCNNWithAttention(nn.Module):\n", + " def __init__(self, num_classes=6):\n", + " super(CustomCNNWithAttention, self).__init__()\n", + " # 1st Convolutional Block\n", + " self.conv1 = nn.Conv2d(3, 16, kernel_size=3, padding=1)\n", + " self.bn1 = nn.BatchNorm2d(16)\n", + " self.pool1 = nn.MaxPool2d(kernel_size=2, stride=2)\n", + "\n", + " # 2nd Convolutional Block\n", + " self.conv2 = nn.Conv2d(16, 32, kernel_size=3, padding=1)\n", + " self.bn2 = nn.BatchNorm2d(32)\n", + " self.pool2 = nn.MaxPool2d(kernel_size=2, stride=2)\n", "\n", " # 3rd Convolutional Block\n", " self.conv3 = nn.Conv2d(32, 64, kernel_size=3, padding=1)\n", @@ -1452,22 +3192,15 @@ " \n", " # Fully Connected Layers\n", " self.fc1 = nn.Linear(128, 512)\n", - " self.fc2 = nn.Linear(512, num_classes) # Output for `num_classes` classes\n", + " self.fc2 = nn.Linear(512, num_classes)\n", "\n", " # Dropout for Regularization\n", " self.dropout = nn.Dropout(0.5)\n", "\n", " def forward(self, x):\n", - " # 1st Convolutional Block\n", " x = self.pool1(F.relu(self.bn1(self.conv1(x))))\n", - " \n", - " # 2nd Convolutional Block\n", " x = self.pool2(F.relu(self.bn2(self.conv2(x))))\n", - " \n", - " # 3rd Convolutional Block\n", " x = self.pool3(F.relu(self.bn3(self.conv3(x))))\n", - "\n", - " # 4th Convolutional Block\n", " x = self.pool4(F.relu(self.bn4(self.conv4(x))))\n", "\n", " # Apply Attention Mechanism\n", @@ -1475,17 +3208,669 @@ "\n", " # Global Average Pooling\n", " x = self.global_avg_pool(x)\n", - " \n", + "\n", " # Flatten the output\n", " x = torch.flatten(x, 1)\n", - " \n", + "\n", " # Fully Connected Layers\n", " x = F.relu(self.fc1(x))\n", " x = self.dropout(x)\n", " x = self.fc2(x)\n", - " \n", - " return x\n", "\n", + " return x" + ] + }, + { + "cell_type": "code", + "execution_count": 78, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Epoch 1/20\n", + "------------------------------\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "Training: 100%|██████████| 516/516 [01:35<00:00, 5.43it/s]\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Training Loss: 0.8523 Acc: 0.6693\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "Validation: 100%|██████████| 31/31 [00:04<00:00, 6.62it/s]\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Validation Loss: 0.8241 Acc: 0.6942\n", + "Epoch 2/20\n", + "------------------------------\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "Training: 100%|██████████| 516/516 [01:27<00:00, 5.88it/s]\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Training Loss: 0.5006 Acc: 0.8139\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "Validation: 100%|██████████| 31/31 [00:05<00:00, 5.83it/s]\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Validation Loss: 0.5936 Acc: 0.7851\n", + "Epoch 3/20\n", + "------------------------------\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "Training: 100%|██████████| 516/516 [02:04<00:00, 4.15it/s]\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Training Loss: 0.3671 Acc: 0.8694\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "Validation: 100%|██████████| 31/31 [00:04<00:00, 6.43it/s]\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Validation Loss: 0.4423 Acc: 0.8471\n", + "Epoch 4/20\n", + "------------------------------\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "Training: 100%|██████████| 516/516 [01:36<00:00, 5.33it/s]\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Training Loss: 0.2947 Acc: 0.9022\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "Validation: 100%|██████████| 31/31 [00:04<00:00, 6.20it/s]\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Validation Loss: 0.2695 Acc: 0.8926\n", + "Epoch 5/20\n", + "------------------------------\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "Training: 100%|██████████| 516/516 [01:31<00:00, 5.61it/s]\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Training Loss: 0.2419 Acc: 0.9163\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "Validation: 100%|██████████| 31/31 [00:05<00:00, 5.95it/s]\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Validation Loss: 0.2735 Acc: 0.9008\n", + "Epoch 6/20\n", + "------------------------------\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "Training: 100%|██████████| 516/516 [01:35<00:00, 5.42it/s]\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Training Loss: 0.2184 Acc: 0.9289\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "Validation: 100%|██████████| 31/31 [00:04<00:00, 6.59it/s]\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Validation Loss: 0.2816 Acc: 0.9008\n", + "Epoch 7/20\n", + "------------------------------\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "Training: 100%|██████████| 516/516 [01:33<00:00, 5.50it/s]\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Training Loss: 0.1793 Acc: 0.9425\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "Validation: 100%|██████████| 31/31 [00:04<00:00, 6.44it/s]\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Validation Loss: 0.0956 Acc: 0.9628\n", + "Epoch 8/20\n", + "------------------------------\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "Training: 100%|██████████| 516/516 [01:34<00:00, 5.44it/s]\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Training Loss: 0.1033 Acc: 0.9689\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "Validation: 100%|██████████| 31/31 [00:05<00:00, 6.02it/s]\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Validation Loss: 0.0610 Acc: 0.9793\n", + "Epoch 9/20\n", + "------------------------------\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "Training: 100%|██████████| 516/516 [01:21<00:00, 6.31it/s]\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Training Loss: 0.0842 Acc: 0.9731\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "Validation: 100%|██████████| 31/31 [00:08<00:00, 3.48it/s]\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Validation Loss: 0.0475 Acc: 0.9876\n", + "Epoch 10/20\n", + "------------------------------\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "Training: 100%|██████████| 516/516 [02:00<00:00, 4.29it/s]\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Training Loss: 0.0681 Acc: 0.9791\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "Validation: 100%|██████████| 31/31 [00:04<00:00, 7.55it/s]\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Validation Loss: 0.0593 Acc: 0.9793\n", + "Epoch 11/20\n", + "------------------------------\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "Training: 100%|██████████| 516/516 [02:14<00:00, 3.83it/s]\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Training Loss: 0.0664 Acc: 0.9813\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "Validation: 100%|██████████| 31/31 [00:08<00:00, 3.58it/s]\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Validation Loss: 0.0565 Acc: 0.9752\n", + "Epoch 12/20\n", + "------------------------------\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "Training: 100%|██████████| 516/516 [01:37<00:00, 5.30it/s]\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Training Loss: 0.0627 Acc: 0.9789\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "Validation: 100%|██████████| 31/31 [00:04<00:00, 7.44it/s]\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Validation Loss: 0.0365 Acc: 0.9876\n", + "Epoch 13/20\n", + "------------------------------\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "Training: 100%|██████████| 516/516 [01:34<00:00, 5.44it/s]\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Training Loss: 0.0521 Acc: 0.9830\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "Validation: 100%|██████████| 31/31 [00:07<00:00, 4.23it/s]\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Validation Loss: 0.0466 Acc: 0.9793\n", + "Epoch 14/20\n", + "------------------------------\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "Training: 100%|██████████| 516/516 [01:45<00:00, 4.89it/s]\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Training Loss: 0.0487 Acc: 0.9850\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "Validation: 100%|██████████| 31/31 [00:05<00:00, 5.75it/s]\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Validation Loss: 0.0441 Acc: 0.9876\n", + "Epoch 15/20\n", + "------------------------------\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "Training: 100%|██████████| 516/516 [01:59<00:00, 4.33it/s]\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Training Loss: 0.0448 Acc: 0.9864\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "Validation: 100%|██████████| 31/31 [00:04<00:00, 6.61it/s]\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Validation Loss: 0.0351 Acc: 0.9835\n", + "Epoch 16/20\n", + "------------------------------\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "Training: 100%|██████████| 516/516 [01:32<00:00, 5.59it/s]\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Training Loss: 0.0448 Acc: 0.9854\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "Validation: 100%|██████████| 31/31 [00:04<00:00, 6.53it/s]\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Validation Loss: 0.0390 Acc: 0.9876\n", + "Epoch 17/20\n", + "------------------------------\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "Training: 100%|██████████| 516/516 [01:46<00:00, 4.84it/s]\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Training Loss: 0.0433 Acc: 0.9876\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "Validation: 100%|██████████| 31/31 [00:05<00:00, 5.75it/s]\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Validation Loss: 0.0345 Acc: 0.9917\n", + "Epoch 18/20\n", + "------------------------------\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "Training: 100%|██████████| 516/516 [01:32<00:00, 5.56it/s]\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Training Loss: 0.0401 Acc: 0.9871\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "Validation: 100%|██████████| 31/31 [00:05<00:00, 5.90it/s]\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Validation Loss: 0.0392 Acc: 0.9917\n", + "Epoch 19/20\n", + "------------------------------\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "Training: 100%|██████████| 516/516 [01:34<00:00, 5.44it/s]\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Training Loss: 0.0416 Acc: 0.9871\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "Validation: 100%|██████████| 31/31 [00:05<00:00, 5.38it/s]\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Validation Loss: 0.0314 Acc: 0.9876\n", + "Epoch 20/20\n", + "------------------------------\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "Training: 100%|██████████| 516/516 [01:48<00:00, 4.77it/s]\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Training Loss: 0.0368 Acc: 0.9884\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "Validation: 100%|██████████| 31/31 [00:05<00:00, 5.80it/s]\n", + "C:\\Users\\Shravya H Jain\\AppData\\Local\\Temp\\ipykernel_22584\\2047599850.py:155: FutureWarning: You are using `torch.load` with `weights_only=False` (the current default value), which uses the default pickle module implicitly. It is possible to construct malicious pickle data which will execute arbitrary code during unpickling (See https://github.com/pytorch/pytorch/blob/main/SECURITY.md#untrusted-models for more details). In a future release, the default value for `weights_only` will be flipped to `True`. This limits the functions that could be executed during unpickling. Arbitrary objects will no longer be allowed to be loaded via this mode unless they are explicitly allowlisted by the user via `torch.serialization.add_safe_globals`. We recommend you start setting `weights_only=True` for any use case where you don't have full control of the loaded file. Please open an issue on GitHub for any issues related to this experimental feature.\n", + " model = torch.load(\"customcnnwithAttention_best.pth\")\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Validation Loss: 0.0398 Acc: 0.9876\n", + "Training complete. Best Validation Acc: 0.9917\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "Testing: 100%|██████████| 61/61 [00:11<00:00, 5.22it/s]\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Test Loss: 0.0382\n", + "Test Accuracy: 0.9856\n" + ] + }, + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAwIAAAKlCAYAAAB40ltaAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjkuMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8hTgPZAAAACXBIWXMAAA9hAAAPYQGoP6dpAACWoUlEQVR4nOzdd3hUVdf38d8kpEEaBELoLRB6DULoSkeRpoiidBtVQxOVklCCNEGQIiBNlFtEUFEE6R2poQgRQ1VCr0kgpL1/8DKPYygJTHIyme/nuc71JHv2nLNmOzeZNWvvfUzJycnJAgAAAGBXHIwOAAAAAEDGIxEAAAAA7BCJAAAAAGCHSAQAAAAAO0QiAAAAANghEgEAAADADpEIAAAAAHaIRAAAAACwQyQCAAAAgB0iEQAAPNbx48fVpEkTeXl5yWQyacWKFVY9/6lTp2QymTR//nyrnteWNWjQQA0aNDA6DABZGIkAANiIyMhIvf322ypevLhcXV3l6emp2rVra8qUKbp9+3a6Xrtz5846dOiQRo8erUWLFikwMDBdr5eRunTpIpPJJE9PzweO4/Hjx2UymWQymTRhwoQ0n//cuXMaMWKEDhw4YIVoAcB6shkdAADg8X7++We9/PLLcnFxUadOnVS+fHndvXtXW7du1cCBA3XkyBF98cUX6XLt27dva8eOHfroo4/Uu3fvdLlGkSJFdPv2bTk5OaXL+R8nW7Zsio2N1U8//aT27dtbPLZ48WK5urrqzp07T3Tuc+fOKSQkREWLFlXlypVT/bw1a9Y80fUAILVIBAAgkzt58qQ6dOigIkWKaP369cqXL5/5sV69eumvv/7Szz//nG7Xv3TpkiTJ29s73a5hMpnk6uqabud/HBcXF9WuXVvffPNNikTg66+/1vPPP69ly5ZlSCyxsbHKnj27nJ2dM+R6AOwXU4MAIJMbN26coqOjNXfuXIsk4D5/f3/169fP/HtCQoJGjhypEiVKyMXFRUWLFtWHH36ouLg4i+cVLVpUL7zwgrZu3apnnnlGrq6uKl68uBYuXGjuM2LECBUpUkSSNHDgQJlMJhUtWlTSvSk193/+txEjRshkMlm0/fbbb6pTp468vb3l7u6ugIAAffjhh+bHH7ZGYP369apbt65y5Mghb29vtWrVSkePHn3g9f766y916dJF3t7e8vLyUteuXRUbG/vwgf2P1157TatWrdL169fNbbt379bx48f12muvpeh/9epVDRgwQBUqVJC7u7s8PT3VvHlzhYeHm/ts3LhR1atXlyR17drVPMXo/uts0KCBypcvr71796pevXrKnj27eVz+u0agc+fOcnV1TfH6mzZtqpw5c+rcuXOpfq0AIJEIAECm99NPP6l48eKqVatWqvr36NFDw4YNU9WqVfXpp5+qfv36CgsLU4cOHVL0/euvv/TSSy+pcePGmjhxonLmzKkuXbroyJEjkqS2bdvq008/lSS9+uqrWrRokSZPnpym+I8cOaIXXnhBcXFxCg0N1cSJE/Xiiy9q27Ztj3ze2rVr1bRpU128eFEjRoxQcHCwtm/frtq1a+vUqVMp+rdv3163bt1SWFiY2rdvr/nz5yskJCTVcbZt21Ymk0nff/+9ue3rr79W6dKlVbVq1RT9T5w4oRUrVuiFF17QpEmTNHDgQB06dEj169c3fygvU6aMQkNDJUlvvfWWFi1apEWLFqlevXrm81y5ckXNmzdX5cqVNXnyZD377LMPjG/KlCnKkyePOnfurMTEREnSrFmztGbNGk2dOlX58+dP9WsFAElSMgAg07px40aypORWrVqlqv+BAweSJSX36NHDon3AgAHJkpLXr19vbitSpEiypOTNmzeb2y5evJjs4uKS3L9/f3PbyZMnkyUljx8/3uKcnTt3Ti5SpEiKGIYPH5787z8vn376abKk5EuXLj007vvXmDdvnrmtcuXKyb6+vslXrlwxt4WHhyc7ODgkd+rUKcX1unXrZnHONm3aJPv4+Dz0mv9+HTly5EhOTk5Ofumll5IbNmyYnJycnJyYmJjs5+eXHBIS8sAxuHPnTnJiYmKK1+Hi4pIcGhpqbtu9e3eK13Zf/fr1kyUlz5w584GP1a9f36Jt9erVyZKSR40alXzixIlkd3f35NatWz/2NQLAg1ARAIBM7ObNm5IkDw+PVPX/5ZdfJEnBwcEW7f3795ekFGsJypYtq7p165p/z5MnjwICAnTixIknjvm/7q8t+OGHH5SUlJSq50RFRenAgQPq0qWLcuXKZW6vWLGiGjdubH6d//bOO+9Y/F63bl1duXLFPIap8dprr2njxo06f/681q9fr/Pnzz9wWpB0b12Bg8O9P6OJiYm6cuWKedrTvn37Un1NFxcXde3aNVV9mzRporfffluh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cWRnZ+Pq6kpISAguLrb/5Xt5edkcl5WV0b9/f959991679W+ffvvlOH2VJ//R1lZGQDbt2+nU6dONm1ubm7fKUdjvPfee8yaNYusrCwGDhyIj48Pb775JocOHWr0e3yX7D/+8Y8ZMWIE27dvJzc3lyVLlpCVlcXUqVO/+82IiDSCCgERkYeUl5cX4eHhje7fr18//vznP9OhQwd8fX0b7BMcHMyhQ4cYMmQIALW1tRw5coR+/fo12D8mJoa6ujr27NlDfHx8vfbbIxJms9l67pFHHsHNzY2ioqK7jiRERUVZFz7fdvDgwfvf5D3s27ePJ598kilTpljPXbx4sV6/EydOUFFRYS1yDh48iLe3N6Ghofj7+983e0NCQ0NJS0sjLS2NuXPnsnLlShUCIvLAadcgEREBYNy4cQQGBjJq1Cj27t3L5cuX2b17N9OmTePf//43ANOnT+eXv/wlW7dupaCggClTptzzGQBdu3YlOTmZl19+ma1bt1rf8y9/+QsAYWFhmEwmtm3bRmlpKWVlZfj4+DBr1ixeffVV1q9fz8WLFzl69CjLly9n/fr1AKSlpXH+/Hlee+01zp49y5/+9CfWrVvXqPv8z3/+w/Hjx22+rl+/Ts+ePfn000/ZsWMH586d4/XXX+fw4cP1vr+6uprU1FROnz5NTk4Ov/jFL3jllVdwcnJqVPY7zZgxgx07dnD58mWOHj1KXl4eUVFRjboXEZGmUCEgIiIAeHp6kp+fT5cuXRgzZgxRUVGkpqZSWVlpHSGYOXMmL730EsnJydbpM6NHj77n+2ZnZzN27FimTJlCZGQkP/nJT7h16xYAnTp1Yv78+cyZM4egoCBeeeUVABYsWMDrr7/OkiVLiIqKIiEhge3bt9OtWzcAunTpwubNm9m6dSuxsbGsWLGCxYsXN+o+f/3rX9O3b1+br+3btzN58mTGjBnDCy+8wIABA/jyyy9tRgduGz58OD179mTIkCG88MILjBw50mbtxf2y38lsNpORkWHt26tXL37/+9836l5ERJrCZLnbCi8REREREXloaURARERERMQBqRAQEREREXFAKgRERERERByQCgEREREREQekQkBERERExAGpEBARERERcUAqBEREREREHJAKARERERERB6RCQERERETEAakQEBERERFxQCoEREREREQc0H8BUWIi8z5dJi4AAAAASUVORK5CYII=", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "image/png": "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jBo1Smvpo8KuAJb7/uS9UERkZKRo3ry5MDMzE56enuLLL78US5cuLbBd7kUTdCnuMXK3bd++vTA3Nxc2Njaibdu24vfff5ceT0lJEcOHDxd2dnYFLppQ3N8P/LuYvi7IszRXZmameO+990SLFi2EtbW1sLS0FC1atChwwYfCcirsPJ89e1YMGjRI2NnZCTMzM9GgQQMxbdo0nfnkdeLECQGgwFJRhV00QQgh9u/fX2C5MSGEuH//vpg4caKoW7euUKlUws7OTgQEBEjLceny+PFjMX36dNGsWTNhYWEhzMzMRNOmTcWUKVNEXFyc1ra+vr7ipZdeeuZrylXctiuEEDt37hRNmzYVSqVSNGjQQPz6669FXjShMBqNRnh4eAgA4rPPPtO5TXHbFFUdCiFKabYDEVV6sbGx8PLywtdff41JkybJnY4sNBoNnJycMHjwYJ1fdVLV061bN7i5uWHlypVyp1Ko6OhotGrVCidOnNBrQiKRIeCYWSKiQmRkZBQYN7lixQo8evQInTt3licpqnA+//xzrFmzRu8JT+Xpiy++QHBwMAtZqpQ4ZpaIqBB//vkn3nnnHQwZMgTVqlXDiRMnsGTJEjRt2hRDhgyROz2qIHx9fZGVlSV3GkVavXq13CkQlRkWs0REhfD09ISHhwe+//57PHr0CA4ODhgxYgS++OILrauHERGRfDhmloiIiIgMFsfMEhEREZHBYjFLRERERAaryo2Z1Wg0uHv3LqytrXkpPCIiIqIKSAiB5ORkuLm5FbiYUH5Vrpi9e/cuPDw85E6DiIiIiJ7h1q1bqFGjRpHbVLli1traGsDTN8fGxkbmbIiIiIgov6SkJHh4eEh1W1GqXDGbO7TAxsaGxSwRERFRBVacIaGcAEZEREREBovFLBEREREZLBazRERERGSwWMwSERERkcFiMUtEREREBovFLBEREREZLBazRERERGSwWMwSERERkcFiMUtEREREBovFLBEREREZLBazRERERGSwWMwSERERkcFiMUtEREREBovFLBEREREZLFmL2QMHDqBfv35wc3ODQqHAxo0bn7nP/v370apVK6hUKtStWxdhYWFlnicRERERVUyyFrOpqalo0aIF5s+fX6ztY2Ji0KdPH3Tp0gXR0dF4++238b///Q87duwo40yJiIiIqCIykfPJe/XqhV69ehV7+wULFsDL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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ "# Train and Validation Function\n", "def train_model(model, train_loader, val_loader, criterion, optimizer, scheduler, num_epochs=20, device=\"cuda\" if torch.cuda.is_available() else \"cpu\"):\n", " model = model.to(device)\n", @@ -1503,26 +3888,21 @@ "\n", " for inputs, labels in tqdm(train_loader, desc=\"Training\"):\n", " inputs = inputs.to(device)\n", - " labels = labels.to(device).long() # Ensure labels are of type torch.long\n", + " labels = labels.to(device).long()\n", "\n", - " # Zero the parameter gradients\n", " optimizer.zero_grad()\n", "\n", - " # Forward Pass\n", " outputs = model(inputs)\n", " loss = criterion(outputs, labels)\n", " _, preds = torch.max(outputs, 1)\n", "\n", - " # Backward Pass and Optimization\n", " loss.backward()\n", " optimizer.step()\n", "\n", - " # Track statistics\n", " running_loss += loss.item() * inputs.size(0)\n", " running_corrects += torch.sum(preds == labels.data)\n", " total_train += labels.size(0)\n", "\n", - " # Adjust learning rate\n", " scheduler.step()\n", "\n", " epoch_loss = running_loss / total_train\n", @@ -1539,14 +3919,12 @@ " with torch.no_grad():\n", " for inputs, labels in tqdm(val_loader, desc=\"Validation\"):\n", " inputs = inputs.to(device)\n", - " labels = labels.to(device).long() # Ensure labels are of type torch.long\n", + " labels = labels.to(device).long()\n", "\n", - " # Forward Pass\n", " outputs = model(inputs)\n", " loss = criterion(outputs, labels)\n", " _, preds = torch.max(outputs, 1)\n", "\n", - " # Track statistics\n", " running_loss += loss.item() * inputs.size(0)\n", " running_corrects += torch.sum(preds == labels.data)\n", " total_val += labels.size(0)\n", @@ -1556,238 +3934,100 @@ "\n", " print(f\"Validation Loss: {epoch_val_loss:.4f} Acc: {epoch_val_acc:.4f}\")\n", "\n", - " # Save the best model\n", " if epoch_val_acc > best_acc:\n", " best_acc = epoch_val_acc\n", - " torch.save(model.state_dict(), \"customcnnwithAttention.pth\")\n", + " # Save the entire model\n", + " torch.save(model, \"customcnnwithAttention_best.pth\")\n", "\n", " print(f\"Training complete. Best Validation Acc: {best_acc:.4f}\")\n", "\n", - "# Example Usage\n", - "if __name__ == \"__main__\":\n", - " # Assuming train_loader and val_loader are defined\n", - " model_deepercnn = CustomCNNWithAttention(num_classes=6)\n", - " criterion = nn.CrossEntropyLoss()\n", - "\n", - " optimizer_deepercnn = optim.Adam(model_deepercnn.parameters(), lr=0.001)\n", - " scheduler_deepercnn = lr_scheduler.StepLR(optimizer_deepercnn, step_size=7, gamma=0.1)\n", - "\n", - " # Train the model\n", - " train_model(model_deepercnn, train_loader, val_loader, criterion, optimizer_deepercnn, scheduler_deepercnn, num_epochs=20)\n" - ] - }, - { - "cell_type": "code", - "execution_count": 12, - "metadata": {}, - "outputs": [ - { - "name": "stderr", - "output_type": "stream", - "text": [ - "C:\\Users\\Shravya H Jain\\AppData\\Local\\Temp\\ipykernel_7300\\3287528403.py:66: FutureWarning: You are using `torch.load` with `weights_only=False` (the current default value), which uses the default pickle module implicitly. It is possible to construct malicious pickle data which will execute arbitrary code during unpickling (See https://github.com/pytorch/pytorch/blob/main/SECURITY.md#untrusted-models for more details). In a future release, the default value for `weights_only` will be flipped to `True`. This limits the functions that could be executed during unpickling. Arbitrary objects will no longer be allowed to be loaded via this mode unless they are explicitly allowlisted by the user via `torch.serialization.add_safe_globals`. We recommend you start setting `weights_only=True` for any use case where you don't have full control of the loaded file. Please open an issue on GitHub for any issues related to this experimental feature.\n", - " model_deepercnn.load_state_dict(torch.load(\"customcnnwithAttention.pth\"))\n", - "Testing: 100%|██████████| 61/61 [00:11<00:00, 5.51it/s]\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Test Loss: 0.0853 Test Acc: 0.9753\n", - "\n", - "Classification Report:\n", - " precision recall f1-score support\n", - "\n", - " Class 0 0.95 0.94 0.95 84\n", - " Class 1 0.93 0.95 0.94 80\n", - " Class 2 1.00 1.00 1.00 80\n", - " Class 3 1.00 0.98 0.99 84\n", - " Class 4 1.00 1.00 1.00 78\n", - " Class 5 0.98 0.99 0.98 80\n", - "\n", - " accuracy 0.98 486\n", - " macro avg 0.98 0.98 0.98 486\n", - "weighted avg 0.98 0.98 0.98 486\n", - "\n", - "\n", - "Confusion Matrix:\n", - "[[79 5 0 0 0 0]\n", - " [ 4 76 0 0 0 0]\n", - " [ 0 0 80 0 0 0]\n", - " [ 0 0 0 82 0 2]\n", - " [ 0 0 0 0 78 0]\n", - " [ 0 1 0 0 0 79]]\n" - ] - }, - { - "data": { - "image/png": "iVBORw0KGgoAAAANSUhEUgAAApMAAAJOCAYAAADrtowMAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjkuMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8hTgPZAAAACXBIWXMAAA9hAAAPYQGoP6dpAABlnElEQVR4nO3deVxVdf7H8fcFFZTdDSQRRUHR3MIWsiyL1DK1oByLcamssVAT3MfdNCqnLI10csyl0bGa1EZzXNLUSswVcx9XMBWcNMEVEM7vD4f7i9C693rwXuT19HEecc/yPZ/zfRB8+Jzv+R6LYRiGAAAAAAe4OTsAAAAAlF0kkwAAAHAYySQAAAAcRjIJAAAAh5FMAgAAwGEkkwAAAHAYySQAAAAcRjIJAAAAh5FMAgAAwGEkkwCc7sCBA2rXrp38/PxksVi0ePFiU9s/evSoLBaLZs+ebWq7ZdmDDz6oBx980NlhALgFkEwCkCQdOnRIf/rTnxQWFiZPT0/5+vqqdevWeu+993Tp0qVSPXfPnj21c+dOTZw4UR9//LFatWpVque7mXr16iWLxSJfX99r9uOBAwdksVhksVj0l7/8xe72T5w4obFjxyotLc2EaAHAfhWcHQAA5/vyyy/19NNPy8PDQz169NDtt9+uvLw8ffvttxo8eLB2796tDz/8sFTOfenSJaWmpmrEiBHq27dvqZwjNDRUly5dUsWKFUul/d9ToUIFXbx4UUuWLFHXrl2LbZs3b548PT11+fJlh9o+ceKExo0bp7p166pFixY2H7dy5UqHzgcAv0YyCZRzR44cUbdu3RQaGqo1a9aoVq1a1m0JCQk6ePCgvvzyy1I7/3//+19Jkr+/f6mdw2KxyNPTs9Ta/z0eHh5q3bq1/vGPf5RIJufPn6+OHTvq888/vymxXLx4UVWqVFGlSpVuyvkA3Pq4zQ2Uc2+99ZbOnz+vmTNnFkskizRo0ECvvvqq9fOVK1f02muvqX79+vLw8FDdunX15z//Wbm5ucWOq1u3rh5//HF9++23uuuuu+Tp6amwsDDNnTvXus/YsWMVGhoqSRo8eLAsFovq1q0r6ert4aKvf2ns2LGyWCzF1q1atUr33Xef/P395e3trYYNG+rPf/6zdfv1xkyuWbNG999/v7y8vOTv768uXbpo79691zzfwYMH1atXL/n7+8vPz0/PPfecLl68eP2O/ZVnn31W//73v3X27Fnrus2bN+vAgQN69tlnS+x/5swZDRo0SE2bNpW3t7d8fX316KOPaseOHdZ91q5dqzvvvFOS9Nxzz1lvlxdd54MPPqjbb79dW7duVZs2bVSlShVrv/x6zGTPnj3l6elZ4vrbt2+vgIAAnThxwuZrBVC+kEwC5dySJUsUFhame++916b9e/furdGjR+uOO+7Q5MmT9cADDyg5OVndunUrse/Bgwf11FNP6ZFHHtHbb7+tgIAA9erVS7t375YkxcbGavLkyZKkZ555Rh9//LHeffddu+LfvXu3Hn/8ceXm5mr8+PF6++231blzZ3333Xe/edxXX32l9u3b69SpUxo7dqySkpK0YcMGtW7dWkePHi2xf9euXXXu3DklJyera9eumj17tsaNG2dznLGxsbJYLFq4cKF13fz589WoUSPdcccdJfY/fPiwFi9erMcff1zvvPOOBg8erJ07d+qBBx6wJnaRkZEaP368JOmll17Sxx9/rI8//lht2rSxtnP69Gk9+uijatGihd599121bdv2mvG99957qlGjhnr27KmCggJJ0l//+letXLlSU6dOVXBwsM3XCqCcMQCUW9nZ2YYko0uXLjbtn5aWZkgyevfuXWz9oEGDDEnGmjVrrOtCQ0MNScb69eut606dOmV4eHgYAwcOtK47cuSIIcmYNGlSsTZ79uxphIaGlohhzJgxxi9/dE2ePNmQZPz3v/+9btxF55g1a5Z1XYsWLYyaNWsap0+ftq7bsWOH4ebmZvTo0aPE+Z5//vlibT755JNGtWrVrnvOX16Hl5eXYRiG8dRTTxkPP/ywYRiGUVBQYAQFBRnjxo27Zh9cvnzZKCgoKHEdHh4exvjx463rNm/eXOLaijzwwAOGJGP69OnX3PbAAw8UW7dixQpDkjFhwgTj8OHDhre3t/HEE0/87jUCKN+oTALlWE5OjiTJx8fHpv2XLVsmSUpKSiq2fuDAgZJUYmxl48aNdf/991s/16hRQw0bNtThw4cdjvnXisZafvHFFyosLLTpmJMnTyotLU29evVS1apVreubNWumRx55xHqdv9SnT59in++//36dPn3a2oe2ePbZZ7V27VplZmZqzZo1yszMvOYtbunqOEs3t6s/ogsKCnT69GnrLfxt27bZfE4PDw8999xzNu3brl07/elPf9L4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AADAcVQmAQAATMbUQAAAAIANqEwCAACYrDxNDURlEgAAAA4rE8mkxWLR4sWLnR0GAACATYrmmTR7cUVOTyYzMzPVr18/hYWFycPDQyEhIerUqZNWr17t7NBK6NOnjywWi959911nhwIAAOASnDpm8ujRo2rdurX8/f01adIkNW3aVPn5+VqxYoUSEhK0b98+Z4ZXzKJFi7Rx40YFBwc7OxQAAODiLDJ/XkgXLUw6tzL5yiuvyGKxaNOmTYqLi1NERISaNGmipKQkbdy48brHDR06VBEREapSpYrCwsI0atQo5efnW7fv2LFDbdu2lY+Pj3x9fRUVFaUtW7ZIktLT09WpUycFBATIy8tLTZo00bJly34zzuPHj6tfv36aN2+eKlasaM7FAwCAW5abLHKzmLy4aDrptGTyzJkzWr58uRISEuTl5VViu7+//3WP9fHx0ezZs7Vnzx699957mjFjhiZPnmzdHh8fr9q1a2vz5s3aunWrhg0bZk0CExISlJubq/Xr12vnzp1688035e3tfd1zFRYWqnv37ho8eLCaNGnyu9eVm5urnJycYgsAAMDNlpycrDvvvFM+Pj6qWbOmnnjiCe3fv7/YPpcvX1ZCQoKqVasmb29vxcXFKSsry67zOC2ZPHjwoAzDUKNGjew+duTIkbr33ntVt25dderUSYMGDdKnn35q3Z6RkaGYmBg1atRI4eHhevrpp9W8eXPrttatW6tp06YKCwvT448/rjZt2lz3XG+++aYqVKig/v372xRbcnKy/Pz8rEtISIjd1wcAAMo2Sykt9li3bp0SEhK0ceNGrVq1Svn5+WrXrp0uXLhg3ScxMVFLlizRZ599pnXr1unEiROKjY216zxOGzNpGIbDx37yySeaMmWKDh06pPPnz+vKlSvy9fW1bk9KSlLv3r318ccfKyYmRk8//bTq168vSerfv79efvllrVy5UjExMYqLi1OzZs2ueZ6tW7fqvffe07Zt22Sx8RGq4cOHKykpyfo5JyeHhBIAANx0y5cvL/Z59uzZqlmzprZu3ao2bdooOztbM2fO1Pz58/XQQw9JkmbNmqXIyEht3LhR99xzj03ncVplMjw8XBaLxe6HbFJTUxUfH6/HHntMS5cu1fbt2zVixAjl5eVZ9xk7dqx2796tjh07as2aNWrcuLEWLVokSerdu7cOHz6s7t27a+fO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8uRJBQQE6PHHH5e/v7+zw0Qp4g04uC6LxaIKFSrop59+kpeXl6SrCWZgYKDeeustjRkzRkuXLlX9+vXVtWtXJ0frenbt2qV69erp5Zdflp+fn9q1a6f4+HgSyt9hGIYWLlyokJCQYn+oNGvWTB4eHowDvI7CwkItWbJE7du319ChQ63r9+3bpy1btuiee+7R7bffrk6dOvH/6+/4+uuvNX36dBUWFmrSpEny9vbWpk2bVKdOHU2dOtXZ4bmUwsJCzZw5U97e3oqIiJAkdenSRSdPntTFixd19OhRPfTQQxo9erSio6OdHC1KC7e5cV1FlcnatWvr559/1vnz5yVJBQUFqlGjhkaPHi1PT0/NmTPHyZG6pqioKPXu3Vv33HOPIiMjtWLFCu3Zs0fx8fH673//a92PB02Ks1gsatOmje655x5VrVrVur5BgwaqXLmysrKynBid63Jzc1O3bt3Uq1cvaxXo9ddf14cffqgnn3xSr776qo4dO6b33ntPx44dc26wLsowDEVERKhx48Y6dOiQ+vfvr7Fjxyo5OVlr165Vhw4dnB2iy3Fzc1O/fv307LPPavr06brttttksVj02WefaefOndqzZ48OHjyot956y9mhohSRTOK6LBaL3N3d1bt3b61evVpvv/22dV1BQYGCgoL0zjvv6N///re2bNni7HBdjp+fn+6//35JVxPGxo0ba+XKldqzZ4/++Mc/6qefftKVK1f0/vvv61//+peTo3Utd9xxhyZMmCCp+BPxbm5uunz5svXzsmXLdOLEiZsenysyDEM1atTQXXfdJUn6+eefdfHiRS1btkyjR49Wr1699Pe//12pqanatGmTk6N1TRaLxfrfdevWSZI2btyoChUqyNPTU5s3b+ahnF8xDEO33Xabhg4dqpYtW+qOO+7QpEmT1KBBA1WqVEn169fXzJkz9cUXX2jHjh3ODhelhNvc+E2FhYVq0aKFPvjgA7300kuqXLmyhgwZInd3d0lShQoV1KhRI/n4+Dg5Utfm5nb177bIyEitXLlS7dq1U/fu3RUYGKi///3vPP34GywWi65cuWJ9qKnoe23EiBFKTk5Wenq6kyN0DUWJUJGAgACNHDlSnp6ekq7eUTh//ryioqJUt25dJ0To+goKCuTu7q5WrVqpsLBQ/fv315dffqkdO3Zo2bJlSkpKUoUKFTRs2DBVqMCvT+nq951hGAoODtb48eO1Y8cOhYeHF9vn3LlzioiIUK1atZwUJUob/zfgNxUlQT169ND58+c1cOBAHTt2TPHx8QoNDdX8+fN1+fJlBlfbITIyUl9++aVatGihgIAAbdq0qcQPXxRXlCgZhiEPDw9NnDhR7733njZt2qSQkBAnR+e6fvnAjbu7u+bNmydJql27trNCcmlFfyQ3a9ZMTz/9tIKCgrRkyRKFhobq5Zdflpubmx566CESyV8pSihr1qypRx55pMT29evXq3bt2jwAdgvjaW7YZcmSJerXr58KCgpUuXJl5ebmatGiRbrjjjucHVqZkZ+fr/79++vjjz/Wpk2b1LhxY2eHVGbcfffdunDhgg4cOKDvvvtOrVq1cnZIZUJaWpr++c9/aurUqfrmm2/UrFkzZ4fk0jIyMjR37lx16tRJzZs3t05/A/ukpaXps88+09SpU/Xdd98xC8MtjGQSkq5WfCwWi06cOCFPT89iDz78WlZWltLT03X58mWFh4eX+1sX9vSddPUH7J/+9Ce9//77uvPOO29SlK7J1r4rLCzU+fPn1ahRI2VlZWnHjh26/fbbb3K0rsOe77mTJ08qMTFRe/bs0ccff6zmzZvfxEhdj619l5ubSyXtV+z5vjtx4oRefvll7du3T59++mm5/7671fGnFqw/IL744gt17dpVX331lc6dO3fdfQMDA3XXXXepTZs2JJJ29F2Rhg0basWKFSSSdvSdm5ubfH199dFHH2nXrl0kknZ8z9WqVUvJyclavnx5uf+Fbk/fkUgWZ+/3XXBwsN5++22tXr263H/flQckk7D+gIiPj1enTp0UHR1d4oGaogL2rwf5l3f29F2RypUrM8ZUjvVdhw4dFBkZeTPDdDmO9Fu9evUUHBx8M8N0SY70Ha6yt+8Mw1CDBg0Yn1tOcJsbOn78uDp06KAXX3xR/fv3V35+vnJzc/X999+ratWqatmypbNDdFn0nePoO8fQb46j7xxH3+G38EgaVKFCBXl5eal27do6ffq0PvjgA3311VfatWuXqlevrtdff11xcXHODtMl0XeOo+8cQ785jr5zHH2H38Jt7nKoqBh96tQpXbx4UZ6enjIMQ1OnTlW9evW0fft2xcXFadWqVQoODtbOnTudHLHroO8cR985hn5zHH3nOPoO9qAyWc4UDaJesmSJ3nrrLQ0ZMkSdOnXSP/7xD61cuVLdunXTM888I19fX0mSt7c3U2L8D33nOPrOMfSb4+g7x9F3sJuBcmfRokWGt7e3MXHiROPQoUPX3OfChQvGsGHDjOrVqxv79++/yRG6LvrOcfSdY+g3x9F3jqPvYA+SyXLm2LFjRqNGjYx3333XMAzDyM/PNy5fvmysX7/e2LNnj2EYhvH3v//dePLJJ43Q0FBj27ZtzgzXpdB3jqPvHEO/OY6+cxx9B3txm7ucuXLliry8vHTHHXfo1KlT+uijj7R8+XJt3bpVzZs312uvvaaYmBgdPXpUkyZNUv369Z0dssug7xxH3zmGfnMcfec4+g72Ymqgcubs2bNq3ry5QkJCtG/fPrVp00atW7fWvffeq5dfflnPPPOMhg4dyuvDroG+cxx95xj6zXH0nePoO9iLyuQtzPjfIOqcnBxVqVJFly5dkr+/vzZs2KDZs2fr2WefVbdu3RQQECCLxaLatWursLBQEpOT03eOo+8cQ785jr5zHH0HUzjvDjtKU2FhoWEYhrFs2TKjU6dOxp133mn06NHDWL9+vWEYV8fAFMnNzTWGDx9u1KhRw/jPf/7jlHhdCX3nOPrOMfSb4+g7x9F3MAv16VuM8YvXHn7xxRd66qmn1KpVK/Xs2VOXLl1St27dtH79elWoUEGGYWju3Ll68sknNW/ePK1YsULh4eFOvgLnoe8cR985hn5zHH3nOPoOpnNODguz/fe//y32ed++fcYdd9xhTJs2zTAMw8jMzDRuu+02IywszAgICDDWrl1rGIZhpKenGyNGjCjXf2nSd46j7xxDvzmOvnMcfYfSQjJ5C5gyZYrRtGlTY9euXdZ1e/fuNfr06WOcO3fOyMjIMMLDw40XX3zRSEtLM1q2bGkEBgYaK1euNAzDMAoKCpwVutPRd46j7xxDvzmOvnMcfYfSRDJ5Czhx4oRRs2ZNo23btsbu3but648fP24YhmH06dPHePrpp42LFy8ahmEYzz77rOHj42PUq1fPOH/+vHXcTHlE3zmOvnMM/eY4+s5x9B1KE2Mmyyjjf2NeCgoKVKtWLe3YsUP79u1Tnz59tGvXLklScHCwLl26pB07dqhx48aqXLmyJMnX11dTp07Vpk2b5OXlVe6eyKPvHEffOYZ+cxx95zj6DjeNMzNZOKbodsOpU6eMzZs3G6mpqYZh/P94l/vvv7/YX54vvPCCERkZaXzyySfGgAEDjJCQEOPo0aNOid3Z6DvH0XeOod8cR985jr7DzUQyWcYU/YDYvXu30bp1a6NDhw5GbGyscenSJcMwiv+gKBobk5qaajz55JNG7dq1jWbNmpXbV1/Rd46j7xxDvzmOvnMcfYebjWSyDCkas7Jr1y7D39/f+POf/2ykp6dbf3AUzQlW9IPivvvuM/bv328YhmHk5eUZ6enpxunTp50TvJPRd46j7xxDvzmOvnMcfQdnIJksY06fPm3cd999Rv/+/YutL/oB8usfFA888IDxww8/3PQ4XRF95zj6zjH0m+PoO8fRd7jZeACnjMnMzNTJkycVFxdnfaWV9P+vtXJ3d5dhGAoMDNSWLVu0ceNGDRs2THl5ec4K2WXQd46j7xxDvzmOvnMcfYebjXdzlzFpaWlKT0/X/fffL4vFosLCQrm5/f/fBBaLRRcvXtSOHTsUHR2tjIwMZWdnq1KlSk6M2jXQd46j7xxDvzmOvnMcfYebjcpkGVO3bl1VqFBBCxculKRiPyCKfPTRRxozZowuXryomjVr8uqr/6HvHEffOYZ+cxx95zj6DjcbyWQZExoaKl9fX82dO1fp6enW9cb/5hOTpKNHjyoqKso6Xxiuou8cR985hn5zHH3nOPoON51zhmriRnz++eeGh4eH0b1792LzhF24cMEYPny4ERoaan06D8XRd46j7xxDvzmOvnMcfYebyWIYv/hTBWVCYWGhZsyYob59+6pBgwaKjo6Wp6enjh8/ro0bN2r58uVq2bKls8N0SfSd4+g7x9BvjqPvHEff4WYimSzDNm3apEmTJungwYPy8fHRvffeqxdeeIGxLzag7xxH3zmGfnMcfec4+g43A8lkGVdQUCB3d3dnh1Em0XeOo+8cQ785jr5zHH2H0sYDOGXcL5/S4+8C+9B3jqPvHEO/OY6+cxx9h9JGZRIAAAAOozIJAAAAh5FMAgAAwGEkkwAAAHAYySQAAAAcRjIJAAAAh5FMAgAAwGEkkwAAAHAYySSAMqdXr1564oknrJ8ffPBBDRgw4KbHsXbtWlksFp09e/a6+1gsFi1evNjmNseOHasWLVrcUFxHjx6VxWJRWlraDbUDALYgmQRgil69eslischisahSpUpq0KCBxo8frytXrpT6uRcuXKjXXnvNpn1tSQABALar4OwAANw6OnTooFmzZik3N1fLli1TQkKCKlasqOHDh5fYNy8vT5UqVTLlvFWrVjWlHQCA/ahMAjCNh4eHgoKCFBoaqpdfflkxMTH617/+Jen/b01PnDhRwcHBatiwoSTp2LFj6tq1q/z9/VW1alV16dJFR48etbZZUFCgpKQk+fv7q1q1ahoyZEiJ9wv/+jZ3bm6uhg4dqpCQEHl4eKhBgwaaOXOmjh49qrZt20qSAgICZLFY1KtXL0lSYWGhkpOTVa9ePVWuXFnNmzfXP//5z2LnWbZsmSIiIlS5cmW1bdu2WJy2Gjp0qCIiIlSlShWFhYVp1KhRys/PL7HfX//6V4WEhKhKlSrq2rWrsrOzi23/29/+psjISHl6eqpRo0b64IMP7I4FAMxAMgmg1FSuXFl5eXnWz6tXr9b+/fu1atUqLV26VPn5+Wrfvr18fHz0zTff6LvvvpO3t7c6dOhgPe7tt9/W7Nmz9dFHH+nbb7/VmTNntGjRot88b48ePfSPf/xDU6ZM0d69e/XXv/5V3t7eCgkJ0eeffy5J2r9/v06ePKn33ntPkpScnKy5c+dq+vTp2r17txITE/XHP/5R69atk3Q16Y2NjVWnTp2Ulpam3r17a9iwYXb3iY+Pj2bPnq09e/bovffe04wZMzR58uRi+xw8eFCffvqplixZouXLl2v79u165ZVXrNvnzZun0aNHa+LEidq7d69ef/11jRo1SnPmzLE7HgC4YQYAmKBnz55Gly5dDMMwjMLCQmPVqlWGh4eHMWjQIOv2wMBAIzc313rMxx9/bDRs2NAoLCy0rsvNzTUqV65srFixwjAMw6hVq5bx1ltvWbfn5+cbtWvXtp7LMAzjgQceMF599VXDMAxj//79hiRj1apV14zz66+/NiQZP//8s3Xd5cuXjSpVqhgbNmwotu8LL7xgPPPMM4ZhGMbw4cONxo0bF9s+dOjQEm39miRj0aJF190+adIkIyoqyvp5zJgxhru7u/Hjjz9a1/373/823NzcjJMnTxqGYRj169c35s+fX6yd1157zYiOjjYMwzCOHDliSDK2b99+3fMCgFkYMwnANEuXLpW3t7fy8/NVWFioZ599VmPHjrVub9q0abFxkjt27NDBgwfl4+NTrJ3Lly/r0KFDys7O1smTJ3X33Xdbt1WoUEGtWrUqcau7SFpamtzd3fXAAw/YHPfBgwd18eJFPfLII8XW5+XlqWXLlpKkvXv3FotDkqKjo20+R5FPPvlEU6ZM0aFDh3T+/HlduXJFvr6+xfapU6eObrvttmLnKSws1P79++Xj46NDhw7phRde0Isvvmjd58qVK/Lz87M7HgC4USSTAEzTtm1bTZs2TZUqVVJwcLAqVCj+I8bLy6vY5/PnzysqKkrz5s0r0VaNGjUciqFy5cp2H3P+/HlJ0pdfflksiZOujgM1S2pqquLj4zVu3Di1b99efn5+WrBggd5++227Y50xY0aJ5Nbd3d20WAHAViSTAEzj5eWlBg0a2Lz/HXfcoU8++UQ1a9YsUZ0rUqtWLX3//fdq06aNpKsVuK1bt+qOO+645v5NmzZVYWGh1q1bp5iYmBLbiyqjBQUF1nWNGzeWh4eHMjIyrlvRjIyMtD5MVGTjxo2/f5G/sGHDBoWGhmrEiBHWdenp6SX2y8jI0IkTJxQcHGw9j5ubmxo2bKjAwEAFBwfr8OHDio+Pt+v8AFAaeAAHgNPEx8erevXq6tKli7755hsdOXJEa9euVf/+/fXjjz9Kkl599VW98cYbWrx4sfbt26dXXnnlN+eIrFu3rnr27Knnn39eixcvtrb56aefSpJCQ0NlsVi0dOlS/fe//9X58+fl4+OjQYMGKTExUXPmzNGhQ4e0bds2TZ061fpQS58+fXTgwAENHjxY+/fv1/z58zV79my7rjc8PFwZGRlasGCBDh06pClTplzzYSJPT0/17NlTO3bs0DfffKP+/fura9euCgoKkiSNGzdOycnJmjJliv7zn/9o586dmjVrlt555x274gEAM5BMAnCaKlWqaP369apTp45iY2MVGRmpF154QZcvX7ZWKgcOHKju3burZ8+eio6Olo+Pj5588snfbHfatGl66qmn9Morr6hRo0Z68cUXdeHCBUnSbbfdpnHjxmnYsGEKDAxU3759JUmvvfaaRo0apeTkZEVGRqpDhw768ssvVa9ePUlXxzF+/vnnWrx4sZo3b67p06fr9ddft+t6O3furMTERPXt21ctWrTQhg0bNGrUqBL7NWjQQLGxsXrsscfUrl07NWvWrNjUP71799bf/vY3zZo1S02bNtUDDzyg2bNnW2MFgJvJYlxvFDsAAADwO6hMAgAAwGEkkwAAAHAYySQAAAAcRjIJAAAAh5FMAgAAwGEkkwAAAHAYySQAAAAcRjIJAAAAh5FMAgAAwGEkkwAAAHAYySQAAAAcRjIJAAAAh/0fwp7e/hi6JR4AAAAASUVORK5CYII=", - "text/plain": [ - "
" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "import torch\n", - "import numpy as np\n", - "import matplotlib.pyplot as plt\n", - "from sklearn.metrics import classification_report, confusion_matrix\n", - "\n", - "# Test Function\n", + "# Testing the model\n", "def test_model(model, test_loader, criterion, device=\"cuda\" if torch.cuda.is_available() else \"cpu\"):\n", - " model = model.to(device)\n", " model.eval()\n", - "\n", " running_loss = 0.0\n", " running_corrects = 0\n", - " total_test = 0\n", + " total_samples = 0\n", + "\n", " all_preds = []\n", " all_labels = []\n", "\n", " with torch.no_grad():\n", " for inputs, labels in tqdm(test_loader, desc=\"Testing\"):\n", " inputs = inputs.to(device)\n", - " labels = labels.to(device).long() # Ensure labels are of type torch.long\n", + " labels = labels.to(device).long()\n", "\n", - " # Forward Pass\n", " outputs = model(inputs)\n", " loss = criterion(outputs, labels)\n", - " _, preds = torch.max(outputs, 1)\n", "\n", - " # Track statistics\n", " running_loss += loss.item() * inputs.size(0)\n", - " running_corrects += torch.sum(preds == labels.data)\n", - " total_test += labels.size(0)\n", + " _, preds = torch.max(outputs, 1)\n", + " running_corrects += torch.sum(preds == labels)\n", + " total_samples += labels.size(0)\n", "\n", " all_preds.extend(preds.cpu().numpy())\n", " all_labels.extend(labels.cpu().numpy())\n", "\n", - " test_loss = running_loss / total_test\n", - " test_acc = running_corrects.double() / total_test\n", - "\n", - " print(f\"Test Loss: {test_loss:.4f} Test Acc: {test_acc:.4f}\")\n", + " test_loss = running_loss / total_samples\n", + " test_accuracy = running_corrects.double() / total_samples\n", "\n", - " # Classification Report\n", - " print(\"\\nClassification Report:\")\n", - " print(classification_report(all_labels, all_preds, target_names=[f\"Class {i}\" for i in range(6)]))\n", + " print(f\"Test Loss: {test_loss:.4f}\")\n", + " print(f\"Test Accuracy: {test_accuracy:.4f}\")\n", "\n", " # Confusion Matrix\n", " cm = confusion_matrix(all_labels, all_preds)\n", - " print(\"\\nConfusion Matrix:\")\n", - " print(cm)\n", "\n", - " # Plot Confusion Matrix\n", " plt.figure(figsize=(8, 6))\n", - " plt.imshow(cm, interpolation='nearest', cmap=plt.cm.Blues)\n", - " plt.title(\"Confusion Matrix\")\n", - " plt.colorbar()\n", - " tick_marks = np.arange(6)\n", - " plt.xticks(tick_marks, [f\"Class {i}\" for i in range(6)], rotation=45)\n", - " plt.yticks(tick_marks, [f\"Class {i}\" for i in range(6)])\n", - " plt.ylabel('True label')\n", - " plt.xlabel('Predicted label')\n", - " plt.tight_layout()\n", + " sns.heatmap(cm, annot=True, fmt='g', cmap='Blues', xticklabels=[\"3_long_blade_rotor\", \"3_short_blade_rotor\", \"Bird\", \"Bird+mini-helicopter\", \"drone\", \"rc_plane\"], yticklabels=[\"3_long_blade_rotor\", \"3_short_blade_rotor\", \"Bird\", \"Bird+mini-helicopter\", \"drone\", \"rc_plane\"])\n", + " plt.xlabel('Predicted Labels')\n", + " plt.ylabel('True Labels')\n", + " plt.title('Confusion Matrix')\n", " plt.show()\n", "\n", - "# Example Usage\n", - "if __name__ == \"__main__\":\n", - " # Assuming test_loader is defined\n", - " model_deepercnn = CustomCNNWithAttention(num_classes=6)\n", - " model_deepercnn.load_state_dict(torch.load(\"customcnnwithAttention.pth\"))\n", - " model_deepercnn.eval()\n", - "\n", - " criterion = nn.CrossEntropyLoss()\n", + " # ROC Curve\n", + " fpr, tpr, _ = roc_curve(all_labels, all_preds, pos_label=1) # Adjust pos_label as needed\n", + " roc_auc = auc(fpr, tpr)\n", "\n", - " # Test the model\n", - " test_model(model_deepercnn, test_loader, criterion)\n" - ] - }, - { - "cell_type": "code", - "execution_count": 10, - "metadata": {}, - "outputs": [ - { - "name": "stderr", - "output_type": "stream", - "text": [ - "C:\\Users\\Shravya H Jain\\AppData\\Local\\Temp\\ipykernel_7300\\66978296.py:37: FutureWarning: You are using `torch.load` with `weights_only=False` (the current default value), which uses the default pickle module implicitly. It is possible to construct malicious pickle data which will execute arbitrary code during unpickling (See https://github.com/pytorch/pytorch/blob/main/SECURITY.md#untrusted-models for more details). In a future release, the default value for `weights_only` will be flipped to `True`. This limits the functions that could be executed during unpickling. Arbitrary objects will no longer be allowed to be loaded via this mode unless they are explicitly allowlisted by the user via `torch.serialization.add_safe_globals`. We recommend you start setting `weights_only=True` for any use case where you don't have full control of the loaded file. Please open an issue on GitHub for any issues related to this experimental feature.\n", - " model_deepercnn.load_state_dict(torch.load(\"customcnnwithAttention.pth\"))\n" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Classification Report:\n", - " precision recall f1-score support\n", - "\n", - " 0 0.9630 0.9286 0.9455 84\n", - " 1 0.9277 0.9625 0.9448 80\n", - " 2 1.0000 1.0000 1.0000 80\n", - " 3 1.0000 0.9762 0.9880 84\n", - " 4 1.0000 1.0000 1.0000 78\n", - " 5 0.9756 1.0000 0.9877 80\n", - "\n", - " accuracy 0.9774 486\n", - " macro avg 0.9777 0.9779 0.9776 486\n", - "weighted avg 0.9777 0.9774 0.9774 486\n", - "\n", - "Confusion Matrix:\n", - "[[78 6 0 0 0 0]\n", - " [ 3 77 0 0 0 0]\n", - " [ 0 0 80 0 0 0]\n", - " [ 0 0 0 82 0 2]\n", - " [ 0 0 0 0 78 0]\n", - " [ 0 0 0 0 0 80]]\n" - ] - } - ], - "source": [ - "from sklearn.metrics import classification_report, confusion_matrix\n", - "import torch\n", + " plt.figure(figsize=(8, 6))\n", + " plt.plot(fpr, tpr, color='blue', lw=2, label=f'ROC Curve (area = {roc_auc:.2f})')\n", + " plt.plot([0, 1], [0, 1], color='gray', lw=2, linestyle='--')\n", + " plt.xlabel('False Positive Rate')\n", + " plt.ylabel('True Positive Rate')\n", + " plt.title('Receiver Operating Characteristic (ROC) Curve')\n", + " plt.legend(loc='lower right')\n", + " plt.show()\n", "\n", - "def test_model(model, test_loader, device=\"cuda\" if torch.cuda.is_available() else \"cpu\"):\n", - " model = model.to(device)\n", - " model.eval()\n", - " \n", - " all_preds = []\n", - " all_targets = []\n", + " return {\n", + " \"test_loss\": test_loss,\n", + " \"test_accuracy\": test_accuracy.item(),\n", + " \"confusion_matrix\": cm,\n", + " \"all_preds\": all_preds,\n", + " \"all_labels\": all_labels,\n", + " }\n", "\n", - " with torch.no_grad():\n", - " for inputs, labels in test_loader:\n", - " inputs = inputs.to(device)\n", - " labels = labels.to(device).long() # Ensure labels are of type torch.long\n", + "# Dataset preparation\n", + "train_size = int(0.85 * len(dataset))\n", + "val_size = int(0.05 * len(dataset))\n", + "test_size = len(dataset) - train_size - val_size\n", + "train_dataset, val_dataset, test_dataset = random_split(dataset, [train_size, val_size, test_size])\n", "\n", - " # Forward pass\n", - " outputs = model(inputs)\n", - " _, preds = torch.max(outputs, 1)\n", + "train_loader = DataLoader(train_dataset, batch_size=8, shuffle=True)\n", + "val_loader = DataLoader(val_dataset, batch_size=8, shuffle=False)\n", + "test_loader = DataLoader(test_dataset, batch_size=8, shuffle=False)\n", "\n", - " # Collect predictions and targets\n", - " all_preds.extend(preds.cpu().numpy())\n", - " all_targets.extend(labels.cpu().numpy())\n", - " \n", - " # Generate Classification Report\n", - " print(\"Classification Report:\")\n", - " print(classification_report(all_targets, all_preds, digits=4))\n", + "# Model, Loss, Optimizer, and Scheduler setup\n", + "model_deepercnn = CustomCNNWithAttention(num_classes=6)\n", + "criterion = nn.CrossEntropyLoss()\n", "\n", - " # Generate Confusion Matrix\n", - " print(\"Confusion Matrix:\")\n", - " print(confusion_matrix(all_targets, all_preds))\n", + "optimizer_deepercnn = optim.Adam(model_deepercnn.parameters(), lr=0.001)\n", + "scheduler_deepercnn = lr_scheduler.StepLR(optimizer_deepercnn, step_size=7, gamma=0.1)\n", "\n", - "# Example Usage\n", - "# Assuming test_loader is defined\n", - "if __name__ == \"__main__\":\n", - " # Load the trained model weights\n", - " model_deepercnn = CustomCNNWithAttention(num_classes=6)\n", - " model_deepercnn.load_state_dict(torch.load(\"customcnnwithAttention.pth\"))\n", + "# Train the model\n", + "train_model(model_deepercnn, train_loader, val_loader, criterion, optimizer_deepercnn, scheduler_deepercnn, num_epochs=20)\n", "\n", - " # Evaluate the model on test data\n", - " test_model(model_deepercnn, test_loader)\n" + "# Load the entire model and evaluate\n", + "model = torch.load(\"customcnnwithAttention_best.pth\")\n", + "model.eval() # Set the model to evaluation mode\n", + "test_results = test_model(model, test_loader, criterion, device=\"cuda\" if torch.cuda.is_available() else \"cpu\")\n" ] } ],