{"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"}],"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","execution":{"iopub.status.busy":"2024-10-18T11:33:14.337567Z","iopub.execute_input":"2024-10-18T11:33:14.338219Z","iopub.status.idle":"2024-10-18T11:33:14.760481Z","shell.execute_reply.started":"2024-10-18T11:33:14.338179Z","shell.execute_reply":"2024-10-18T11:33:14.759575Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# For PyTorch with CUDA 11.7\n!pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu117\n","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import torch\nprint(torch.cuda.is_available())  # This should return True if CUDA is available\n","metadata":{"execution":{"iopub.status.busy":"2024-10-18T09:22:34.105429Z","iopub.execute_input":"2024-10-18T09:22:34.105861Z","iopub.status.idle":"2024-10-18T09:22:37.041885Z","shell.execute_reply.started":"2024-10-18T09:22:34.105824Z","shell.execute_reply":"2024-10-18T09:22:37.040724Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"!pip install py7zr","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import torch\nimport torch.nn as nn\nimport torch.optim as optim\nimport torch.nn.functional as F\nfrom torch.optim.lr_scheduler import CosineAnnealingLR, LambdaLR\nfrom torch.utils.data import DataLoader, Dataset\nfrom torchvision import datasets, transforms\nfrom torchvision.transforms import RandomErasing\nfrom tqdm import tqdm\nimport math\nimport os\nimport pandas as pd\nfrom PIL import Image\nimport py7zr\n\n# 1. Print all the files in the input directory to verify paths\nfor dirname, _, filenames in os.walk('/kaggle/input'):\n    for filename in filenames:\n        print(os.path.join(dirname, filename))","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import py7zr\nimport os\n\n# Extract train and test images\nwith py7zr.SevenZipFile('/kaggle/input/cifar-10/train.7z', mode='r') as z:\n    z.extractall(path='/kaggle/working/train_images')\n    \nwith py7zr.SevenZipFile('/kaggle/input/cifar-10/test.7z', mode='r') as z:\n    z.extractall(path='/kaggle/working/test_images')","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# import py7zr\n# import os\n\n# # Extract train and test images\n# with py7zr.SevenZipFile('/kaggle/input/cifar-10/train.7z', mode='r') as z:\n#     z.extractall(path='/kaggle/working/train_images')\n    \n# with py7zr.SevenZipFile('/kaggle/input/cifar-10/test.7z', mode='r') as z:\n#     z.extractall(path='/kaggle/working/test_images')# Load the train labels\ntrain_labels_df = pd.read_csv('/kaggle/input/cifar-10/trainLabels.csv')\n\n# Map image filenames with labels\ntrain_filenames = [os.path.join('/kaggle/working/train_images/train', f\"{i}.png\") for i in train_labels_df['id']]\ntrain_labels = train_labels_df['label'].values\n\n# CIFAR-10 classes (convert labels from string to index)\nclasses = ('airplane', 'automobile', 'bird', 'cat', 'deer', 'dog', 'frog', 'horse', 'ship', 'truck')\nlabel_to_index = {label: idx for idx, label in enumerate(classes)}\ntrain_labels = [label_to_index[label] for label in train_labels]\n\n# Data Augmentation with CutOut (RandomErasing) for training data\ntrain_transform = transforms.Compose([\n    transforms.RandomHorizontalFlip(),\n    transforms.RandomCrop(32, padding=4),\n    transforms.ToTensor(),\n    transforms.Normalize((0.4914, 0.4822, 0.4465), (0.2023, 0.1994, 0.2010)),\n    RandomErasing(scale=(0.02, 0.33))\n])\n\n# Define a simpler transform for test data\ntest_transform = transforms.Compose([\n    transforms.ToTensor(),\n    transforms.Normalize((0.4914, 0.4822, 0.4465), (0.2023, 0.1994, 0.2010))\n])","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Create a custom dataset class for the training data\nclass CIFAR10CustomDataset(Dataset):\n    def __init__(self, image_paths, labels, transform=None):\n        self.image_paths = image_paths\n        self.labels = labels\n        self.transform = transform\n\n    def __len__(self):\n        return len(self.image_paths)\n\n    def __getitem__(self, idx):\n        img_path = self.image_paths[idx]\n        image = Image.open(img_path)\n        label = self.labels[idx]\n\n        if self.transform:\n            image = self.transform(image)\n\n        return image, label\n\n# Create the dataset and dataloader for training data\ntrain_dataset = CIFAR10CustomDataset(train_filenames, train_labels, transform=train_transform)\ntrain_loader = DataLoader(dataset=train_dataset, batch_size=128, shuffle=True, num_workers=2)","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Define the Residual Block and ResNet Model (same as before)\nclass ResidualBlock(nn.Module):\n    def __init__(self, in_channels, out_channels, stride=1, downsample=None):\n        super(ResidualBlock, 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, padding=1, bias=False)\n        self.bn2 = nn.BatchNorm2d(out_channels)\n        self.downsample = downsample\n\n    def forward(self, x):\n        residual = x\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        if self.downsample:\n            residual = self.downsample(x)\n        out += residual\n        out = self.relu(out)\n        return out\n\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.conv = nn.Conv2d(3, 64, kernel_size=3, stride=1, padding=1, bias=False)\n        self.bn = 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.avg_pool = nn.AdaptiveAvgPool2d((1, 1))\n        self.fc = nn.Linear(512, 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:\n            downsample = nn.Sequential(\n                nn.Conv2d(self.in_channels, out_channels, kernel_size=1, stride=stride, bias=False),\n                nn.BatchNorm2d(out_channels)\n            )\n        layers = []\n        layers.append(block(self.in_channels, out_channels, stride, downsample))\n        self.in_channels = out_channels\n        for _ in range(1, blocks):\n            layers.append(block(out_channels, out_channels))\n        return nn.Sequential(*layers)\n\n    def forward(self, x):\n        x = self.conv(x)\n        x = self.bn(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.avg_pool(x)\n        x = torch.flatten(x, 1)\n        x = self.fc(x)\n        return x\n\n# Initialize model, loss function, optimizer, and learning rate scheduler\nmodel = ResNet(ResidualBlock, [2, 2, 2, 2]).cuda()\ncriterion = nn.CrossEntropyLoss()\noptimizer = optim.AdamW(model.parameters(), lr=0.001, weight_decay=1e-4)","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Cosine Annealing with Warmup\ndef warmup_cosine_lr_scheduler(optimizer, warmup_iters, max_iters):\n    def lr_lambda(current_iter):\n        if current_iter < warmup_iters:\n            return float(current_iter) / float(warmup_iters)  # Warmup phase\n        else:\n            # Cosine annealing phase\n            return 0.5 * (1 + math.cos(float(current_iter - warmup_iters) / float(max_iters - warmup_iters) * math.pi))\n    return LambdaLR(optimizer, lr_lambda)\n\n# Training and Testing Functions (same as before)\ndef train(model, train_loader, criterion, optimizer, scheduler):\n    model.train()\n    running_loss = 0.0\n    correct = 0\n    total = 0\n    for images, labels in tqdm(train_loader):\n        images, labels = images.cuda(), labels.cuda()\n        optimizer.zero_grad()\n        outputs = model(images)\n        loss = criterion(outputs, labels)\n        loss.backward()\n        optimizer.step()\n        running_loss += loss.item()\n        _, predicted = outputs.max(1)\n        total += labels.size(0)\n        correct += predicted.eq(labels).sum().item()\n    scheduler.step()\n    print(f\"Train Loss: {running_loss/len(train_loader)}, Train Accuracy: {100 * correct/total:.2f}%\")\n\ndef test(model, test_loader, criterion):\n    model.eval()\n    running_loss = 0.0\n    correct = 0\n    total = 0\n    with torch.no_grad():\n        for images, labels in tqdm(test_loader):\n            images, labels = images.cuda(), labels.cuda()\n            outputs = model(images)\n            loss = criterion(outputs, labels)\n            running_loss += loss.item()\n            _, predicted = outputs.max(1)\n            total += labels.size(0)\n            correct += predicted.eq(labels).sum().item()\n    print(f\"Test Loss: {running_loss/len(test_loader)}, Test Accuracy: {100 * correct/total:.2f}%\")\n    return 100 * correct/total\n\n# Main training loop\nmax_iters = 45\nwarmup_iters = 20  # Warmup phase epochs\nscheduler = warmup_cosine_lr_scheduler(optimizer, warmup_iters, max_iters)\n\nbest_acc = 0\n\nfor epoch in range(max_iters):\n    print(f\"Epoch {epoch+1}/{max_iters}\")\n    train(model, train_loader, criterion, optimizer, scheduler)\n    acc = test(model, train_loader, criterion)\n    if acc > best_acc:\n        best_acc = acc\n        torch.save(model.state_dict(), \"best_model.pth\")","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Test dataset setup (as before)\ntest_filenames = [os.path.join('/kaggle/working/test_images/test', f) for f in os.listdir('/kaggle/working/test_images/test')]\ntest_filenames.sort(key=lambda x: int(x.split('/')[-1].split('.')[0]))\n\nclass CIFAR10TestDataset(Dataset):\n    def __init__(self, filenames, transform):\n        self.filenames = filenames\n        self.transform = transform\n\n    def __len__(self):\n        return len(self.filenames)\n\n    def __getitem__(self, idx):\n        img = Image.open(self.filenames[idx])\n        if self.transform:\n            img = self.transform(img)\n        return img\n\ntest_dataset = CIFAR10TestDataset(test_filenames, test_transform)\ntest_loader = DataLoader(test_dataset, batch_size=128, shuffle=False, num_workers=2)\n\n# Predict on the test data (same as before)\nmodel.load_state_dict(torch.load('best_model.pth'))\nmodel = model.cuda()\n\nresult = []\nwith torch.no_grad():\n    model.eval()\n    for images in tqdm(test_loader):\n        images = images.cuda()\n        outputs = model(images)\n        preds = torch.argmax(outputs, 1)\n        preds = preds.cpu().numpy()\n        result.extend([classes[i] for i in preds])\n\n# Save the predictions to CSV\nsample = pd.read_csv('/kaggle/input/cifar-10/sampleSubmission.csv')\nsample['label'] = result\nsample.to_csv('./submissionfile.csv', index=False)\n\nprint(\"Predictions saved to submissionfile.csv\")","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import shutil\n\nshutil.rmtree('/kaggle/working/train_images')\nshutil.rmtree('/kaggle/working/test_images')\n\n# Check if the file exists and delete it\nfile_path = '/kaggle/working/best_model.pth'\nif os.path.exists(file_path):\n    os.remove(file_path)\n    print(f\"{file_path} has been deleted.\")\nelse:\n    print(f\"{file_path} does not exist.\")","metadata":{},"execution_count":null,"outputs":[]}]}