{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"pygments_lexer":"ipython3","nbconvert_exporter":"python","version":"3.6.4","file_extension":".py","codemirror_mode":{"name":"ipython","version":3},"name":"python","mimetype":"text/x-python"}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"import os\nfrom os import walk\nimport numpy as np\nimport pandas as pd\nimport matplotlib.pyplot as plt\nfrom PIL import Image\nfrom sklearn.utils import shuffle\nfrom sklearn.model_selection import train_test_split\nimport torch\nfrom torch import nn\nimport torch.nn.functional as F\nfrom torch.utils.data import DataLoader, Dataset\nfrom torchvision import models, transforms\nfrom tqdm import tqdm","metadata":{"_uuid":"6b80ea23-760c-4e21-b759-3d395d6b3796","_cell_guid":"105bd75e-2845-4611-a7df-83736090026e","collapsed":false,"jupyter":{"outputs_hidden":false},"execution":{"iopub.status.busy":"2022-07-08T02:50:53.051045Z","iopub.execute_input":"2022-07-08T02:50:53.051769Z","iopub.status.idle":"2022-07-08T02:50:56.124684Z","shell.execute_reply.started":"2022-07-08T02:50:53.051731Z","shell.execute_reply":"2022-07-08T02:50:56.123628Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"HP = {\n    'epochs': 25,\n    'batch_size': 32,\n    'learning_rate': 1e-3,\n    'momentum': 0.9,\n    'test_size': 0.05,\n    'seed': 1\n}","metadata":{"_uuid":"068549fa-6ea1-4b67-93f3-87fd1c8e0bc7","_cell_guid":"cd2077fc-a2dc-4ab1-abb7-544541c9afa6","collapsed":false,"jupyter":{"outputs_hidden":false},"execution":{"iopub.status.busy":"2022-07-08T03:31:07.652457Z","iopub.execute_input":"2022-07-08T03:31:07.653446Z","iopub.status.idle":"2022-07-08T03:31:07.659273Z","shell.execute_reply.started":"2022-07-08T03:31:07.653391Z","shell.execute_reply":"2022-07-08T03:31:07.657925Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"torch.manual_seed(HP['seed'])\ndevice = 'cuda' if torch.cuda.is_available() else 'cpu'\nif device == 'cuda':\n    torch.backends.cudnn.benchmark = True\nprint(f'using {device} device')","metadata":{"_uuid":"7529e3de-8244-4aa5-b636-8f1790a75a9c","_cell_guid":"acea0027-18f1-47e0-b3ac-0c3ad0860341","collapsed":false,"jupyter":{"outputs_hidden":false},"execution":{"iopub.status.busy":"2022-07-15T03:08:55.906668Z","iopub.execute_input":"2022-07-15T03:08:55.906991Z","iopub.status.idle":"2022-07-15T03:08:55.999422Z","shell.execute_reply.started":"2022-07-15T03:08:55.906893Z","shell.execute_reply":"2022-07-15T03:08:55.997968Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"dataset_dir = '/kaggle/input/paddy-disease-classification/train_images/'\nsubmission_dir = '/kaggle/input/paddy-disease-classification/test_images/'\ndataset_file = '/kaggle/input/paddy-disease-classification/train.csv'\nsubmission_sample = '/kaggle/input/paddy-disease-classification/sample_submission.csv'\nsubmission_output = '/kaggle/working/submission.csv'\n\ndf = pd.read_csv(dataset_file)\ndf = shuffle(df, random_state=HP['seed'])\n\nprint(f'count: {len(df)} \\n')\ndf.head(5)","metadata":{"_uuid":"66e5bced-b509-4d2b-afee-8b82e1083393","_cell_guid":"6523c24e-ca22-445f-9aa2-e9b27d7d1316","collapsed":false,"jupyter":{"outputs_hidden":false},"execution":{"iopub.status.busy":"2022-07-08T03:31:10.819528Z","iopub.execute_input":"2022-07-08T03:31:10.819866Z","iopub.status.idle":"2022-07-08T03:31:10.847727Z","shell.execute_reply.started":"2022-07-08T03:31:10.819839Z","shell.execute_reply":"2022-07-08T03:31:10.846796Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df['variety'] = pd.factorize(df['variety'])[0]\ndf.describe().T","metadata":{"_uuid":"8e688b06-68ad-4a91-83d8-2f3801341354","_cell_guid":"cef17867-7863-4473-8f8b-be4bda6fbf80","execution":{"iopub.status.busy":"2022-07-08T03:31:13.416175Z","iopub.execute_input":"2022-07-08T03:31:13.416519Z","iopub.status.idle":"2022-07-08T03:31:13.443601Z","shell.execute_reply.started":"2022-07-08T03:31:13.416491Z","shell.execute_reply":"2022-07-08T03:31:13.442556Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"idx_to_label = df['label'].unique()\nlabel_to_idx = {idx: label for label, idx in enumerate(idx_to_label)}\nprint(label_to_idx)","metadata":{"_uuid":"11abbace-7f24-4047-aaab-b88457021e36","_cell_guid":"7d88fbbb-a9d2-46df-9b70-b9c19fad76b5","collapsed":false,"jupyter":{"outputs_hidden":false},"execution":{"iopub.status.busy":"2022-07-08T03:31:14.567776Z","iopub.execute_input":"2022-07-08T03:31:14.568456Z","iopub.status.idle":"2022-07-08T03:31:14.575383Z","shell.execute_reply.started":"2022-07-08T03:31:14.568419Z","shell.execute_reply":"2022-07-08T03:31:14.57436Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_df, test_df = train_test_split(df, test_size=HP['test_size'])\nprint(f'train len: {len(train_df)}, test len: {len(test_df)}')","metadata":{"_uuid":"da04383e-da68-41cc-a6d5-3c8a7baf4ced","_cell_guid":"32376e24-2953-4878-be10-8277a410eae7","collapsed":false,"jupyter":{"outputs_hidden":false},"execution":{"iopub.status.busy":"2022-07-08T03:31:16.178452Z","iopub.execute_input":"2022-07-08T03:31:16.17895Z","iopub.status.idle":"2022-07-08T03:31:16.1899Z","shell.execute_reply.started":"2022-07-08T03:31:16.178905Z","shell.execute_reply":"2022-07-08T03:31:16.188312Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_df['label'].value_counts()","metadata":{"execution":{"iopub.status.busy":"2022-07-08T03:31:17.471108Z","iopub.execute_input":"2022-07-08T03:31:17.471467Z","iopub.status.idle":"2022-07-08T03:31:17.480733Z","shell.execute_reply.started":"2022-07-08T03:31:17.471429Z","shell.execute_reply":"2022-07-08T03:31:17.479731Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_transform = transforms.Compose([\n    transforms.RandomHorizontalFlip(),\n    transforms.RandomVerticalFlip(),\n    transforms.RandomChoice([\n        transforms.Pad(padding=10),\n        transforms.CenterCrop(480),\n        transforms.RandomRotation(20),\n        transforms.CenterCrop((576,432)),\n        transforms.ColorJitter(\n            brightness=0.1,\n            contrast=0.1, \n            saturation=0.1,\n            hue=0.1\n        )\n    ]),\n    transforms.Resize((224,224)),\n    transforms.ToTensor(),\n    transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225])\n])\n\ntest_transform = transforms.Compose([\n    transforms.Resize((224,224)),\n    transforms.ToTensor(),\n    transforms.Normalize([0.485, 0.456, 0.406], [0.229, 0.224, 0.225])\n])\n\nclass PaddyDataset(Dataset):\n    def __init__(self, dataset_dir, df, label_to_idx, transforms):\n        self.df = df\n        self.label_to_idx = label_to_idx\n        self.transforms = transforms\n        self.df['path'] = dataset_dir + '/' + self.df.label + '/' + self.df.image_id\n        # 0: image_id, 1: label, 2: variety, 3: age, 4: path\n        self.df = self.df.values.tolist()\n\n    def __len__(self):\n        return len(self.df)\n\n    def __getitem__(self, idx):\n        row = self.df[idx]\n        image = Image.open(row[4])\n        image = self.transforms(image)\n        idx = self.label_to_idx[row[1]]\n        return image, idx\n\n\ntrain_dataset = PaddyDataset(dataset_dir, train_df, label_to_idx, train_transform)\ntest_dataset = PaddyDataset(dataset_dir, test_df, label_to_idx, test_transform)\ntrain_dataloader = DataLoader(train_dataset, batch_size=HP['batch_size'], shuffle=True, pin_memory=True)\ntest_dataloader = DataLoader(test_dataset, batch_size=HP['batch_size'], shuffle=True, pin_memory=True)","metadata":{"_uuid":"2e430d2f-360d-44f8-b498-e1e51f3f82c9","_cell_guid":"be09c486-e082-4c0f-8022-1e839932e9d0","collapsed":false,"jupyter":{"outputs_hidden":false},"execution":{"iopub.status.busy":"2022-07-08T03:31:19.020844Z","iopub.execute_input":"2022-07-08T03:31:19.02156Z","iopub.status.idle":"2022-07-08T03:31:19.051971Z","shell.execute_reply.started":"2022-07-08T03:31:19.021523Z","shell.execute_reply":"2022-07-08T03:31:19.050868Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model = models.resnet34(pretrained=True)\nmodel.fc = nn.Sequential(\n    nn.Dropout(0.1),\n    nn.Linear(model.fc.in_features, len(label_to_idx))\n)\nmodel = model.to(device)\n\ncriterion = torch.nn.CrossEntropyLoss()\noptimizer = torch.optim.SGD(model.parameters(), lr=HP['learning_rate'], momentum=HP['momentum'])","metadata":{"_uuid":"da7e71ee-c24d-4a2e-9abe-5a70c2454904","_cell_guid":"6d03ae27-a665-41d3-8952-7b6de626239a","collapsed":false,"jupyter":{"outputs_hidden":false},"execution":{"iopub.status.busy":"2022-07-08T03:31:28.881933Z","iopub.execute_input":"2022-07-08T03:31:28.882474Z","iopub.status.idle":"2022-07-08T03:31:29.358925Z","shell.execute_reply.started":"2022-07-08T03:31:28.882432Z","shell.execute_reply":"2022-07-08T03:31:29.357925Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def train(model, criterion, optimizer, train_dataloader, test_dataloader):\n\n    total_train_loss = 0\n    total_test_loss = 0\n    \n    model.train()\n    with tqdm(train_dataloader, unit='batch', leave=False) as pbar:\n        pbar.set_description(f'training')\n        for images, idxs in pbar:\n            images = images.to(device, non_blocking=True)\n            idxs = idxs.to(device, non_blocking=True)\n            output = model(images)\n\n            loss = criterion(output, idxs)\n            total_train_loss += loss.item()\n\n            loss.backward()\n            optimizer.step()\n            optimizer.zero_grad(set_to_none=True)\n\n    model.eval()\n    with tqdm(test_dataloader, unit='batch', leave=False) as pbar:\n        pbar.set_description(f'testing')\n        for images, idxs in pbar:\n            images = images.to(device, non_blocking=True)\n            idxs = idxs.to(device, non_blocking=True)\n\n            output = model(images)\n            loss = criterion(output, idxs)\n            total_test_loss += loss.item()\n\n    train_acc = total_train_loss / len(train_dataset)\n    test_acc = total_test_loss / len(test_dataset)\n    print(f'Train loss: {train_acc:.4f} Test loss: {test_acc:.4f} ')","metadata":{"_uuid":"5494d587-d236-423c-b45d-e5b6703c9850","_cell_guid":"00d1ae9b-1098-46ae-aecb-f56ebc8552d9","collapsed":false,"jupyter":{"outputs_hidden":false},"execution":{"iopub.status.busy":"2022-07-08T03:31:30.834309Z","iopub.execute_input":"2022-07-08T03:31:30.834666Z","iopub.status.idle":"2022-07-08T03:31:30.844907Z","shell.execute_reply.started":"2022-07-08T03:31:30.834637Z","shell.execute_reply":"2022-07-08T03:31:30.843841Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"%%time\nfor i in range(HP['epochs']):\n    print(f\"Epoch {i+1}/{HP['epochs']}\")\n    train(model, criterion, optimizer, train_dataloader, test_dataloader)","metadata":{"execution":{"iopub.status.busy":"2022-07-08T03:31:34.051114Z","iopub.execute_input":"2022-07-08T03:31:34.052003Z","iopub.status.idle":"2022-07-08T04:04:03.615695Z","shell.execute_reply.started":"2022-07-08T03:31:34.051967Z","shell.execute_reply":"2022-07-08T04:04:03.614731Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"%%time\nmodel.eval()\nimage_ids, labels = [], []\nfor (dirpath, dirname, filenames) in walk(submission_dir):\n    for filename in filenames:\n        image = Image.open(dirpath+filename)\n        image = test_transform(image)\n        image = image.unsqueeze(0).to(device)\n        image_ids.append(filename)\n        labels.append(idx_to_label[model(image).argmax().item()])","metadata":{"_uuid":"1aad70ca-91e7-4dca-b085-2c9323309453","_cell_guid":"a9399787-1f8f-47fc-82ee-dd6076bc55f5","collapsed":false,"jupyter":{"outputs_hidden":false},"execution":{"iopub.status.busy":"2022-07-08T04:06:37.709837Z","iopub.execute_input":"2022-07-08T04:06:37.710544Z","iopub.status.idle":"2022-07-08T04:07:34.932839Z","shell.execute_reply.started":"2022-07-08T04:06:37.71051Z","shell.execute_reply":"2022-07-08T04:07:34.931696Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"submission = pd.DataFrame({\n    'image_id': image_ids,\n    'label': labels,\n})\n# submission['label'].value_counts()","metadata":{"execution":{"iopub.status.busy":"2022-07-08T04:07:39.590445Z","iopub.execute_input":"2022-07-08T04:07:39.590865Z","iopub.status.idle":"2022-07-08T04:07:39.597159Z","shell.execute_reply.started":"2022-07-08T04:07:39.590835Z","shell.execute_reply":"2022-07-08T04:07:39.596115Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"submission.to_csv(submission_output, index=False, header=True)","metadata":{"execution":{"iopub.status.busy":"2022-07-08T04:07:43.49264Z","iopub.execute_input":"2022-07-08T04:07:43.493011Z","iopub.status.idle":"2022-07-08T04:07:43.507817Z","shell.execute_reply.started":"2022-07-08T04:07:43.492981Z","shell.execute_reply":"2022-07-08T04:07:43.506927Z"},"trusted":true},"execution_count":null,"outputs":[]}]}