{"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":"markdown","source":"# Phase 3: Convolutional Neural Networks\n\nDataset: Kaggle CIFAR-10 Competition Dataset\n\nFramework: PyTorch\n\nGPU: Kaggle P100\n\nObjective:\nBuild a small CNN from scratch to classify 10 object categories using convolution, ReLU activation functions, max-pooling, and a complete training pipeline.","metadata":{}},{"cell_type":"markdown","source":"Since the Kaggle CIFAR-10 competition test set does not contain labels, the training data was split into training and validation sets. Validation accuracy is reported as the final performance metric.","metadata":{}},{"cell_type":"code","source":"!pip install py7zr -q","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-06-24T15:51:58.504907Z","iopub.execute_input":"2026-06-24T15:51:58.505717Z","iopub.status.idle":"2026-06-24T15:52:01.788982Z","shell.execute_reply.started":"2026-06-24T15:51:58.505681Z","shell.execute_reply":"2026-06-24T15:52:01.788150Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import os\nimport py7zr\nimport numpy as np\nimport pandas as pd\nimport matplotlib.pyplot as plt\n\nfrom PIL import Image\n\nimport torch\nimport torch.nn as nn\nimport torch.optim as optim\n\nfrom torch.utils.data import Dataset\nfrom torch.utils.data import DataLoader\nfrom torch.utils.data import random_split\n\nimport torchvision.transforms as transforms","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"device = torch.device(\n    \"cuda\" if torch.cuda.is_available() else \"cpu\"\n)\n\nprint(\"Using Device:\", device)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-06-24T15:52:50.868801Z","iopub.execute_input":"2026-06-24T15:52:50.869934Z","iopub.status.idle":"2026-06-24T15:52:50.875709Z","shell.execute_reply.started":"2026-06-24T15:52:50.869881Z","shell.execute_reply":"2026-06-24T15:52:50.874874Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"with py7zr.SevenZipFile(\n    \"/kaggle/input/competitions/cifar-10/train.7z\",\n    mode=\"r\"\n) as z:\n\n    z.extractall(\"/kaggle/working/\")\n\nprint(\"Dataset Extracted Successfully\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-06-24T15:53:50.093825Z","iopub.execute_input":"2026-06-24T15:53:50.094916Z","iopub.status.idle":"2026-06-24T15:54:25.599845Z","shell.execute_reply.started":"2026-06-24T15:53:50.094849Z","shell.execute_reply":"2026-06-24T15:54:25.599164Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"!find /kaggle/working -type f | head","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-06-24T15:54:45.496000Z","iopub.execute_input":"2026-06-24T15:54:45.496670Z","iopub.status.idle":"2026-06-24T15:54:45.695465Z","shell.execute_reply.started":"2026-06-24T15:54:45.496633Z","shell.execute_reply":"2026-06-24T15:54:45.694699Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"IMAGE_DIR = \"/kaggle/working/train\"","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-06-24T15:55:03.127656Z","iopub.execute_input":"2026-06-24T15:55:03.128610Z","iopub.status.idle":"2026-06-24T15:55:03.133167Z","shell.execute_reply.started":"2026-06-24T15:55:03.128573Z","shell.execute_reply":"2026-06-24T15:55:03.132396Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"labels_df = pd.read_csv(\n    \"/kaggle/input/competitions/cifar-10/trainLabels.csv\"\n)\n\nlabels_df.head()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-06-24T15:57:00.580169Z","iopub.execute_input":"2026-06-24T15:57:00.581213Z","iopub.status.idle":"2026-06-24T15:57:00.605778Z","shell.execute_reply.started":"2026-06-24T15:57:00.581099Z","shell.execute_reply":"2026-06-24T15:57:00.605189Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"transform = transforms.Compose([\n    transforms.ToTensor(),\n    transforms.Normalize(\n        (0.5,0.5,0.5),\n        (0.5,0.5,0.5)\n    )\n])","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-06-24T15:57:52.940299Z","iopub.execute_input":"2026-06-24T15:57:52.940571Z","iopub.status.idle":"2026-06-24T15:57:52.945050Z","shell.execute_reply.started":"2026-06-24T15:57:52.940548Z","shell.execute_reply":"2026-06-24T15:57:52.944299Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"class CIFAR10Dataset(Dataset):\n\n    def __init__(self, image_dir, labels_df, transform=None):\n\n        self.image_dir = image_dir\n        self.labels_df = labels_df\n        self.transform = transform\n\n        self.classes = sorted(\n            labels_df[\"label\"].unique()\n        )\n\n        self.class_to_idx = {\n            cls:i\n            for i,cls in enumerate(self.classes)\n        }\n\n    def __len__(self):\n        return len(self.labels_df)\n\n    def __getitem__(self, idx):\n\n        image_id = self.labels_df.iloc[idx][\"id\"]\n        label_name = self.labels_df.iloc[idx][\"label\"]\n\n        image_path = os.path.join(\n            self.image_dir,\n            f\"{image_id}.png\"\n        )\n\n        image = Image.open(image_path).convert(\"RGB\")\n\n        label = self.class_to_idx[label_name]\n\n        if self.transform:\n            image = self.transform(image)\n\n        return image, label","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-06-24T15:58:03.493212Z","iopub.execute_input":"2026-06-24T15:58:03.493825Z","iopub.status.idle":"2026-06-24T15:58:03.500358Z","shell.execute_reply.started":"2026-06-24T15:58:03.493797Z","shell.execute_reply":"2026-06-24T15:58:03.499536Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"IMAGE_DIR = \"/kaggle/working/train\"","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-06-24T15:58:15.840392Z","iopub.execute_input":"2026-06-24T15:58:15.840977Z","iopub.status.idle":"2026-06-24T15:58:15.844383Z","shell.execute_reply.started":"2026-06-24T15:58:15.840947Z","shell.execute_reply":"2026-06-24T15:58:15.843571Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"dataset = CIFAR10Dataset(\n    image_dir=IMAGE_DIR,\n    labels_df=labels_df,\n    transform=transform\n)\n\nprint(\"Total Images:\", len(dataset))","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-06-24T15:58:48.584045Z","iopub.execute_input":"2026-06-24T15:58:48.584834Z","iopub.status.idle":"2026-06-24T15:58:48.591565Z","shell.execute_reply.started":"2026-06-24T15:58:48.584801Z","shell.execute_reply":"2026-06-24T15:58:48.590927Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"train_size = 40000\nval_size = 10000\n\ntrain_dataset, val_dataset = random_split(\n    dataset,\n    [train_size, val_size]\n)\n\nprint(\"Train:\", len(train_dataset))\nprint(\"Validation:\", len(val_dataset))","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-06-24T15:59:04.392716Z","iopub.execute_input":"2026-06-24T15:59:04.393055Z","iopub.status.idle":"2026-06-24T15:59:04.403563Z","shell.execute_reply.started":"2026-06-24T15:59:04.393026Z","shell.execute_reply":"2026-06-24T15:59:04.402797Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"train_loader = DataLoader(\n    train_dataset,\n    batch_size=64,\n    shuffle=True\n)\n\nval_loader = DataLoader(\n    val_dataset,\n    batch_size=64,\n    shuffle=False\n)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-06-24T15:59:13.314016Z","iopub.execute_input":"2026-06-24T15:59:13.314382Z","iopub.status.idle":"2026-06-24T15:59:13.319904Z","shell.execute_reply.started":"2026-06-24T15:59:13.314350Z","shell.execute_reply":"2026-06-24T15:59:13.318994Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"class_names = sorted(\n    labels_df[\"label\"].unique()\n)\n\nimages, labels = next(iter(train_loader))\n\nfig, axes = plt.subplots(\n    2,5,\n    figsize=(10,5)\n)\n\nfor i, ax in enumerate(axes.flat):\n\n    img = images[i]/2 + 0.5\n\n    npimg = img.numpy().transpose((1,2,0))\n\n    ax.imshow(npimg)\n\n    ax.set_title(\n        class_names[labels[i]]\n    )\n\n    ax.axis(\"off\")\n\nplt.show()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-06-24T15:59:55.663747Z","iopub.execute_input":"2026-06-24T15:59:55.664084Z","iopub.status.idle":"2026-06-24T15:59:56.038460Z","shell.execute_reply.started":"2026-06-24T15:59:55.664056Z","shell.execute_reply":"2026-06-24T15:59:56.037783Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"class SimpleCNN(nn.Module):\n\n    def __init__(self):\n\n        super().__init__()\n\n        self.conv1 = nn.Conv2d(\n            3,32,\n            kernel_size=3,\n            padding=1\n        )\n\n        self.conv2 = nn.Conv2d(\n            32,64,\n            kernel_size=3,\n            padding=1\n        )\n\n        self.pool = nn.MaxPool2d(2,2)\n\n        self.relu = nn.ReLU()\n\n        self.fc1 = nn.Linear(\n            64*8*8,\n            128\n        )\n\n        self.fc2 = nn.Linear(\n            128,\n            10\n        )\n\n    def forward(self,x):\n\n        x = self.pool(\n            self.relu(\n                self.conv1(x)\n            )\n        )\n\n        x = self.pool(\n            self.relu(\n                self.conv2(x)\n            )\n        )\n\n        x = x.view(\n            x.size(0),\n            -1\n        )\n\n        x = self.relu(\n            self.fc1(x)\n        )\n\n        x = self.fc2(x)\n\n        return x","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-06-24T16:00:17.756710Z","iopub.execute_input":"2026-06-24T16:00:17.757345Z","iopub.status.idle":"2026-06-24T16:00:17.764195Z","shell.execute_reply.started":"2026-06-24T16:00:17.757310Z","shell.execute_reply":"2026-06-24T16:00:17.763461Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import torch\n\ndevice = torch.device(\"cpu\")\n\nprint(\"Using Device:\", device)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-06-24T16:04:49.840457Z","iopub.execute_input":"2026-06-24T16:04:49.841220Z","iopub.status.idle":"2026-06-24T16:04:49.847039Z","shell.execute_reply.started":"2026-06-24T16:04:49.841186Z","shell.execute_reply":"2026-06-24T16:04:49.845606Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"model = SimpleCNN().to(device)\n\nprint(model)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-06-24T16:04:53.533124Z","iopub.execute_input":"2026-06-24T16:04:53.533402Z","iopub.status.idle":"2026-06-24T16:04:53.543978Z","shell.execute_reply.started":"2026-06-24T16:04:53.533379Z","shell.execute_reply":"2026-06-24T16:04:53.543121Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"criterion = nn.CrossEntropyLoss()\n\noptimizer = optim.Adam(\n    model.parameters(),\n    lr=0.001\n)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-06-24T16:05:02.524661Z","iopub.execute_input":"2026-06-24T16:05:02.525225Z","iopub.status.idle":"2026-06-24T16:05:02.531862Z","shell.execute_reply.started":"2026-06-24T16:05:02.525190Z","shell.execute_reply":"2026-06-24T16:05:02.531034Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"train_losses = []\nval_losses = []\n\nepochs = 10\n\nfor epoch in range(epochs):\n\n    model.train()\n\n    train_loss = 0\n\n    for images, labels in train_loader:\n\n        images = images.to(device)\n        labels = labels.to(device)\n\n        optimizer.zero_grad()\n\n        outputs = model(images)\n\n        loss = criterion(outputs, labels)\n\n        loss.backward()\n\n        optimizer.step()\n\n        train_loss += loss.item()\n\n    train_loss /= len(train_loader)\n\n    train_losses.append(train_loss)\n\n    model.eval()\n\n    val_loss = 0\n\n    with torch.no_grad():\n\n        for images, labels in val_loader:\n\n            images = images.to(device)\n            labels = labels.to(device)\n\n            outputs = model(images)\n\n            loss = criterion(outputs, labels)\n\n            val_loss += loss.item()\n\n    val_loss /= len(val_loader)\n\n    val_losses.append(val_loss)\n\n    print(\n        f\"Epoch {epoch+1}/10 | \"\n        f\"Train Loss: {train_loss:.4f} | \"\n        f\"Val Loss: {val_loss:.4f}\"\n    )","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-06-24T16:05:06.001088Z","iopub.execute_input":"2026-06-24T16:05:06.002000Z","iopub.status.idle":"2026-06-24T16:16:12.163286Z","shell.execute_reply.started":"2026-06-24T16:05:06.001966Z","shell.execute_reply":"2026-06-24T16:16:12.162494Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"plt.figure(figsize=(8,5))\n\nplt.plot(\n    train_losses,\n    label=\"Training Loss\"\n)\n\nplt.plot(\n    val_losses,\n    label=\"Validation Loss\"\n)\n\nplt.xlabel(\"Epoch\")\nplt.ylabel(\"Loss\")\n\nplt.title(\n    \"Training vs Validation Loss\"\n)\n\nplt.legend()\n\nplt.show()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-06-24T16:21:07.668321Z","iopub.execute_input":"2026-06-24T16:21:07.668580Z","iopub.status.idle":"2026-06-24T16:21:07.811275Z","shell.execute_reply.started":"2026-06-24T16:21:07.668557Z","shell.execute_reply":"2026-06-24T16:21:07.810243Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"model.eval()\n\ncorrect = 0\ntotal = 0\n\nwith torch.no_grad():\n\n    for images, labels in val_loader:\n\n        outputs = model(images)\n\n        _, predicted = torch.max(outputs, 1)\n\n        total += labels.size(0)\n\n        correct += (\n            predicted == labels\n        ).sum().item()\n\naccuracy = 100 * correct / total\n\nprint(\n    f\"Validation Accuracy: {accuracy:.2f}%\"\n)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-06-24T16:21:35.229876Z","iopub.execute_input":"2026-06-24T16:21:35.230587Z","iopub.status.idle":"2026-06-24T16:21:44.344204Z","shell.execute_reply.started":"2026-06-24T16:21:35.230553Z","shell.execute_reply":"2026-06-24T16:21:44.343305Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"images, labels = next(iter(val_loader))\n\nwith torch.no_grad():\n\n    outputs = model(images)\n\n    _, preds = torch.max(outputs, 1)\n\nfig, axes = plt.subplots(\n    2,\n    5,\n    figsize=(12,5)\n)\n\nfor i, ax in enumerate(axes.flat):\n\n    img = images[i] / 2 + 0.5\n\n    npimg = img.numpy().transpose((1,2,0))\n\n    ax.imshow(npimg)\n\n    ax.set_title(\n        f\"P:{class_names[preds[i]]}\\nT:{class_names[labels[i]]}\"\n    )\n\n    ax.axis(\"off\")\n\nplt.tight_layout()\nplt.show()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-06-24T16:22:01.583917Z","iopub.execute_input":"2026-06-24T16:22:01.584798Z","iopub.status.idle":"2026-06-24T16:22:02.073642Z","shell.execute_reply.started":"2026-06-24T16:22:01.584761Z","shell.execute_reply":"2026-06-24T16:22:02.073023Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"# Phase 3: Convolutional Neural Networks\n\nDataset: Kaggle CIFAR-10 Competition Dataset\n\nFramework: PyTorch\n\nModel:\n- 2 Convolution Layers\n- ReLU Activations\n- Max Pooling\n- Fully Connected Layers\n\nTraining:\n- Epochs: 10\n- Optimizer: Adam\n- Loss Function: CrossEntropyLoss\n\nResults:\n- Training vs Validation Loss Graph Included\n- Final Validation Accuracy: (insert your output)\n- 10 Sample Predictions Displayed\n\nNote:\nThe Kaggle CIFAR-10 competition test set does not provide labels. Therefore, the training data was split into training and validation sets, and validation accuracy is reported as the final performance metric.\n\nThe Kaggle P100 GPU was enabled as required. Due to a CUDA compatibility issue between the current PyTorch build and the P100 device, training was executed on CPU.","metadata":{}}]}