{"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":"markdown","source":"# Great Barrier Reef CenterNet2 with Detectron2 (Training)","metadata":{"papermill":{"duration":0.031035,"end_time":"2022-01-11T21:48:03.714582","exception":false,"start_time":"2022-01-11T21:48:03.683547","status":"completed"},"tags":[]}},{"cell_type":"markdown","source":"## All thanks to - AMMAR ALHAJ ALI\n## Original Detectron2 Notebook - https://www.kaggle.com/ammarnassanalhajali/barrier-reef-detectron2-training","metadata":{}},{"cell_type":"markdown","source":"# 📚 Detectron2\nDetectron2 is Facebook AI Research's next generation software system that implements state-of-the-art object detection algorithms. It is a ground-up rewrite of the previous version, Detectron, and it originates from maskrcnn-benchmark","metadata":{"papermill":{"duration":0.028461,"end_time":"2022-01-11T21:48:03.862124","exception":false,"start_time":"2022-01-11T21:48:03.833663","status":"completed"},"tags":[]}},{"cell_type":"markdown","source":"#  ⬇️ Install Detectron2","metadata":{"papermill":{"duration":0.02947,"end_time":"2022-01-11T21:48:03.920059","exception":false,"start_time":"2022-01-11T21:48:03.890589","status":"completed"},"tags":[]}},{"cell_type":"code","source":"import torch\n!nvidia-smi","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"!python -m pip install 'git+https://github.com/facebookresearch/detectron2.git'","metadata":{"_kg_hide-output":true,"papermill":{"duration":195.132199,"end_time":"2022-01-11T21:51:20.98611","exception":false,"start_time":"2022-01-11T21:48:05.853911","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2022-01-18T11:57:25.300735Z","iopub.status.idle":"2022-01-18T11:57:25.301065Z","shell.execute_reply.started":"2022-01-18T11:57:25.30091Z","shell.execute_reply":"2022-01-18T11:57:25.300927Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# ☀️ Importing Libraries","metadata":{"papermill":{"duration":0.053331,"end_time":"2022-01-11T21:51:21.097102","exception":false,"start_time":"2022-01-11T21:51:21.043771","status":"completed"},"tags":[]}},{"cell_type":"code","source":"import warnings\nwarnings.filterwarnings(\"ignore\")\n\nimport pandas as pd\nimport numpy as np\nimport pandas as pd \n\nfrom tqdm import tqdm\nfrom tqdm import tqdm_notebook as tqdm # progress bar\nfrom tqdm.notebook import tqdm\ntqdm.pandas()\n\nfrom datetime import datetime\nimport time\nimport matplotlib.pyplot as plt\n\nimport os, json, cv2, random\nimport skimage.io as io\nimport copy\nfrom pathlib import Path\nfrom typing import Optional\nimport json\nimport matplotlib.pyplot as plt\nimport shutil\nimport ast\n\n\nfrom tqdm import tqdm\nimport itertools\n\nimport torch\nimport albumentations as A\nfrom albumentations.pytorch.transforms import ToTensorV2\n\nfrom glob import glob\n#import numba\n#from numba import jit\n\nfrom pycocotools.coco import COCO\n# detectron2\nfrom detectron2.structures import BoxMode\nfrom detectron2 import model_zoo\nfrom detectron2.config import get_cfg\nfrom detectron2.data import DatasetCatalog, MetadataCatalog\nfrom detectron2.engine import DefaultPredictor, DefaultTrainer, launch\nfrom detectron2.evaluation import COCOEvaluator\nfrom detectron2.structures import BoxMode\nfrom detectron2.utils.visualizer import ColorMode\nfrom detectron2.utils.logger import setup_logger\nfrom detectron2.utils.visualizer import Visualizer\n\nfrom detectron2.data import DatasetCatalog, MetadataCatalog, build_detection_test_loader, build_detection_train_loader\nfrom detectron2.data import detection_utils as utils\n\n\nfrom detectron2.data import DatasetCatalog, MetadataCatalog, build_detection_test_loader, build_detection_train_loader\nfrom detectron2.data import detection_utils as utils\nimport detectron2.data.transforms as T\nfrom detectron2.evaluation import COCOEvaluator, inference_on_dataset\n\n\n\nfrom detectron2.evaluation.evaluator import DatasetEvaluator\nimport pycocotools.mask as mask_util\nfrom detectron2.engine import BestCheckpointer\nfrom detectron2.checkpoint import DetectionCheckpointer\n\nsetup_logger()","metadata":{"_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","_kg_hide-input":true,"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","papermill":{"duration":2.474108,"end_time":"2022-01-11T21:51:23.623877","exception":false,"start_time":"2022-01-11T21:51:21.149769","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2022-01-18T11:57:25.303049Z","iopub.status.idle":"2022-01-18T11:57:25.304026Z","shell.execute_reply.started":"2022-01-18T11:57:25.303806Z","shell.execute_reply":"2022-01-18T11:57:25.303832Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# 🔨 Functions","metadata":{"papermill":{"duration":0.075372,"end_time":"2022-01-11T21:51:23.752424","exception":false,"start_time":"2022-01-11T21:51:23.677052","status":"completed"},"tags":[]}},{"cell_type":"code","source":"def get_bbox(annots):\n    bboxes = [list(annot.values()) for annot in annots]\n    return bboxes\ndef get_path(row):\n    row['image_path'] = f'{TRAIN_PATH}/train_images/video_{row.video_id}/{row.video_frame}.jpg'\n    return row\ndef load_image(image_path):\n    return cv2.cvtColor(cv2.imread(image_path), cv2.COLOR_BGR2RGB)","metadata":{"_kg_hide-input":true,"papermill":{"duration":0.109041,"end_time":"2022-01-11T21:51:23.966258","exception":false,"start_time":"2022-01-11T21:51:23.857217","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2022-01-18T11:57:25.305675Z","iopub.status.idle":"2022-01-18T11:57:25.306467Z","shell.execute_reply.started":"2022-01-18T11:57:25.306159Z","shell.execute_reply":"2022-01-18T11:57:25.306189Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# 🍮 Loading Data","metadata":{"papermill":{"duration":0.090596,"end_time":"2022-01-11T21:51:24.147926","exception":false,"start_time":"2022-01-11T21:51:24.05733","status":"completed"},"tags":[]}},{"cell_type":"code","source":"# --- Read data ---\nTRAIN_PATH = '/kaggle/input/tensorflow-great-barrier-reef'\n# Read in the data CSV files\ndf = pd.read_csv(\"/kaggle/input/tensorflow-great-barrier-reef/train.csv\")\ndf.head(5)","metadata":{"papermill":{"duration":0.155709,"end_time":"2022-01-11T21:51:24.392815","exception":false,"start_time":"2022-01-11T21:51:24.237106","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2022-01-18T11:57:25.307731Z","iopub.status.idle":"2022-01-18T11:57:25.308557Z","shell.execute_reply.started":"2022-01-18T11:57:25.308263Z","shell.execute_reply":"2022-01-18T11:57:25.30829Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"\n# BBoxes\n##### 📌 Note \n> We can see there are many images without any BBox. ","metadata":{"papermill":{"duration":0.052411,"end_time":"2022-01-11T21:51:24.49814","exception":false,"start_time":"2022-01-11T21:51:24.445729","status":"completed"},"tags":[]}},{"cell_type":"code","source":"df[\"NumBBox\"]=df['annotations'].apply(lambda x: str.count(x, 'x'))\ndf.head(5)","metadata":{"papermill":{"duration":0.085829,"end_time":"2022-01-11T21:51:24.637488","exception":false,"start_time":"2022-01-11T21:51:24.551659","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2022-01-18T11:57:25.310006Z","iopub.status.idle":"2022-01-18T11:57:25.310765Z","shell.execute_reply.started":"2022-01-18T11:57:25.31052Z","shell.execute_reply":"2022-01-18T11:57:25.310556Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print(df[\"NumBBox\"].unique())","metadata":{"papermill":{"duration":0.064803,"end_time":"2022-01-11T21:51:24.755723","exception":false,"start_time":"2022-01-11T21:51:24.69092","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2022-01-18T11:57:25.311767Z","iopub.status.idle":"2022-01-18T11:57:25.312075Z","shell.execute_reply.started":"2022-01-18T11:57:25.311921Z","shell.execute_reply":"2022-01-18T11:57:25.311938Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df_train=df[df[\"NumBBox\"]>0]\ndf_train.sample(2)","metadata":{"papermill":{"duration":0.071255,"end_time":"2022-01-11T21:51:24.881012","exception":false,"start_time":"2022-01-11T21:51:24.809757","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2022-01-18T11:57:25.313481Z","iopub.status.idle":"2022-01-18T11:57:25.313784Z","shell.execute_reply.started":"2022-01-18T11:57:25.313625Z","shell.execute_reply":"2022-01-18T11:57:25.313641Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print(df_train['NumBBox'].sum())","metadata":{"papermill":{"duration":0.06236,"end_time":"2022-01-11T21:51:24.998375","exception":false,"start_time":"2022-01-11T21:51:24.936015","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2022-01-18T11:57:25.314653Z","iopub.status.idle":"2022-01-18T11:57:25.314952Z","shell.execute_reply.started":"2022-01-18T11:57:25.314799Z","shell.execute_reply":"2022-01-18T11:57:25.314815Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"> We have just 4919 images with 11898 BBox, we will use them in training.","metadata":{"papermill":{"duration":0.054713,"end_time":"2022-01-11T21:51:25.107309","exception":false,"start_time":"2022-01-11T21:51:25.052596","status":"completed"},"tags":[]}},{"cell_type":"code","source":"df_train['annotations'] = df_train['annotations'].progress_apply(lambda x: ast.literal_eval(x))\ndf_train['bboxes'] = df_train.annotations.progress_apply(get_bbox)\ndf_train.sample(2)","metadata":{"papermill":{"duration":0.371226,"end_time":"2022-01-11T21:51:25.534152","exception":false,"start_time":"2022-01-11T21:51:25.162926","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2022-01-18T11:57:25.315806Z","iopub.status.idle":"2022-01-18T11:57:25.316115Z","shell.execute_reply.started":"2022-01-18T11:57:25.315965Z","shell.execute_reply":"2022-01-18T11:57:25.315982Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Size of Images\n##### 📌 Note \n> All images have Width=1280 & Height=720 ","metadata":{"papermill":{"duration":0.058205,"end_time":"2022-01-11T21:51:25.649792","exception":false,"start_time":"2022-01-11T21:51:25.591587","status":"completed"},"tags":[]}},{"cell_type":"code","source":"df_train[\"Width\"]=1280\ndf_train[\"Height\"]=720\ndf_train.sample(2)","metadata":{"papermill":{"duration":0.073743,"end_time":"2022-01-11T21:51:25.781258","exception":false,"start_time":"2022-01-11T21:51:25.707515","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2022-01-18T11:57:25.317967Z","iopub.status.idle":"2022-01-18T11:57:25.318313Z","shell.execute_reply.started":"2022-01-18T11:57:25.318158Z","shell.execute_reply":"2022-01-18T11:57:25.318175Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Path of Images","metadata":{"papermill":{"duration":0.057239,"end_time":"2022-01-11T21:51:25.894645","exception":false,"start_time":"2022-01-11T21:51:25.837406","status":"completed"},"tags":[]}},{"cell_type":"code","source":"df_train = df_train.progress_apply(get_path, axis=1)\ndf_train.sample(2)","metadata":{"papermill":{"duration":3.246444,"end_time":"2022-01-11T21:51:29.197504","exception":false,"start_time":"2022-01-11T21:51:25.95106","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2022-01-18T11:57:25.319202Z","iopub.status.idle":"2022-01-18T11:57:25.319521Z","shell.execute_reply.started":"2022-01-18T11:57:25.319337Z","shell.execute_reply":"2022-01-18T11:57:25.319353Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# 🍚 Splitting Dataset","metadata":{"papermill":{"duration":0.056047,"end_time":"2022-01-11T21:51:29.310577","exception":false,"start_time":"2022-01-11T21:51:29.25453","status":"completed"},"tags":[]}},{"cell_type":"code","source":"Selected_Fold=4 #0..4\nfilename=\"A_Fold\"+ str(Selected_Fold) +\"_v12_R_50\"\n\nfrom sklearn.model_selection import GroupKFold\nkf = GroupKFold(n_splits = 5) \ndf_train = df_train.reset_index(drop=True)\ndf_train['fold'] = -1\nfor fold, (train_idx, val_idx) in enumerate(kf.split(df_train, y = df_train.video_id.tolist(), groups=df_train.sequence)):\n    df_train.loc[val_idx, 'fold'] = fold\ndisplay(df_train.fold.value_counts())\n","metadata":{"papermill":{"duration":0.084641,"end_time":"2022-01-11T21:51:29.45164","exception":false,"start_time":"2022-01-11T21:51:29.366999","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2022-01-18T11:57:25.320477Z","iopub.status.idle":"2022-01-18T11:57:25.320797Z","shell.execute_reply.started":"2022-01-18T11:57:25.320643Z","shell.execute_reply":"2022-01-18T11:57:25.320659Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def get_data_dicts(\n    _train_df: pd.DataFrame,\n    debug: bool = False,\n    data_type:str=\"train\"\n   \n):\n\n    if debug:\n        _train_df = _train_df.iloc[:10]  # For debug...\n    dataset_dicts = []\n    if data_type==\"train\":\n        _train_df=_train_df[_train_df.fold != Selected_Fold]\n    else: # val\n        _train_df=_train_df[_train_df.fold == Selected_Fold] \n        \n    for index, row in tqdm(_train_df.iterrows(), total=len(_train_df)):\n        record = {}\n        filename  = row.image_path #filename = str(f'{imgdir}/{image_id}.png')\n        image_id = row.image_id\n        image_height= row.Height\n        image_width = row.Width\n        bboxes_coco = row.bboxes\n        #bboxes_coco  = np.array(row.bboxes).astype(np.float32).copy()\n        record[\"file_name\"] = filename\n        record[\"image_id\"] = image_id\n        record[\"width\"] = image_width\n        record[\"height\"] = image_height\n        objs = []\n        class_id = 0\n        iscrowd=0\n        for bbox_idx in range(len(bboxes_coco)):\n            bbox=bboxes_coco[bbox_idx]\n            obj = {\n                    \"bbox\": bbox,\n                    \"bbox_mode\": BoxMode.XYWH_ABS,\n                    \"category_id\": class_id,\n                    \"area\": int(bbox[2])*int(bbox[3]),\n                    \"iscrowd\": iscrowd\n                }\n            objs.append(obj)\n            record[\"annotations\"] = objs\n        dataset_dicts.append(record)\n    return dataset_dicts","metadata":{"papermill":{"duration":0.070878,"end_time":"2022-01-11T21:51:29.579631","exception":false,"start_time":"2022-01-11T21:51:29.508753","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2022-01-18T11:57:25.322029Z","iopub.status.idle":"2022-01-18T11:57:25.322706Z","shell.execute_reply.started":"2022-01-18T11:57:25.322481Z","shell.execute_reply":"2022-01-18T11:57:25.322504Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"thing_classes=['starfish']\ndebug=False\n\nData_Resister_training=\"BR_data_train\";\nData_Resister_valid=\"BR_data_valid\";\n\n\nDatasetCatalog.register(\n    Data_Resister_training,\n    lambda: get_data_dicts(\n        df_train,\n        debug=debug,\n        data_type=\"train\"\n    ),\n)\nMetadataCatalog.get(Data_Resister_training).set(thing_classes=thing_classes)\n    \n\nDatasetCatalog.register(\n    Data_Resister_valid,\n    lambda: get_data_dicts(\n        df_train,\n        debug=debug,\n        data_type=\"val\"\n        ),\n    )\nMetadataCatalog.get(Data_Resister_valid).set(thing_classes=thing_classes)\n    \n\ndataset_dicts_train = DatasetCatalog.get(Data_Resister_training)\nmetadata_dicts_train = MetadataCatalog.get(Data_Resister_training)\n\ndataset_dicts_valid = DatasetCatalog.get(Data_Resister_valid)\nmetadata_dicts_valid = MetadataCatalog.get(Data_Resister_valid)","metadata":{"papermill":{"duration":0.496204,"end_time":"2022-01-11T21:51:30.134079","exception":false,"start_time":"2022-01-11T21:51:29.637875","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2022-01-18T11:57:25.32457Z","iopub.status.idle":"2022-01-18T11:57:25.324898Z","shell.execute_reply.started":"2022-01-18T11:57:25.324729Z","shell.execute_reply":"2022-01-18T11:57:25.324751Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# 🌈 Visualizing BBoxes\nIt's also very easy to visualize prepared training dataset with detectron2.\nIt provides Visualizer class, we can use it to draw an image with bounding box as following.","metadata":{"papermill":{"duration":0.059678,"end_time":"2022-01-11T21:51:30.253958","exception":false,"start_time":"2022-01-11T21:51:30.19428","status":"completed"},"tags":[]}},{"cell_type":"code","source":"fig, ax = plt.subplots(2, 1, figsize =(35,20))\ni=-1\nfor d in random.sample(dataset_dicts_valid, 2):\n    i=i+1    \n    img = cv2.imread(d[\"file_name\"])\n    v = Visualizer(img[:, :, :],\n                   metadata=metadata_dicts_train, \n                   scale=0.5,\n                   instance_mode=ColorMode.IMAGE_BW # remove the colors of unsegmented pixels. This option is only available for segmentation models\n    )\n    out = v.draw_dataset_dict(d)\n    ax[i].grid(False)\n    ax[i].axis('off')\n    ax[i].imshow(out.get_image()[:, :, ::-1])","metadata":{"papermill":{"duration":1.397719,"end_time":"2022-01-11T21:51:31.711972","exception":false,"start_time":"2022-01-11T21:51:30.314253","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2022-01-18T11:57:25.326168Z","iopub.status.idle":"2022-01-18T11:57:25.326734Z","shell.execute_reply.started":"2022-01-18T11:57:25.326532Z","shell.execute_reply":"2022-01-18T11:57:25.326559Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Evaluator","metadata":{"papermill":{"duration":0.124283,"end_time":"2022-01-11T21:51:31.961574","exception":false,"start_time":"2022-01-11T21:51:31.837291","status":"completed"},"tags":[]}},{"cell_type":"code","source":"from detectron2.evaluation.evaluator import DatasetEvaluator\nimport pycocotools.mask as mask_util\nfrom detectron2.engine import BestCheckpointer\nfrom detectron2.checkpoint import DetectionCheckpointer\n\ndef calc_iou(bboxes1, bboxes2, bbox_mode='xywh'):\n    \"\"\"\n    This function is taken from\n    competition metric implementation\n    https://www.kaggle.com/bamps53/competition-metric-implementation\n    Thanks:Camaro\n    \"\"\"\n    assert len(bboxes1.shape) == 2 and bboxes1.shape[1] == 4\n    assert len(bboxes2.shape) == 2 and bboxes2.shape[1] == 4\n    \n    bboxes1 = bboxes1.copy()\n    bboxes2 = bboxes2.copy()\n    \n    if bbox_mode == 'xywh':\n        bboxes1[:, 2:] += bboxes1[:, :2]\n        bboxes2[:, 2:] += bboxes2[:, :2]\n\n    x11, y11, x12, y12 = np.split(bboxes1, 4, axis=1)\n    x21, y21, x22, y22 = np.split(bboxes2, 4, axis=1)\n    xA = np.maximum(x11, np.transpose(x21))\n    yA = np.maximum(y11, np.transpose(y21))\n    xB = np.minimum(x12, np.transpose(x22))\n    yB = np.minimum(y12, np.transpose(y22))\n    interArea = np.maximum((xB - xA + 1), 0) * np.maximum((yB - yA + 1), 0)\n    boxAArea = (x12 - x11 + 1) * (y12 - y11 + 1)\n    boxBArea = (x22 - x21 + 1) * (y22 - y21 + 1)\n    iou = interArea / (boxAArea + np.transpose(boxBArea) - interArea)\n    return iou\n\ndef precision_at(threshold, iou):\n    matches = iou > threshold\n    true_positives = np.sum(matches, axis=1) == 1  # Correct objects\n    false_positives = np.sum(matches, axis=0) == 0  # Missed objects\n    false_negatives = np.sum(matches, axis=1) == 0  # Extra objects\n    return np.sum(true_positives), np.sum(false_positives), np.sum(false_negatives)\n\ndef score(pred, targ):\n    enc_targs = list(map(lambda x:x['bbox'], targ))\n    \n    enc_preds = pred['instances'].pred_boxes.tensor.cpu().numpy()\n    enc_preds = BoxMode.convert(enc_preds, BoxMode.XYXY_ABS, BoxMode.XYWH_ABS)\n    enc_preds = enc_preds.tolist()\n    \n    #ious = calc_iou(np.asarray(enc_preds[:len(enc_targs)]),np.asarray(enc_targs))\n    ious = calc_iou(np.asarray(enc_preds),np.asarray(enc_targs))\n    #res = {score[i]: boxes[i] for i in range(len(score))}\n    #a = sorted(res.items(), key=lambda x: x[0])\n    beta=2\n    prec = []\n    for t in np.arange(0.30, 0.85, 0.05):\n        tp, fp, fn = precision_at(t, ious)\n        p= (1+beta**2)*tp / ((1+beta**2)*tp + beta**2*fn+fp)\n        prec.append(p)\n    return np.mean(prec)\n\nclass F2ScoreEvaluator(DatasetEvaluator):\n    def __init__(self, dataset_name):\n        dataset_dicts = DatasetCatalog.get(dataset_name)\n        self.annotations_cache = {item['image_id']:item['annotations'] for item in dataset_dicts}\n            \n    def reset(self):\n        self.scores = []\n\n    def process(self, inputs, outputs):\n        for inp, out in zip(inputs, outputs):\n            if len(out['instances']) == 0:\n                self.scores.append(0)    \n            else:\n                targ = self.annotations_cache[inp['image_id']]\n                self.scores.append(score(out, targ))\n\n    def evaluate(self):\n        return {\"F2 Score\": np.mean(self.scores)}\n\nclass Trainer(DefaultTrainer):\n    @classmethod\n    def build_evaluator(cls, cfg, dataset_name, output_folder=None):\n        return F2ScoreEvaluator(dataset_name)\n        #return COCOEvaluator(dataset_name, cfg, True, output_folder)\n        \n    def build_hooks(self):\n        cfg = self.cfg.clone()\n        hooks = super().build_hooks()\n        hooks.insert(-1, BestCheckpointer(cfg.TEST.EVAL_PERIOD,\n                                          DetectionCheckpointer(self.model, cfg.OUTPUT_DIR),\n                                         \"F2 Score\",\n                                         \"max\",\n                                         ))\n        return hooks","metadata":{"papermill":{"duration":0.149951,"end_time":"2022-01-11T21:51:32.234585","exception":false,"start_time":"2022-01-11T21:51:32.084634","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2022-01-18T11:57:25.32809Z","iopub.status.idle":"2022-01-18T11:57:25.328578Z","shell.execute_reply.started":"2022-01-18T11:57:25.328358Z","shell.execute_reply":"2022-01-18T11:57:25.328374Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Albumentation","metadata":{"papermill":{"duration":0.126904,"end_time":"2022-01-11T21:51:32.730295","exception":false,"start_time":"2022-01-11T21:51:32.603391","status":"completed"},"tags":[]}},{"cell_type":"code","source":"def custom_mapper(dataset_dict):\n    \n    dataset_dict = copy.deepcopy(dataset_dict)\n    image = utils.read_image(dataset_dict[\"file_name\"], format=\"BGR\")\n    transform_list = [\n            T.RandomBrightness(0.8, 1.2),\n            T.RandomContrast(0.8, 1.2),\n           T.RandomSaturation(0.8, 1.2),\n            T.RandomLighting(0.8),\n            # T.RandomFlip(prob=0.5, horizontal=False, vertical=True),\n            #T.RandomFlip(prob=0.5, horizontal=True, vertical=False),\n    ]\n    image, transforms = T.apply_transform_gens(transform_list, image)\n    dataset_dict[\"image\"] = torch.as_tensor(image.transpose(2, 0, 1).astype(\"float32\"))\n\n    annos = [\n        utils.transform_instance_annotations(obj, transforms, image.shape[:2])\n        for obj in dataset_dict.pop(\"annotations\")\n        if obj.get(\"iscrowd\", 0) == 0\n    ]\n    instances = utils.annotations_to_instances(annos, image.shape[:2])\n    dataset_dict[\"instances\"] = utils.filter_empty_instances(instances)\n    return dataset_dict\n\nclass AugTrainer(DefaultTrainer):\n    @classmethod\n    def build_train_loader(cls, cfg):\n        return build_detection_train_loader(cfg, mapper=custom_mapper)\n    @classmethod\n    def build_evaluator(cls, cfg, dataset_name, output_folder=None):\n        return F2ScoreEvaluator(dataset_name)\n\n    def build_hooks(self):\n        cfg = self.cfg.clone()\n        hooks = super().build_hooks()\n        hooks.insert(-1, BestCheckpointer(cfg.TEST.EVAL_PERIOD,\n                                          DetectionCheckpointer(self.model, cfg.OUTPUT_DIR),\n                                         \"F2 Score\",\n                                         \"max\",\n                                         ))\n        return hooks","metadata":{"papermill":{"duration":0.139284,"end_time":"2022-01-11T21:51:32.997004","exception":false,"start_time":"2022-01-11T21:51:32.85772","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2022-01-18T11:57:25.329381Z","iopub.status.idle":"2022-01-18T11:57:25.330147Z","shell.execute_reply.started":"2022-01-18T11:57:25.329942Z","shell.execute_reply":"2022-01-18T11:57:25.329969Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Training","metadata":{"papermill":{"duration":0.123709,"end_time":"2022-01-11T21:51:33.243999","exception":false,"start_time":"2022-01-11T21:51:33.12029","status":"completed"},"tags":[]}},{"cell_type":"code","source":"%cd /kaggle/working\n!git clone https://github.com/facebookresearch/detectron2\n#!git clone https://github.com/xingyizhou/CenterNet2\n!git clone https://github.com/SahilChachra/CenterNet2","metadata":{"execution":{"iopub.status.busy":"2022-01-18T11:57:25.330939Z","iopub.status.idle":"2022-01-18T11:57:25.331503Z","shell.execute_reply.started":"2022-01-18T11:57:25.331298Z","shell.execute_reply":"2022-01-18T11:57:25.331318Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"!cp -r /kaggle/working/CenterNet2/projects/CenterNet2 /kaggle/working/detectron2/projects/","metadata":{"execution":{"iopub.status.busy":"2022-01-18T11:57:25.334481Z","iopub.status.idle":"2022-01-18T11:57:25.334803Z","shell.execute_reply.started":"2022-01-18T11:57:25.334637Z","shell.execute_reply":"2022-01-18T11:57:25.334661Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"%cd detectron2\nprint('')\n!ls projects\nprint('')\n!ls projects/CenterNet2","metadata":{"execution":{"iopub.status.busy":"2022-01-18T11:57:25.335874Z","iopub.status.idle":"2022-01-18T11:57:25.336476Z","shell.execute_reply.started":"2022-01-18T11:57:25.336283Z","shell.execute_reply":"2022-01-18T11:57:25.336302Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from projects.CenterNet2 import centernet","metadata":{"execution":{"iopub.status.busy":"2022-01-18T11:57:25.337469Z","iopub.status.idle":"2022-01-18T11:57:25.33798Z","shell.execute_reply.started":"2022-01-18T11:57:25.337817Z","shell.execute_reply":"2022-01-18T11:57:25.337834Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"cfg = get_cfg()\nconfig_name = \"/kaggle/working/detectron2/projects/CenterNet2/configs/CenterNet2_DLA-BiFPN-P3_4x.yaml\"  \n\ncenternet.add_centernet_config(cfg)\n\ncfg.merge_from_file(config_name)\ncfg.DATASETS.TRAIN = (Data_Resister_training,)\ncfg.DATASETS.TEST = (Data_Resister_valid,)\n\n\ncfg.MODEL.WEIGHTS =\"/kaggle/input/centernet2-dla-bifpn-p3-4x-weight-file/CenterNet2_DLA-BiFPN-P3_4x.pth\"\n#cfg.MODEL.WEIGHTS = model_zoo.get_checkpoint_url(config_name)\ncfg.MODEL.ROI_HEADS.SCORE_THRESH_TEST = 0.45 \n\ncfg.DATALOADER.NUM_WORKERS = 2\n# cfg.MODEL.ROI_HEADS.BATCH_SIZE_PER_IMAGE = 4  # 64 is slower but more accurate (128 faster but less accurate)\n\n\ncfg.MODEL.ROI_HEADS.NUM_CLASSES = 1  # only has one class  + 1\n# cfg.MODEL.RETINANET.NUM_CLASSES = 1 # only has one class  + 1\n\ncfg.SOLVER.IMS_PER_BATCH = 4 #(2 is per defaults)\ncfg.SOLVER.BASE_LR = 0.005 #(quite high base learning rate but should drop)\n# cfg.SOLVER.GAMMA = 0.5\n#cfg.SOLVER.MOMENTUM = 0.938\n#cfg.SOLVER.WEIGHT_DECAY = 0.0005\n\n    \ncfg.SOLVER.WARMUP_ITERS = 5000 #How many iterations to go from 0 to reach base LR\ncfg.SOLVER.MAX_ITER = 25000 #Maximum of iterations 1\n#cfg.SOLVER.STEPS = (3000,4500) #At which point to change the LR 0.25,0.5\n\ncfg.TEST.EVAL_PERIOD = 500\ncfg.SOLVER.CHECKPOINT_PERIOD=5000\n\ncfg.INPUT.MIN_SIZE_TRAIN = 720\ncfg.INPUT.MAX_SIZE_TRAIN = 1280\ncfg.MAX_SIZE_TEST: 1280\ncfg.MIN_SIZE_TEST: 720\n\ncfg.OUTPUT_DIR = \"/kaggle/working/centernet2_output\"\n\nos.makedirs(cfg.OUTPUT_DIR, exist_ok=True)\n","metadata":{"_kg_hide-output":true,"papermill":{"duration":11443.937278,"end_time":"2022-01-12T01:02:17.322151","exception":false,"start_time":"2022-01-11T21:51:33.384873","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2022-01-18T11:57:25.339194Z","iopub.status.idle":"2022-01-18T11:57:25.339522Z","shell.execute_reply.started":"2022-01-18T11:57:25.339336Z","shell.execute_reply":"2022-01-18T11:57:25.339351Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import torch.distributed as dist\ndist.init_process_group('gloo', init_method='file:///tmp/somefile', rank=0, world_size=1)","metadata":{"execution":{"iopub.status.busy":"2022-01-18T11:57:25.340601Z","iopub.status.idle":"2022-01-18T11:57:25.3412Z","shell.execute_reply.started":"2022-01-18T11:57:25.341019Z","shell.execute_reply":"2022-01-18T11:57:25.341039Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# trainer = AugTrainer(cfg) # with  data augmentation  \ntrainer = Trainer(cfg)  # without data augmentation\ntrainer.resume_or_load(resume=False)\ntrainer.train()","metadata":{"execution":{"iopub.status.busy":"2022-01-18T11:57:25.342148Z","iopub.status.idle":"2022-01-18T11:57:25.342685Z","shell.execute_reply.started":"2022-01-18T11:57:25.342495Z","shell.execute_reply":"2022-01-18T11:57:25.342516Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Evaluator\n* Famouns dataset's evaluator is already implemented in detectron2.\n* For example, many kinds of AP (Average Precision) are calculted in COCOEvaluator.\n* COCOEvaluator calculates AP with IoU from 0.50 to 0.95\n### F2ScoreEvaluator\n* F2ScoreEvaluator calculates F2 Score with IoU from 0.30 to 0.80","metadata":{"papermill":{"duration":0.959172,"end_time":"2022-01-12T01:02:19.273515","exception":false,"start_time":"2022-01-12T01:02:18.314343","status":"completed"},"tags":[]}},{"cell_type":"code","source":"print('################################################################')\nprint('################### test the best model: F2 Score ##################')\nprint('################################################################')\ncfg.MODEL.WEIGHTS = os.path.join(cfg.OUTPUT_DIR, \"model_best.pth\")  # path to the model we just trained\ncfg.MODEL.ROI_HEADS.SCORE_THRESH_TEST = 0.5   # set a custom testing threshold\npredictor = DefaultPredictor(cfg)\nevaluator = F2ScoreEvaluator(Data_Resister_valid)\nval_loader = build_detection_test_loader(cfg, Data_Resister_valid)\nFS_bm=inference_on_dataset(predictor.model, val_loader, evaluator)['F2 Score']\nprint(\"F2 Score for best model=\",FS_bm)\n\nprint('################################################################')\nprint('################### test the best model : AP@50-95 ##################')\nprint('################################################################')\nevaluator = COCOEvaluator(Data_Resister_valid, output_dir=\"./output\")\nval_loader = build_detection_test_loader(cfg, Data_Resister_valid)\nAP_bm=inference_on_dataset(predictor.model, val_loader, evaluator)['bbox']['AP']\nprint(\"AP for best model=\",AP_bm)\n\nprint('################################################################')\nprint('################## test the final model: F2 Score ##################')\nprint('################################################################')\ncfg.MODEL.WEIGHTS = os.path.join(cfg.OUTPUT_DIR, \"model_final.pth\")  # path to the model we just trained\ncfg.MODEL.ROI_HEADS.SCORE_THRESH_TEST = 0.5   # set a custom testing threshold\npredictor = DefaultPredictor(cfg)\nevaluator = F2ScoreEvaluator(Data_Resister_valid)\nval_loader = build_detection_test_loader(cfg, Data_Resister_valid)\nFS_fm=inference_on_dataset(predictor.model, val_loader, evaluator)['F2 Score']\nprint(\"F2 Score for the final model=\",FS_fm)\nprint('################################################################')\nprint('################## test final model: AP@50-95 ##################')\nprint('################################################################')\nevaluator = COCOEvaluator(Data_Resister_valid, output_dir=\"./output\")\nval_loader = build_detection_test_loader(cfg, Data_Resister_valid)\nAP_fm=inference_on_dataset(predictor.model, val_loader, evaluator)['bbox']['AP']\nprint(\"AP for the final model=\",AP_fm)","metadata":{"_kg_hide-input":true,"_kg_hide-output":true,"papermill":{"duration":316.280736,"end_time":"2022-01-12T01:07:38.187216","exception":false,"start_time":"2022-01-12T01:02:21.90648","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2022-01-18T11:57:25.343612Z","iopub.status.idle":"2022-01-18T11:57:25.344182Z","shell.execute_reply.started":"2022-01-18T11:57:25.344005Z","shell.execute_reply":"2022-01-18T11:57:25.344024Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print(\"F2 Score for the best model=\",FS_bm)\nprint(\"F2 Score for the final model=\",FS_fm)\nprint(\"AP for the best model=\",AP_bm)\nprint(\"AP for the final model=\",AP_fm)","metadata":{"_kg_hide-input":true,"papermill":{"duration":0.917502,"end_time":"2022-01-12T01:07:40.030986","exception":false,"start_time":"2022-01-12T01:07:39.113484","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2022-01-18T11:57:25.345037Z","iopub.status.idle":"2022-01-18T11:57:25.345682Z","shell.execute_reply.started":"2022-01-18T11:57:25.345498Z","shell.execute_reply":"2022-01-18T11:57:25.345519Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Predictor","metadata":{"papermill":{"duration":1.069267,"end_time":"2022-01-12T01:07:46.749322","exception":false,"start_time":"2022-01-12T01:07:45.680055","status":"completed"},"tags":[]}},{"cell_type":"code","source":"cfg.MODEL.WEIGHTS = os.path.join(cfg.OUTPUT_DIR, \"model_best.pth\") \ncfg.MODEL.ROI_HEADS.SCORE_THRESH_TEST = 0.6   # set a custom testing threshold for this model\ncfg.DATASETS.TEST = (Data_Resister_valid, )\npredictor = DefaultPredictor(cfg)\n\nfig, ax = plt.subplots(4, 1, figsize =(20,50))\nindices=[ax[0],ax[1],ax[2],ax[3] ]\ni=-1\nfor d in random.sample(dataset_dicts_valid, 4):\n    i=i+1    \n    im = cv2.imread(d[\"file_name\"])\n    outputs = predictor(im)\n    v = Visualizer(im[:, :, :],\n                   metadata=metadata_dicts_valid, \n                   scale=1 # remove the colors of unsegmented pixels. This option is only available for segmentation models\n    )\n    out = v.draw_instance_predictions(outputs[\"instances\"].to(\"cpu\"))\n    indices[i].grid(False)\n    indices[i].imshow(out.get_image()[:, :, ::-1])","metadata":{"papermill":{"duration":5.5184,"end_time":"2022-01-12T01:07:53.183875","exception":false,"start_time":"2022-01-12T01:07:47.665475","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2022-01-18T11:57:25.348212Z","iopub.status.idle":"2022-01-18T11:57:25.348722Z","shell.execute_reply.started":"2022-01-18T11:57:25.348545Z","shell.execute_reply":"2022-01-18T11:57:25.348566Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"src=\"/kaggle/working/centernet2_output/model_best.pth\"\ndst=\"/kaggle/working/\"+str(filename)+\"_F2S\"+str(format(FS_bm,'.3f'))+\"_AP\"+ str(format(AP_bm,'.3f')) +\"_best.pth\"\nshutil.copy(src,dst)","metadata":{"papermill":{"duration":1.317256,"end_time":"2022-01-12T01:07:55.621963","exception":false,"start_time":"2022-01-12T01:07:54.304707","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2022-01-18T11:57:25.349642Z","iopub.status.idle":"2022-01-18T11:57:25.350094Z","shell.execute_reply.started":"2022-01-18T11:57:25.349932Z","shell.execute_reply":"2022-01-18T11:57:25.34995Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"src=\"/kaggle/working/centernet2_output/model_final.pth\"\ndst=\"/kaggle/working/\"+str(filename)+\"_F2S\"+str(format(FS_fm,'.3f'))+\"_AP\"+ str(format(AP_fm,'.3f')) +\"_final.pth\"\nshutil.copy(src,dst)","metadata":{"papermill":{"duration":1.57846,"end_time":"2022-01-12T01:07:58.61665","exception":false,"start_time":"2022-01-12T01:07:57.03819","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2022-01-18T11:57:25.351197Z","iopub.status.idle":"2022-01-18T11:57:25.351817Z","shell.execute_reply.started":"2022-01-18T11:57:25.351655Z","shell.execute_reply":"2022-01-18T11:57:25.351673Z"},"trusted":true},"execution_count":null,"outputs":[]}]}