{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.12.13","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"none","dataSources":[],"dockerImageVersionId":28755,"isInternetEnabled":false,"language":"python","sourceType":"notebook","isGpuEnabled":false}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"# This Python 3 environment comes with many helpful analytics libraries installed\n# It is defined by the kaggle/python Docker image: https://github.com/kaggle/docker-python\n# For example, here's several helpful packages to load\n\nimport numpy as np # linear algebra\nimport pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)\n\n# Input data files are available in the read-only \"../input/\" directory\n# For example, running this (by clicking run or pressing Shift+Enter) will list all files under the input directory\n\nimport os\nfor dirname, _, filenames in os.walk('/kaggle/input'):\n    for filename in filenames:\n        print(os.path.join(dirname, filename))\n\n# You can write up to 20GB to the current directory (/kaggle/working/) that gets preserved as output when you create a version using \"Save & Run All\" \n# You can also write temporary files to /kaggle/temp/, but they won't be saved outside of the current session\n\n# Use the kagglehub client library to attach Kaggle resources like competitions, datasets, and models to your session\n# Learn more about kagglehub: https://github.com/Kaggle/kagglehub/blob/main/README.md\n\nimport kagglehub\n# kagglehub.dataset_download('<owner>/<dataset-slug>')","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true,"execution":{"iopub.status.busy":"2026-08-24T05:43:53.154231Z","iopub.execute_input":"2026-08-24T05:43:53.154644Z","iopub.status.idle":"2026-08-24T05:43:54.310775Z","shell.execute_reply.started":"2026-08-24T05:43:53.154614Z","shell.execute_reply":"2026-08-24T05:43:54.310077Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import torch\nimport torch.nn as nn\nimport torch.optim as optim\nfrom torchvision import datasets, transforms, models\nfrom torch.utils.data import DataLoader\nfrom sklearn.metrics import confusion_matrix, classification_report\nimport matplotlib.pyplot as plt\nimport seaborn as sns\nimport numpy as np","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-08-24T05:43:54.468568Z","iopub.execute_input":"2026-08-24T05:43:54.469144Z","iopub.status.idle":"2026-08-24T05:44:03.505782Z","shell.execute_reply.started":"2026-08-24T05:43:54.469112Z","shell.execute_reply":"2026-08-24T05:44:03.504927Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"device = torch.device(\"cuda\" if torch.cuda.is_available() else \"cpu\")\nprint(True if torch.cuda.is_available() else False, f\"Using device: {device}\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-08-24T05:44:03.506967Z","iopub.execute_input":"2026-08-24T05:44:03.507405Z","iopub.status.idle":"2026-08-24T05:44:03.791453Z","shell.execute_reply.started":"2026-08-24T05:44:03.507381Z","shell.execute_reply":"2026-08-24T05:44:03.790206Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"transform_train = transforms.Compose([\n    transforms.Resize((224, 224)), \n    transforms.ToTensor(),\n    transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225])\n])\n\ntransform_test = transforms.Compose([\n    transforms.Resize((224, 224)),\n    transforms.ToTensor(),\n    transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225])\n])\n\ntrain_dataset = datasets.CIFAR10(root='./data', train=True, download=True, transform=transform_train)\ntest_dataset = datasets.CIFAR10(root='./data', train=False, download=True, transform=transform_test)\n\ntrain_loader = DataLoader(train_dataset, batch_size=64, shuffle=True)\ntest_loader = DataLoader(test_dataset, batch_size=64, shuffle=False)\n\nclasses = ('plane', 'car', 'bird', 'cat', 'deer', 'dog', 'frog', 'horse', 'ship', 'truck')","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-08-24T05:45:41.688300Z","iopub.execute_input":"2026-08-24T05:45:41.689317Z","iopub.status.idle":"2026-08-24T06:18:13.289260Z","shell.execute_reply.started":"2026-08-24T05:45:41.689284Z","shell.execute_reply":"2026-08-24T06:18:13.288302Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"model = models.resnet50(weights=models.ResNet50_Weights.DEFAULT)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-08-24T06:19:14.416267Z","iopub.execute_input":"2026-08-24T06:19:14.416705Z","iopub.status.idle":"2026-08-24T06:19:15.516145Z","shell.execute_reply.started":"2026-08-24T06:19:14.416675Z","shell.execute_reply":"2026-08-24T06:19:15.515144Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"for param in model.parameters():\n    param.requires_grad = False\n\n# Replace the final layer\nnum_features = model.fc.in_features\nmodel.fc = nn.Linear(num_features, 10) \nmodel = model.to(device)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-08-24T06:19:26.836461Z","iopub.execute_input":"2026-08-24T06:19:26.837498Z","iopub.status.idle":"2026-08-24T06:19:27.188324Z","shell.execute_reply.started":"2026-08-24T06:19:26.837466Z","shell.execute_reply":"2026-08-24T06:19:27.187396Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"criterion = nn.CrossEntropyLoss()\noptimizer = optim.Adam(model.fc.parameters(), lr=0.001)\n\nepochs = 3 # 3 epochs is plenty for a lab demo using transfer learning\nprint(\"Starting Training...\")\n\nfor epoch in range(epochs):\n    model.train()\n    running_loss = 0.0\n    correct = 0\n    total = 0\n    \n    for inputs, labels in train_loader:\n        inputs, labels = inputs.to(device), labels.to(device)\n        \n        optimizer.zero_grad()\n        outputs = model(inputs)\n        loss = criterion(outputs, labels)\n        loss.backward()\n        optimizer.step()\n        \n        running_loss += loss.item() * inputs.size(0)\n        _, predicted = outputs.max(1)\n        total += labels.size(0)\n        correct += predicted.eq(labels).sum().item()\n        \n    epoch_loss = running_loss / len(train_loader.dataset)\n    epoch_acc = 100. * correct / total\n    print(f\"Epoch [{epoch+1}/{epochs}] - Loss: {epoch_loss:.4f} - Accuracy: {epoch_acc:.2f}%\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-08-24T06:19:41.183319Z","iopub.execute_input":"2026-08-24T06:19:41.184100Z","iopub.status.idle":"2026-08-24T06:31:52.886573Z","shell.execute_reply.started":"2026-08-24T06:19:41.184069Z","shell.execute_reply":"2026-08-24T06:31:52.885925Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"model.eval()\ntest_loss = 0.0\nall_preds = []\nall_labels = []\n\nwith torch.no_grad():\n    for inputs, labels in test_loader:\n        inputs, labels = inputs.to(device), labels.to(device)\n        outputs = model(inputs)\n        loss = criterion(outputs, labels)\n        \n        test_loss += loss.item() * inputs.size(0)\n        _, predicted = outputs.max(1)\n        \n        all_preds.extend(predicted.cpu().numpy())\n        all_labels.extend(labels.cpu().numpy())\n\ntest_loss = test_loss / len(test_loader.dataset)\nall_preds = np.array(all_preds)\nall_labels = np.array(all_labels)\ntest_accuracy = np.mean(all_preds == all_labels) * 100\n\nprint(\"\\n--- Final Evaluation Results ---\")\nprint(f\"Test Loss: {test_loss:.4f}\")\nprint(f\"Test Accuracy: {test_accuracy:.2f}%\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-08-24T06:32:33.253894Z","iopub.execute_input":"2026-08-24T06:32:33.254436Z","iopub.status.idle":"2026-08-24T06:33:20.798295Z","shell.execute_reply.started":"2026-08-24T06:32:33.254407Z","shell.execute_reply":"2026-08-24T06:33:20.797617Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"cm = confusion_matrix(all_labels, all_preds)\nplt.figure(figsize=(10, 8))\nsns.heatmap(cm, annot=True, fmt='d', cmap='Blues', xticklabels=classes, yticklabels=classes)\nplt.xlabel('Predicted Labels')\nplt.ylabel('Actual Labels')\nplt.title('10x10 Confusion Matrix - CIFAR-10')\nplt.show()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-08-24T06:33:42.254965Z","iopub.execute_input":"2026-08-24T06:33:42.255241Z","iopub.status.idle":"2026-08-24T06:33:42.849794Z","shell.execute_reply.started":"2026-08-24T06:33:42.255219Z","shell.execute_reply":"2026-08-24T06:33:42.848569Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"print(\"\\nSample Actual vs Predicted Labels:\")\nfor i in range(10):\n    print(f\"Sample {i+1} -> Actual: {classes[all_labels[i]]} | Predicted: {classes[all_preds[i]]}\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-08-24T06:34:36.789269Z","iopub.execute_input":"2026-08-24T06:34:36.789976Z","iopub.status.idle":"2026-08-24T06:34:36.794862Z","shell.execute_reply.started":"2026-08-24T06:34:36.789934Z","shell.execute_reply":"2026-08-24T06:34:36.793902Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"","metadata":{"trusted":true},"outputs":[],"execution_count":null}]}