{"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":"# Detectron2 Faster R-CNN starter\n\nThis is very basic starter notebook for [TensorFlow - Help Protect the Great Barrier Reef](https://www.kaggle.com/c/tensorflow-great-barrier-reef/overview) competetion.\n\nIt uses Detectron2's Faster R-CNN pretrained network with default settings.\n\nChangelog:\n\n* 02-Dec: initial version, box score threshold = 0.1 (LB 0.158)\n* 04-Dec: switch to Faster R-CNN X101 FPN (LB 0.269)\n\nHope it will be useful, enjoy)","metadata":{}},{"cell_type":"code","source":"!pip install ../input/detectron-05/whls/pycocotools-2.0.2/dist/pycocotools-2.0.2.tar --no-index --find-links ../input/detectron-05/whls \n!pip install ../input/detectron-05/whls/fvcore-0.1.5.post20211019/fvcore-0.1.5.post20211019 --no-index --find-links ../input/detectron-05/whls \n!pip install ../input/detectron-05/whls/antlr4-python3-runtime-4.8/antlr4-python3-runtime-4.8 --no-index --find-links ../input/detectron-05/whls \n!pip install ../input/detectron-05/whls/detectron2-0.5/detectron2 --no-index --find-links ../input/detectron-05/whls ","metadata":{"_kg_hide-output":true,"execution":{"iopub.status.busy":"2021-12-04T14:59:22.137101Z","iopub.execute_input":"2021-12-04T14:59:22.137664Z","iopub.status.idle":"2021-12-04T14:59:57.74891Z","shell.execute_reply.started":"2021-12-04T14:59:22.137572Z","shell.execute_reply":"2021-12-04T14:59:57.748072Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import sys\nimport os\nimport random\nimport logging\n\nfrom ast import literal_eval\n\nimport numpy as np\nimport pandas as pd\n\nimport cv2\n\nimport matplotlib.pyplot as plt\n\nimport torch, torchvision\n\nimport greatbarrierreef","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","execution":{"iopub.status.busy":"2021-12-04T14:59:57.752636Z","iopub.execute_input":"2021-12-04T14:59:57.753029Z","iopub.status.idle":"2021-12-04T14:59:58.727534Z","shell.execute_reply.started":"2021-12-04T14:59:57.752995Z","shell.execute_reply":"2021-12-04T14:59:58.726746Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from detectron2 import model_zoo\nfrom detectron2.data import DatasetCatalog, MetadataCatalog\nfrom detectron2.structures import BoxMode\nfrom detectron2.engine import DefaultTrainer, DefaultPredictor\nfrom detectron2.config import get_cfg","metadata":{"execution":{"iopub.status.busy":"2021-12-04T14:59:58.728964Z","iopub.execute_input":"2021-12-04T14:59:58.729238Z","iopub.status.idle":"2021-12-04T14:59:58.826678Z","shell.execute_reply.started":"2021-12-04T14:59:58.729202Z","shell.execute_reply":"2021-12-04T14:59:58.825133Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# configure logging to see info messages from detectron\nroot = logging.getLogger()\nroot.setLevel(logging.INFO)\nhandler = logging.StreamHandler(sys.stdout)\nhandler.setLevel(logging.INFO)\nformatter = logging.Formatter('%(levelname)s: %(message)s')\nhandler.setFormatter(formatter)\nroot.addHandler(handler)","metadata":{"execution":{"iopub.status.busy":"2021-12-04T14:59:58.827983Z","iopub.status.idle":"2021-12-04T14:59:58.828402Z","shell.execute_reply.started":"2021-12-04T14:59:58.828175Z","shell.execute_reply":"2021-12-04T14:59:58.828197Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# data directory\nDATA_DIR = '../input/tensorflow-great-barrier-reef'\n\n# function to return competition training data in Detectron format\ndef get_tf_gbreef_train():\n    df_train = pd.read_csv(os.path.join(DATA_DIR, 'train.csv'))\n                           \n    items = []\n    for index, row in df_train.iterrows():\n        # https://www.kaggle.com/c/tensorflow-great-barrier-reef/data \n        # train/ - Folder containing training set photos of the form video_{video_id}/{video_frame_number}.jpg\n        video_fn = os.path.join(DATA_DIR, 'train_images', f'video_{row[\"video_id\"]}', f'{row[\"video_frame\"]}.jpg')\n        boxes = []\n        for b in literal_eval(row['annotations']):\n            boxes.append({'bbox': [b['x'], b['y'], b['width'], b['height']],\n                          'bbox_mode': BoxMode.XYWH_ABS,\n                          'category_id': 0})\n        items.append({'file_name': video_fn,\n                      'height': 720,\n                      'width': 1280, \n                      'image_id': row['image_id'],\n                      'annotations': boxes})\n                     \n    return items\n\n# register train dataset\nDatasetCatalog.register('tf_gbreef_train', get_tf_gbreef_train)\nds_train = DatasetCatalog.get('tf_gbreef_train')","metadata":{"execution":{"iopub.status.busy":"2021-12-04T14:59:58.829957Z","iopub.status.idle":"2021-12-04T14:59:58.830383Z","shell.execute_reply.started":"2021-12-04T14:59:58.830152Z","shell.execute_reply":"2021-12-04T14:59:58.830175Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# show some random images and bounding boxes from training set\nnrows, ncols = 5, 2\nfig, ax = plt.subplots(nrows, ncols, figsize=(20,31))\n\ndisplayed = 0\nfor ti in random.sample(range(23500), 10000):\n    d = ds_train[ti]\n    if 0 == len(d['annotations']): continue  # skip images without bounding boxes\n        \n    img = cv2.cvtColor(cv2.imread(d[\"file_name\"]), cv2.COLOR_BGR2RGB)\n    for a in d['annotations']:\n        b = a['bbox']\n        cv2.rectangle(img, (b[0], b[1]), (b[0]+b[2], b[1]+b[3]), color=(255, 255, 255), thickness=2)\n    \n    ax[displayed // ncols, displayed % ncols].grid(False)\n    ax[displayed // ncols, displayed % ncols].axis('off')\n    ax[displayed // ncols, displayed % ncols].imshow(img)\n    \n    displayed += 1\n    if nrows * ncols <= displayed: break\n        \nplt.tight_layout()\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2021-12-04T14:59:58.831884Z","iopub.status.idle":"2021-12-04T14:59:58.832487Z","shell.execute_reply.started":"2021-12-04T14:59:58.832249Z","shell.execute_reply":"2021-12-04T14:59:58.832274Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# get config and merge it with Faster R-CNN config from Detectron zoo\ncfg = get_cfg()\ncfg.merge_from_file(model_zoo.get_config_file('COCO-Detection/faster_rcnn_X_101_32x8d_FPN_3x.yaml'))\n\ncfg.DATASETS.TRAIN = ('tf_gbreef_train',)\ncfg.DATASETS.TEST = ()\ncfg.DATALOADER.NUM_WORKERS = 1\ncfg.MODEL.WEIGHTS = \"../input/detectron2-faster-rcnn-x101/model_final_68b088.pkl\"  # get weigths from attached dataset\ncfg.SOLVER.IMS_PER_BATCH = 2  # batch size\ncfg.SOLVER.BASE_LR = 0.001  # learning rate\ncfg.SOLVER.MAX_ITER = 20000  # dataset has ~5000 images with annotations so 100000 iterations is ~40 epochs with batch size of 2\ncfg.MODEL.ROI_HEADS.NUM_CLASSES = 1  # we have single class in this competition","metadata":{"execution":{"iopub.status.busy":"2021-12-04T14:59:58.833437Z","iopub.status.idle":"2021-12-04T14:59:58.834315Z","shell.execute_reply.started":"2021-12-04T14:59:58.834068Z","shell.execute_reply":"2021-12-04T14:59:58.834094Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# make output dir, created default trainer and go ahead)\nos.makedirs(cfg.OUTPUT_DIR, exist_ok=True)\ntrainer = DefaultTrainer(cfg) \ntrainer.resume_or_load(resume=False)\ntrainer.train()","metadata":{"_kg_hide-output":true,"execution":{"iopub.status.busy":"2021-12-04T14:59:58.835326Z","iopub.status.idle":"2021-12-04T14:59:58.836107Z","shell.execute_reply.started":"2021-12-04T14:59:58.835874Z","shell.execute_reply":"2021-12-04T14:59:58.835898Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# pickup weights from training and create predictor\ncfg.MODEL.WEIGHTS = os.path.join(cfg.OUTPUT_DIR, \"model_final.pth\")\ncfg.MODEL.ROI_HEADS.SCORE_THRESH_TEST = 0.3   # set threshold for boxes to return\npredictor = DefaultPredictor(cfg)","metadata":{"execution":{"iopub.status.busy":"2021-12-04T14:59:58.837165Z","iopub.status.idle":"2021-12-04T14:59:58.838001Z","shell.execute_reply.started":"2021-12-04T14:59:58.83771Z","shell.execute_reply":"2021-12-04T14:59:58.837754Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# simple function to format predictions\ndef format_predictions(out):\n    l = []\n    for i in range(len(out['instances'])):\n        box = out['instances'].pred_boxes[i].tensor.cpu().numpy().flatten()\n        score = out['instances'].scores[0].cpu().numpy()\n        # XYXY to XYWH\n        l.append(f'{score:.3f} {box[0]:.0f} {box[1]:.0f} {(box[2]-box[0]):.0f} {(box[3]-box[1]):.0f}')\n    return ' '.join(l)\n\n# create prediction env and iterator\nenv = greatbarrierreef.make_env()   # initialize the environment\niter_test = env.iter_test()    # an iterator which loops over the test set and sample submission\n\n# iterate over test images and do prediction\nfor (pixel_array, sample_prediction_df) in iter_test:\n    out = predictor(pixel_array)\n    sample_prediction_df['annotations'] = format_predictions(out)\n    env.predict(sample_prediction_df)","metadata":{"execution":{"iopub.status.busy":"2021-12-04T14:59:58.839097Z","iopub.status.idle":"2021-12-04T14:59:58.839895Z","shell.execute_reply.started":"2021-12-04T14:59:58.839618Z","shell.execute_reply":"2021-12-04T14:59:58.839644Z"},"trusted":true},"execution_count":null,"outputs":[]}]}