{"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 pandas as pd\nimport numpy as np\nimport matplotlib.pyplot as plt \nimport os\n\nimport torch\nimport torch.nn as nn\nfrom torch.utils.data import Dataset, DataLoader\nimport torch.optim as optim\n\nimport torchvision\n\nfrom sklearn.model_selection import train_test_split\nfrom sklearn.metrics import accuracy_score\n\nimport cv2\nfrom PIL import Image\n\nimport albumentations","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","execution":{"iopub.status.busy":"2023-03-10T10:54:26.498177Z","iopub.execute_input":"2023-03-10T10:54:26.498905Z","iopub.status.idle":"2023-03-10T10:54:29.221962Z","shell.execute_reply.started":"2023-03-10T10:54:26.498865Z","shell.execute_reply":"2023-03-10T10:54:29.220914Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# load data\nbase_path = '/kaggle/input/cassava-leaf-disease-classification'\ntrain_data = 'train.csv'\ntrain_imges_path = 'train_images'","metadata":{"execution":{"iopub.status.busy":"2023-03-10T10:54:29.223971Z","iopub.execute_input":"2023-03-10T10:54:29.22508Z","iopub.status.idle":"2023-03-10T10:54:29.230157Z","shell.execute_reply.started":"2023-03-10T10:54:29.225037Z","shell.execute_reply":"2023-03-10T10:54:29.229048Z"}},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"dfx = pd.read_csv(os.path.join(base_path,train_data))\ndfx.head()","metadata":{"execution":{"iopub.status.busy":"2023-03-10T10:54:29.231492Z","iopub.execute_input":"2023-03-10T10:54:29.232516Z","iopub.status.idle":"2023-03-10T10:54:29.277702Z","shell.execute_reply.started":"2023-03-10T10:54:29.232475Z","shell.execute_reply":"2023-03-10T10:54:29.276667Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"dfx.label.value_counts()","metadata":{"execution":{"iopub.status.busy":"2023-03-10T10:54:29.280005Z","iopub.execute_input":"2023-03-10T10:54:29.280825Z","iopub.status.idle":"2023-03-10T10:54:29.292872Z","shell.execute_reply.started":"2023-03-10T10:54:29.280787Z","shell.execute_reply":"2023-03-10T10:54:29.291649Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# split training data\ndf_train, df_test = train_test_split(\n    dfx,\n    test_size=0.1,\n    random_state = 42,\n    stratify=dfx.label.values\n)\n\ndf_train = df_train.reset_index(drop=True)\ndf_test = df_test.reset_index(drop=True)","metadata":{"execution":{"iopub.status.busy":"2023-03-10T10:54:29.295607Z","iopub.execute_input":"2023-03-10T10:54:29.296334Z","iopub.status.idle":"2023-03-10T10:54:29.316448Z","shell.execute_reply.started":"2023-03-10T10:54:29.296291Z","shell.execute_reply":"2023-03-10T10:54:29.315417Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df_train.shape","metadata":{"execution":{"iopub.status.busy":"2023-03-10T10:54:29.318086Z","iopub.execute_input":"2023-03-10T10:54:29.318506Z","iopub.status.idle":"2023-03-10T10:54:29.325751Z","shell.execute_reply.started":"2023-03-10T10:54:29.318466Z","shell.execute_reply":"2023-03-10T10:54:29.324497Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df_test.shape","metadata":{"execution":{"iopub.status.busy":"2023-03-10T10:54:29.327811Z","iopub.execute_input":"2023-03-10T10:54:29.328228Z","iopub.status.idle":"2023-03-10T10:54:29.339947Z","shell.execute_reply.started":"2023-03-10T10:54:29.328186Z","shell.execute_reply":"2023-03-10T10:54:29.338651Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# prepare train and validation image paths.\ntrain_image_paths =[\n    os.path.join(base_path,train_imges_path,img_name) for img_name in df_train.image_id.values\n]\n\ntest_image_paths =[\n    os.path.join(base_path,train_imges_path,img_name) for img_name in df_test.image_id.values\n]","metadata":{"execution":{"iopub.status.busy":"2023-03-10T10:54:29.387294Z","iopub.execute_input":"2023-03-10T10:54:29.387959Z","iopub.status.idle":"2023-03-10T10:54:29.433232Z","shell.execute_reply.started":"2023-03-10T10:54:29.387931Z","shell.execute_reply":"2023-03-10T10:54:29.432338Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_image_paths[:5]","metadata":{"execution":{"iopub.status.busy":"2023-03-10T10:56:06.538243Z","iopub.execute_input":"2023-03-10T10:56:06.538967Z","iopub.status.idle":"2023-03-10T10:56:06.546733Z","shell.execute_reply.started":"2023-03-10T10:56:06.538926Z","shell.execute_reply":"2023-03-10T10:56:06.545618Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_targets = df_train.label.values\ntest_targets = df_test.label.values","metadata":{"execution":{"iopub.status.busy":"2023-03-10T10:56:07.236668Z","iopub.execute_input":"2023-03-10T10:56:07.23705Z","iopub.status.idle":"2023-03-10T10:56:07.244244Z","shell.execute_reply.started":"2023-03-10T10:56:07.237016Z","shell.execute_reply":"2023-03-10T10:56:07.241338Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Define custom Dataset preparation class.\nclass CustomImageDataset(Dataset):\n    def __init__(\n        self,\n        image_paths,\n        targets,\n        augmentations=None,\n        backend='pil',\n        channel_first=True,\n        gray_scale=False\n    ):\n         \"\"\"\n        :param image_paths: list of paths to images\n        :param targets: numpy array\n        :param augmentations: albumentations augmentations\n        \"\"\"\n        self.image_paths= image_paths\n        self.targets = targets\n        self.augmentation = augmentations\n        self.backend = backend\n        self.channel_first= channel_first\n        self.gray_scale = gray_scale\n        \n    def __len__(self):\n        return len(self.image_paths)\n\n    def __getitem__(self,item):\n        targets = self.targets[item]\n        if self.backend == 'pil':\n            image = Image.open(self.image_paths[item])\n            image = np.array(image)\n            if self.augmentation is not None:\n                augmented = self.augmentation(image = image)\n                image = augmented['image']\n        elif self.backend == 'cv2':\n            image = cv2.imread(self.image_paths[item])\n            if self.gray_scale is False:\n                image = cv2.cvtColor(image,cv2.COLOR_BGR2RGB)\n            else:\n                image = cv2.cvtColor(image,cv2.COLOR_BGR2GRAY)\n            if self.augmentation is not None:\n                augmented = self.augmentation(image = image)\n                image = augmented['image']\n        else:\n            raise Exception('No backend defined')\n            \n        if self.channel_first is True and self.gray_scale is False:\n            image = np.transpose(image,(2,0,1)).astype(np.float32)\n        \n        image_tensor = torch.tensor(image)\n        if self.gray_scale:\n            image_tensor = image_tensor.unsqueeze(0)\n            \n        return {\n            \"image\": image_tensor,\n            'targets': torch.tensor(targets)\n        }\n        ","metadata":{"execution":{"iopub.status.busy":"2023-03-10T10:56:10.592808Z","iopub.execute_input":"2023-03-10T10:56:10.59377Z","iopub.status.idle":"2023-03-10T10:56:10.606979Z","shell.execute_reply.started":"2023-03-10T10:56:10.593716Z","shell.execute_reply":"2023-03-10T10:56:10.605892Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def plot_img(image_dict):\n    img_tensor = image_dict['image']\n    target = image_dict['targets']\n    plt.figure(figsize=(5,5))\n    img = img_tensor.permute(1,2,0)/255\n    plt.imshow(img)","metadata":{"execution":{"iopub.status.busy":"2023-03-10T10:56:13.337148Z","iopub.execute_input":"2023-03-10T10:56:13.337516Z","iopub.status.idle":"2023-03-10T10:56:13.343052Z","shell.execute_reply.started":"2023-03-10T10:56:13.337484Z","shell.execute_reply":"2023-03-10T10:56:13.341937Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Define data augumentation parameters.\ndata_agumnetation = [\n        albumentations.RandomResizedCrop(180,180),\n        albumentations.Transpose(p=0.5),\n        albumentations.HorizontalFlip(p=0.5),\n        albumentations.VerticalFlip(p=0.5)\n    ]\ntrain_aug = albumentations.Compose(data_agumnetation)\ntest_aug = albumentations.Compose(data_agumnetation)","metadata":{"execution":{"iopub.status.busy":"2023-03-10T11:00:22.240089Z","iopub.execute_input":"2023-03-10T11:00:22.240576Z","iopub.status.idle":"2023-03-10T11:00:22.252217Z","shell.execute_reply.started":"2023-03-10T11:00:22.240536Z","shell.execute_reply":"2023-03-10T11:00:22.250837Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Prepare train and validation dataset\ntrain_dataset = CustomImageDataset(\n    image_paths = train_image_paths,\n    targets = train_targets,\n    backend ='pil',\n    gray_scale =False,\n    augmentations = train_aug\n)\n\ntest_dataset = CustomImageDataset(\n    image_paths = test_image_paths,\n    targets = test_targets,\n    backend ='pil',\n    gray_scale =False,\n    augmentations = test_aug\n)","metadata":{"execution":{"iopub.status.busy":"2023-03-10T11:00:22.449692Z","iopub.execute_input":"2023-03-10T11:00:22.450019Z","iopub.status.idle":"2023-03-10T11:00:22.455619Z","shell.execute_reply.started":"2023-03-10T11:00:22.449989Z","shell.execute_reply":"2023-03-10T11:00:22.454424Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"del train_aug\ndel test_aug","metadata":{"execution":{"iopub.status.busy":"2023-03-10T11:00:22.661087Z","iopub.execute_input":"2023-03-10T11:00:22.661711Z","iopub.status.idle":"2023-03-10T11:00:22.666147Z","shell.execute_reply.started":"2023-03-10T11:00:22.661678Z","shell.execute_reply":"2023-03-10T11:00:22.665138Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"plot_img(train_dataset[np.random.randint(len(train_image_paths))])","metadata":{"execution":{"iopub.status.busy":"2023-03-10T11:00:23.309607Z","iopub.execute_input":"2023-03-10T11:00:23.310012Z","iopub.status.idle":"2023-03-10T11:00:23.693022Z","shell.execute_reply.started":"2023-03-10T11:00:23.309976Z","shell.execute_reply":"2023-03-10T11:00:23.69204Z"},"collapsed":true,"jupyter":{"outputs_hidden":true},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"plot_img(test_dataset[np.random.randint(len(test_image_paths))])","metadata":{"execution":{"iopub.status.busy":"2023-03-10T11:00:27.308302Z","iopub.execute_input":"2023-03-10T11:00:27.309023Z","iopub.status.idle":"2023-03-10T11:00:27.687459Z","shell.execute_reply.started":"2023-03-10T11:00:27.308982Z","shell.execute_reply":"2023-03-10T11:00:27.686486Z"},"collapsed":true,"jupyter":{"outputs_hidden":true},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Define Leaf desease classification model\n# Using pretrained resnet model\nclass LeafDeseaseModel(nn.Module):\n    def __init__(self,num_classes,pretrained = True):\n        super().__init__()\n        self.convnet = torchvision.models.resnet18(pretrained = pretrained)\n        self.convnet.fc = nn.Linear(512,num_classes)\n        \n#     def loss(self,outputs,targets):\n#         if targets is None:\n#             return None\n#         return nn.CrossEntropyLoss()(outputs,targets)\n    \n    def forward(self,image,targets=None):\n        outputs = self.convnet(image)\n#         if targets is not None:\n#             loss = self.loss(outputs,targets)\n#             return outputs,loss\n        return outputs, None","metadata":{"execution":{"iopub.status.busy":"2023-03-10T11:01:00.523196Z","iopub.execute_input":"2023-03-10T11:01:00.523687Z","iopub.status.idle":"2023-03-10T11:01:00.531657Z","shell.execute_reply.started":"2023-03-10T11:01:00.523645Z","shell.execute_reply":"2023-03-10T11:01:00.530443Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')\ndevice","metadata":{"execution":{"iopub.status.busy":"2023-03-10T11:01:01.746918Z","iopub.execute_input":"2023-03-10T11:01:01.747312Z","iopub.status.idle":"2023-03-10T11:01:01.756054Z","shell.execute_reply.started":"2023-03-10T11:01:01.747279Z","shell.execute_reply":"2023-03-10T11:01:01.754867Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model = LeafDeseaseModel(num_classes = dfx.label.nunique(),pretrained=True)\nmodel = nn.DataParallel(model)\nmodel = model.to(device)","metadata":{"execution":{"iopub.status.busy":"2023-03-10T11:01:02.27415Z","iopub.execute_input":"2023-03-10T11:01:02.274863Z","iopub.status.idle":"2023-03-10T11:01:05.813436Z","shell.execute_reply.started":"2023-03-10T11:01:02.274825Z","shell.execute_reply":"2023-03-10T11:01:05.812348Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"img = train_dataset[0]['image'].to(device)\ny = train_dataset[0]['targets'].to(device)\nmodel(img.unsqueeze(0),y.unsqueeze(0))","metadata":{"execution":{"iopub.status.busy":"2023-03-10T11:01:11.995406Z","iopub.execute_input":"2023-03-10T11:01:11.996093Z","iopub.status.idle":"2023-03-10T11:01:18.092535Z","shell.execute_reply.started":"2023-03-10T11:01:11.996054Z","shell.execute_reply":"2023-03-10T11:01:18.091417Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Training data loader\ntrainloader = DataLoader(train_dataset,batch_size=32)","metadata":{"execution":{"iopub.status.busy":"2023-03-10T11:01:25.23921Z","iopub.execute_input":"2023-03-10T11:01:25.240115Z","iopub.status.idle":"2023-03-10T11:01:25.245631Z","shell.execute_reply.started":"2023-03-10T11:01:25.240068Z","shell.execute_reply":"2023-03-10T11:01:25.244314Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Start training model upto 10 epocs\ndef train_model(train_dl,mdl,epochs=10):\n#     mdl.train()\n    loss_fn = nn.CrossEntropyLoss()\n    optimizer = optim.Adam(mdl.parameters(), lr=1e-3)\n    for epoch in range(epochs):\n        for i,data in enumerate(train_dl):\n            inputs,label = data['image'].to(device),data['targets'].to(device)\n            optimizer.zero_grad()\n            out = mdl(inputs)\n            loss = loss_fn(out[0],label)\n            loss.backward()\n            optimizer.step()\n#             break\n    return mdl\n\nmodel = train_model(trainloader,model)","metadata":{"execution":{"iopub.status.busy":"2023-03-10T11:01:26.582387Z","iopub.execute_input":"2023-03-10T11:01:26.583053Z","iopub.status.idle":"2023-03-10T11:37:03.582631Z","shell.execute_reply.started":"2023-03-10T11:01:26.583016Z","shell.execute_reply":"2023-03-10T11:37:03.581543Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Test loader\ntestloader = DataLoader(test_dataset,batch_size=1)","metadata":{"execution":{"iopub.status.busy":"2023-03-10T11:38:00.502832Z","iopub.execute_input":"2023-03-10T11:38:00.503968Z","iopub.status.idle":"2023-03-10T11:38:00.509895Z","shell.execute_reply.started":"2023-03-10T11:38:00.503918Z","shell.execute_reply":"2023-03-10T11:38:00.508794Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Evaluating validation data\ndef evaluate_model(test_dl,mdl):\n    predictions,actuals = [],[]\n    with torch.no_grad():\n        for i, data in enumerate(test_dl):\n            inputs,label = data['image'].to(device),data['targets'].to(device)\n            yhat = mdl(inputs)\n            yhat = yhat[0][0]\n            yhat = torch.argmax(yhat).cpu().detach().numpy()\n            targets = label.cpu().detach().numpy()\n            predictions.append(yhat)\n            actuals.append(targets)\n    predictions, actuals = np.vstack(predictions), np.vstack(actuals)\n    # calculate accuracy\n    acc = accuracy_score(actuals, predictions)\n    return acc","metadata":{"execution":{"iopub.status.busy":"2023-03-10T11:38:04.091465Z","iopub.execute_input":"2023-03-10T11:38:04.092184Z","iopub.status.idle":"2023-03-10T11:38:04.100239Z","shell.execute_reply.started":"2023-03-10T11:38:04.092127Z","shell.execute_reply":"2023-03-10T11:38:04.099196Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"acc = evaluate_model(testloader, model)","metadata":{"execution":{"iopub.status.busy":"2023-03-10T11:38:14.932577Z","iopub.execute_input":"2023-03-10T11:38:14.933816Z","iopub.status.idle":"2023-03-10T11:39:08.020785Z","shell.execute_reply.started":"2023-03-10T11:38:14.93377Z","shell.execute_reply":"2023-03-10T11:39:08.019427Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"acc","metadata":{"execution":{"iopub.status.busy":"2023-03-10T11:39:23.187779Z","iopub.execute_input":"2023-03-10T11:39:23.188713Z","iopub.status.idle":"2023-03-10T11:39:23.195755Z","shell.execute_reply.started":"2023-03-10T11:39:23.188653Z","shell.execute_reply":"2023-03-10T11:39:23.194619Z"},"jupyter":{"source_hidden":true},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Predict \ndef predict(img, mdl):\n    # make prediction\n    yhat = mdl(img)\n    # retrieve numpy array\n    yhat = torch.argmax(yhat[0]).cpu().detach().numpy()\n    return yhat","metadata":{"execution":{"iopub.status.busy":"2023-03-10T11:39:41.858614Z","iopub.execute_input":"2023-03-10T11:39:41.859622Z","iopub.status.idle":"2023-03-10T11:39:41.865443Z","shell.execute_reply.started":"2023-03-10T11:39:41.859583Z","shell.execute_reply":"2023-03-10T11:39:41.864356Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"img = test_dataset[100]['image']\nimg = img.unsqueeze(0).to(device)\ny = test_dataset[100]['targets']\nyhat = predict(img,model)\nprint('Predicted class = %d' %  yhat)\nprint('Actual class = %d' %  y)","metadata":{"execution":{"iopub.status.busy":"2023-03-10T11:42:34.018494Z","iopub.execute_input":"2023-03-10T11:42:34.019545Z","iopub.status.idle":"2023-03-10T11:42:34.058387Z","shell.execute_reply.started":"2023-03-10T11:42:34.019506Z","shell.execute_reply":"2023-03-10T11:42:34.057236Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]}]}