{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.10.12","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":30822,"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,"execution":{"iopub.status.busy":"2025-01-05T13:41:57.100201Z","iopub.execute_input":"2025-01-05T13:41:57.100524Z","iopub.status.idle":"2025-01-05T13:41:57.106700Z","shell.execute_reply.started":"2025-01-05T13:41:57.100497Z","shell.execute_reply":"2025-01-05T13:41:57.106006Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"%pip install py7zr","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-01-05T13:41:59.197017Z","iopub.execute_input":"2025-01-05T13:41:59.197299Z","iopub.status.idle":"2025-01-05T13:42:05.298874Z","shell.execute_reply.started":"2025-01-05T13:41:59.197279Z","shell.execute_reply":"2025-01-05T13:42:05.297795Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import py7zr\nimport os\n\ndef unzip_file(zip_filepath, extract_to='.'):\n    if not os.path.isfile(zip_filepath):\n        print(f\"Error: {zip_filepath} does not exist.\")\n        return\n    \n    if not os.path.exists(extract_to):\n        os.makedirs(extract_to)\n    \n    try:\n        with py7zr.SevenZipFile(zip_filepath, 'r') as zip_ref:\n            # extract .7z files to extract_to dir\n            zip_ref.extractall(extract_to)\n            print(f\"All files have been extracted to {extract_to}.\")\n    except Exception as e:\n        print(f\"An error occurred while extracting the file {zip_filepath}: {e}\")\n\n\nextract_to = '/kaggle/working'\nunzip_file('/kaggle/input/cifar-10/test.7z', extract_to)\nunzip_file('/kaggle/input/cifar-10/train.7z', extract_to)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-01-05T13:42:05.300072Z","iopub.execute_input":"2025-01-05T13:42:05.300316Z","iopub.status.idle":"2025-01-05T13:44:34.720190Z","shell.execute_reply.started":"2025-01-05T13:42:05.300296Z","shell.execute_reply":"2025-01-05T13:44:34.719241Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import os\nimport pandas as pd\nfrom PIL import Image\nfrom torchvision import transforms\nfrom torch.utils.data import Dataset, DataLoader\n\n\n\"\"\"\n2. Data warapping, loading.\n\"\"\"\n\n\nLABEL_CLASS_LIST = [\"airplane\", \"automobile\", \"bird\", \"cat\", \"deer\", \"dog\", \"frog\", \"horse\", \"ship\", \"truck\"]\n\n\nclass CustomImageDataset(Dataset):\n    def __init__(self, img_dir, label_file=None, transform=None, target_transform=None, train=True):\n        \"\"\"\n        img_dir (string): Directory with all the images.  \n        label_file (string): Path to the csv file with labels.      \n        transform (callable, optional): Optional transform to be applied on a sample.  \n        target_transform (callable, optional): Optional transform to be applied on a target.\n        train (bool): default train dataset, if False, test dataset.\n        \"\"\"\n        super().__init__()\n        self.img_dir = img_dir\n        self.label_file = label_file\n        self.train = train\n        if self.train:\n            self.img_labels = pd.read_csv(self.label_file)\n        self.transform = transform\n        self.target_transform = target_transform\n\n    def __len__(self):\n        return len(self.img_labels) if self.train else len(os.listdir(self.img_dir))\n\n    def __getitem__(self, index):\n        target = LABEL_CLASS_LIST.index(self.img_labels.iloc[index, 1]) if self.train else None\n        img_path = os.path.join(self.img_dir, str(index + 1) + '.png')\n        img = Image.open(img_path)   # ImageFile.ImageFile object (PIL Image)\n        if self.transform:\n            img = self.transform(img)\n        if target is not None and self.target_transform:\n            target = self.target_transform(target)\n        return (img, target) if self.train else img\n    \n\ntrain_img_dir = \"/kaggle/working/train\"\ntest_img_dir = \"/kaggle/working/test\"\nlabel_file = \"/kaggle/input/cifar-10/trainLabels.csv\"\n\n\ntrain_transform = transforms.Compose([\n    transforms.Resize(40),\n    transforms.RandomResizedCrop(32, scale=(0.64, 1.0), ratio=(1.0, 1.0)),\n    transforms.RandomHorizontalFlip(),\n    transforms.ToTensor(),\n    transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225])    # learn from trained ImageNet Dataset\n])\n\ntest_transform = transforms.Compose([\n    transforms.ToTensor(),\n    transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225])\n])\n\n\ntrain_dataset = CustomImageDataset(train_img_dir, label_file=label_file, transform=train_transform)\ntest_dataset = CustomImageDataset(test_img_dir, transform=test_transform, train=False)\n\ntrain_batch_size = 1024\ntest_batch_size = 10240\ntrain_dataloader = DataLoader(train_dataset, batch_size=train_batch_size, shuffle=True)\ntest_dataloader = DataLoader(test_dataset, batch_size=test_batch_size)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-01-05T14:00:14.590060Z","iopub.execute_input":"2025-01-05T14:00:14.590395Z","iopub.status.idle":"2025-01-05T14:00:14.612461Z","shell.execute_reply.started":"2025-01-05T14:00:14.590371Z","shell.execute_reply":"2025-01-05T14:00:14.611784Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"len(train_dataset), len(test_dataset)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-01-05T13:48:32.887013Z","iopub.execute_input":"2025-01-05T13:48:32.887299Z","iopub.status.idle":"2025-01-05T13:48:33.027469Z","shell.execute_reply.started":"2025-01-05T13:48:32.887279Z","shell.execute_reply":"2025-01-05T13:48:33.026745Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"img, target = train_dataset[0]","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-01-05T13:48:34.821143Z","iopub.execute_input":"2025-01-05T13:48:34.821435Z","iopub.status.idle":"2025-01-05T13:48:34.913413Z","shell.execute_reply.started":"2025-01-05T13:48:34.821412Z","shell.execute_reply":"2025-01-05T13:48:34.912509Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"img, img.shape, target","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-01-05T13:48:37.377769Z","iopub.execute_input":"2025-01-05T13:48:37.378062Z","iopub.status.idle":"2025-01-05T13:48:37.410291Z","shell.execute_reply.started":"2025-01-05T13:48:37.378041Z","shell.execute_reply":"2025-01-05T13:48:37.409594Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"target = test_dataset[0]","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-01-05T13:48:39.982151Z","iopub.execute_input":"2025-01-05T13:48:39.982453Z","iopub.status.idle":"2025-01-05T13:48:39.987501Z","shell.execute_reply.started":"2025-01-05T13:48:39.982429Z","shell.execute_reply":"2025-01-05T13:48:39.986796Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"target, target.shape","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-01-05T13:48:41.641141Z","iopub.execute_input":"2025-01-05T13:48:41.641439Z","iopub.status.idle":"2025-01-05T13:48:41.648849Z","shell.execute_reply.started":"2025-01-05T13:48:41.641416Z","shell.execute_reply":"2025-01-05T13:48:41.648045Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"len(train_dataloader), len(test_dataloader)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-01-05T13:48:44.182977Z","iopub.execute_input":"2025-01-05T13:48:44.183265Z","iopub.status.idle":"2025-01-05T13:48:44.322290Z","shell.execute_reply.started":"2025-01-05T13:48:44.183245Z","shell.execute_reply":"2025-01-05T13:48:44.321596Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import torch\ntorch.cuda.is_available()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-01-05T13:48:46.381943Z","iopub.execute_input":"2025-01-05T13:48:46.382222Z","iopub.status.idle":"2025-01-05T13:48:46.387250Z","shell.execute_reply.started":"2025-01-05T13:48:46.382203Z","shell.execute_reply":"2025-01-05T13:48:46.386564Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"\"\"\"\nmodel building\n\"\"\"\nimport torch\nfrom torch import nn\n\n\nclass MyModel(nn.Module):\n    def __init__(self, in_channels, out_features):\n        super().__init__()\n        self.layer = nn.Sequential(\n            nn.Conv2d(in_channels=in_channels, out_channels=128, kernel_size=3, padding=1),\n            nn.BatchNorm2d(128),\n            nn.ReLU(inplace=True),\n            nn.MaxPool2d(kernel_size=2, stride=2),\n\n            nn.Conv2d(in_channels=128, out_channels=64, kernel_size=3),\n            nn.BatchNorm2d(64),\n            nn.ReLU(inplace=True),\n            nn.MaxPool2d(kernel_size=2, stride=2, padding=1),\n\n            nn.Conv2d(in_channels=64, out_channels=16, kernel_size=3, padding=1),\n            nn.BatchNorm2d(16),\n            nn.ReLU(inplace=True),\n            nn.MaxPool2d(kernel_size=2, stride=2),\n\n            nn.Flatten(),  # (N, 16 * 4 * 4)\n            nn.Linear(256, 128),\n            nn.ReLU(inplace=True),\n            nn.Linear(128, 64),\n            nn.ReLU(inplace=True),\n            nn.Linear(64, 32),\n            nn.ReLU(inplace=True),\n            nn.Linear(32, out_features)    # Last layer not need to activate, instead keep original logits beacuse loss function use CrossEntropyLoss.\n        )\n\n    def forward(self, x):\n        return self.layer(x)\n\n\n# Check if CUDA is available and set the device accordingly.\ndevice = torch.device(\"cuda\" if torch.cuda.is_available() else \"cpu\")\nprint(f\"Using device: {device}\")\n\n\nin_channels = train_dataset[0][0].shape[0]    \nout_features = len(LABEL_CLASS_LIST)\n# Move model to GPU\nmodel = MyModel(in_channels, out_features).to(device)\n\nlr = 0.002\nweight_decay = 0.001\n# Ensure that loss function and optimizer are defined after moving the model to the device\noptimizer = torch.optim.Adam(model.parameters(), lr=lr, weight_decay=weight_decay)\ncriterion = nn.CrossEntropyLoss()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-01-05T14:00:19.660796Z","iopub.execute_input":"2025-01-05T14:00:19.661076Z","iopub.status.idle":"2025-01-05T14:00:19.676861Z","shell.execute_reply.started":"2025-01-05T14:00:19.661057Z","shell.execute_reply":"2025-01-05T14:00:19.676026Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"\"\"\"\n4. training\n\"\"\"\n\n\ndef train(epochs):\n    batch_num = len(train_dataloader)   # (len(train_dataset) + train_batch_size - 1) // train_batch_size\n    model.train()\n    for epoch in range(epochs):\n        total_mean_loss = 0\n        total_correct_class_count = 0\n        for input_datas, labels in train_dataloader:\n            # Move inputs and labels to the device\n            input_datas, labels = input_datas.to(device), labels.to(device)\n            optimizer.zero_grad()\n            output_datas = model(input_datas)            \n            loss = criterion(output_datas, labels)\n            loss.backward()\n            optimizer.step()\n            total_mean_loss += loss.item()\n            total_correct_class_count += torch.sum(torch.argmax(output_datas, dim=1) == labels).item()\n        accurancy = round((total_correct_class_count / len(train_dataset)) * 100, 2)\n        print(f\"epoch={epoch}, accurancy is: {accurancy} %\")\n        if epoch % 2 == 0:            \n            print(f\"epoch={epoch}, mean loss is: {total_mean_loss / batch_num}\")\n\nepochs = 33\ntrain(epochs)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-01-05T14:00:23.027767Z","iopub.execute_input":"2025-01-05T14:00:23.028061Z","iopub.status.idle":"2025-01-05T14:23:41.293572Z","shell.execute_reply.started":"2025-01-05T14:00:23.028041Z","shell.execute_reply":"2025-01-05T14:23:41.292686Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"sample_data = pd.read_csv(\"/kaggle/input/cifar-10/sampleSubmission.csv\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-01-05T14:26:16.678833Z","iopub.execute_input":"2025-01-05T14:26:16.679130Z","iopub.status.idle":"2025-01-05T14:26:16.781313Z","shell.execute_reply.started":"2025-01-05T14:26:16.679107Z","shell.execute_reply":"2025-01-05T14:26:16.780581Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"sample_data.head()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-01-05T14:26:23.743801Z","iopub.execute_input":"2025-01-05T14:26:23.744073Z","iopub.status.idle":"2025-01-05T14:26:23.758372Z","shell.execute_reply.started":"2025-01-05T14:26:23.744053Z","shell.execute_reply":"2025-01-05T14:26:23.757480Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"from tqdm import tqdm\n\n\npre_labels = []\nwith torch.no_grad():\n    model.eval()\n    for input_datas in tqdm(test_dataloader):\n        input_datas = input_datas.to(device)\n        output_datas = model(input_datas)\n        pre_labels.extend(torch.argmax(output_datas, dim=1).cpu().numpy())","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-01-05T14:36:24.148272Z","iopub.execute_input":"2025-01-05T14:36:24.148562Z","iopub.status.idle":"2025-01-05T14:38:45.671277Z","shell.execute_reply.started":"2025-01-05T14:36:24.148540Z","shell.execute_reply":"2025-01-05T14:38:45.670398Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"len(pre_labels)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-01-05T14:39:13.093050Z","iopub.execute_input":"2025-01-05T14:39:13.093331Z","iopub.status.idle":"2025-01-05T14:39:13.098150Z","shell.execute_reply.started":"2025-01-05T14:39:13.093310Z","shell.execute_reply":"2025-01-05T14:39:13.097455Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"pre_labels[:10]","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-01-05T14:39:31.094646Z","iopub.execute_input":"2025-01-05T14:39:31.094981Z","iopub.status.idle":"2025-01-05T14:39:31.100586Z","shell.execute_reply.started":"2025-01-05T14:39:31.094956Z","shell.execute_reply":"2025-01-05T14:39:31.099789Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"pre_labels = [LABEL_CLASS_LIST[label] for label in pre_labels]","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-01-05T14:40:50.746187Z","iopub.execute_input":"2025-01-05T14:40:50.746563Z","iopub.status.idle":"2025-01-05T14:40:50.772547Z","shell.execute_reply.started":"2025-01-05T14:40:50.746539Z","shell.execute_reply":"2025-01-05T14:40:50.771810Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"pre_labels[:10]","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-01-05T14:40:56.485909Z","iopub.execute_input":"2025-01-05T14:40:56.486192Z","iopub.status.idle":"2025-01-05T14:40:56.491812Z","shell.execute_reply.started":"2025-01-05T14:40:56.486172Z","shell.execute_reply":"2025-01-05T14:40:56.490626Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"sample_data['label'] = np.array(pre_labels)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-01-05T14:43:02.100516Z","iopub.execute_input":"2025-01-05T14:43:02.100846Z","iopub.status.idle":"2025-01-05T14:43:02.169522Z","shell.execute_reply.started":"2025-01-05T14:43:02.100806Z","shell.execute_reply":"2025-01-05T14:43:02.168889Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"sample_data.head()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-01-05T14:43:10.748574Z","iopub.execute_input":"2025-01-05T14:43:10.748927Z","iopub.status.idle":"2025-01-05T14:43:10.756882Z","shell.execute_reply.started":"2025-01-05T14:43:10.748898Z","shell.execute_reply":"2025-01-05T14:43:10.756131Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"sample_data.to_csv('/kaggle/working/submission.csv', index=False)\nprint(\"Submission file created successfully!\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-01-05T14:44:10.848920Z","iopub.execute_input":"2025-01-05T14:44:10.849239Z","iopub.status.idle":"2025-01-05T14:44:11.056942Z","shell.execute_reply.started":"2025-01-05T14:44:10.849215Z","shell.execute_reply":"2025-01-05T14:44:11.056206Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import shutil\n\nshutil.rmtree('/kaggle/working/train')\nshutil.rmtree('/kaggle/working/test')","metadata":{"trusted":true},"outputs":[],"execution_count":null}]}