{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.10.14","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":30776,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":true}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"import torch\nimport torch.nn as nn\nimport torch.optim as optim\nimport torch.nn.functional as F\nimport torchvision\nimport torchvision.transforms as transforms\n\n# Define the ResNet block\nclass BasicBlock(nn.Module):\n    def __init__(self, in_planes, planes, stride=1):\n        super(BasicBlock, self).__init__()\n        self.conv1 = nn.Conv2d(in_planes, planes, kernel_size=3, stride=stride, padding=1, bias=False)\n        self.bn1 = nn.BatchNorm2d(planes)\n        self.conv2 = nn.Conv2d(planes, planes, kernel_size=3, stride=1, padding=1, bias=False)\n        self.bn2 = nn.BatchNorm2d(planes)\n\n        self.shortcut = nn.Sequential()\n        if stride != 1 or in_planes != planes:\n            self.shortcut = nn.Sequential(\n                nn.Conv2d(in_planes, planes, kernel_size=1, stride=stride, bias=False),\n                nn.BatchNorm2d(planes)\n            )\n\n    def forward(self, x):\n        out = F.relu(self.bn1(self.conv1(x)))\n        out = self.bn2(self.conv2(out))\n        out += self.shortcut(x)\n        out = F.relu(out)\n        return out\n\n# Define the ResNet model\nclass ResNet(nn.Module):\n    def __init__(self, block, num_blocks, num_classes=10):\n        super(ResNet, self).__init__()\n        self.in_planes = 64\n\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, 64, num_blocks[0], stride=1)\n        self.layer2 = self._make_layer(block, 128, num_blocks[1], stride=2)\n        self.layer3 = self._make_layer(block, 256, num_blocks[2], stride=2)\n        self.layer4 = self._make_layer(block, 512, num_blocks[3], stride=2)\n        self.linear = nn.Linear(512, num_classes)\n\n    def _make_layer(self, block, planes, num_blocks, stride):\n        strides = [stride] + [1] * (num_blocks - 1)\n        layers = []\n        for stride in strides:\n            layers.append(block(self.in_planes, planes, stride))\n            self.in_planes = planes\n        return nn.Sequential(*layers)\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 = self.layer4(out)\n        out = F.avg_pool2d(out, 4)\n        out = out.view(out.size(0), -1)\n        out = self.linear(out)\n        return out\n\ndef ResNet34():\n    return ResNet(BasicBlock, [3, 4, 6, 3])\n\n# Data augmentation and normalization for training\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.247, 0.243, 0.261))\n])\n\ntransform_test = transforms.Compose([\n    transforms.ToTensor(),\n    transforms.Normalize((0.4914, 0.4822, 0.4465), (0.247, 0.243, 0.261))\n])\n\n# Load CIFAR10 dataset\ntrainset = torchvision.datasets.CIFAR10(root='./data', train=True, download=True, transform=transform_train)\ntrainloader = torch.utils.data.DataLoader(trainset, batch_size=128, shuffle=True)\n\ntestset = torchvision.datasets.CIFAR10(root='./data', train=False, download=True, transform=transform_test)\ntestloader = torch.utils.data.DataLoader(testset, batch_size=128, shuffle=False)\n\ndevice = 'cuda' if torch.cuda.is_available() else 'cpu'\nnet = ResNet34().to(device)\n\n# Loss function and optimizer\ncriterion = nn.CrossEntropyLoss()\noptimizer = optim.SGD(net.parameters(), lr=0.1, momentum=0.9, weight_decay=5e-4)\nscheduler = torch.optim.lr_scheduler.StepLR(optimizer, step_size=20, gamma=0.1)\n\n# Training function\ndef train(epoch):\n    print(f'\\nEpoch: {epoch}')\n    net.train()\n    train_loss = 0\n    correct = 0\n    total = 0\n    for batch_idx, (inputs, targets) in enumerate(trainloader):\n        inputs, targets = inputs.to(device), targets.to(device)\n        optimizer.zero_grad()\n        outputs = net(inputs)\n        loss = criterion(outputs, targets)\n        loss.backward()\n        optimizer.step()\n\n        train_loss += loss.item()\n        _, predicted = outputs.max(1)\n        total += targets.size(0)\n        correct += predicted.eq(targets).sum().item()\n\n        print(f'Batch {batch_idx}/{len(trainloader)} | Loss: {train_loss/(batch_idx+1):.3f} | Acc: {100.*correct/total:.3f}% ({correct}/{total})')\n\n# Testing function\ndef test(epoch):\n    net.eval()\n    test_loss = 0\n    correct = 0\n    total = 0\n    with torch.no_grad():\n        for batch_idx, (inputs, targets) in enumerate(testloader):\n            inputs, targets = inputs.to(device), targets.to(device)\n            outputs = net(inputs)\n            loss = criterion(outputs, targets)\n\n            test_loss += loss.item()\n            _, predicted = outputs.max(1)\n            total += targets.size(0)\n            correct += predicted.eq(targets).sum().item()\n\n            print(f'Batch {batch_idx}/{len(testloader)} | Loss: {test_loss/(batch_idx+1):.3f} | Acc: {100.*correct/total:.3f}% ({correct}/{total})')\n\n# Main training loop for 50 epochs\nfor epoch in range(50):\n    train(epoch)\n    test(epoch)\n    scheduler.step()\n    print(\"Sucessfull Training\")\n","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","execution":{"iopub.status.busy":"2024-10-03T13:12:15.719707Z","iopub.execute_input":"2024-10-03T13:12:15.720058Z","iopub.status.idle":"2024-10-03T14:05:57.180166Z","shell.execute_reply.started":"2024-10-03T13:12:15.720022Z","shell.execute_reply":"2024-10-03T14:05:57.179218Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"torch.save(net.state_dict(), f'model_weights_epoch_{epoch+1}.pth')\nprint(f'Successfully saved model epoch {epoch+1}')","metadata":{"execution":{"iopub.status.busy":"2024-10-03T14:08:08.634914Z","iopub.execute_input":"2024-10-03T14:08:08.635731Z","iopub.status.idle":"2024-10-03T14:08:08.769625Z","shell.execute_reply.started":"2024-10-03T14:08:08.635693Z","shell.execute_reply":"2024-10-03T14:08:08.768716Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"!pip install  py7zr\n# Required Imports\nimport py7zr\nimport os\nfrom tqdm import tqdm\nimport pandas as pd\nfrom PIL import Image\nimport torch\nfrom torch.utils.data import Dataset, DataLoader\nimport torchvision.transforms as transforms\n\n# Decompressing data\nwith py7zr.SevenZipFile('/kaggle/input/cifar-10/test.7z', mode='r') as z:\n    z.extractall('/kaggle/working/')\n\n# Sorting filenames and extracting IDs from filenames\ntest_filenames = [os.path.join('/kaggle/working/test', f) for f in os.listdir('/kaggle/working/test')]\ntest_filenames.sort(key=lambda x: int(x.split('/')[-1].split('.')[0]))","metadata":{"execution":{"iopub.status.busy":"2024-10-03T18:48:41.101371Z","iopub.execute_input":"2024-10-03T18:48:41.101671Z","iopub.status.idle":"2024-10-03T18:51:26.068871Z","shell.execute_reply.started":"2024-10-03T18:48:41.101638Z","shell.execute_reply":"2024-10-03T18:51:26.068020Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import os\nimport torch\nimport torch.nn as nn\nimport torch.optim as optim\nimport torch.nn.functional as F\nfrom torch.utils.data import Dataset, DataLoader\nfrom torchvision import transforms\nimport pandas as pd\nfrom PIL import Image\n\n# CIFAR-10 class labels\nCIFAR10_CLASSES = ['airplane', 'automobile', 'bird', 'cat', 'deer', 'dog', 'frog', 'horse', 'ship', 'truck']\n\n# Custom Dataset class for CIFAR-10 test set (without labels)\nclass CIFAR10TestDataset(Dataset):\n    def __init__(self, root_dir, transform=None):\n        self.root_dir = root_dir\n        self.transform = transform\n        self.image_files = sorted([f for f in os.listdir(root_dir) if f.endswith('.png') or f.endswith('.jpg')])\n\n    def __len__(self):\n        return len(self.image_files)\n\n    def __getitem__(self, idx):\n        img_name = os.path.join(self.root_dir, self.image_files[idx])\n        image = Image.open(img_name)\n        if self.transform:\n            image = self.transform(image)\n        return image, self.image_files[idx]  # Return the image and the filename (to identify later)\n\n# Define transformations for the test dataset (normalize the data same as training)\ntransform_test = transforms.Compose([\n    transforms.ToTensor(),\n    transforms.Normalize((0.4914, 0.4822, 0.4465), (0.247, 0.243, 0.261))\n])\n\n# Load the test dataset (images in the test set)\ntestset_dir = '/kaggle/working/test'  # Path where you unzipped the test.7z\ntestset = CIFAR10TestDataset(root_dir=testset_dir, transform=transform_test)\n\n# Create a DataLoader for the test dataset\ntestloader = DataLoader(testset, batch_size=128, shuffle=False)\n\ndevice = 'cuda' if torch.cuda.is_available() else 'cpu'\n\n# Define your ResNet34 model (unchanged)\nclass BasicBlock(nn.Module):\n    def __init__(self, in_planes, planes, stride=1):\n        super(BasicBlock, self).__init__()\n        self.conv1 = nn.Conv2d(in_planes, planes, kernel_size=3, stride=stride, padding=1, bias=False)\n        self.bn1 = nn.BatchNorm2d(planes)\n        self.conv2 = nn.Conv2d(planes, planes, kernel_size=3, stride=1, padding=1, bias=False)\n        self.bn2 = nn.BatchNorm2d(planes)\n\n        self.shortcut = nn.Sequential()\n        if stride != 1 or in_planes != planes:\n            self.shortcut = nn.Sequential(\n                nn.Conv2d(in_planes, planes, kernel_size=1, stride=stride, bias=False),\n                nn.BatchNorm2d(planes)\n            )\n\n    def forward(self, x):\n        out = F.relu(self.bn1(self.conv1(x)))\n        out = self.bn2(self.conv2(out))\n        out += self.shortcut(x)\n        out = F.relu(out)\n        return out\n\nclass ResNet(nn.Module):\n    def __init__(self, block, num_blocks, num_classes=10):\n        super(ResNet, self).__init__()\n        self.in_planes = 64\n\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, 64, num_blocks[0], stride=1)\n        self.layer2 = self._make_layer(block, 128, num_blocks[1], stride=2)\n        self.layer3 = self._make_layer(block, 256, num_blocks[2], stride=2)\n        self.layer4 = self._make_layer(block, 512, num_blocks[3], stride=2)\n        self.linear = nn.Linear(512, num_classes)\n\n    def _make_layer(self, block, planes, num_blocks, stride):\n        strides = [stride] + [1] * (num_blocks - 1)\n        layers = []\n        for stride in strides:\n            layers.append(block(self.in_planes, planes, stride))\n            self.in_planes = planes\n        return nn.Sequential(*layers)\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 = self.layer4(out)\n        out = F.avg_pool2d(out, 4)\n        out = out.view(out.size(0), -1)\n        out = self.linear(out)\n        return out\n\ndef ResNet34():\n    return ResNet(BasicBlock, [3, 4, 6, 3])\n\n# Load the model and weights\nnet = ResNet34().to(device)\nmodel_weights_path = '/kaggle/working/model_weights_epoch_50.pth'  # Path to the saved model weights\nnet.load_state_dict(torch.load(model_weights_path))\nnet.eval()  # Set model to evaluation mode\n\n# Inference on the test set\ndef inference():\n    net.eval()\n    predictions = []\n    file_names = []\n    with torch.no_grad():\n        for batch_idx, (inputs, file_ids) in enumerate(testloader):\n            inputs = inputs.to(device)\n            outputs = net(inputs)\n            _, predicted = outputs.max(1)\n            predictions.extend(predicted.cpu().numpy())  # Store the predicted labels\n            file_names.extend(file_ids)  # Keep track of image file names\n\n    return file_names, predictions\n\n# Run inference\ntest_file_names, test_predictions = inference()\n\n# Convert integer predictions to class labels\ntest_predictions_labels = [CIFAR10_CLASSES[pred] for pred in test_predictions]\n\n# Create a CSV file with 'id' and 'label'\nsubmission_df = pd.DataFrame({\n    \"id\": [name.split('.')[0] for name in test_file_names],  # Extract id from file name\n    \"label\": test_predictions_labels  # Use the class labels instead of integers\n})\n\n# Save the predictions to a CSV file\noutput_file = '/kaggle/working/submission_updated.csv'\nsubmission_df.to_csv(output_file, index=False)\nprint(f\"Predictions saved to {output_file}\")\n","metadata":{"execution":{"iopub.status.busy":"2024-10-03T19:09:36.193610Z","iopub.execute_input":"2024-10-03T19:09:36.194031Z","iopub.status.idle":"2024-10-03T19:13:20.499250Z","shell.execute_reply.started":"2024-10-03T19:09:36.193979Z","shell.execute_reply":"2024-10-03T19:13:20.498169Z"},"trusted":true},"execution_count":null,"outputs":[]}]}