{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.13.15","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":"!apt-get update -y\n!apt-get install -y libarchive-dev\n!pip install libarchive","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-10-13T07:55:32.551326Z","iopub.execute_input":"2026-10-13T07:55:32.552409Z","iopub.status.idle":"2026-10-13T07:55:59.298024Z","shell.execute_reply.started":"2026-10-13T07:55:32.552371Z","shell.execute_reply":"2026-10-13T07:55:59.296987Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"\n\nimport libarchive.public\n\nimport glob\n\n# Extract test.7z using the correct Kaggle path\ncnt = 0\nfor entry in libarchive.public.file_pour('/kaggle/input/competitions/cifar-10/test.7z'):\n    cnt += 1\n    if cnt % 1000 == 0: \n        print(f\"Extracted {cnt} files...\")\n\nprint(\"Total extracted files:\", len(glob.glob('test/*')))","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-10-13T07:54:01.841894Z","iopub.execute_input":"2026-10-13T07:54:01.842636Z","iopub.status.idle":"2026-10-13T07:54:08.618538Z","shell.execute_reply.started":"2026-10-13T07:54:01.842597Z","shell.execute_reply":"2026-10-13T07:54:08.617317Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import libarchive.public\nimport glob\nimport os\n\n# Extract train.7z if not already done\nif not os.path.exists('train'):\n    print(\"Extracting train.7z...\")\n    cnt = 0\n    for entry in libarchive.public.file_pour('/kaggle/input/competitions/cifar-10/train.7z'):\n        cnt += 1\n        if cnt % 5000 == 0: \n            print(f\"Extracted {cnt} training files...\")\n    print(\"Total extracted train files:\", len(glob.glob('train/*')))\nelse:\n    print(\"Train folder already exists.\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-10-13T07:57:01.405291Z","iopub.execute_input":"2026-10-13T07:57:01.406099Z","iopub.status.idle":"2026-10-13T07:57:12.686277Z","shell.execute_reply.started":"2026-10-13T07:57:01.406066Z","shell.execute_reply":"2026-10-13T07:57:12.685359Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import libarchive.public\nimport glob\n\n# Extract test.7z using the correct Kaggle path\ncnt = 0\nfor entry in libarchive.public.file_pour('/kaggle/input/competitions/cifar-10/test.7z'):\n    cnt += 1\n    if cnt % 1000 == 0: \n        print(f\"Extracted {cnt} files...\")\n\nprint(\"Total extracted files:\", len(glob.glob('test/*')))","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-10-13T07:58:08.650293Z","iopub.execute_input":"2026-10-13T07:58:08.651247Z","iopub.status.idle":"2026-10-13T07:59:17.402122Z","shell.execute_reply.started":"2026-10-13T07:58:08.651214Z","shell.execute_reply":"2026-10-13T07:59:17.401469Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import torch\nimport torch.nn as nn\nimport torch.optim as optim\nimport torchvision.transforms as transforms\nfrom torch.utils.data import Dataset, DataLoader, random_split\nimport pandas as pd\nimport os\nimport glob\nfrom PIL import Image\n\n# 1. Device configuration\ndevice = torch.device(\"cuda\" if torch.cuda.is_available() else \"cpu\")\nprint(f\"Using device: {device}\")\n\n# 2. Enhanced Data Augmentation with Random Erasing & Normalization\ntransform_train = transforms.Compose([\n    transforms.RandomCrop(32, padding=4),\n    transforms.RandomHorizontalFlip(),\n    transforms.ToTensor(),\n    transforms.Normalize((0.4914, 0.4822, 0.4465), (0.2023, 0.1994, 0.2010)),\n    transforms.RandomErasing(p=0.2, scale=(0.02, 0.23), value='random')\n])\n\ntransform_test = transforms.Compose([\n    transforms.ToTensor(),\n    transforms.Normalize((0.4914, 0.4822, 0.4465), (0.2023, 0.1994, 0.2010)),\n])\n\nclasses = ('airplane', 'automobile', 'bird', 'cat', 'deer', 'dog', 'frog', 'horse', 'ship', 'truck')\nclass_to_idx = {cls_name: i for i, cls_name in enumerate(classes)}\n\n# 3. Custom Dataset for Kaggle Training Data\nclass KaggleTrainDataset(Dataset):\n    def __init__(self, csv_file, img_dir, transform=None):\n        self.df = pd.read_csv(csv_file)\n        self.img_dir = img_dir\n        self.transform = transform\n\n    def __len__(self):\n        return len(self.df)\n\n    def __getitem__(self, idx):\n        row = self.df.iloc[idx]\n        img_id = row['id']\n        label_str = row['label']\n        \n        img_path = os.path.join(self.img_dir, f\"{img_id}.png\")\n        image = Image.open(img_path).convert('RGB')\n        label = class_to_idx[label_str]\n        \n        if self.transform:\n            image = self.transform(image)\n            \n        return image, label\n\n# Load full training dataset\nfull_dataset = KaggleTrainDataset(\n    csv_file='/kaggle/input/competitions/cifar-10/trainLabels.csv',\n    img_dir='train',\n    transform=transform_train\n)\n\n# Split into 90% training and 10% validation\ntrain_size = int(0.9 * len(full_dataset))\nval_size = len(full_dataset) - train_size\ntrainset, valset = random_split(full_dataset, [train_size, val_size])\n\n# Apply test transform to validation set\nvalset.dataset.transform = transform_test\n\ntrainloader = DataLoader(trainset, batch_size=128, shuffle=True, num_workers=4, pin_memory=True)\nvalloader = DataLoader(valset, batch_size=128, shuffle=False, num_workers=4, pin_memory=True)\n\n# 4. Custom High-Performance CNN Architecture Built From Scratch\nclass FastCIFARCNN(nn.Module):\n    def __init__(self, num_classes=10):\n        super(FastCIFARCNN, self).__init__()\n        \n        def conv_block(in_channels, out_channels, pool=False):\n            layers = [\n                nn.Conv2d(in_channels, out_channels, kernel_size=3, padding=1, bias=False),\n                nn.BatchNorm2d(out_channels),\n                nn.LeakyReLU(0.1, inplace=True)\n            ]\n            if pool:\n                layers.append(nn.MaxPool2d(2))\n            return nn.Sequential(*layers)\n\n        self.prep = conv_block(3, 64)\n        self.layer1 = nn.Sequential(\n            conv_block(64, 128, pool=True),\n            nn.Conv2d(128, 128, kernel_size=3, padding=1, bias=False),\n            nn.BatchNorm2d(128),\n            nn.LeakyReLU(0.1, inplace=True)\n        )\n        self.layer2 = conv_block(128, 256, pool=True)\n        self.layer3 = nn.Sequential(\n            conv_block(256, 512, pool=True),\n            nn.Conv2d(512, 512, kernel_size=3, padding=1, bias=False),\n            nn.BatchNorm2d(512),\n            nn.LeakyReLU(0.1, inplace=True)\n        )\n        self.classifier = nn.Sequential(\n            nn.AdaptiveAvgPool2d((1, 1)),\n            nn.Flatten(),\n            nn.Dropout(0.3),\n            nn.Linear(512, num_classes)\n        )\n\n    def forward(self, x):\n        out = self.prep(x)\n        out = self.layer1(out)\n        out = self.layer2(out)\n        out = self.layer3(out)\n        out = self.classifier(out)\n        return out\n\nmodel = FastCIFARCNN(num_classes=10).to(device)\n\n# 5. Loss, Optimizer, Scheduler, and Modern AMP Scaler\nepochs = 45\ncriterion = nn.CrossEntropyLoss(label_smoothing=0.1)\noptimizer = optim.AdamW(model.parameters(), lr=0.002, weight_decay=1e-4)\nscheduler = optim.lr_scheduler.OneCycleLR(\n    optimizer, max_lr=0.005, steps_per_epoch=len(trainloader), epochs=epochs\n)\nscaler = torch.amp.GradScaler('cuda')\n\n# 6. Training Loop with AMP\nbest_val_acc = 0.0\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 trainloader:\n        inputs, labels = inputs.to(device), labels.to(device)\n        \n        optimizer.zero_grad()\n        with torch.amp.autocast('cuda'):\n            outputs = model(inputs)\n            loss = criterion(outputs, labels)\n            \n        scaler.scale(loss).backward()\n        scaler.step(optimizer)\n        scaler.update()\n        scheduler.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    train_acc = correct / total\n    \n    model.eval()\n    val_correct = 0\n    val_total = 0\n    with torch.no_grad():\n        for inputs, labels in valloader:\n            inputs, labels = inputs.to(device), labels.to(device)\n            with torch.amp.autocast('cuda'):\n                outputs = model(inputs)\n            _, predicted = outputs.max(1)\n            val_total += labels.size(0)\n            val_correct += predicted.eq(labels).sum().item()\n            \n    val_acc = val_correct / val_total\n    if val_acc > best_val_acc:\n        best_val_acc = val_acc\n        \n    print(f\"Epoch [{epoch+1}/{epochs}] | Loss: {running_loss/total:.4f} | Train Acc: {train_acc:.4f} | Val Acc: {val_acc:.4f} (Best: {best_val_acc:.4f})\")\n\n# 7. Generate Predictions for the Kaggle Test Set (300k images)\nclass KaggleTestDataset(Dataset):\n    def __init__(self, image_paths, transform=None):\n        self.image_paths = image_paths\n        self.transform = transform\n\n    def __len__(self):\n        return len(self.image_paths)\n\n    def __getitem__(self, idx):\n        path = self.image_paths[idx]\n        img_id = int(os.path.basename(path).split('.')[0])\n        image = Image.open(path).convert('RGB')\n        if self.transform:\n            image = self.transform(image)\n        return image, img_id\n\ntest_images = sorted(glob.glob('test/*'), key=lambda x: int(os.path.basename(x).split('.')[0]))\nkaggle_dataset = KaggleTestDataset(test_images, transform=transform_test)\nkaggle_loader = DataLoader(kaggle_dataset, batch_size=512, shuffle=False, num_workers=4, pin_memory=True)\n\nmodel.eval()\nresults = []\nprint(\"Generating predictions on the Kaggle test set...\")\nwith torch.no_grad():\n    for inputs, img_ids in kaggle_loader:\n        inputs = inputs.to(device)\n        with torch.amp.autocast('cuda'):\n            outputs = model(inputs)\n        _, predicted = outputs.max(1)\n        for img_id, pred in zip(img_ids, predicted):\n            results.append({'id': img_id.item(), 'label': classes[pred.item()]})\n\ndf = pd.DataFrame(results)\ndf.to_csv('submission.csv', index=False)\nprint(\"Submission file 'submission.csv' generated successfully in /kaggle/working/!\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-10-13T08:56:11.808269Z","iopub.execute_input":"2026-10-13T08:56:11.808804Z","iopub.status.idle":"2026-10-13T09:06:28.319831Z","shell.execute_reply.started":"2026-10-13T08:56:11.808774Z","shell.execute_reply":"2026-10-13T09:06:28.319043Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"from IPython.display import FileLink\nFileLink('submission.csv')","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2026-10-13T09:08:58.484138Z","iopub.execute_input":"2026-10-13T09:08:58.484848Z","iopub.status.idle":"2026-10-13T09:08:58.491886Z","shell.execute_reply.started":"2026-10-13T09:08:58.484815Z","shell.execute_reply":"2026-10-13T09:08:58.491151Z"}},"outputs":[],"execution_count":null}]}