{"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":"markdown","source":"# Import Libraries","metadata":{}},{"cell_type":"code","source":"import numpy as np\nimport matplotlib.pyplot as plt\nfrom PIL import Image\nimport torchvision.datasets as dsets\nimport torchvision.transforms as transforms\nimport torch\nimport torch.nn as nn\nimport torch.nn.functional as F\nfrom sklearn.metrics import confusion_matrix, classification_report\ntorch.manual_seed(1) # Set manual seed\nfrom sklearn import preprocessing\nfrom torch.utils.data import DataLoader, Dataset, Subset\nimport torch.optim as optim\nimport torchvision\nfrom torch.utils.data import DataLoader\nfrom torch.optim.lr_scheduler import StepLR\nmps_device = torch.device(\"mps\")  #Define GPU device - We will run our model on GPU\nimport matplotlib.pyplot as plt\nimport seaborn as sns\nfrom sklearn.metrics import confusion_matrix\nfrom sklearn.metrics import ConfusionMatrixDisplay\n","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","execution":{"iopub.status.busy":"2024-10-02T11:11:19.824667Z","iopub.execute_input":"2024-10-02T11:11:19.825133Z","iopub.status.idle":"2024-10-02T11:11:25.649735Z","shell.execute_reply.started":"2024-10-02T11:11:19.825097Z","shell.execute_reply":"2024-10-02T11:11:25.648869Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Prepare the Data","metadata":{}},{"cell_type":"code","source":"IMAGE_SIZE = 32\n\nmean, std = [0.4914, 0.4822, 0.4465], [0.247, 0.243, 0.261]\n# These values are mostly used by researchers as found to very useful in fast convergence\n\n\n# https://pytorch.org/vision/stable/transforms.html\n# We can try various transformation for good generalization of model\ncomposed_train = transforms.Compose([transforms.Resize((IMAGE_SIZE, IMAGE_SIZE)), # Resize the image in a 32X32 shape\n                                     transforms.RandomRotation(20), # Randomly rotate some images by 20 degrees\n                                     transforms.RandomHorizontalFlip(0.1), # Randomly horizontal flip the images\n                                     transforms.ColorJitter(brightness = 0.1, # Randomly adjust color jitter of the images\n                                                            contrast = 0.1, \n                                                            saturation = 0.1), \n                                     transforms.RandomAdjustSharpness(sharpness_factor = 2,\n                                                                      p = 0.1), # Randomly adjust sharpness\n                                     transforms.ToTensor(),   # Converting image to tensor\n                                     transforms.Normalize(mean, std), # Normalizing with standard mean and standard deviation\n                                     transforms.RandomErasing(p=0.75,scale=(0.02, 0.1),value=1.0, inplace=False)])\n\n\ncomposed_test = transforms.Compose([transforms.Resize((IMAGE_SIZE,IMAGE_SIZE)),\n                                    transforms.ToTensor(),\n                                    transforms.Normalize(mean, std)])","metadata":{"execution":{"iopub.status.busy":"2024-10-02T02:11:04.325748Z","iopub.execute_input":"2024-10-02T02:11:04.326139Z","iopub.status.idle":"2024-10-02T02:11:04.334824Z","shell.execute_reply.started":"2024-10-02T02:11:04.326080Z","shell.execute_reply":"2024-10-02T02:11:04.333678Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Load the data","metadata":{}},{"cell_type":"code","source":"# Load the data and transform the dataset\ntrain_dataset =  dsets.CIFAR10(root='./data', train=True, download=True, transform = composed_train)\nvalidation_dataset = dsets.CIFAR10(root='./data', train=False, download=True, transform = composed_test)\n\n# Create train and validation batch for training\ntrain_loader = torch.utils.data.DataLoader(dataset=train_dataset, batch_size=100)\nvalidation_loader = torch.utils.data.DataLoader(dataset=validation_dataset, batch_size=100)","metadata":{"execution":{"iopub.status.busy":"2024-10-02T02:11:08.950073Z","iopub.execute_input":"2024-10-02T02:11:08.950894Z","iopub.status.idle":"2024-10-02T02:11:17.382177Z","shell.execute_reply.started":"2024-10-02T02:11:08.950844Z","shell.execute_reply":"2024-10-02T02:11:17.381382Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Display the data","metadata":{}},{"cell_type":"code","source":"def show_data(img):\n    try:\n        plt.imshow(img[0])\n    except Exception as e:\n        print(e)\n    print(img[0].shape, img[0].permute(1,2,0).shape)\n    plt.imshow(img[0].permute(1,2,0))\n    plt.title('y = '+ str(img[1]))\n    plt.show()\n    \n# We need to convert the images to numpy arrays as tensors are not compatible with matplotlib.\ndef im_convert(tensor):\n    #Lets\n    img = tensor.cpu().clone().detach().numpy() #\n    img = img.transpose(1, 2, 0)\n    img = img * np.array(tuple(mean)) + np.array(tuple(std))\n    img = img.clip(0, 1) # Clipping the size to print the images later\n    return img","metadata":{"execution":{"iopub.status.busy":"2024-10-02T02:11:19.111854Z","iopub.execute_input":"2024-10-02T02:11:19.112626Z","iopub.status.idle":"2024-10-02T02:11:19.119865Z","shell.execute_reply.started":"2024-10-02T02:11:19.112582Z","shell.execute_reply":"2024-10-02T02:11:19.118983Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"show_data(train_dataset[8])","metadata":{"execution":{"iopub.status.busy":"2024-10-02T02:11:23.738091Z","iopub.execute_input":"2024-10-02T02:11:23.738456Z","iopub.status.idle":"2024-10-02T02:11:24.067039Z","shell.execute_reply.started":"2024-10-02T02:11:23.738423Z","shell.execute_reply":"2024-10-02T02:11:24.066034Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Classes Visualization","metadata":{}},{"cell_type":"code","source":"# Different classes in CIFAR 10 dataset. \nclasses = ('airplane', 'automobile', 'bird','cat','deer','dog', \n           'frog','horse','ship','truck')\n\n# Define an iterable on the data\ndata_iterable = iter(train_loader) # converting our train_dataloader to iterable so that we can iter through it. \nimages, labels = next(data_iterable) #going from 1st batch of 100 images to the next batch\nfig = plt.figure(figsize=(20, 10)) \n\n# Lets plot 50 images from our train_dataset\nfor idx in np.arange(10):\n    ax = fig.add_subplot(2, 5, idx+1, xticks=[], yticks=[])\n    \n    # Note: imshow cant print tensor !\n    # Lets convert tensor image to numpy using im_convert function for imshow to print the image\n    plt.imshow(im_convert(images[idx]))\n    ax.set_title(classes[labels[idx].item()])","metadata":{"execution":{"iopub.status.busy":"2024-10-02T02:11:28.411535Z","iopub.execute_input":"2024-10-02T02:11:28.412542Z","iopub.status.idle":"2024-10-02T02:11:29.140104Z","shell.execute_reply.started":"2024-10-02T02:11:28.412489Z","shell.execute_reply":"2024-10-02T02:11:29.139155Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Build Resnet","metadata":{}},{"cell_type":"code","source":"\n# Define the basic block of ResNet\nclass BasicBlock(nn.Module):\n    expansion = 1\n\n    def __init__(self, in_channels, out_channels, stride=1, downsample=None):\n        super(BasicBlock, self).__init__()\n        self.conv1 = nn.Conv2d(in_channels, out_channels, kernel_size=3, stride=stride, padding=1, bias=False)\n        self.bn1 = nn.BatchNorm2d(out_channels)\n        self.relu = nn.ReLU(inplace=True)\n        self.conv2 = nn.Conv2d(out_channels, out_channels, kernel_size=3, stride=1, padding=1, bias=False)\n        self.bn2 = nn.BatchNorm2d(out_channels)\n        self.downsample = downsample\n\n    def forward(self, x):\n        identity = x\n        if self.downsample is not None:\n            identity = self.downsample(x)\n\n        out = self.conv1(x)\n        out = self.bn1(out)\n        out = self.relu(out)\n        out = self.conv2(out)\n        out = self.bn2(out)\n        out += identity\n        out = self.relu(out)\n        return out\n\n# Define the ResNet-34 architecture\nclass ResNet(nn.Module):\n    def __init__(self, block, layers, num_classes=10):\n        super(ResNet, 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.relu = nn.ReLU(inplace=True)\n        self.layer1 = self._make_layer(block, 64, layers[0])\n        self.layer2 = self._make_layer(block, 128, layers[1], stride=2)\n        self.layer3 = self._make_layer(block, 256, layers[2], stride=2)\n        self.layer4 = self._make_layer(block, 512, layers[3], stride=2)\n        self.avgpool = nn.AdaptiveAvgPool2d((1, 1))\n        self.fc = nn.Linear(512 * block.expansion, num_classes)\n\n    def _make_layer(self, block, out_channels, blocks, stride=1):\n        downsample = None\n        if stride != 1 or self.in_channels != out_channels * block.expansion:\n            downsample = nn.Sequential(\n                nn.Conv2d(self.in_channels, out_channels * block.expansion, kernel_size=1, stride=stride, bias=False),\n                nn.BatchNorm2d(out_channels * block.expansion)\n            )\n\n        layers = []\n        layers.append(block(self.in_channels, out_channels, stride, downsample))\n        self.in_channels = out_channels * block.expansion\n        for _ in range(1, blocks):\n            layers.append(block(self.in_channels, out_channels))\n\n        return nn.Sequential(*layers)\n\n    def forward(self, x):\n        x = self.conv1(x)\n        x = self.bn1(x)\n        x = self.relu(x)\n        x = self.layer1(x)\n        x = self.layer2(x)\n        x = self.layer3(x)\n        x = self.layer4(x)\n        x = self.avgpool(x)\n        x = torch.flatten(x, 1)\n        x = self.fc(x)\n        return x\n\n# Define ResNet-34\ndef ResNet34():\n    return ResNet(BasicBlock, [3, 4, 6, 3])\n","metadata":{"execution":{"iopub.status.busy":"2024-10-02T11:11:31.529924Z","iopub.execute_input":"2024-10-02T11:11:31.530442Z","iopub.status.idle":"2024-10-02T11:11:31.549083Z","shell.execute_reply.started":"2024-10-02T11:11:31.530403Z","shell.execute_reply":"2024-10-02T11:11:31.548104Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Data Augmentation","metadata":{}},{"cell_type":"code","source":"# Step 3: Load CIFAR-10 Dataset\ntransform = transforms.Compose([\n    transforms.RandomHorizontalFlip(),\n    transforms.RandomCrop(32, padding=4),\n    transforms.RandomRotation(15),\n    transforms.ColorJitter(brightness=0.2, contrast=0.2, saturation=0.2, hue=0.1),\n    transforms.ToTensor(),\n    transforms.Normalize((0.4914, 0.4822, 0.4465), (0.2023, 0.1994, 0.2010))\n])\n\ntrainset = torchvision.datasets.CIFAR10(root='./data', train=True, download=True, transform=transform)\ntrainloader = DataLoader(trainset, batch_size=128, shuffle=True, num_workers=2)\n\ntestset = torchvision.datasets.CIFAR10(root='./data', train=False, download=True, transform=transform)\ntestloader = DataLoader(testset, batch_size=100, shuffle=False, num_workers=2)\n\n# Step 4: Training the Model\ndevice = torch.device('cuda' if torch.cuda.is_available() else 'cpu')\nmodel = ResNet34().to(device)\n\ncriterion = nn.CrossEntropyLoss()\n\n  # Lower the learning rate\noptimizer = optim.SGD(model.parameters(), lr=0.01, momentum=0.9, weight_decay=5e-4)\n\nscheduler = torch.optim.lr_scheduler.StepLR(optimizer, step_size=20, gamma=0.1)\n","metadata":{"execution":{"iopub.status.busy":"2024-10-02T11:11:37.223335Z","iopub.execute_input":"2024-10-02T11:11:37.224186Z","iopub.status.idle":"2024-10-02T11:11:44.300684Z","shell.execute_reply.started":"2024-10-02T11:11:37.224148Z","shell.execute_reply":"2024-10-02T11:11:44.299797Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Training","metadata":{}},{"cell_type":"code","source":"# Step 5: Train the Model\ndef train(model, trainloader, criterion, optimizer, epochs=10):\n    model.train()\n    for epoch in range(epochs):\n        running_loss = 0.0\n        for i, (inputs, labels) in enumerate(trainloader):\n            inputs, labels = inputs.to(device), labels.to(device)\n            \n            # Zero the gradients\n            optimizer.zero_grad()\n            \n            # Forward pass\n            outputs = model(inputs)\n            loss = criterion(outputs, labels)\n            \n            # Backward pass and optimization\n            loss.backward()\n            optimizer.step()\n            \n            running_loss += loss.item()\n            if i % 100 == 99:  # Print every 100 mini-batches\n                print(f'Epoch [{epoch+1}/{epochs}], Step [{i+1}/{len(trainloader)}], Loss: {running_loss / 100:.4f}')\n                running_loss = 0.0\n        scheduler.step()","metadata":{"execution":{"iopub.status.busy":"2024-10-02T11:11:46.574708Z","iopub.execute_input":"2024-10-02T11:11:46.575125Z","iopub.status.idle":"2024-10-02T11:11:46.583569Z","shell.execute_reply.started":"2024-10-02T11:11:46.575086Z","shell.execute_reply":"2024-10-02T11:11:46.582339Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Evaluation","metadata":{}},{"cell_type":"code","source":"# Step 6: Evaluate the Model\ndef test(model, testloader):\n    model.eval()\n    correct = 0\n    total = 0\n    all_preds = []\n    all_labels = []\n    with torch.no_grad():\n        for inputs, labels in testloader:\n            inputs, labels = inputs.to(device), labels.to(device)\n            outputs = model(inputs)\n            _, predicted = torch.max(outputs, 1)\n            total += labels.size(0)\n            correct += (predicted == labels).sum().item()\n            all_preds.extend(predicted.cpu().numpy())\n            all_labels.extend(labels.cpu().numpy())\n    \n    accuracy = 100 * correct / total\n    print(f'Accuracy: {accuracy:.2f}%')\n    \n    return all_preds, all_labels\n    \n    print(f'Accuracy: {100 * correct / total:.2f}%')","metadata":{"execution":{"iopub.status.busy":"2024-10-02T11:11:50.471260Z","iopub.execute_input":"2024-10-02T11:11:50.471691Z","iopub.status.idle":"2024-10-02T11:11:50.479564Z","shell.execute_reply.started":"2024-10-02T11:11:50.471655Z","shell.execute_reply":"2024-10-02T11:11:50.478470Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Start Training","metadata":{}},{"cell_type":"code","source":"# Training\ntrain(model, trainloader, criterion, optimizer, epochs=10) ","metadata":{"execution":{"iopub.status.busy":"2024-10-02T11:11:54.449007Z","iopub.execute_input":"2024-10-02T11:11:54.449430Z","iopub.status.idle":"2024-10-02T12:06:35.644853Z","shell.execute_reply.started":"2024-10-02T11:11:54.449390Z","shell.execute_reply":"2024-10-02T12:06:35.643607Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Start Evaluation ","metadata":{}},{"cell_type":"code","source":"test(model, testloader)","metadata":{"execution":{"iopub.status.busy":"2024-10-02T12:06:42.286695Z","iopub.execute_input":"2024-10-02T12:06:42.287129Z","iopub.status.idle":"2024-10-02T12:06:48.803444Z","shell.execute_reply.started":"2024-10-02T12:06:42.287091Z","shell.execute_reply":"2024-10-02T12:06:48.802394Z"},"collapsed":true,"jupyter":{"outputs_hidden":true},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Save model","metadata":{}},{"cell_type":"code","source":"torch.save(model.state_dict(), '/kaggle/working/resnet34_cifar10_90%_test4.pth')","metadata":{"execution":{"iopub.status.busy":"2024-10-02T12:07:07.739284Z","iopub.execute_input":"2024-10-02T12:07:07.739685Z","iopub.status.idle":"2024-10-02T12:07:07.951685Z","shell.execute_reply.started":"2024-10-02T12:07:07.739647Z","shell.execute_reply":"2024-10-02T12:07:07.950611Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Load and Evaluate the Model","metadata":{}},{"cell_type":"code","source":"# Create the model architecture (same as the one used for training)\nmodel = ResNet34().to(device)\n\n# Load the saved model weights\nmodel.load_state_dict(torch.load('/kaggle/working/resnet34_cifar10_90%_test4.pth'))\n\n# Ensure the model is in evaluation mode (not training)\nmodel.eval()\n\n# Now run the test function\ntest(model, testloader)","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Confusion Matrix","metadata":{}},{"cell_type":"code","source":"def test_with_confusion_matrix(model, testloader):\n    model.eval()\n    correct = 0\n    total = 0\n    all_preds = []\n    all_labels = []\n\n    with torch.no_grad():\n        for inputs, labels in testloader:\n            inputs, labels = inputs.to(device), labels.to(device)\n            outputs = model(inputs)\n            _, predicted = torch.max(outputs, 1)\n            total += labels.size(0)\n            correct += (predicted == labels).sum().item()\n            \n            all_preds.extend(predicted.cpu().numpy())\n            all_labels.extend(labels.cpu().numpy())\n    \n    accuracy = 100 * correct / total\n    print(f'Accuracy: {accuracy:.2f}%')\n    \n    return all_preds, all_labels\n","metadata":{"execution":{"iopub.status.busy":"2024-10-02T12:07:17.145171Z","iopub.execute_input":"2024-10-02T12:07:17.145550Z","iopub.status.idle":"2024-10-02T12:07:17.154410Z","shell.execute_reply.started":"2024-10-02T12:07:17.145515Z","shell.execute_reply":"2024-10-02T12:07:17.153363Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def plot_confusion_matrix(all_preds, all_labels):\n    # Create confusion matrix\n    cm = confusion_matrix(all_labels, all_preds)\n    \n    # Plot confusion matrix using seaborn\n    plt.figure(figsize=(10,8))\n    sns.heatmap(cm, annot=True, fmt='d', cmap='Blues', xticklabels=range(10), yticklabels=range(10))\n    plt.title('Confusion Matrix')\n    plt.xlabel('Predicted Labels')\n    plt.ylabel('True Labels')\n    plt.show()\n\n# Run the test function and get predictions and labels\nall_preds, all_labels = test_with_confusion_matrix(model, testloader)\n\n# Plot the confusion matrix\nplot_confusion_matrix(all_preds, all_labels)\n","metadata":{"execution":{"iopub.status.busy":"2024-10-02T12:07:20.298582Z","iopub.execute_input":"2024-10-02T12:07:20.299505Z","iopub.status.idle":"2024-10-02T12:07:28.735927Z","shell.execute_reply.started":"2024-10-02T12:07:20.299463Z","shell.execute_reply":"2024-10-02T12:07:28.734718Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Prediction Vs True Labels","metadata":{}},{"cell_type":"code","source":"import csv\n\n# Step 1: Modify the test function to return true and predicted labels\ndef test_with_confusion_matrix_csv(model, testloader):\n    model.eval()\n    all_preds = []\n    all_labels = []\n    \n    with torch.no_grad():\n        for inputs, labels in testloader:\n            inputs, labels = inputs.to(device), labels.to(device)\n            outputs = model(inputs)\n            _, predicted = torch.max(outputs, 1)\n            \n            # Collect predictions and true labels for confusion matrix\n            all_preds.extend(predicted.cpu().numpy())\n            all_labels.extend(labels.cpu().numpy())\n    \n    return all_preds, all_labels\n\n# Step 2: Write results to a CSV file\ndef write_results_to_csv(true_labels, predicted_labels, filename=\"predictions_vs_true_labels.csv\"):\n    with open(filename, mode='w', newline='') as file:\n        writer = csv.writer(file)\n        writer.writerow(['ID', 'Label'])  # Write header\n        for true_label, predicted_label in zip(true_labels, predicted_labels):\n            writer.writerow([true_label, predicted_label])\n\n# Step 3: Run the test and write the results to CSV\npredicted_labels, true_labels = test_with_confusion_matrix_csv(model, testloader)\nwrite_results_to_csv(true_labels, predicted_labels, filename=\"predictions_vs_true_labels.csv\")\n\nprint(f\"Results saved to 'predictions_vs_true_labels.csv'\")\n","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Prediction on Kaggle testset","metadata":{}},{"cell_type":"code","source":"# CIFAR-10 class names\nclass_names = [\n    'airplane', 'automobile', 'bird', 'cat', 'deer', \n    'dog', 'frog', 'horse', 'ship', 'truck'\n]","metadata":{"execution":{"iopub.status.busy":"2024-10-02T12:07:41.576953Z","iopub.execute_input":"2024-10-02T12:07:41.577363Z","iopub.status.idle":"2024-10-02T12:07:41.582474Z","shell.execute_reply.started":"2024-10-02T12:07:41.577325Z","shell.execute_reply":"2024-10-02T12:07:41.581383Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"pip install py7zr\n","metadata":{"execution":{"iopub.status.busy":"2024-10-02T12:07:44.108190Z","iopub.execute_input":"2024-10-02T12:07:44.109183Z","iopub.status.idle":"2024-10-02T12:08:00.197988Z","shell.execute_reply.started":"2024-10-02T12:07:44.109127Z","shell.execute_reply":"2024-10-02T12:08:00.196695Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import py7zr\nimport os\n\n# Path to the test.7z file\nseven_z_file = '/kaggle/input/cifar-10/test.7z'\n\n# Destination folder to extract\noutput_folder = '/kaggle/working/testset' \n\n# Ensure the output directory exists\nif not os.path.exists(output_folder):\n    os.makedirs(output_folder)\n\n# Extract the 7z file\nwith py7zr.SevenZipFile(seven_z_file, mode='r') as archive:\n    archive.extractall(path=output_folder)\n\nprint(f'Extracted test.7z to {output_folder}')\n","metadata":{"execution":{"iopub.status.busy":"2024-10-02T12:08:14.913973Z","iopub.execute_input":"2024-10-02T12:08:14.915189Z","iopub.status.idle":"2024-10-02T12:10:50.068659Z","shell.execute_reply.started":"2024-10-02T12:08:14.915130Z","shell.execute_reply":"2024-10-02T12:10:50.067462Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import os\nfrom PIL import Image\nimport torch\nfrom torch.utils.data import Dataset\nimport torchvision.transforms as transforms\n\n# Custom Dataset class for test data\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 = os.listdir(root_dir)\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).convert('RGB')\n\n        if self.transform:\n            image = self.transform(image)\n\n        return image, self.image_files[idx]  # Return image and the filename (can be used as ID)\n\n# Transforms for the test data\ntransform = transforms.Compose([\n    transforms.ToTensor(),\n    transforms.Normalize((0.4914, 0.4822, 0.4465), (0.2023, 0.1994, 0.2010))  # CIFAR-10 normalization\n])\n\n# Create the dataset\ntest_dataset = CIFAR10TestDataset(root_dir='/kaggle/working/testset/test', transform=transform)\n\n# Create a DataLoader for the test dataset\ntest_loader = DataLoader(test_dataset, batch_size=64, shuffle=False, num_workers=2)\n","metadata":{"execution":{"iopub.status.busy":"2024-10-02T12:11:26.996019Z","iopub.execute_input":"2024-10-02T12:11:26.996645Z","iopub.status.idle":"2024-10-02T12:11:27.176552Z","shell.execute_reply.started":"2024-10-02T12:11:26.996605Z","shell.execute_reply":"2024-10-02T12:11:27.175720Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Creating submission csv","metadata":{}},{"cell_type":"code","source":"# List to store the predictions for saving as CSV\npredictions = []\n\n# Predict and store results\nwith torch.no_grad():\n    for inputs, image_filenames in test_loader:\n        inputs = inputs.to(device)\n        \n        # Get model predictions\n        outputs = model(inputs)\n        _, predicted = torch.max(outputs, 1)\n        \n        # Store the image filename (ID) and predicted class\n        for idx in range(predicted.size(0)):\n            classname = class_names[predicted[idx].item()]  # Get the class name\n            image_id = image_filenames[idx].split('.')[0]  # Use the image filename as the ID\n            predictions.append([image_id, classname])\n","metadata":{"execution":{"iopub.status.busy":"2024-10-02T12:11:30.887149Z","iopub.execute_input":"2024-10-02T12:11:30.887569Z","iopub.status.idle":"2024-10-02T12:13:26.544402Z","shell.execute_reply.started":"2024-10-02T12:11:30.887528Z","shell.execute_reply":"2024-10-02T12:13:26.543069Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Saving the Result","metadata":{}},{"cell_type":"code","source":"import pandas as pd\n# Convert predictions to a DataFrame\ndf = pd.DataFrame(predictions, columns=['id', 'label'])\n\n# Save the DataFrame to a CSV file\ndf.to_csv('/kaggle/working/submission.csv', index=False)\nprint(f\"Results saved to 'submission.csv'\")","metadata":{"execution":{"iopub.status.busy":"2024-10-02T12:13:39.511881Z","iopub.execute_input":"2024-10-02T12:13:39.512290Z","iopub.status.idle":"2024-10-02T12:13:39.966354Z","shell.execute_reply.started":"2024-10-02T12:13:39.512255Z","shell.execute_reply":"2024-10-02T12:13:39.965232Z"},"trusted":true},"execution_count":null,"outputs":[]}]}