{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.10.13","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":30699,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":true}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"markdown","source":"## 1. Import libraries","metadata":{"_uuid":"15c97614-46aa-4093-b737-cb0928a7c3dc","_cell_guid":"1d21cb44-045d-4c61-bd8e-2bb7e27d9c6f","trusted":true}},{"cell_type":"code","source":"import numpy as np\nimport pandas as pd\nfrom tqdm import tqdm\nfrom PIL import Image\n\nimport torch\nimport torch.nn as nn\nfrom torch.utils.data import Dataset, DataLoader\nimport torchvision.datasets as datasets\nfrom torchvision.models import resnet50\nfrom torchvision import transforms","metadata":{"_uuid":"ce587be6-1cc5-4e94-a147-668cfd4c5db5","_cell_guid":"9a3d5c34-88eb-4791-aa5a-2f92fd18968f","collapsed":false,"jupyter":{"outputs_hidden":false},"execution":{"iopub.status.busy":"2024-08-29T04:07:27.856575Z","iopub.execute_input":"2024-08-29T04:07:27.856944Z","iopub.status.idle":"2024-08-29T04:07:35.492114Z","shell.execute_reply.started":"2024-08-29T04:07:27.856913Z","shell.execute_reply":"2024-08-29T04:07:35.491296Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## 2. Set hyperparameters","metadata":{"_uuid":"bb758196-90e5-45d6-a790-11c9ea7a4879","_cell_guid":"7f58db5f-ad17-4a55-a722-208eeb3acc13","trusted":true}},{"cell_type":"code","source":"batch_size = 64\nlearning_rate = 1e-4\nnum_epochs = 10\nimg_size = 128","metadata":{"_uuid":"71d9efe5-2d54-43af-bbba-d85235060845","_cell_guid":"fc1f446c-4b93-403b-b5f3-9878c0a038ed","collapsed":false,"jupyter":{"outputs_hidden":false},"execution":{"iopub.status.busy":"2024-08-29T04:07:35.493809Z","iopub.execute_input":"2024-08-29T04:07:35.494319Z","iopub.status.idle":"2024-08-29T04:07:35.499077Z","shell.execute_reply.started":"2024-08-29T04:07:35.494285Z","shell.execute_reply":"2024-08-29T04:07:35.498230Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Set seed\nimport os\nimport random\nimport numpy as np\nimport torch\n\nrandom_seed = 42\nrandom.seed(random_seed)\nnp.random.seed(random_seed)\nos.environ[\"PYTHONHASHSEED\"] = str(random_seed)\ntorch.manual_seed(random_seed)\ntorch.cuda.manual_seed(random_seed)\ntorch.cuda.manual_seed_all(random_seed)\ntorch.backends.cudnn.deterministic = True\ntorch.backends.cudnn.benchmark = False\ntorch.use_deterministic_algorithms(False)","metadata":{"_uuid":"56d29896-dca6-4b73-b6f5-ef167c993631","_cell_guid":"ab6bca90-61b3-481a-aaed-ffe41cb211f6","collapsed":false,"jupyter":{"outputs_hidden":false},"execution":{"iopub.status.busy":"2024-08-29T04:07:35.500337Z","iopub.execute_input":"2024-08-29T04:07:35.500920Z","iopub.status.idle":"2024-08-29T04:07:35.528761Z","shell.execute_reply.started":"2024-08-29T04:07:35.500889Z","shell.execute_reply":"2024-08-29T04:07:35.527865Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## 3. Data preprocessing","metadata":{"_uuid":"f28a1799-6619-4876-81e3-21e563f49b35","_cell_guid":"330d3b15-8083-4b57-a90a-3e28e54b4450","trusted":true}},{"cell_type":"code","source":"# Read csv\nsample = pd.read_csv('/kaggle/input/cifar-10/sampleSubmission.csv')","metadata":{"_uuid":"fe527227-3168-4b40-9d47-1c3d5a71f6d2","_cell_guid":"0a068502-1de6-4e57-b432-cdc70f486368","collapsed":false,"jupyter":{"outputs_hidden":false},"execution":{"iopub.status.busy":"2024-08-29T04:07:35.531062Z","iopub.execute_input":"2024-08-29T04:07:35.531441Z","iopub.status.idle":"2024-08-29T04:07:35.664264Z","shell.execute_reply.started":"2024-08-29T04:07:35.531415Z","shell.execute_reply":"2024-08-29T04:07:35.663458Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Check the form of data\nsample.head(10)","metadata":{"_uuid":"c2e86e10-fe97-4dd0-abb6-46bb0c6a123e","_cell_guid":"aab2bff7-8a1c-4a4b-8638-a3f22df1c6f9","collapsed":false,"jupyter":{"outputs_hidden":false},"execution":{"iopub.status.busy":"2024-08-29T04:07:35.665435Z","iopub.execute_input":"2024-08-29T04:07:35.665809Z","iopub.status.idle":"2024-08-29T04:07:35.684469Z","shell.execute_reply.started":"2024-08-29T04:07:35.665778Z","shell.execute_reply":"2024-08-29T04:07:35.683573Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Define transforms\ntrain_transforms = transforms.Compose(\n    [\n        transforms.Resize(img_size),\n        transforms.RandomRotation(20),\n        transforms.RandomHorizontalFlip(0.5),\n        transforms.ToTensor(),\n        transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]),\n    ]\n)\ntest_transforms = transforms.Compose(\n    [\n        transforms.Resize(img_size),\n        transforms.ToTensor(),\n        transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225]),\n    ]\n)","metadata":{"_uuid":"d344be57-ccf2-424c-9fa4-ed790826770c","_cell_guid":"b516324b-8a29-4763-a8c1-24e65766f167","collapsed":false,"jupyter":{"outputs_hidden":false},"execution":{"iopub.status.busy":"2024-08-29T04:07:35.685444Z","iopub.execute_input":"2024-08-29T04:07:35.685725Z","iopub.status.idle":"2024-08-29T04:07:35.692357Z","shell.execute_reply.started":"2024-08-29T04:07:35.685700Z","shell.execute_reply":"2024-08-29T04:07:35.691471Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Load data\ntrain_dataset = datasets.CIFAR10(root='./data', train=True, transform=train_transforms, download=True)\nvalid_dataset = datasets.CIFAR10(root='./data', train=False, transform=test_transforms, download=True)\n\ntrain_loader = DataLoader(train_dataset, batch_size=batch_size, shuffle=False)\nvalid_loader = DataLoader(valid_dataset, batch_size=batch_size, shuffle=False)","metadata":{"_uuid":"bc34383f-180c-4373-b388-9e75148159dc","_cell_guid":"f96943a2-4414-4bf2-a89c-d563faeb1eda","collapsed":false,"jupyter":{"outputs_hidden":false},"execution":{"iopub.status.busy":"2024-08-29T04:07:35.693611Z","iopub.execute_input":"2024-08-29T04:07:35.694343Z","iopub.status.idle":"2024-08-29T04:07:37.390457Z","shell.execute_reply.started":"2024-08-29T04:07:35.694308Z","shell.execute_reply":"2024-08-29T04:07:37.389594Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## 4. Define the model","metadata":{"_uuid":"060a2926-39ff-40df-89ec-91abc77de93f","_cell_guid":"58615b02-a21a-4866-b56b-5e9d92a56f04","trusted":true}},{"cell_type":"code","source":"# Get pretrained ResNet50 model and customize for CIFAR10 classification\nclass ResNet50(nn.Module):\n    def __init__(self, num_classes):\n        super(ResNet50, self).__init__()\n        self.model = resnet50(weights=\"DEFAULT\")\n        self.in_features = self.model.fc.in_features\n        self.model.fc = nn.Linear(self.in_features, num_classes)\n        \n    def forward(self, x):\n        x = self.model(x)\n        return x","metadata":{"_uuid":"248605b5-9be4-43d5-be69-632d22299c69","_cell_guid":"c216c7ad-319b-4dc3-bcf6-42f72fafcb17","collapsed":false,"jupyter":{"outputs_hidden":false},"execution":{"iopub.status.busy":"2024-08-29T04:07:37.391757Z","iopub.execute_input":"2024-08-29T04:07:37.392203Z","iopub.status.idle":"2024-08-29T04:07:37.398431Z","shell.execute_reply.started":"2024-08-29T04:07:37.392167Z","shell.execute_reply":"2024-08-29T04:07:37.397560Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Use cuda if you have gpu\ndevice = 'cuda' if torch.cuda.is_available() else 'cpu'\n\n# Define model, optimizer, loss function\nmodel = ResNet50(num_classes=10).to(device)\noptimizer = torch.optim.Adam(model.parameters(), lr=learning_rate)\ncriterion = nn.CrossEntropyLoss().to(device)\nscheduler = torch.optim.lr_scheduler.StepLR(optimizer, step_size=5, gamma=0.5)","metadata":{"_uuid":"e516522d-1434-4593-82ac-7d78e0cb9b97","_cell_guid":"188a935b-7dd2-452a-8c10-7d520a770b37","collapsed":false,"jupyter":{"outputs_hidden":false},"execution":{"iopub.status.busy":"2024-08-29T04:08:13.345037Z","iopub.execute_input":"2024-08-29T04:08:13.345443Z","iopub.status.idle":"2024-08-29T04:08:14.877076Z","shell.execute_reply.started":"2024-08-29T04:08:13.345408Z","shell.execute_reply":"2024-08-29T04:08:14.875866Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import torchinfo\ntorchinfo.summary(model, input_size = (1,3,224,2224), verbose = 1, col_names=[\"input_size\", \"output_size\", \"kernel_size\", \"num_params\", \"params_percent\", \"trainable\"]);\n","metadata":{"_kg_hide-input":false,"_kg_hide-output":true,"execution":{"iopub.status.busy":"2024-08-29T04:13:06.927962Z","iopub.execute_input":"2024-08-29T04:13:06.928785Z","iopub.status.idle":"2024-08-29T04:13:06.995460Z","shell.execute_reply.started":"2024-08-29T04:13:06.928747Z","shell.execute_reply":"2024-08-29T04:13:06.994493Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## 5. Train and validation","metadata":{"_uuid":"1bfc3931-552f-4d53-9c65-a161984f8ec3","_cell_guid":"c28e1c65-894d-4067-ab9d-7b1c500e4d0a","trusted":true}},{"cell_type":"code","source":"# Train\nbest_epoch = 0\nbest_acc = 0.0\nfor epoch in range(1, num_epochs + 1):\n    print(\"-\" * 40)\n    print(f\"Epoch: {epoch}\")\n    epoch_loss = 0.0\n    epoch_corrects = 0\n    model.train()\n    for batch_in, batch_out in tqdm(train_loader):\n        batch_in = batch_in.to(device)\n        batch_out = batch_out.to(device)\n\n        y_pred = model(batch_in)\n        preds = torch.argmax(y_pred, 1)\n        loss = criterion(y_pred, batch_out)\n\n        optimizer.zero_grad()\n        loss.backward()\n        optimizer.step()\n\n        epoch_loss += loss.item() * batch_in.size(0)\n        epoch_corrects += torch.sum(preds == batch_out.data)\n\n    epoch_loss = epoch_loss / len(train_loader.dataset)\n    epoch_acc = epoch_corrects / len(train_loader.dataset)\n\n    print(f\"Train loss: {epoch_loss:.4f}\")\n    print(f\"Train acc: {epoch_acc:.4f}\")\n\n# Validation\n    with torch.no_grad():\n        epoch_loss = 0.0\n        epoch_corrects = 0\n        model.eval()\n        for batch_in, batch_out in tqdm(valid_loader):\n            batch_in = batch_in.to(device)\n            batch_out = batch_out.to(device)\n\n            y_pred = model(batch_in)\n            preds = torch.argmax(y_pred, 1)\n            loss = criterion(y_pred, batch_out)\n\n            epoch_loss += loss.item() * batch_in.size(0)\n            epoch_corrects += torch.sum(preds == batch_out.data)\n\n    epoch_loss = epoch_loss / len(valid_loader.dataset)\n    epoch_acc = epoch_corrects / len(valid_loader.dataset)\n    \n    scheduler.step()\n\n    print(f\"Valid loss: {epoch_loss:.4f}\")\n    print(f\"Valid acc: {epoch_acc:.4f}\")\n\n    if epoch_acc >= best_acc:\n        best_epoch = epoch\n        best_acc = epoch_acc\n        torch.save(model, \"./model.pt\")\n\n    print(f\"Best epoch: {best_epoch}\")\n    print(f\"Best acc: {best_acc:.4f}\")\n    print(\"-\" * 40)","metadata":{"_uuid":"914de009-d4fe-4303-930b-d2a63352ba17","_cell_guid":"74e855b5-f902-4c12-b0c6-eb85301d9832","collapsed":false,"jupyter":{"outputs_hidden":false},"execution":{"iopub.status.busy":"2024-08-28T10:00:17.847275Z","iopub.execute_input":"2024-08-28T10:00:17.847676Z","iopub.status.idle":"2024-08-28T10:12:59.979109Z","shell.execute_reply.started":"2024-08-28T10:00:17.847638Z","shell.execute_reply":"2024-08-28T10:12:59.977685Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## 6. Result","metadata":{"_uuid":"307b67e5-6ec8-47b6-9d4d-faff4c381144","_cell_guid":"9fb0783c-d37b-4082-8379-9d29d4060798","trusted":true}},{"cell_type":"code","source":"# Decompression data\n!pip install py7zr\n\nimport py7zr\n\nwith py7zr.SevenZipFile('/kaggle/input/cifar-10/test.7z', mode='r') as z:\n    z.extractall('/kaggle/working/')","metadata":{"_uuid":"3b451ab8-c727-4af9-898b-2d1663258269","_cell_guid":"0a7c8741-c635-43c6-82f4-864500cf0501","collapsed":false,"jupyter":{"outputs_hidden":false},"execution":{"iopub.status.busy":"2024-08-28T10:13:04.735327Z","iopub.execute_input":"2024-08-28T10:13:04.735676Z","iopub.status.idle":"2024-08-28T10:16:00.715228Z","shell.execute_reply.started":"2024-08-28T10:13:04.735649Z","shell.execute_reply":"2024-08-28T10:16:00.714141Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Make a list of data filenames for dataset\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":{"_uuid":"763c75cf-4a1f-46bd-88a0-5567cd65daf6","_cell_guid":"afa5bdbd-458d-4f41-aaf9-df661a51e274","collapsed":false,"jupyter":{"outputs_hidden":false},"execution":{"iopub.status.busy":"2024-08-28T10:16:00.716943Z","iopub.execute_input":"2024-08-28T10:16:00.717224Z","iopub.status.idle":"2024-08-28T10:16:01.732406Z","shell.execute_reply.started":"2024-08-28T10:16:00.717198Z","shell.execute_reply":"2024-08-28T10:16:01.731419Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Define dataset\nclass CIFAR10(Dataset):\n    def __init__(self, filenames, transforms):\n        self.filenames = filenames\n        self.transforms = transforms\n        \n    def __len__(self):\n        return len(self.filenames)\n    \n    def __getitem__(self, idx):\n        img = Image.open(self.filenames[idx])\n        transformed_img = self.transforms(img)\n        return transformed_img","metadata":{"_uuid":"6c0a5b4a-0e06-4fcf-b58f-ef69de13aeb6","_cell_guid":"03be0468-34df-48ad-ac33-e69844e67abf","collapsed":false,"jupyter":{"outputs_hidden":false},"execution":{"iopub.status.busy":"2024-08-28T10:16:01.733777Z","iopub.execute_input":"2024-08-28T10:16:01.734070Z","iopub.status.idle":"2024-08-28T10:16:01.739943Z","shell.execute_reply.started":"2024-08-28T10:16:01.734045Z","shell.execute_reply":"2024-08-28T10:16:01.739205Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Load dataset\ntest_dataset = CIFAR10(test_filenames, test_transforms)\n\ntest_loader = DataLoader(test_dataset, batch_size=batch_size, shuffle=False)","metadata":{"_uuid":"96c8a7df-2373-4c04-b010-38bbe5bcfc42","_cell_guid":"e5226fbf-12d3-4cec-9446-18918e2f97d6","collapsed":false,"jupyter":{"outputs_hidden":false},"execution":{"iopub.status.busy":"2024-08-28T10:16:01.741986Z","iopub.execute_input":"2024-08-28T10:16:01.742263Z","iopub.status.idle":"2024-08-28T10:16:01.750772Z","shell.execute_reply.started":"2024-08-28T10:16:01.742241Z","shell.execute_reply":"2024-08-28T10:16:01.749818Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# For one-hot encoding\nclasses = ('airplane', \n           'automobile', \n           'bird',\n           'cat',\n           'deer',\n           'dog', \n           'frog', \n           'horse', \n           'ship',\n           'truck')","metadata":{"_uuid":"f46534b6-022f-40e1-87ff-ba4077a9efc9","_cell_guid":"73897953-4322-4d3a-91ee-b152c1ed044e","collapsed":false,"jupyter":{"outputs_hidden":false},"execution":{"iopub.status.busy":"2024-08-28T10:16:01.751925Z","iopub.execute_input":"2024-08-28T10:16:01.752238Z","iopub.status.idle":"2024-08-28T10:16:01.762917Z","shell.execute_reply.started":"2024-08-28T10:16:01.752214Z","shell.execute_reply":"2024-08-28T10:16:01.762024Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Load the best model\nmodel = torch.load('./model.pt').to(device)\n\n# Get the result\nresult = []\n\nwith torch.no_grad():\n    model.eval()\n    for batch_in in tqdm(test_loader):\n        batch_in = batch_in.to(device)\n        \n        y_pred = model(batch_in)\n        preds = torch.argmax(y_pred, 1)\n        preds = preds.cpu().numpy()\n        result.extend([classes[i] for i in preds])\n\nsample['label'] = result\nsample.to_csv('./predict.csv', index=False)","metadata":{"_uuid":"de0cc814-5546-4664-9185-f4536fc9252a","_cell_guid":"57993979-5b42-4ba0-9f7d-7b2026d7867c","collapsed":false,"jupyter":{"outputs_hidden":false},"execution":{"iopub.status.busy":"2024-08-28T10:16:01.764038Z","iopub.execute_input":"2024-08-28T10:16:01.764311Z","iopub.status.idle":"2024-08-28T10:23:02.707196Z","shell.execute_reply.started":"2024-08-28T10:16:01.764287Z","shell.execute_reply":"2024-08-28T10:23:02.706457Z"},"trusted":true},"execution_count":null,"outputs":[]}]}