{"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":"# 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\n#for 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","execution":{"iopub.status.busy":"2022-07-29T19:26:57.809305Z","iopub.execute_input":"2022-07-29T19:26:57.810121Z","iopub.status.idle":"2022-07-29T19:26:57.851316Z","shell.execute_reply.started":"2022-07-29T19:26:57.809950Z","shell.execute_reply":"2022-07-29T19:26:57.850063Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Global Wheat Detection Using Resnet50 Faster-RCNN\n#### Training Notebook: https://www.kaggle.com/code/wasdac/global-wheat-train\n#### Inference Notebook: https://www.kaggle.com/code/wasdac/global-wheat-inference","metadata":{}},{"cell_type":"markdown","source":"# Imports","metadata":{}},{"cell_type":"markdown","source":"### General Imports","metadata":{}},{"cell_type":"code","source":"import numpy as np\nimport cv2\nimport pandas as pd\nimport os\nimport matplotlib.pyplot as plt\nfrom tqdm.auto import tqdm","metadata":{"execution":{"iopub.status.busy":"2022-07-31T18:47:20.662089Z","iopub.execute_input":"2022-07-31T18:47:20.662546Z","iopub.status.idle":"2022-07-31T18:47:21.033393Z","shell.execute_reply.started":"2022-07-31T18:47:20.662437Z","shell.execute_reply":"2022-07-31T18:47:21.032438Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### PyTorch Imports","metadata":{}},{"cell_type":"code","source":"import torch\nimport torch.nn as nn\nimport torchvision\nfrom torchvision import datasets\nfrom torch.utils.data import Dataset, DataLoader\nfrom torchvision import transforms\nimport albumentations as A\nfrom albumentations.pytorch import ToTensorV2\nfrom torchvision.models.detection.faster_rcnn import FastRCNNPredictor","metadata":{"execution":{"iopub.status.busy":"2022-07-31T18:47:21.967198Z","iopub.execute_input":"2022-07-31T18:47:21.967559Z","iopub.status.idle":"2022-07-31T18:47:24.200036Z","shell.execute_reply.started":"2022-07-31T18:47:21.967534Z","shell.execute_reply":"2022-07-31T18:47:24.199059Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### PyTorch Configuration","metadata":{}},{"cell_type":"code","source":"class CFG:\n    learning_rate = 3e-3\n    num_epochs = 1  # increase if required\n    batch_size = 10 \n    device = \"cuda\" if torch.cuda.is_available() else \"cpu\"","metadata":{"execution":{"iopub.status.busy":"2022-07-31T18:47:24.201470Z","iopub.execute_input":"2022-07-31T18:47:24.201882Z","iopub.status.idle":"2022-07-31T18:47:24.207424Z","shell.execute_reply.started":"2022-07-31T18:47:24.201858Z","shell.execute_reply":"2022-07-31T18:47:24.206018Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Directories","metadata":{}},{"cell_type":"code","source":"working_dir = \"./\"\ntrain_root = \"../input/global-wheat-detection/train\"","metadata":{"execution":{"iopub.status.busy":"2022-07-29T19:27:02.880851Z","iopub.execute_input":"2022-07-29T19:27:02.884818Z","iopub.status.idle":"2022-07-29T19:27:02.894176Z","shell.execute_reply.started":"2022-07-29T19:27:02.884762Z","shell.execute_reply":"2022-07-29T19:27:02.892733Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Exploring & Working with Data","metadata":{}},{"cell_type":"code","source":"df = pd.read_csv(\"../input/global-wheat-detection/train.csv\")\ndf","metadata":{"execution":{"iopub.status.busy":"2022-07-29T19:27:02.897353Z","iopub.execute_input":"2022-07-29T19:27:02.898084Z","iopub.status.idle":"2022-07-29T19:27:03.313879Z","shell.execute_reply.started":"2022-07-29T19:27:02.898033Z","shell.execute_reply":"2022-07-29T19:27:03.312630Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df[\"image_id\"].nunique()","metadata":{"execution":{"iopub.status.busy":"2022-07-29T19:27:03.315795Z","iopub.execute_input":"2022-07-29T19:27:03.316537Z","iopub.status.idle":"2022-07-29T19:27:03.363465Z","shell.execute_reply.started":"2022-07-29T19:27:03.316478Z","shell.execute_reply":"2022-07-29T19:27:03.362120Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df[\"width\"].unique(), df[\"height\"].unique()","metadata":{"execution":{"iopub.status.busy":"2022-07-29T19:27:03.369392Z","iopub.execute_input":"2022-07-29T19:27:03.372435Z","iopub.status.idle":"2022-07-29T19:27:03.392387Z","shell.execute_reply.started":"2022-07-29T19:27:03.372381Z","shell.execute_reply":"2022-07-29T19:27:03.390765Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df.loc[0,\"bbox\"]","metadata":{"execution":{"iopub.status.busy":"2022-07-29T19:27:03.397848Z","iopub.execute_input":"2022-07-29T19:27:03.398375Z","iopub.status.idle":"2022-07-29T19:27:03.430968Z","shell.execute_reply.started":"2022-07-29T19:27:03.398332Z","shell.execute_reply":"2022-07-29T19:27:03.429706Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df['bbox'] = df['bbox'].apply(lambda x: eval(x))\nbbox_lst = np.array(list(df['bbox']))\nbbox_lst","metadata":{"execution":{"iopub.status.busy":"2022-07-29T19:27:03.436496Z","iopub.execute_input":"2022-07-29T19:27:03.439481Z","iopub.status.idle":"2022-07-29T19:27:05.523085Z","shell.execute_reply.started":"2022-07-29T19:27:03.439433Z","shell.execute_reply":"2022-07-29T19:27:05.521946Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df.head()","metadata":{"execution":{"iopub.status.busy":"2022-07-29T19:27:05.529076Z","iopub.execute_input":"2022-07-29T19:27:05.529408Z","iopub.status.idle":"2022-07-29T19:27:05.547788Z","shell.execute_reply.started":"2022-07-29T19:27:05.529379Z","shell.execute_reply":"2022-07-29T19:27:05.546337Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"#### Creating x, y, w, h columns from 'bbox'  ","metadata":{}},{"cell_type":"code","source":"for i,elem in enumerate([\"x\",\"y\",\"w\",\"h\"]):\n    df[elem] = bbox_lst[:, i]\n\ndf.head()","metadata":{"execution":{"iopub.status.busy":"2022-07-29T19:27:05.549696Z","iopub.execute_input":"2022-07-29T19:27:05.550053Z","iopub.status.idle":"2022-07-29T19:27:05.581263Z","shell.execute_reply.started":"2022-07-29T19:27:05.550025Z","shell.execute_reply":"2022-07-29T19:27:05.579992Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df.drop([\"bbox\"], axis=1, inplace=True)","metadata":{"execution":{"iopub.status.busy":"2022-07-29T19:27:05.583188Z","iopub.execute_input":"2022-07-29T19:27:05.583963Z","iopub.status.idle":"2022-07-29T19:27:05.606644Z","shell.execute_reply.started":"2022-07-29T19:27:05.583919Z","shell.execute_reply":"2022-07-29T19:27:05.605018Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df","metadata":{"execution":{"iopub.status.busy":"2022-07-29T19:27:05.608512Z","iopub.execute_input":"2022-07-29T19:27:05.614869Z","iopub.status.idle":"2022-07-29T19:27:05.646370Z","shell.execute_reply.started":"2022-07-29T19:27:05.614823Z","shell.execute_reply":"2022-07-29T19:27:05.645103Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"#### Modifying column names to obtain x1, y1, w, h, x2, y2","metadata":{}},{"cell_type":"code","source":"df.rename(columns={\"x\":\"x1\", \"y\": \"y1\"}, inplace=True)","metadata":{"execution":{"iopub.status.busy":"2022-07-29T19:27:05.648343Z","iopub.execute_input":"2022-07-29T19:27:05.648754Z","iopub.status.idle":"2022-07-29T19:27:05.657517Z","shell.execute_reply.started":"2022-07-29T19:27:05.648716Z","shell.execute_reply":"2022-07-29T19:27:05.655992Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df[\"x2\"] = bbox_lst[:,0] + bbox_lst[:,2] # x1 + w\ndf[\"y2\"] = bbox_lst[:,1] + bbox_lst[:,3] # y1 + h","metadata":{"execution":{"iopub.status.busy":"2022-07-29T19:27:05.659433Z","iopub.execute_input":"2022-07-29T19:27:05.660034Z","iopub.status.idle":"2022-07-29T19:27:05.673321Z","shell.execute_reply.started":"2022-07-29T19:27:05.659991Z","shell.execute_reply":"2022-07-29T19:27:05.672101Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df","metadata":{"execution":{"iopub.status.busy":"2022-07-29T19:27:05.675456Z","iopub.execute_input":"2022-07-29T19:27:05.676022Z","iopub.status.idle":"2022-07-29T19:27:05.706470Z","shell.execute_reply.started":"2022-07-29T19:27:05.675981Z","shell.execute_reply":"2022-07-29T19:27:05.704969Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df[df[\"image_id\"] == \"b6ab77fd7\"] # all bounding boxes for id: \"b6ab77fd7\"","metadata":{"execution":{"iopub.status.busy":"2022-07-29T19:27:05.708933Z","iopub.execute_input":"2022-07-29T19:27:05.710512Z","iopub.status.idle":"2022-07-29T19:27:05.792206Z","shell.execute_reply.started":"2022-07-29T19:27:05.710468Z","shell.execute_reply":"2022-07-29T19:27:05.790934Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Dataset Class","metadata":{}},{"cell_type":"code","source":"class WheatDataset(Dataset):\n    def __init__(self, df, root_dir, transforms = None):\n        self.df = df\n        self.root_dir = root_dir\n        self.img_ids = self.df[\"image_id\"].unique()\n        self.transforms = transforms\n        \n    def __len__(self):\n        return len(df)\n    \n    def __getitem__(self, idx):\n        image_id = self.img_ids[idx]\n        records = df[df[\"image_id\"] == image_id]\n        \n        image_path = os.path.join(self.root_dir, f\"{image_id}.jpg\")\n        img = cv2.imread(image_path)\n        targets = {}   \n        targets[\"boxes\"] = records[[\"x1\",\"y1\",\"x2\",\"y2\"]].values\n        targets[\"labels\"] = torch.ones((records.shape[0]),dtype=torch.int64)\n        targets[\"image_id\"] = torch.tensor([idx])\n        \n        bboxes = targets[\"boxes\"]\n        labels = targets[\"labels\"]\n        \n        if self.transforms:\n            transform_dict = {\n                        \"image\": img,\n                        \"bboxes\" : bboxes,\n                        \"labels\": labels}\n            transform = self.transforms(**transform_dict)\n            img = transform[\"image\"]\n            targets[\"boxes\"] = transform[\"bboxes\"]\n            targets[\"labels\"] = transform[\"labels\"]\n        \n        return img, targets","metadata":{"execution":{"iopub.status.busy":"2022-07-29T19:27:05.793936Z","iopub.execute_input":"2022-07-29T19:27:05.795345Z","iopub.status.idle":"2022-07-29T19:27:05.808379Z","shell.execute_reply.started":"2022-07-29T19:27:05.795256Z","shell.execute_reply":"2022-07-29T19:27:05.807196Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Data Augmentation","metadata":{}},{"cell_type":"code","source":"train_transform = A.Compose([A.Flip(p=0.5),\n                             A.Normalize(mean=(0, 0, 0), std=(1, 1, 1), max_pixel_value=255.0),\n                             ToTensorV2()],\n                             bbox_params = A.BboxParams('pascal_voc', [\"labels\"]))\n                            \nvalid_transform = A.Compose([A.Normalize(mean=(0, 0, 0), std=(1, 1, 1), max_pixel_value=255.0),\n                            ToTensorV2()],\n                            bbox_params = A.BboxParams('pascal_voc', [\"labels\"]))","metadata":{"execution":{"iopub.status.busy":"2022-07-29T19:27:05.810302Z","iopub.execute_input":"2022-07-29T19:27:05.811051Z","iopub.status.idle":"2022-07-29T19:27:05.824215Z","shell.execute_reply.started":"2022-07-29T19:27:05.811010Z","shell.execute_reply":"2022-07-29T19:27:05.822771Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Packs images and targets in tuple\ndef collate_fn(batch):\n    return tuple(zip(*batch))","metadata":{"execution":{"iopub.status.busy":"2022-07-29T19:27:05.828010Z","iopub.execute_input":"2022-07-29T19:27:05.829477Z","iopub.status.idle":"2022-07-29T19:27:05.841792Z","shell.execute_reply.started":"2022-07-29T19:27:05.829445Z","shell.execute_reply":"2022-07-29T19:27:05.840378Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Sample Dataset & Dataloader","metadata":{}},{"cell_type":"code","source":"train_dataset = WheatDataset(df, train_root, train_transform)\nimg, target = train_dataset[0]\na = DataLoader(train_dataset, batch_size=CFG.batch_size, collate_fn = collate_fn)\nb = iter(a)","metadata":{"execution":{"iopub.status.busy":"2022-07-29T19:27:05.843568Z","iopub.execute_input":"2022-07-29T19:27:05.844275Z","iopub.status.idle":"2022-07-29T19:27:05.973665Z","shell.execute_reply.started":"2022-07-29T19:27:05.844218Z","shell.execute_reply":"2022-07-29T19:27:05.972255Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Visualizing Sample Dataloader","metadata":{}},{"cell_type":"code","source":"def show_dataloader_sample(dataloader):\n    img_plt_lst = []\n    for i, (img, target) in enumerate(dataloader):\n        for j in range(len(target)):\n            image = np.array(img[j]*255, dtype=np.uint8)\n            image = image.transpose(1, 2, 0)\n            actual_bbox = target[j][\"boxes\"]\n            image_id = target[j][\"image_id\"]\n            #print(image.shape)\n            #plt.imshow(image)\n            #plt.show()\n        \n            for k in actual_bbox:\n                cv2.rectangle(image, [int(k[0]), int(k[1])], [int(k[2]), int(k[3])], color=(0,0,255), thickness=2)\n            \n            image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)\n            #cv2.imwrite(f\"{image_id[0]}.jpg\", image)\n        \n            img_plt_lst.append(image)\n        \n            #plt.imshow(image)\n            #plt.show()\n        break\n\n    f, axarr = plt.subplots(2, 5, figsize=(50,20)) # figsize=(w,h)\n    k=-1\n    for i in range(0,2):\n        for j in range(0,5):\n            k +=1\n            axarr[i][j].imshow(img_plt_lst[k])\n    plt.show()\n    print(target[:2])\n    \n\nshow_dataloader_sample(a)","metadata":{"execution":{"iopub.status.busy":"2022-07-29T19:27:05.976707Z","iopub.execute_input":"2022-07-29T19:27:05.977498Z","iopub.status.idle":"2022-07-29T19:27:11.417514Z","shell.execute_reply.started":"2022-07-29T19:27:05.977455Z","shell.execute_reply":"2022-07-29T19:27:11.416382Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## K-Fold for Cross-Validation","metadata":{}},{"cell_type":"code","source":"from sklearn.model_selection import KFold","metadata":{"execution":{"iopub.status.busy":"2022-07-29T19:27:11.419121Z","iopub.execute_input":"2022-07-29T19:27:11.420123Z","iopub.status.idle":"2022-07-29T19:27:11.425921Z","shell.execute_reply.started":"2022-07-29T19:27:11.420083Z","shell.execute_reply":"2022-07-29T19:27:11.424788Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"kfolds = KFold(n_splits=5, shuffle=True, random_state=1234) # Cross-Validation is not yet used in this version of the notebook","metadata":{"execution":{"iopub.status.busy":"2022-07-29T19:27:11.427413Z","iopub.execute_input":"2022-07-29T19:27:11.429417Z","iopub.status.idle":"2022-07-29T19:27:11.439341Z","shell.execute_reply.started":"2022-07-29T19:27:11.429379Z","shell.execute_reply":"2022-07-29T19:27:11.437994Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"unique_ids = df[\"image_id\"].unique()","metadata":{"execution":{"iopub.status.busy":"2022-07-29T19:27:11.441243Z","iopub.execute_input":"2022-07-29T19:27:11.441977Z","iopub.status.idle":"2022-07-29T19:27:11.471484Z","shell.execute_reply.started":"2022-07-29T19:27:11.441922Z","shell.execute_reply":"2022-07-29T19:27:11.469666Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Resnet50 Faster-RCNN Model","metadata":{}},{"cell_type":"code","source":"model = torchvision.models.detection.fasterrcnn_resnet50_fpn(pretrained=True)","metadata":{"execution":{"iopub.status.busy":"2022-07-29T19:27:11.473953Z","iopub.execute_input":"2022-07-29T19:27:11.474795Z","iopub.status.idle":"2022-07-29T19:27:21.608083Z","shell.execute_reply.started":"2022-07-29T19:27:11.474746Z","shell.execute_reply":"2022-07-29T19:27:21.606753Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"num_classes = 2 \n\nin_features = model.roi_heads.box_predictor.cls_score.in_features\n\nmodel.roi_heads.box_predictor = FastRCNNPredictor(in_features, num_classes)\nmodel = model.to(CFG.device)","metadata":{"execution":{"iopub.status.busy":"2022-07-29T19:27:21.610276Z","iopub.execute_input":"2022-07-29T19:27:21.610693Z","iopub.status.idle":"2022-07-29T19:27:24.860014Z","shell.execute_reply.started":"2022-07-29T19:27:21.610650Z","shell.execute_reply":"2022-07-29T19:27:24.858620Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"optimizer = torch.optim.SGD(model.parameters(), lr=CFG.learning_rate, momentum=0.9)","metadata":{"execution":{"iopub.status.busy":"2022-07-29T19:27:24.867264Z","iopub.execute_input":"2022-07-29T19:27:24.867597Z","iopub.status.idle":"2022-07-29T19:27:24.875204Z","shell.execute_reply.started":"2022-07-29T19:27:24.867568Z","shell.execute_reply":"2022-07-29T19:27:24.873923Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from torchmetrics.detection.mean_ap import MeanAveragePrecision","metadata":{"execution":{"iopub.status.busy":"2022-07-29T19:27:24.876810Z","iopub.execute_input":"2022-07-29T19:27:24.878135Z","iopub.status.idle":"2022-07-29T19:27:25.553077Z","shell.execute_reply.started":"2022-07-29T19:27:24.878076Z","shell.execute_reply":"2022-07-29T19:27:25.551880Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"metric = MeanAveragePrecision(iou_thresholds=[0.5])","metadata":{"execution":{"iopub.status.busy":"2022-07-29T19:27:25.554645Z","iopub.execute_input":"2022-07-29T19:27:25.555133Z","iopub.status.idle":"2022-07-29T19:27:25.566471Z","shell.execute_reply.started":"2022-07-29T19:27:25.555092Z","shell.execute_reply":"2022-07-29T19:27:25.565160Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Train Loop","metadata":{}},{"cell_type":"code","source":"loss_lst = []\nmean_ap = []\nfor e in range(CFG.num_epochs):\n    for i, (train_split, val_split) in enumerate(kfolds.split(unique_ids)):\n        print(len(train_split), len(val_split))\n        train_subsampler = torch.utils.data.SubsetRandomSampler(train_split)\n        val_subsampler = torch.utils.data.SubsetRandomSampler(val_split)\n    \n        train_dataloader = DataLoader(train_dataset, batch_size=CFG.batch_size, sampler=train_subsampler, collate_fn = collate_fn)\n        val_dataloader = DataLoader(train_dataset, batch_size=CFG.batch_size, sampler=val_subsampler, collate_fn = collate_fn) #\n              \n        print(len(train_dataloader))\n        #show_dataloader_sample(train_dataloader)\n        print(len(val_dataloader))\n        #show_dataloader_sample(val_dataloader)\n        print(\"--------------<[TRAINING]>--------------\")\n        for j,(images, targets) in enumerate(tqdm(train_dataloader)):\n            model.train()\n            #images = torch.tensor(images)\n            #targets = torch.tensor(targets)\n            #print(images[0].shape)\n            #print(len(targets[0]))\n            images = list(image.to(CFG.device) for image in images)\n            targets = [{k: torch.as_tensor(v).to(CFG.device) for k,v in t.items()} for t in targets]\n            #targets = targets.to(CFG.device)\n            #print(type(targets[0][\"boxes\"]))\n            optimizer.zero_grad()\n            loss_dict = model(images, targets)\n            losses = sum(loss for loss in loss_dict.values())\n            loss_value = losses.item()\n            losses.backward()\n            optimizer.step()\n            if j%50 == 0:# and j!=0:\n                print(f\"Epoch: {e}, Fold: {i}, Batch: {j}, Loss:{loss_value}\")\n                #break\n            #break\n                \n        loss_lst.append(loss_value)\n        print(\"--------------<[VALIDATION]>--------------\")\n        with torch.no_grad():\n            for m, (val_imgs, val_targets) in enumerate(tqdm(val_dataloader)):\n                val_imgs = list(val_image.to(CFG.device) for val_image in val_imgs)\n                val_targets = [{k: torch.as_tensor(v).to(CFG.device) for k,v in t.items()} for t in val_targets]\n                model.eval()\n                output = model(val_imgs)\n                \n            metric.update(output, val_targets)\n            computed_metric = metric.compute()\n            mean_ap.append(computed_metric)\n            print(f\"Epoch: {e}, Fold: {i}, MAP@0.5:{computed_metric['map']}\")\n            \n                \n\n                \n\"\"\"    \n                if m%30 == 0 and m != 0:\n                    metric.update(output, val_targets)\n                    computed_metric = metric.compute()\n                    print(f\"Epoch: {e}, Fold: {i}, Batch: {e}, MAP:{computed_metric}\")\n                    break\n                    \n                #print(len(output))\n                #print(output)\n                \n                #print(target[\"boxes\"])\n                \n\nfor sample in range(1): #CFG.batch_size\n                    #print(output[sample])\n                    #print(len(output[sample]))\n                    #print(output[sample][\"boxes\"])\n                    #print(output[sample][\"boxes\"].shape)\n                    #print(\"-------------------\")\n                    #print(val_targets[sample])\n                    #print(len(val_targets[sample]))\n                    #print(val_targets[sample][\"boxes\"])\n                    #print(val_targets[sample][\"boxes\"].shape)\n                    img = val_imgs[0].cpu().detach().numpy()\n                    img = img.transpose(1,2,0)\n                    plt.figure(figsize=(10,10))\n                    plt.imshow(img)\n                    plt.show()\n                    for enum,x in enumerate(output[sample][\"boxes\"]):\n                        score = output[sample][\"scores\"][enum]\n                        if score > 0.5:\n                            cv2.rectangle(img, (int(x[0]), int(x[1])), (int(x[2]), int(x[3])), color=(255,0,0), thickness=3)\n                    plt.figure(figsize=(10,10))\n                    plt.imshow(img)\n                    plt.show()\n                    for x in val_targets[sample][\"boxes\"]:\n                        cv2.rectangle(img, (int(x[0]), int(x[1])), (int(x[2]), int(x[3])), color=(0,255,0), thickness=3)\n                    plt.figure(figsize=(10,10))\n                    plt.imshow(img)\n                    plt.show()\n                \n                    if m % 10 == 0 and m!=0:\n                        break\n                    break\n                break\n\"\"\"","metadata":{"execution":{"iopub.status.busy":"2022-07-29T19:27:28.611536Z","iopub.execute_input":"2022-07-29T19:27:28.611930Z","iopub.status.idle":"2022-07-29T20:07:50.847283Z","shell.execute_reply.started":"2022-07-29T19:27:28.611899Z","shell.execute_reply":"2022-07-29T20:07:50.845822Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Saving Model","metadata":{}},{"cell_type":"code","source":"PATH = \"./resnet50_faster_rcnn.pth\"\ntorch.save(model.state_dict(), PATH)","metadata":{"execution":{"iopub.status.busy":"2022-07-29T20:08:21.987825Z","iopub.execute_input":"2022-07-29T20:08:21.989005Z","iopub.status.idle":"2022-07-29T20:08:22.336556Z","shell.execute_reply.started":"2022-07-29T20:08:21.988957Z","shell.execute_reply":"2022-07-29T20:08:22.335174Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from IPython.display import FileLink\nFileLink(r'./resnet50_faster_rcnn.pth')","metadata":{"execution":{"iopub.status.busy":"2022-07-29T20:10:19.670360Z","iopub.execute_input":"2022-07-29T20:10:19.671084Z","iopub.status.idle":"2022-07-29T20:10:19.679372Z","shell.execute_reply.started":"2022-07-29T20:10:19.671050Z","shell.execute_reply":"2022-07-29T20:10:19.677726Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Testing","metadata":{}},{"cell_type":"markdown","source":"## Model","metadata":{}},{"cell_type":"code","source":"model = torchvision.models.detection.fasterrcnn_resnet50_fpn(pretrained=False, pretrained_backbone=False)\nnum_classes = 2  \nin_features = model.roi_heads.box_predictor.cls_score.in_features\nmodel.roi_heads.box_predictor = FastRCNNPredictor(in_features, num_classes)\nmodel.eval()\nmodel = model.to(CFG.device)","metadata":{"execution":{"iopub.status.busy":"2022-07-31T18:47:32.898711Z","iopub.execute_input":"2022-07-31T18:47:32.899039Z","iopub.status.idle":"2022-07-31T18:47:33.759108Z","shell.execute_reply.started":"2022-07-31T18:47:32.899010Z","shell.execute_reply":"2022-07-31T18:47:33.757924Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Loading Custom Trained Weights","metadata":{}},{"cell_type":"code","source":"LOAD_PATH = \"../input/resnet50wheatdetection2/resnet50_faster_rcnn_2.pth\"\nmodel.load_state_dict(torch.load(LOAD_PATH, map_location=torch.device(CFG.device)))","metadata":{"execution":{"iopub.status.busy":"2022-07-31T18:47:39.355812Z","iopub.execute_input":"2022-07-31T18:47:39.356198Z","iopub.status.idle":"2022-07-31T18:47:42.663714Z","shell.execute_reply.started":"2022-07-31T18:47:39.356162Z","shell.execute_reply":"2022-07-31T18:47:42.662526Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Test Images","metadata":{}},{"cell_type":"code","source":"test_imgs_root = \"../input/global-wheat-detection/test\"\ntest_img_lst = os.listdir(test_imgs_root)\ntest_img_lst","metadata":{"execution":{"iopub.status.busy":"2022-07-31T18:47:45.127502Z","iopub.execute_input":"2022-07-31T18:47:45.128157Z","iopub.status.idle":"2022-07-31T18:47:45.140836Z","shell.execute_reply.started":"2022-07-31T18:47:45.128125Z","shell.execute_reply":"2022-07-31T18:47:45.139540Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Visualizing Detection of Test Set","metadata":{}},{"cell_type":"code","source":"threshold = 0.5\nsubmission_dict = {}\nfor img in test_img_lst:\n    img_name = img.split(\".\")[0]\n    #print(img_name)\n    test_img_path = os.path.join(test_imgs_root, img)\n    test_img = cv2.imread(test_img_path)\n    test_img_rgb = cv2.cvtColor(test_img, cv2.COLOR_BGR2RGB)\n    test_img_tensor = transforms.ToTensor()(test_img_rgb)\n    test_img_unsqueezed = test_img_tensor.unsqueeze(0)\n    with torch.no_grad():\n        loss = model(test_img_unsqueezed.to(CFG.device))\n        loss_0 = loss[0]\n        #print(loss_0[\"boxes\"][:5])\n        #print(loss_0[\"scores\"][:5])\n        #break\n        pred_string = \"\"\n        for enum, test_bbox in enumerate(loss_0[\"boxes\"]):\n            score = loss_0[\"scores\"][enum]\n            if score > threshold:\n                x1, y1 = int(test_bbox[0]), int(test_bbox[1])\n                x2, y2 = int(test_bbox[2]), int(test_bbox[3])\n                w = x2-x1\n                h = y2-y1\n                cv2.rectangle(test_img, (x1,y1), (x2,y2), color=(255,0,0), thickness=3)\n                pred_string += f\"{score:.3f} {x1} {y1} {w} {h} \"\n        #print(pred_string)\n    submission_dict[img_name] = pred_string\n    print(pred_string)\n    plt.figure(figsize=(5,5))\n    plt.imshow(test_img)\n    plt.show()","metadata":{"execution":{"iopub.status.busy":"2022-07-31T18:47:47.708022Z","iopub.execute_input":"2022-07-31T18:47:47.708353Z","iopub.status.idle":"2022-07-31T18:48:22.294120Z","shell.execute_reply.started":"2022-07-31T18:47:47.708326Z","shell.execute_reply":"2022-07-31T18:48:22.292765Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"submission_dict","metadata":{"execution":{"iopub.status.busy":"2022-07-31T18:48:28.639469Z","iopub.execute_input":"2022-07-31T18:48:28.639815Z","iopub.status.idle":"2022-07-31T18:48:28.648523Z","shell.execute_reply.started":"2022-07-31T18:48:28.639789Z","shell.execute_reply":"2022-07-31T18:48:28.647141Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Submission","metadata":{}},{"cell_type":"code","source":"submission_df_path = \"../input/global-wheat-detection/sample_submission.csv\"\nsubmission_df = pd.read_csv(submission_df_path)\nsubmission_df","metadata":{"execution":{"iopub.status.busy":"2022-07-31T18:48:31.335830Z","iopub.execute_input":"2022-07-31T18:48:31.336214Z","iopub.status.idle":"2022-07-31T18:48:31.362022Z","shell.execute_reply.started":"2022-07-31T18:48:31.336184Z","shell.execute_reply":"2022-07-31T18:48:31.361406Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"for en, (k,v) in enumerate(submission_dict.items()):\n    #print(k,v)\n    submission_df[\"image_id\"][en] = k\n    submission_df[\"PredictionString\"][en] = v\n    \nsubmission_df","metadata":{"execution":{"iopub.status.busy":"2022-07-31T18:48:31.822601Z","iopub.execute_input":"2022-07-31T18:48:31.823333Z","iopub.status.idle":"2022-07-31T18:48:31.841012Z","shell.execute_reply.started":"2022-07-31T18:48:31.823306Z","shell.execute_reply":"2022-07-31T18:48:31.840244Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"submission_df.to_csv(\"submission.csv\", index=False)","metadata":{"execution":{"iopub.status.busy":"2022-07-31T18:48:34.543339Z","iopub.execute_input":"2022-07-31T18:48:34.543945Z","iopub.status.idle":"2022-07-31T18:48:34.551278Z","shell.execute_reply.started":"2022-07-31T18:48:34.543909Z","shell.execute_reply":"2022-07-31T18:48:34.550512Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Rough Work","metadata":{}},{"cell_type":"code","source":"threshold = 0.5\nsubmission_dict = {}\nfor img in test_img_lst:\n    img_name = img.split(\".\")[0]\n    #print(img_name)\n    test_img_path = os.path.join(test_imgs_root, img)\n    test_img = cv2.imread(test_img_path)\n    test_img_rgb = cv2.cvtColor(test_img, cv2.COLOR_BGR2RGB)\n    test_img_tensor = transforms.ToTensor()(test_img_rgb)\n    test_img_unsqueezed = test_img_tensor.unsqueeze(0)\n    with torch.no_grad():\n        loss = model(test_img_unsqueezed.to(CFG.device))\n        loss_0 = loss[0]\n        #print(loss_0[\"boxes\"][:5])\n        #print(loss_0[\"scores\"][:5])\n        #break\n        pred_string = \"\"\n        for enum, test_bbox in enumerate(loss_0[\"boxes\"]):\n            score = loss_0[\"scores\"][enum]\n            if score > threshold:\n                cv2.rectangle(test_img, (int(test_bbox[0]), int(test_bbox[1])), (int(test_bbox[2]), int(test_bbox[3])), color=(255,0,0), thickness=3)\n                pred_string += f\"{score:.3f} {int(test_bbox[0])} {int(test_bbox[1])} {int(test_bbox[2])} {int(test_bbox[3])} \"\n        #print(pred_string)\n    submission_dict[img_name] = pred_string\n    #print(pred_string)\n    plt.figure(figsize=(10,10))\n    plt.imshow(test_img)\n    plt.show()","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"images, boxes = torch.rand(4, 3, 600, 1200), torch.rand(4, 11, 4)\n\nboxes\n\nboxes[:, :, 2:4] = boxes[:, :, 0:2] + boxes[:, :, 2:4]\n\nboxes\n\nlabels = torch.randint(1, 91, (4, 11))\n\nlabels\n\nimages = list(image for image in images)\n\nimages\n\ntargets = []\nfor i in range(len(images)):\n    d = {}\n    d['boxes'] = boxes[i]\n    d['labels'] = labels[i]\n    targets.append(d)\n\ntargets\n\ntargets = [{k: v for k, v in t.items()} for t in targets]\n\ntargets\n\noutput = model(images, targets)\n\noutput\n\nmodel.eval()\nx = [torch.rand(3, 300, 400), torch.rand(3, 500, 400)]\npredictions = model(x)\n\nprint(x)\n\npredictions","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print(pred_string)\nplt.figure(figsize=(10,10))\nplt.imshow(test_img)\nplt.show()\n\ntest_img = cv2.imread(test_img_path)\n#print(test_img)\nplt.imshow(test_img)\nplt.show()\n\nmodel.eval()\nprint(test_img.shape)\ntest_img = transforms.ToTensor()(test_img)\ntest_img = test_img.unsqueeze(0)\ntest_img.shape\n\nloss = model(test_img.to(CFG.device))\nloss_0 = loss[0]\n\ntest_img_cv2 = cv2.imread(test_img_path)\ntest_img_rgb = cv2.cvtColor(test_img_cv2, cv2.COLOR_BGR2RGB)\n\nfor test_box in loss[0][\"boxes\"]:\n    cv2.rectangle(test_img_rgb, (int(test_box[0]), int(test_box[1])), (int(test_box[2]), int(test_box[3])), color=(0,0,255), thickness=3)\n\nplt.figure(figsize=(10,10))\nplt.imshow(test_img_rgb)\nplt.show()\n\nnms_boxes = loss[0][\"boxes\"]\nnms_scores = loss[0][\"scores\"]\nnms_iou_thresh = 0.5\n\nprint(len(nms_boxes))\nnms_kept = nms(nms_boxes, nms_scores, nms_iou_thresh)\nnms_kept\n\nprint(nms_boxes)\nprint(nms_scores)\n\nnms_dict = dict(zip(nms_scores, nms_boxes))\nsorted_nms_dict = sorted(nms_dict.items(), reverse=True)\n\nsorted_nms_dict\n\ntest_img_cv2_nms = cv2.imread(test_img_path)\ntest_img_rgb_nms = cv2.cvtColor(test_img_cv2_nms, cv2.COLOR_BGR2RGB)\n\nfor k,v in sorted_nms_dict:\n    if k > 0.5:\n        pt1 = (int(v[0]), int(v[1]))\n        pt2 = (int(v[2]), int(v[3]))\n        color = (255,0,0)\n        thickness = 3\n        cv2.rectangle(test_img_rgb_nms, pt1, pt2, color, thickness)\n\nplt.figure(figsize=(10,10))\nplt.imshow(test_img_rgb_nms)\nplt.show()\n        ","metadata":{},"execution_count":null,"outputs":[]}]}