{"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 path\nimport json\nimport collections\nimport pandas as pd\nimport numpy as np\nimport pandas as pd\nimport cv2\nfrom PIL import Image\nimport torch\nimport torch.optim as optim \nfrom torch.utils.data import DataLoader, Dataset\nimport torch.nn as nn\nfrom torchvision.utils import make_grid\nfrom torchvision import datasets, transforms, models\nfrom torch.utils import data as torch_data\nfrom torch.utils.data.sampler import SubsetRandomSampler\nfrom tqdm import tqdm\n\nimport matplotlib.pyplot as plt\n\nimport sklearn # For LabelEncoder and Metrics\nfrom sklearn import preprocessing # For the 🏷 Label Encoder","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","execution":{"iopub.status.busy":"2021-09-17T10:55:08.072755Z","iopub.execute_input":"2021-09-17T10:55:08.073564Z","iopub.status.idle":"2021-09-17T10:55:10.361837Z","shell.execute_reply.started":"2021-09-17T10:55:08.073461Z","shell.execute_reply":"2021-09-17T10:55:10.361011Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Data Loading","metadata":{}},{"cell_type":"code","source":"PATH = '../input/herbarium-2021-fgvc8'\nTRAIN_PATH = os.path.join(PATH, \"train/\")\nTRAIN_METADATA_PATH = os.path.join(TRAIN_PATH, \"metadata.json\")\nTEST_PATH = os.path.join(PATH, \"test/\")\nTEST_METADATA_PATH = os.path.join(TEST_PATH, \"metadata.json\")","metadata":{"execution":{"iopub.status.busy":"2021-09-17T10:55:13.495678Z","iopub.execute_input":"2021-09-17T10:55:13.495995Z","iopub.status.idle":"2021-09-17T10:55:13.501003Z","shell.execute_reply.started":"2021-09-17T10:55:13.495963Z","shell.execute_reply":"2021-09-17T10:55:13.500065Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"with open(TRAIN_METADATA_PATH) as json_file:\n    metadata = json.load(json_file)\n    \nmetadata.keys()","metadata":{"execution":{"iopub.status.busy":"2021-09-17T10:55:36.070633Z","iopub.execute_input":"2021-09-17T10:55:36.071079Z","iopub.status.idle":"2021-09-17T10:55:42.836124Z","shell.execute_reply.started":"2021-09-17T10:55:36.071047Z","shell.execute_reply":"2021-09-17T10:55:42.835573Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print(metadata[\"annotations\"][0])\nprint(metadata[\"images\"][0])\nprint(metadata[\"categories\"][0])\nprint(metadata[\"licenses\"][0])\nprint(metadata[\"institutions\"][0])","metadata":{"execution":{"iopub.status.busy":"2021-09-15T09:40:17.319737Z","iopub.execute_input":"2021-09-15T09:40:17.320268Z","iopub.status.idle":"2021-09-15T09:40:17.330292Z","shell.execute_reply.started":"2021-09-15T09:40:17.32021Z","shell.execute_reply":"2021-09-15T09:40:17.328406Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"\nclass Dataframe_Data():\n    def __init__(self, datafile):\n        with open(datafile) as json_file:\n            self.metadata = json.load(json_file)\n            \n    def create_dataframe(self):\n        ids = []\n        categories = []\n        paths = []\n        \n        for annotation, image in zip(metadata[\"annotations\"], metadata[\"images\"]):\n            assert annotation[\"image_id\"] == image[\"id\"]\n            ids.append(image[\"id\"])\n            categories.append(annotation[\"category_id\"])\n            paths.append(image[\"file_name\"])\n            \n        self.df = pd.DataFrame({\"id\": ids, \"category\": categories, \"paths\": paths})\n","metadata":{"execution":{"iopub.status.busy":"2021-09-17T10:55:16.426538Z","iopub.execute_input":"2021-09-17T10:55:16.427163Z","iopub.status.idle":"2021-09-17T10:55:16.433109Z","shell.execute_reply.started":"2021-09-17T10:55:16.427127Z","shell.execute_reply":"2021-09-17T10:55:16.432411Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"\nImage_Paths_Obj = Dataframe_Data(TRAIN_METADATA_PATH)\nImage_Paths_Obj.create_dataframe()\nImage_Paths_Obj.df\n","metadata":{"execution":{"iopub.status.busy":"2021-09-17T10:55:51.481832Z","iopub.execute_input":"2021-09-17T10:55:51.482257Z","iopub.status.idle":"2021-09-17T10:56:01.328392Z","shell.execute_reply.started":"2021-09-17T10:55:51.482229Z","shell.execute_reply":"2021-09-17T10:56:01.327616Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"n_class = len(Image_Paths_Obj.df.groupby('category'))\nn_class","metadata":{"execution":{"iopub.status.busy":"2021-09-15T13:49:30.527998Z","iopub.execute_input":"2021-09-15T13:49:30.528261Z","iopub.status.idle":"2021-09-15T13:49:34.363159Z","shell.execute_reply.started":"2021-09-15T13:49:30.528234Z","shell.execute_reply":"2021-09-15T13:49:34.3625Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"\nclass custom_dataset(Dataset):\n    def __init__(self, df, root_dir, transforms = None):\n        self.df = df\n        self.root_dir = root_dir\n        self.transforms = transforms\n        \n    def __len__(self):\n        return len(self.df)\n    \n    def __getitem__(self, index):\n        img = os.path.join(self.root_dir, self.df.iloc[index, 2:])\n        image = Image.open(img)\n        y = self.df.iloc[idx, 1]\n        sample = {'image': image, 'y': y}\n        \n        if self.transform:\n            sample = self.transforms(sample)\n            \n        return sample\n        \n","metadata":{"execution":{"iopub.status.busy":"2021-09-15T10:38:11.646334Z","iopub.execute_input":"2021-09-15T10:38:11.646694Z","iopub.status.idle":"2021-09-15T10:38:11.659496Z","shell.execute_reply.started":"2021-09-15T10:38:11.64665Z","shell.execute_reply":"2021-09-15T10:38:11.657422Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def get_transforms():\n    return transforms.Compose([\n        transforms.RandomRotation(10),      # rotate +/- 10 degrees\n        transforms.RandomHorizontalFlip(),  # reverse 50% of images\n        transforms.Resize(224),             # resize shortest side to 224 pixels\n        transforms.CenterCrop(224),         # crop longest side to 224 pixels at center\n        transforms.ToTensor(),\n        transforms.Normalize([0.485, 0.456, 0.406],\n                             [0.229, 0.224, 0.225])\n    ])","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"tr_df = Image_Paths_Obj.df\ntmp_path = tr_df[\"path\"].tolist()\ntmp_category = tr_df[\"category\"].tolist()\nBATCH = 10\ntrain_data_retriever = custom_dataset(\n    tmp_path,\n    tmp_category,\n    transforms=get_transforms(),\n)","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"Base_model = models.resnet34(pretrained = True)\nfor param in Base_model.parameters():\n    param.requires_grad = False\n\ntorch.manual_seed(42)\nBase_model.fc = nn.Linear(512, n_class, bias=True)","metadata":{"execution":{"iopub.status.busy":"2021-09-15T13:51:44.977363Z","iopub.execute_input":"2021-09-15T13:51:44.977631Z","iopub.status.idle":"2021-09-15T13:51:49.75191Z","shell.execute_reply.started":"2021-09-15T13:51:44.977602Z","shell.execute_reply":"2021-09-15T13:51:49.751135Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"device = torch.device(\"cuda:0\" if torch.cuda.is_available() else \"cpu\")\n\nmodel = Base_model.to(device)","metadata":{"execution":{"iopub.status.busy":"2021-09-15T13:51:51.136323Z","iopub.execute_input":"2021-09-15T13:51:51.136597Z","iopub.status.idle":"2021-09-15T13:51:56.381431Z","shell.execute_reply.started":"2021-09-15T13:51:51.136568Z","shell.execute_reply":"2021-09-15T13:51:56.380562Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# DataLoader","metadata":{}},{"cell_type":"code","source":"# percentage of training set to use as validation\nvalid_size = 0.2\n#we obtain training indices that will be used for validation\nnum_train = len(train_data_retriever)\nindices = list(range(num_train))\nnp.random.shuffle(indices)\nsplit = int(np.floor(valid_size * num_train))\ntrain_idx, valid_idx = indices[split:], indices[:split]\n# define samplers for obtaining training and validation batches\ntrain_sampler = SubsetRandomSampler(train_idx)\nvalid_sampler = SubsetRandomSampler(valid_idx)\n\n\ntrain_loader = torch.utils.data.DataLoader(train_data_retriever, batch_size =16 , sampler = train_sampler)\nvalid_loader = torch.utils.data.DataLoader(train_data_retriever, batch_size =16, sampler = valid_sampler)\n\n","metadata":{"execution":{"iopub.status.busy":"2021-09-15T13:51:59.000462Z","iopub.execute_input":"2021-09-15T13:51:59.000733Z","iopub.status.idle":"2021-09-15T13:51:59.52813Z","shell.execute_reply.started":"2021-09-15T13:51:59.000705Z","shell.execute_reply":"2021-09-15T13:51:59.527409Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Loss and optimizer","metadata":{}},{"cell_type":"code","source":"criterion = nn.CrossEntropyLoss()\noptimizer = optim.Adam(model.parameters(), lr = 0.01)","metadata":{"execution":{"iopub.status.busy":"2021-09-15T13:52:02.61058Z","iopub.execute_input":"2021-09-15T13:52:02.610995Z","iopub.status.idle":"2021-09-15T13:52:02.619513Z","shell.execute_reply.started":"2021-09-15T13:52:02.610962Z","shell.execute_reply":"2021-09-15T13:52:02.618765Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Define Scheduler","metadata":{}},{"cell_type":"code","source":"step_size = 4*len(train_loader)\nscheduler = torch.optim.lr_scheduler.CosineAnnealingLR(optimizer, step_size)","metadata":{"execution":{"iopub.status.busy":"2021-09-15T13:52:04.344427Z","iopub.execute_input":"2021-09-15T13:52:04.345014Z","iopub.status.idle":"2021-09-15T13:52:04.349499Z","shell.execute_reply.started":"2021-09-15T13:52:04.344975Z","shell.execute_reply":"2021-09-15T13:52:04.348454Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Train Network","metadata":{}},{"cell_type":"code","source":"num_epochs = 100\nfor epoch in range(1, num_epochs):\n    tr_loss = 0.0\n    model = model.train()\n    for batch_idx, (data, target) in enumerate(train_loader):\n        data = data.to(device)\n        target = target.to(device)\n        \n        # forward\n        scores = model(data)\n        loss = criterion(scores, target)\n        \n         # Update parameters\n        optimizer.zero_grad()\n        loss.backward()\n        optimizer.step()\n        tr_loss += loss.detach().item()\n    print('Epoch: %d | Loss: %.4f'%(epoch, tr_loss / batch_idx))\n\n# Process is complete.\nprint('Training process has finished. Saving trained model.')\n# Saving the model\nsave_path = f'model-fold-{fold}.pth'\ntorch.save(model.state_dict(), save_path)\n        \n                 \n    \n    \n    ","metadata":{"execution":{"iopub.status.busy":"2021-09-15T14:17:47.01608Z","iopub.execute_input":"2021-09-15T14:17:47.016333Z","iopub.status.idle":"2021-09-15T14:26:47.465839Z","shell.execute_reply.started":"2021-09-15T14:17:47.0163Z","shell.execute_reply":"2021-09-15T14:26:47.46402Z"},"trusted":true},"execution_count":null,"outputs":[]}]}