{"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":"# 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-02T14:59:09.069160Z","iopub.execute_input":"2024-10-02T14:59:09.069497Z","iopub.status.idle":"2024-10-02T14:59:09.458785Z","shell.execute_reply.started":"2024-10-02T14:59:09.069462Z","shell.execute_reply":"2024-10-02T14:59:09.457860Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"!pip install -q py7zr","metadata":{"execution":{"iopub.status.busy":"2024-10-02T14:58:53.359381Z","iopub.execute_input":"2024-10-02T14:58:53.360160Z","iopub.status.idle":"2024-10-02T14:59:09.067059Z","shell.execute_reply.started":"2024-10-02T14:58:53.360123Z","shell.execute_reply":"2024-10-02T14:59:09.065742Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import torch\nimport torch.nn as nn\nimport torch.optim as optim\nimport torchvision\nimport torchvision.transforms as transforms\nfrom torch.utils.data import DataLoader\nimport pandas as pd\nimport numpy as np\n\n# Define data augmentation and normalization for training and testing\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])\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\n# Load CIFAR-10 training and test sets\ntrainset = torchvision.datasets.CIFAR10(root='./data', train=True, download=True, transform=transform_train)\ntrainloader = DataLoader(trainset, batch_size=128, shuffle=True, num_workers=2)\n\ntestset = torchvision.datasets.CIFAR10(root='./data', train=False, download=True, transform=transform_test)\ntestloader = DataLoader(testset, batch_size=100, shuffle=False, num_workers=2)","metadata":{"execution":{"iopub.status.busy":"2024-10-02T14:59:09.459958Z","iopub.execute_input":"2024-10-02T14:59:09.460339Z","iopub.status.idle":"2024-10-02T14:59:21.117885Z","shell.execute_reply.started":"2024-10-02T14:59:09.460305Z","shell.execute_reply":"2024-10-02T14:59:21.117066Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import torch\nimport torch.nn as nn\nimport torch.nn.functional as F\n\n# Define the basic block for ResNet\nclass BasicBlock(nn.Module):\n    def __init__(self, in_channels, out_channels, stride=1):\n        super(BasicBlock, self).__init__()\n        self.conv1 = nn.Conv2d(in_channels, out_channels, kernel_size=3, stride=stride, padding=1)\n        self.bn1 = nn.BatchNorm2d(out_channels)\n        self.conv2 = nn.Conv2d(out_channels, out_channels, kernel_size=3, stride=1, padding=1)\n        self.bn2 = nn.BatchNorm2d(out_channels)\n        self.shortcut = nn.Sequential()\n\n        if stride != 1 or in_channels != out_channels:\n            self.shortcut = nn.Sequential(\n                nn.Conv2d(in_channels, out_channels, kernel_size=1, stride=stride),\n                nn.BatchNorm2d(out_channels)\n            )\n\n    def forward(self, x):\n        out = torch.relu(self.bn1(self.conv1(x)))\n        out = self.bn2(self.conv2(out))\n        out += self.shortcut(x)\n        out = torch.relu(out)\n        return out\n\n# Define the ResNet model\nclass ResNet(nn.Module):\n    def __init__(self, num_classes=10):\n        super(ResNet, self).__init__()\n        self.conv1 = nn.Conv2d(3, 64, kernel_size=3, stride=1, padding=1)\n        self.bn1 = nn.BatchNorm2d(64)\n        self.layer1 = self._make_layer(64, 128, stride=2)\n        self.layer2 = self._make_layer(128, 256, stride=2)\n        \n        # Using AdaptiveAvgPool2d to always output a 1x1 feature map\n        self.avg_pool = nn.AdaptiveAvgPool2d((1, 1))\n        \n        # Adjusting the fully connected layer input size\n        self.fc = nn.Linear(256, num_classes)\n\n    def _make_layer(self, in_channels, out_channels, stride):\n        layers = []\n        layers.append(BasicBlock(in_channels, out_channels, stride))\n        layers.append(BasicBlock(out_channels, out_channels))\n        return nn.Sequential(*layers)\n\n    def forward(self, x):\n        out = torch.relu(self.bn1(self.conv1(x)))\n        out = self.layer1(out)\n        out = self.layer2(out)\n        out = self.avg_pool(out)  # Use adaptive pooling to get 1x1 output\n        out = out.view(out.size(0), -1)  # Flatten the output\n        out = self.fc(out)  # Pass it through the fully connected layer\n        return out\n\n# Random weight initialization\ndef initialize_weights(model):\n    for m in model.modules():\n        if isinstance(m, nn.Conv2d) or isinstance(m, nn.Linear):\n            nn.init.kaiming_normal_(m.weight)\n        elif isinstance(m, nn.BatchNorm2d):\n            nn.init.constant_(m.weight, 1)\n            nn.init.constant_(m.bias, 0)\n\n# Instantiate the ResNet model\nnet = ResNet(num_classes=10)\ninitialize_weights(net)","metadata":{"execution":{"iopub.status.busy":"2024-10-02T14:59:21.120858Z","iopub.execute_input":"2024-10-02T14:59:21.121686Z","iopub.status.idle":"2024-10-02T14:59:21.224218Z","shell.execute_reply.started":"2024-10-02T14:59:21.121647Z","shell.execute_reply":"2024-10-02T14:59:21.223439Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Set device\ndevice = torch.device(\"cuda\" if torch.cuda.is_available() else \"cpu\")\nnet.to(device)\n\n# Define loss function and optimizer\ncriterion = nn.CrossEntropyLoss()\noptimizer = optim.Adam(net.parameters(), lr=0.001)\n\n# Training loop\ndef train_model(net, trainloader, num_epochs=25):\n    for epoch in range(num_epochs):\n        running_loss = 0.0\n        net.train()\n        for i, data in enumerate(trainloader, 0):\n            inputs, labels = data\n            inputs, labels = inputs.to(device), labels.to(device)\n            \n            # Zero the parameter gradients\n            optimizer.zero_grad()\n\n            # Forward + backward + optimize\n            outputs = net(inputs)\n            loss = criterion(outputs, labels)\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}, {i + 1}] loss: {running_loss / 100:.3f}')\n                running_loss = 0.0\n    print('Finished Training')\n\ntrain_model(net, trainloader, num_epochs=25)","metadata":{"execution":{"iopub.status.busy":"2024-10-02T14:59:21.225426Z","iopub.execute_input":"2024-10-02T14:59:21.225817Z","iopub.status.idle":"2024-10-02T15:04:45.314309Z","shell.execute_reply.started":"2024-10-02T14:59:21.225772Z","shell.execute_reply":"2024-10-02T15:04:45.313125Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Evaluate on the test set\ndef evaluate_model(net, testloader):\n    net.eval()  # Set to evaluation mode\n    correct = 0\n    total = 0\n    with torch.no_grad():\n        for data in testloader:\n            images, labels = data\n            images, labels = images.to(device), labels.to(device)\n            outputs = net(images)\n            _, predicted = torch.max(outputs.data, 1)\n            total += labels.size(0)\n            correct += (predicted == labels).sum().item()\n\n    print(f'Accuracy on the test set: {100 * correct / total:.2f}%')\n\nevaluate_model(net, testloader)","metadata":{"execution":{"iopub.status.busy":"2024-10-02T15:04:45.316194Z","iopub.execute_input":"2024-10-02T15:04:45.316648Z","iopub.status.idle":"2024-10-02T15:04:47.144861Z","shell.execute_reply.started":"2024-10-02T15:04:45.316601Z","shell.execute_reply":"2024-10-02T15:04:47.143729Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import pickle\nimport numpy as np\nimport os\n\n# Define the path to the test batch file\ntest_batch_path = './data/cifar-10-batches-py/test_batch'\n\n# Function to unpickle the CIFAR-10 batch files\ndef unpickle(file):\n    with open(file, 'rb') as fo:\n        dict = pickle.load(fo, encoding='bytes')\n    return dict\n\n# Load the test batch\ntest_batch = unpickle(test_batch_path)\n\n# Extract the images and reshape them\ntest_images = test_batch[b'data'].reshape((10000, 3, 32, 32))  # CIFAR-10 has 10,000 test images\ntest_images = np.transpose(test_images, (0, 2, 3, 1))  # Transpose to match expected format (N, H, W, C)\n","metadata":{"execution":{"iopub.status.busy":"2024-10-02T15:04:47.146323Z","iopub.execute_input":"2024-10-02T15:04:47.146689Z","iopub.status.idle":"2024-10-02T15:04:47.196899Z","shell.execute_reply.started":"2024-10-02T15:04:47.146653Z","shell.execute_reply":"2024-10-02T15:04:47.196048Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import torch\nfrom torch.utils.data import Dataset, DataLoader\nfrom torchvision import transforms\nfrom PIL import Image\n\n# Custom dataset for CIFAR-10 test images\nclass CIFAR10TestDataset(Dataset):\n    def __init__(self, images, transform=None):\n        self.images = images\n        self.transform = transform\n\n    def __len__(self):\n        return len(self.images)\n\n    def __getitem__(self, idx):\n        image = Image.fromarray(self.images[idx])  # Convert from numpy to PIL\n        if self.transform:\n            image = self.transform(image)\n        return image\n\n# Define test transforms\ntransform_test = transforms.Compose([\n    transforms.ToTensor(),\n    transforms.Normalize((0.4914, 0.4822, 0.4465), (0.2023, 0.1994, 0.2010)),\n])\n\n# Create the test dataset and loader\ncifar10_test_dataset = CIFAR10TestDataset(test_images, transform=transform_test)\ntestloader = DataLoader(cifar10_test_dataset, batch_size=100, shuffle=False, num_workers=2)","metadata":{"execution":{"iopub.status.busy":"2024-10-02T15:04:47.198045Z","iopub.execute_input":"2024-10-02T15:04:47.198357Z","iopub.status.idle":"2024-10-02T15:04:47.207315Z","shell.execute_reply.started":"2024-10-02T15:04:47.198323Z","shell.execute_reply":"2024-10-02T15:04:47.206209Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# CIFAR-10 class names\nclasses = ['airplane', 'automobile', 'bird', 'cat', 'deer', 'dog', 'frog', 'horse', 'ship', 'truck']\n\n# Generate predictions for Kaggle submission\ndef generate_kaggle_submission(net, testloader):\n    net.eval()\n    predictions = []\n    image_ids = []\n    with torch.no_grad():\n        for i, images in enumerate(testloader):\n            images = images.to(device)\n            outputs = net(images)\n            _, predicted = torch.max(outputs.data, 1)\n            predicted = predicted.cpu().numpy()\n            predicted_classes = [classes[p] for p in predicted]  # Map numeric labels to class names\n            predictions.extend(predicted_classes)\n            image_ids.extend(list(range(i * testloader.batch_size + 1, (i + 1) * testloader.batch_size + 1)))  # Adjust IDs to start from 1\n\n    # Prepare the submission DataFrame\n    submission = pd.DataFrame({'id': image_ids, 'label': predictions})\n    submission.to_csv('submission.csv', index=False)\n    print('Kaggle submission file generated: submission.csv')\n\ngenerate_kaggle_submission(net, testloader)","metadata":{"execution":{"iopub.status.busy":"2024-10-02T15:04:47.208492Z","iopub.execute_input":"2024-10-02T15:04:47.208812Z","iopub.status.idle":"2024-10-02T15:04:48.940471Z","shell.execute_reply.started":"2024-10-02T15:04:47.208780Z","shell.execute_reply":"2024-10-02T15:04:48.939337Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Check the contents of submission.csv\n!head submission.csv","metadata":{"execution":{"iopub.status.busy":"2024-10-02T15:04:48.943297Z","iopub.execute_input":"2024-10-02T15:04:48.943636Z","iopub.status.idle":"2024-10-02T15:04:49.948489Z","shell.execute_reply.started":"2024-10-02T15:04:48.943604Z","shell.execute_reply":"2024-10-02T15:04:49.947445Z"},"trusted":true},"execution_count":null,"outputs":[]}]}