{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.11.13","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"gpu","dataSources":[{"sourceId":3649,"databundleVersionId":46718,"sourceType":"competition"}],"dockerImageVersionId":31090,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":true}},"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","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true,"execution":{"iopub.status.busy":"2025-10-07T06:57:38.433610Z","iopub.execute_input":"2025-10-07T06:57:38.433887Z","iopub.status.idle":"2025-10-07T06:57:38.441078Z","shell.execute_reply.started":"2025-10-07T06:57:38.433865Z","shell.execute_reply":"2025-10-07T06:57:38.440382Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"!pip install py7zr","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-10-07T06:57:38.442251Z","iopub.execute_input":"2025-10-07T06:57:38.442694Z","iopub.status.idle":"2025-10-07T06:57:41.520640Z","shell.execute_reply.started":"2025-10-07T06:57:38.442678Z","shell.execute_reply":"2025-10-07T06:57:41.519834Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"\nimport py7zr\ndataset_archive_dir = '/kaggle/input/cifar-10/'\ndataset_train = pd.read_csv(dataset_archive_dir + \"trainLabels.csv\")\ndataset_test = pd.read_csv(dataset_archive_dir + \"sampleSubmission.csv\")\n\ntrain_archive_dir = dataset_archive_dir + 'train.7z'\ntest_archive_dir = dataset_archive_dir + 'test.7z'\n\ndataset_output_dir = '/kaggle/working/cifar/'\ntrain_dataset_dir = dataset_output_dir + 'train/'\ntest_dataset_dir = dataset_output_dir + 'test/'\n\n# os.makedirs(train_dataset_dir, exist_ok=True)\n# os.makedirs(test_dataset_dir, exist_ok=True)\nos.makedirs(dataset_output_dir, exist_ok=True)\n\nwith py7zr.SevenZipFile(train_archive_dir, mode='r') as archive:\n    archive.extractall(path=dataset_output_dir)\n\nprint(f\"Successfully extracted '{train_archive_dir}' to '{dataset_output_dir}'\")\n\nwith py7zr.SevenZipFile(test_archive_dir, mode='r') as archive:\n    archive.extractall(path=dataset_output_dir)\n\nprint(f\"Successfully extracted '{test_archive_dir}' to '{dataset_output_dir}'\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-10-07T06:57:41.521746Z","iopub.execute_input":"2025-10-07T06:57:41.522033Z","iopub.status.idle":"2025-10-07T07:00:07.231231Z","shell.execute_reply.started":"2025-10-07T06:57:41.521999Z","shell.execute_reply":"2025-10-07T07:00:07.230478Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import torch\nfrom torchvision import datasets, transforms\nfrom torch.utils.data import DataLoader\n\n# Step 1: Convert images to tensors and scale pixel values to 0–1\ntransform = transforms.ToTensor()  # Only this is needed\n\n# Step 2: Download and load CIFAR-10 training and test data\ntrain_data = datasets.CIFAR10(root='./data', train=True, download=True, transform=transform)\ntest_data = datasets.CIFAR10(root='./data', train=False, download=True, transform=transform)\n\n# Step 3: Create data loaders\ntrain_loader = DataLoader(train_data, batch_size=64, shuffle=True)\ntest_loader = DataLoader(test_data, batch_size=64, shuffle=False)\n\n# Step 4: Check one batch\ndata_iter = iter(train_loader)\nimages, labels = next(data_iter)\n\n# Step 5: Print info about the batch\nprint(\"Image batch shape:\", images.shape)  # Should be [64, 3, 32, 32]\nprint(\"Max pixel value:\", images.max().item())  # Should be <= 1.0\nprint(\"Min pixel value:\", images.min().item())  # Should be >= 0.0\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-10-07T07:00:07.232956Z","iopub.execute_input":"2025-10-07T07:00:07.233194Z","iopub.status.idle":"2025-10-07T07:00:08.818189Z","shell.execute_reply.started":"2025-10-07T07:00:07.233177Z","shell.execute_reply":"2025-10-07T07:00:08.817499Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import torch\nimport torch.nn as nn\nimport torch.nn.functional as F\n\nclass SimpleCNN(nn.Module):\n    def __init__(self):\n        super(SimpleCNN, self).__init__()\n\n        # 1. Convolutional layer: input=3 channels (RGB), output=32 channels, 3x3 kernel\n        self.conv = nn.Conv2d(in_channels=3, out_channels=32, kernel_size=3, padding=1)\n        \n        # 2. Max pooling layer: 2x2\n        self.pool = nn.MaxPool2d(kernel_size=2, stride=2)\n\n        # After conv + pooling, image size goes from 32x32 → 16x16\n        # So, flatten size = 32 filters * 16 * 16 = 8192\n        self.flatten_size = 32 * 16 * 16\n\n        # 3. Fully connected (dense) layer with 128 units\n        self.fc1 = nn.Linear(self.flatten_size, 128)\n\n        # 4. Output layer: 10 units (for 10 classes)\n        self.fc2 = nn.Linear(128, 10)\n\n    def forward(self, x):\n        # Convolution + ReLU\n        x = F.relu(self.conv(x))\n\n        # Max Pooling\n        x = self.pool(x)\n\n        # Flatten\n        x = x.view(-1, self.flatten_size)\n\n        # Fully connected + ReLU\n        x = F.relu(self.fc1(x))\n\n        # Output layer (no softmax here — explained below)\n        x = self.fc2(x)\n\n        return x\n\n# Instantiate model\nmodel = SimpleCNN()\n\n# Move model to GPU if available\ndevice = torch.device(\"cuda\" if torch.cuda.is_available() else \"cpu\")\nmodel.to(device)\n\n# Print the model structure\nprint(model)\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-10-07T07:00:08.819079Z","iopub.execute_input":"2025-10-07T07:00:08.819333Z","iopub.status.idle":"2025-10-07T07:00:08.835923Z","shell.execute_reply.started":"2025-10-07T07:00:08.819308Z","shell.execute_reply":"2025-10-07T07:00:08.835394Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import torch\nimport torch.nn as nn\nimport torch.optim as optim\n\n# ============================================\n# 1. Compile the model\n# ============================================\n\ndevice = torch.device(\"cuda\" if torch.cuda.is_available() else \"cpu\")\n\nmodel = SimpleCNN().to(device)\n\ncriterion = nn.CrossEntropyLoss()\noptimizer = optim.Adam(model.parameters(), lr=0.001)\n\n# ============================================\n# 2. Train the model\n# ============================================\n\nnum_epochs = 10\n\n# For storing metrics\ntrain_losses = []\nval_losses = []\ntrain_accuracies = []\nval_accuracies = []\n\nfor epoch in range(num_epochs):\n    model.train()\n    running_loss = 0.0\n    correct = 0\n    total = 0\n\n    for images, labels in train_loader:\n        images, labels = images.to(device), labels.to(device)\n\n        optimizer.zero_grad()\n        outputs = model(images)\n        loss = criterion(outputs, labels)\n        loss.backward()\n        optimizer.step()\n\n        running_loss += loss.item()\n        _, predicted = torch.max(outputs, 1)\n        total += labels.size(0)\n        correct += (predicted == labels).sum().item()\n\n    train_loss = running_loss / len(train_loader)\n    train_acc = 100 * correct / total\n\n    # Validation\n    model.eval()\n    val_loss = 0.0\n    val_correct = 0\n    val_total = 0\n\n    with torch.no_grad():\n        for images, labels in test_loader:\n            images, labels = images.to(device), labels.to(device)\n            outputs = model(images)\n            loss = criterion(outputs, labels)\n\n            val_loss += loss.item()\n            _, predicted = torch.max(outputs, 1)\n            val_total += labels.size(0)\n            val_correct += (predicted == labels).sum().item()\n\n    val_loss /= len(test_loader)\n    val_acc = 100 * val_correct / val_total\n\n    # Store metrics\n    train_losses.append(train_loss)\n    val_losses.append(val_loss)\n    train_accuracies.append(train_acc)\n    val_accuracies.append(val_acc)\n\n    # Print progress\n    print(f\"Epoch [{epoch+1}/{num_epochs}]\")\n    print(f\"Train Loss: {train_loss:.4f}, Train Accuracy: {train_acc:.2f}%\")\n    print(f\"Val   Loss: {val_loss:.4f}, Val   Accuracy: {val_acc:.2f}%\\n\")\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-10-07T07:00:08.836571Z","iopub.execute_input":"2025-10-07T07:00:08.836830Z","iopub.status.idle":"2025-10-07T07:01:36.364776Z","shell.execute_reply.started":"2025-10-07T07:00:08.836806Z","shell.execute_reply":"2025-10-07T07:01:36.364102Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import matplotlib.pyplot as plt\n\n# ============================================\n# 3. Plot Loss and Accuracy\n# ============================================\n\n# Plot Loss\nplt.figure(figsize=(10,4))\nplt.subplot(1,2,1)\nplt.plot(train_losses, label='Train Loss')\nplt.plot(val_losses, label='Validation Loss')\nplt.title('Loss Over Epochs')\nplt.xlabel('Epoch')\nplt.ylabel('Loss')\nplt.legend()\n\n# Plot Accuracy\nplt.subplot(1,2,2)\nplt.plot(train_accuracies, label='Train Accuracy')\nplt.plot(val_accuracies, label='Validation Accuracy')\nplt.title('Accuracy Over Epochs')\nplt.xlabel('Epoch')\nplt.ylabel('Accuracy (%)')\nplt.legend()\n\nplt.tight_layout()\nplt.show()\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-10-07T07:01:36.365528Z","iopub.execute_input":"2025-10-07T07:01:36.365775Z","iopub.status.idle":"2025-10-07T07:01:36.703723Z","shell.execute_reply.started":"2025-10-07T07:01:36.365752Z","shell.execute_reply":"2025-10-07T07:01:36.702888Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Set model to evaluation mode\nmodel.eval()\n\ncorrect = 0\ntotal = 0\n\nwith torch.no_grad():\n    for images, labels in test_loader:\n        images, labels = images.to(device), labels.to(device)\n        outputs = model(images)\n        _, predicted = torch.max(outputs, 1)\n        correct += (predicted == labels).sum().item()\n        total += labels.size(0)\n\naccuracy = 100 * correct / total\nprint(f\"Test Accuracy: {accuracy:.2f}%\")\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-10-07T07:01:36.704534Z","iopub.execute_input":"2025-10-07T07:01:36.704726Z","iopub.status.idle":"2025-10-07T07:01:37.993785Z","shell.execute_reply.started":"2025-10-07T07:01:36.704710Z","shell.execute_reply":"2025-10-07T07:01:37.992997Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import torch\n\n# ===== Save the trained model =====\ntorch.save(model.state_dict(), 'cnn_cifar10.pth')\nprint(\"✅ Model saved!\")\n\n# ===== Load the model later =====\nmodel = SimpleCNN()  # Recreate the model structure\nmodel.load_state_dict(torch.load('cnn_cifar10.pth'))\nmodel.to(device)\nmodel.eval()\nprint(\"✅ Model loaded!\")\n\n# Get a batch of test images\ndataiter = iter(test_loader)  # Correct variable name\nimages, labels = next(dataiter)\nimages, labels = images.to(device), labels.to(device)\n\n# Run the model\noutputs = model(images)\n\n# Get predicted classes\n_, predicted = torch.max(outputs, 1)\n\n# Show results for first 10 images\nprint(\"Predicted: \", predicted[:10].cpu().numpy())\nprint(\"Actual:    \", labels[:10].cpu().numpy())\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-10-07T07:01:37.995773Z","iopub.execute_input":"2025-10-07T07:01:37.996428Z","iopub.status.idle":"2025-10-07T07:01:38.036487Z","shell.execute_reply.started":"2025-10-07T07:01:37.996402Z","shell.execute_reply":"2025-10-07T07:01:38.035858Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import torch\nimport torchvision\nimport torchvision.transforms as transforms\nimport matplotlib.pyplot as plt\nimport numpy as np\n\n# Define transform to convert PIL images to tensors and normalize\ntransform = transforms.Compose([\n    transforms.ToTensor()\n])\n\n# Load CIFAR-10 training dataset\ntrain_dataset = torchvision.datasets.CIFAR10(root='./data', train=True,\n                                             download=True, transform=transform)\n\n# Create a data loader\ntrain_loader = torch.utils.data.DataLoader(train_dataset, batch_size=20,\n                                           shuffle=False, num_workers=2)\n\n# Get a batch of 20 images\ndataiter = iter(train_loader)\nimages, labels = next(dataiter)\n\n# CIFAR-10 class names\nclasses = ['airplane', 'automobile', 'bird', 'cat', 'deer',\n           'dog', 'frog', 'horse', 'ship', 'truck']\n\n# Function to show images\ndef imshow(img):\n    img = img / 2 + 0.5     # unnormalize if needed (for normalized images)\n    npimg = img.numpy()\n    plt.figure(figsize=(12,6))\n    plt.imshow(np.transpose(npimg, (1, 2, 0)))\n    plt.axis('off')\n    plt.show()\n\n# Show the images\nimshow(torchvision.utils.make_grid(images))\n\n# Print class labels\nprint(' '.join(f'{classes[labels[j]]:10s}' for j in range(20)))\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-10-07T07:26:25.433454Z","iopub.execute_input":"2025-10-07T07:26:25.434213Z","iopub.status.idle":"2025-10-07T07:26:26.576952Z","shell.execute_reply.started":"2025-10-07T07:26:25.434188Z","shell.execute_reply":"2025-10-07T07:26:26.575906Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"\nmodel.eval()\npredictions = []\n\nwith torch.no_grad():\n    for images, _ in test_loader:  # Assuming test_loader yields (images, _) without labels\n        images = images.to(device)\n        outputs = model(images)\n        _, preds = torch.max(outputs, 1)\n        predictions.extend(preds.cpu().numpy())\n\n# Create a DataFrame with two columns: Id and Category (predicted class)\nsubmission_df = pd.DataFrame({\n    'Id': list(range(len(predictions))),\n    'Category': predictions\n})\n\n# Save to CSV\nsubmission_df.to_csv('submission22.csv', index=False)\nprint(\"✅ Submission file saved as 'submission.csv'\")\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-10-07T07:01:38.037232Z","iopub.execute_input":"2025-10-07T07:01:38.037436Z","iopub.status.idle":"2025-10-07T07:01:39.337314Z","shell.execute_reply.started":"2025-10-07T07:01:38.037421Z","shell.execute_reply":"2025-10-07T07:01:39.336578Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import os\nimport torch\nimport pandas as pd\nfrom PIL import Image\nfrom torch.utils.data import Dataset, DataLoader\nfrom torchvision import transforms\n\n# ===========================================\n# 1. Custom Dataset for Unlabeled Images\n# ===========================================\nclass TestImageDataset(Dataset):\n    def __init__(self, image_dir, transform=None):\n        self.image_dir = image_dir\n        self.image_files = sorted([\n            f for f in os.listdir(image_dir)\n            if f.lower().endswith(('.jpg', '.jpeg', '.png'))\n        ])\n        self.transform = transform\n\n    def __len__(self):\n        return len(self.image_files)\n\n    def __getitem__(self, idx):\n        img_name = self.image_files[idx]\n        img_path = os.path.join(self.image_dir, img_name)\n\n        image = Image.open(img_path).convert('RGB')\n\n        if self.transform:\n            image = self.transform(image)\n\n        return image, img_name\n\n# ===========================================\n# 2. Transform and DataLoader\n# ===========================================\ntransform = transforms.Compose([\n    transforms.Resize((32, 32)),\n    transforms.ToTensor(),\n    transforms.Normalize((0.5,), (0.5,))\n])\n\ntest_dir = '/kaggle/working/cifar/test'  # ⬅️ Change this to your folder path\n\ntest_dataset = TestImageDataset(test_dir, transform=transform)\ntest_loader = DataLoader(test_dataset, batch_size=64, shuffle=False)\n\n# ===========================================\n# 3. Model Inference\n# ===========================================\ndevice = torch.device(\"cuda\" if torch.cuda.is_available() else \"cpu\")\nmodel = SimpleCNN().to(device)  # ⬅️ Make sure SimpleCNN is defined and loaded with weights\nmodel.eval()\n\npredictions = []\nimage_ids = [x for x in range(300000)]\n\nwith torch.no_grad():\n    \n    for images, filenames in test_loader:\n        images = images.to(device)\n        outputs = model(images)\n        _, preds = torch.max(outputs, 1)\n\n        predictions.extend(preds.cpu().numpy())\n        \n\n# ===========================================\n# 4. Create Submission CSV\n# ===========================================\nsubmission = pd.DataFrame({\n    'Id': image_ids,\n    'Label': predictions\n})\nsubmission.to_csv(\"submission.csv\", index=False)\nprint(\"✅ Submission file saved as 'submission.csv'\")\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-10-07T07:01:39.338188Z","iopub.execute_input":"2025-10-07T07:01:39.338478Z","iopub.status.idle":"2025-10-07T07:03:44.772905Z","shell.execute_reply.started":"2025-10-07T07:01:39.338453Z","shell.execute_reply":"2025-10-07T07:03:44.772161Z"}},"outputs":[],"execution_count":null}]}