{"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":"nvidiaTeslaT4","dataSources":[{"sourceId":3649,"databundleVersionId":46718,"sourceType":"competition"}],"dockerImageVersionId":31154,"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},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# -----------------------------\n# Install Required Package\n# -----------------------------\n!pip install py7zr\n\n# -----------------------------\n# Imports\n# -----------------------------\nimport torch\nimport torch.nn as nn\nimport torch.optim as optim\nimport torch.nn.functional as F\nfrom torchvision import datasets, transforms\nfrom torch.utils.data import DataLoader\nimport math\nfrom tqdm import tqdm\nimport os\nimport py7zr\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-10-16T06:26:29.574395Z","iopub.execute_input":"2025-10-16T06:26:29.574682Z","iopub.status.idle":"2025-10-16T06:26:43.354522Z","shell.execute_reply.started":"2025-10-16T06:26:29.574660Z","shell.execute_reply":"2025-10-16T06:26:43.353835Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# -----------------------------\n# Device\n# -----------------------------\ndevice = torch.device(\"cuda\" if torch.cuda.is_available() else \"cpu\")\nprint(f\"Using device: {device}\")\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-10-16T06:26:55.511499Z","iopub.execute_input":"2025-10-16T06:26:55.512068Z","iopub.status.idle":"2025-10-16T06:26:55.591185Z","shell.execute_reply.started":"2025-10-16T06:26:55.512045Z","shell.execute_reply":"2025-10-16T06:26:55.590214Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"class ResNeXtBottleneck(nn.Module):\n    expansion = 4\n    def __init__(self, in_channels, out_channels, stride=1, cardinality=32, base_width=4):\n        super(ResNeXtBottleneck, self).__init__()\n        D = int(math.floor(out_channels * (base_width / 64.0))) * cardinality\n        self.conv1 = nn.Conv2d(in_channels, D, kernel_size=1, bias=False)\n        self.bn1 = nn.BatchNorm2d(D)\n        self.conv2 = nn.Conv2d(D, D, kernel_size=3, stride=stride, padding=1,\n                               groups=cardinality, bias=False)\n        self.bn2 = nn.BatchNorm2d(D)\n        self.conv3 = nn.Conv2d(D, out_channels * self.expansion, kernel_size=1, bias=False)\n        self.bn3 = nn.BatchNorm2d(out_channels * self.expansion)\n\n        self.shortcut = nn.Sequential()\n        if stride != 1 or in_channels != out_channels * self.expansion:\n            self.shortcut = nn.Sequential(\n                nn.Conv2d(in_channels, out_channels * self.expansion,\n                          kernel_size=1, stride=stride, bias=False),\n                nn.BatchNorm2d(out_channels * self.expansion)\n            )\n\n    def forward(self, x):\n        out = F.relu(self.bn1(self.conv1(x)))\n        out = F.relu(self.bn2(self.conv2(out)))\n        out = self.bn3(self.conv3(out))\n        out += self.shortcut(x)\n        out = F.relu(out)\n        return out\n\n\nclass ResNeXt(nn.Module):\n    def __init__(self, block, num_blocks, cardinality=32, num_classes=10):\n        super(ResNeXt, self).__init__()\n        self.in_channels = 64\n        self.conv1 = nn.Conv2d(3, 64, kernel_size=3, stride=1, padding=1, bias=False)\n        self.bn1 = nn.BatchNorm2d(64)\n        self.layer1 = self._make_layer(block, 128, num_blocks[0], stride=1, cardinality=cardinality)\n        self.layer2 = self._make_layer(block, 256, num_blocks[1], stride=2, cardinality=cardinality)\n        self.layer3 = self._make_layer(block, 512, num_blocks[2], stride=2, cardinality=cardinality)\n        self.linear = nn.Linear(512 * block.expansion, num_classes)\n        self._initialize_weights()\n\n    def _make_layer(self, block, out_channels, num_blocks, stride, cardinality):\n        strides = [stride] + [1] * (num_blocks - 1)\n        layers = []\n        for s in strides:\n            layers.append(block(self.in_channels, out_channels, s, cardinality))\n            self.in_channels = out_channels * block.expansion\n        return nn.Sequential(*layers)\n\n    def _initialize_weights(self):\n        for m in self.modules():\n            if isinstance(m, nn.Conv2d):\n                nn.init.kaiming_normal_(m.weight, mode='fan_out', nonlinearity='relu')\n            elif isinstance(m, nn.BatchNorm2d):\n                nn.init.ones_(m.weight)\n                nn.init.zeros_(m.bias)\n            elif isinstance(m, nn.Linear):\n                nn.init.normal_(m.weight, 0, 0.01)\n                nn.init.zeros_(m.bias)\n\n    def forward(self, x):\n        out = F.relu(self.bn1(self.conv1(x)))\n        out = self.layer1(out)\n        out = self.layer2(out)\n        out = self.layer3(out)\n        out = F.avg_pool2d(out, 8)\n        out = out.view(out.size(0), -1)\n        out = self.linear(out)\n        return out\n\n\ndef ResNeXt50_32x4d():\n    return ResNeXt(ResNeXtBottleneck, [3, 4, 6], cardinality=32)\n\n# Instantiate model\nmodel = ResNeXt50_32x4d().to(device)\nprint(\"ResNeXt50 (32x4d) model instantiated successfully.\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-10-16T06:27:17.737002Z","iopub.execute_input":"2025-10-16T06:27:17.737255Z","iopub.status.idle":"2025-10-16T06:27:18.534580Z","shell.execute_reply.started":"2025-10-16T06:27:17.737237Z","shell.execute_reply":"2025-10-16T06:27:18.533828Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# -----------------------------\n# Data Augmentation\n# -----------------------------\n\nclass Cutout(object):\n    def __init__(self, length):\n        self.length = length\n\n    def __call__(self, img):\n        h, w = img.size(1), img.size(2)\n        mask = torch.ones(h, w, dtype=img.dtype)\n        y = torch.randint(h, (1,)).item()\n        x = torch.randint(w, (1,)).item()\n        y1 = max(0, y - self.length // 2)\n        y2 = min(h, y + self.length // 2)\n        x1 = max(0, x - self.length // 2)\n        x2 = min(w, x + self.length // 2)\n        mask[y1:y2, x1:x2] = 0\n        img = img * mask.unsqueeze(0)\n        return img\n\n\nCIFAR10_MEAN = (0.4914, 0.4822, 0.4465)\nCIFAR10_STD = (0.2023, 0.1994, 0.2010)\n\ntransform_train = transforms.Compose([\n    transforms.RandomCrop(32, padding=4),\n    transforms.RandomHorizontalFlip(),\n    transforms.ToTensor(),\n    transforms.Normalize(CIFAR10_MEAN, CIFAR10_STD),\n    Cutout(length=16),\n])\n\ntransform_test = transforms.Compose([\n    transforms.ToTensor(),\n    transforms.Normalize(CIFAR10_MEAN, CIFAR10_STD),\n])\n\ntrainset = datasets.CIFAR10(root='./data', train=True, download=True, transform=transform_train)\ntrainloader = DataLoader(trainset, batch_size=128, shuffle=True, num_workers=4)\n\ntestset = datasets.CIFAR10(root='./data', train=False, download=True, transform=transform_test)\ntestloader = DataLoader(testset, batch_size=100, shuffle=False, num_workers=4)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-10-16T06:27:58.590046Z","iopub.execute_input":"2025-10-16T06:27:58.590717Z","iopub.status.idle":"2025-10-16T06:28:04.863274Z","shell.execute_reply.started":"2025-10-16T06:27:58.590692Z","shell.execute_reply":"2025-10-16T06:28:04.862675Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# -----------------------------\n# Loss, Optimizer, Scheduler\n# -----------------------------\n\ncriterion = nn.CrossEntropyLoss()\noptimizer = optim.AdamW(model.parameters(), lr=0.001, weight_decay=5e-4)\n\nclass CosineAnnealingWarmupRestarts(optim.lr_scheduler._LRScheduler):\n    def __init__(self, optimizer, T_0, T_mult=1, eta_max=0.001, T_up=5, gamma=0.5, last_epoch=-1):\n        self.T_0 = T_0\n        self.T_mult = T_mult\n        self.base_eta_max = eta_max\n        self.eta_max = eta_max\n        self.T_up = T_up\n        self.gamma = gamma\n        self.cycle = 0\n        self.T_i = T_0\n        super(CosineAnnealingWarmupRestarts, self).__init__(optimizer, last_epoch)\n\n    def get_lr(self):\n        if self.last_epoch < self.T_up:\n            return [(self.base_lrs[i] + (self.eta_max - self.base_lrs[i]) * self.last_epoch / self.T_up)\n                    for i in range(len(self.base_lrs))]\n        else:\n            cos_inner = (self.last_epoch - self.T_up) / (self.T_i - self.T_up)\n            return [self.base_lrs[i] + 0.5 * (self.eta_max - self.base_lrs[i]) *\n                    (1 + math.cos(math.pi * cos_inner))\n                    for i in range(len(self.base_lrs))]\n\nscheduler = CosineAnnealingWarmupRestarts(optimizer, T_0=60, eta_max=0.001, T_up=10)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-10-16T06:28:29.110415Z","iopub.execute_input":"2025-10-16T06:28:29.111036Z","iopub.status.idle":"2025-10-16T06:28:29.118773Z","shell.execute_reply.started":"2025-10-16T06:28:29.111002Z","shell.execute_reply":"2025-10-16T06:28:29.118180Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# -----------------------------\n# Training and Validation\n# -----------------------------\n\ndef train(epoch):\n    model.train()\n    running_loss = 0.0\n    for batch_idx, (inputs, targets) in enumerate(tqdm(trainloader, desc=f\"Training Epoch {epoch+1}\")):\n        inputs, targets = inputs.to(device), targets.to(device)\n        optimizer.zero_grad()\n        outputs = model(inputs)\n        loss = criterion(outputs, targets)\n        loss.backward()\n        optimizer.step()\n        running_loss += loss.item()\n        if batch_idx % 100 == 99:\n            print(f'[Epoch {epoch + 1}, Batch {batch_idx + 1}] loss: {running_loss / 100:.3f}')\n            running_loss = 0.0\n\ndef validate(epoch):\n    model.eval()\n    correct, total = 0, 0\n    with torch.no_grad():\n        for inputs, targets in tqdm(testloader, desc=f\"Validation Epoch {epoch+1}\"):\n            inputs, targets = inputs.to(device), targets.to(device)\n            outputs = model(inputs)\n            _, predicted = torch.max(outputs, 1)\n            total += targets.size(0)\n            correct += predicted.eq(targets).sum().item()\n    acc = 100. * correct / total\n    print(f'Validation Accuracy after Epoch {epoch + 1}: {acc:.2f}%')\n    return acc\n\n# -----------------------------\n# Training Loop\n# -----------------------------\nbest_acc = 0.0\nnum_epochs = 60\nfor epoch in range(num_epochs):\n    train(epoch)\n    acc = validate(epoch)\n    scheduler.step()\n    if acc > best_acc:\n        best_acc = acc\n        torch.save(model.state_dict(), 'resnext50_cifar10_best.pt')\n        print(f\"Best model saved with accuracy: {best_acc:.2f}%\")\n\nprint(\"Initial Training completed.\")\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-10-16T06:29:57.451770Z","iopub.execute_input":"2025-10-16T06:29:57.452348Z","iopub.status.idle":"2025-10-16T15:53:03.637068Z","shell.execute_reply.started":"2025-10-16T06:29:57.452323Z","shell.execute_reply":"2025-10-16T15:53:03.636239Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# -----------------------------\n# Inference on Test Set\n# -----------------------------\n\n# Decompressing Test Data (Assuming you have a 7z file)\n# Note: Adjust the paths based on your environment\ntest_archive_path = '/kaggle/input/cifar-10/test.7z'\nextracted_path = '/kaggle/working/test'\n\nif not os.path.exists(extracted_path):\n    os.makedirs(extracted_path, exist_ok=True)\n    with py7zr.SevenZipFile(test_archive_path, mode='r') as z:\n        z.extractall(extracted_path)\n    print(\"Test data decompressed successfully.\")\nelse:\n    print(\"Test data already decompressed.\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-10-16T16:06:20.620734Z","iopub.execute_input":"2025-10-16T16:06:20.621288Z","iopub.status.idle":"2025-10-16T16:06:20.626001Z","shell.execute_reply.started":"2025-10-16T16:06:20.621262Z","shell.execute_reply":"2025-10-16T16:06:20.625420Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import os\nimport py7zr\n\ntest_archive = '/kaggle/input/cifar-10/test.7z'\nextracted_path = '/kaggle/working/test'\n\nif not os.path.exists(extracted_path):\n    os.makedirs(extracted_path, exist_ok=True)\n\nwith py7zr.SevenZipFile(test_archive, mode='r') as archive:\n    archive.extractall(path=extracted_path)\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-10-16T17:26:58.603270Z","iopub.execute_input":"2025-10-16T17:26:58.603799Z","iopub.status.idle":"2025-10-16T17:28:56.939527Z","shell.execute_reply.started":"2025-10-16T17:26:58.603776Z","shell.execute_reply":"2025-10-16T17:28:56.938910Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# List all files and folders in the extracted directory\nfor root, dirs, files in os.walk(extracted_path):\n    print(\"Folder:\", root)\n    print(\"Files:\", files[:5])  # Show first 5 files only\n    print(\"----\")\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-10-16T17:30:27.768626Z","iopub.execute_input":"2025-10-16T17:30:27.769355Z","iopub.status.idle":"2025-10-16T17:30:27.960485Z","shell.execute_reply.started":"2025-10-16T17:30:27.769330Z","shell.execute_reply":"2025-10-16T17:30:27.959706Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# -----------------------------\n# Required Packages\n# -----------------------------\n!pip install py7zr\n\nimport os\nimport torch\nimport torch.nn as nn\nimport torch.nn.functional as F\nfrom torch.utils.data import Dataset, DataLoader\nfrom PIL import Image\nimport pandas as pd\nimport torchvision.transforms as transforms\nfrom tqdm import tqdm\nimport py7zr\nimport zipfile\n\n# -----------------------------\n# Device\n# -----------------------------\ndevice = 'cuda' if torch.cuda.is_available() else 'cpu'\nprint(\"Using device:\", device)\n\n# -----------------------------\n# ResNeXt Model Definition\n# -----------------------------\nclass ResNeXtBottleneck(nn.Module):\n    expansion = 4\n    def __init__(self, in_channels, out_channels, stride=1, cardinality=32, base_width=4):\n        super().__init__()\n        D = int(out_channels * (base_width / 64.0)) * cardinality\n        self.conv1 = nn.Conv2d(in_channels, D, 1, bias=False)\n        self.bn1 = nn.BatchNorm2d(D)\n        self.conv2 = nn.Conv2d(D, D, 3, stride=stride, padding=1, groups=cardinality, bias=False)\n        self.bn2 = nn.BatchNorm2d(D)\n        self.conv3 = nn.Conv2d(D, out_channels * self.expansion, 1, bias=False)\n        self.bn3 = nn.BatchNorm2d(out_channels * self.expansion)\n        self.shortcut = nn.Sequential()\n        if stride != 1 or in_channels != out_channels * self.expansion:\n            self.shortcut = nn.Sequential(\n                nn.Conv2d(in_channels, out_channels * self.expansion, 1, stride=stride, bias=False),\n                nn.BatchNorm2d(out_channels * self.expansion)\n            )\n    def forward(self, x):\n        out = F.relu(self.bn1(self.conv1(x)))\n        out = F.relu(self.bn2(self.conv2(out)))\n        out = self.bn3(self.conv3(out))\n        out += self.shortcut(x)\n        return F.relu(out)\n\nclass ResNeXt(nn.Module):\n    def __init__(self, block, num_blocks, cardinality=32, num_classes=10):\n        super().__init__()\n        self.in_channels = 64\n        self.conv1 = nn.Conv2d(3, 64, 3, stride=1, padding=1, bias=False)\n        self.bn1 = nn.BatchNorm2d(64)\n        self.layer1 = self._make_layer(block, 128, num_blocks[0], 1, cardinality)\n        self.layer2 = self._make_layer(block, 256, num_blocks[1], 2, cardinality)\n        self.layer3 = self._make_layer(block, 512, num_blocks[2], 2, cardinality)\n        self.linear = nn.Linear(512 * block.expansion, num_classes)\n    def _make_layer(self, block, out_channels, num_blocks, stride, cardinality):\n        layers = []\n        strides = [stride] + [1]*(num_blocks-1)\n        for s in strides:\n            layers.append(block(self.in_channels, out_channels, s, cardinality))\n            self.in_channels = out_channels * block.expansion\n        return nn.Sequential(*layers)\n    def forward(self, x):\n        out = F.relu(self.bn1(self.conv1(x)))\n        out = self.layer1(out)\n        out = self.layer2(out)\n        out = self.layer3(out)\n        out = F.avg_pool2d(out, 8)\n        out = out.view(out.size(0), -1)\n        return self.linear(out)\n\ndef ResNeXt50_32x4d():\n    return ResNeXt(ResNeXtBottleneck, [3,4,6], cardinality=32)\n\n# -----------------------------\n# CIFAR-10 Classes\n# -----------------------------\nclasses = ['airplane','automobile','bird','cat','deer','dog','frog','horse','ship','truck']\n\n# -----------------------------\n# Custom Dataset\n# -----------------------------\nclass CustomImageDataset(Dataset):\n    def __init__(self, image_dir, transform=None):\n        self.image_dir = image_dir\n        self.transform = transform\n        self.image_filenames = sorted(os.listdir(image_dir))\n    def __len__(self):\n        return len(self.image_filenames)\n    def __getitem__(self, idx):\n        img_path = os.path.join(self.image_dir, self.image_filenames[idx])\n        image = Image.open(img_path).convert('RGB')\n        if self.transform:\n            image = self.transform(image)\n        digits = ''.join(filter(str.isdigit, self.image_filenames[idx]))\n        img_id = int(digits) if digits else idx\n        return image, img_id\n\n# -----------------------------\n# Test Transforms\n# -----------------------------\nCIFAR10_MEAN = (0.4914, 0.4822, 0.4465)\nCIFAR10_STD = (0.2023, 0.1994, 0.2010)\ntest_transforms = transforms.Compose([\n    transforms.Resize((32,32)),\n    transforms.ToTensor(),\n    transforms.Normalize(CIFAR10_MEAN, CIFAR10_STD)\n])\n\n# -----------------------------\n# Decompress Test Data\n# -----------------------------\ntest_archive = '/kaggle/input/cifar-10/test.7z'\ntest_dir = '/kaggle/working/test/test'  # ✅ Correct folder with images\n\nif not os.path.exists(test_dir):\n    os.makedirs(test_dir, exist_ok=True)\n    with py7zr.SevenZipFile(test_archive, mode='r') as archive:\n        archive.extractall(test_dir)\n    print(\"Test data decompressed ✅\")\nelse:\n    print(\"Test data already exists ✅\")\n\n# -----------------------------\n# Load Model\n# -----------------------------\nmodel_path = '/kaggle/working/resnext50_cifar10_best.pt'\nmodel = ResNeXt50_32x4d().to(device)\nmodel.load_state_dict(torch.load(model_path, map_location=device))\nmodel.eval()\nprint(\"Model loaded ✅\")\n\n# -----------------------------\n# Test DataLoader\n# -----------------------------\ntest_dataset = CustomImageDataset(test_dir, transform=test_transforms)\ntest_loader = DataLoader(test_dataset, batch_size=128, shuffle=False, num_workers=4)\n\n# -----------------------------\n# Inference\n# -----------------------------\nall_predictions = []\nwith torch.no_grad():\n    for images, img_ids in tqdm(test_loader, desc=\"Inference\"):\n        images = images.to(device)\n        outputs = model(images)\n        _, preds = torch.max(outputs,1)\n        preds = preds.cpu().numpy()\n        for img_id, pred in zip(img_ids, preds):\n            all_predictions.append((img_id, classes[pred]))\n\n# -----------------------------\n# Save CSV\n# -----------------------------\nsubmission_df = pd.DataFrame(all_predictions, columns=['id','label'])\nsubmission_df = submission_df.sort_values('id').reset_index(drop=True)\nsubmission_csv = '/kaggle/working/submission.csv'\nsubmission_df.to_csv(submission_csv, index=False)\nprint(\"CSV saved ✅\", submission_csv)\n\n# -----------------------------\n# Zip CSV for Kaggle Submission\n# -----------------------------\nzip_path = '/kaggle/working/submission.zip'\nwith zipfile.ZipFile(zip_path,'w') as zipf:\n    zipf.write(submission_csv, arcname='submission.csv')\nprint(\"ZIP created ✅\", zip_path)\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-10-16T17:31:58.263547Z","iopub.execute_input":"2025-10-16T17:31:58.264264Z","iopub.status.idle":"2025-10-16T17:48:53.900270Z","shell.execute_reply.started":"2025-10-16T17:31:58.264238Z","shell.execute_reply":"2025-10-16T17:48:53.899290Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import pandas as pd\n\nsubmission_csv = '/kaggle/working/submission.csv'\ndf = pd.read_csv(submission_csv)\n\n# Check basic info\nprint(\"Number of rows:\", len(df))\nprint(\"Columns:\", df.columns)\nprint(\"First 10 rows:\\n\", df.head(10))\n\n# Check the unique labels predicted\nprint(\"Unique predicted labels:\", df['label'].unique())\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-10-16T17:52:12.685467Z","iopub.execute_input":"2025-10-16T17:52:12.686125Z","iopub.status.idle":"2025-10-16T17:52:12.895151Z","shell.execute_reply.started":"2025-10-16T17:52:12.686103Z","shell.execute_reply":"2025-10-16T17:52:12.894268Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import pandas as pd\n\n# Load your submission CSV\ndf = pd.read_csv('/kaggle/working/submission.csv')\n\n# Convert 'tensor(1)' -> 1\ndf['id'] = df['id'].apply(lambda x: int(''.join(filter(str.isdigit, x))))\n\n# Save cleaned CSV\nsubmission_clean = '/kaggle/working/submission_clean.csv'\ndf.to_csv(submission_clean, index=False)\n\nprint(\"Cleaned submission CSV saved ✅\", submission_clean)\nprint(df.head())\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-10-16T17:54:13.160123Z","iopub.execute_input":"2025-10-16T17:54:13.160826Z","iopub.status.idle":"2025-10-16T17:54:13.772868Z","shell.execute_reply.started":"2025-10-16T17:54:13.160803Z","shell.execute_reply":"2025-10-16T17:54:13.771981Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"","metadata":{"trusted":true},"outputs":[],"execution_count":null}]}