{"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":"!pip install 'git+https://github.com/facebookresearch/detectron2.git' -Uqqq","metadata":{"execution":{"iopub.status.busy":"2022-05-09T05:33:10.267487Z","iopub.execute_input":"2022-05-09T05:33:10.267774Z","iopub.status.idle":"2022-05-09T05:33:21.370725Z","shell.execute_reply.started":"2022-05-09T05:33:10.267743Z","shell.execute_reply":"2022-05-09T05:33:21.369783Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import detectron2\nfrom pathlib import Path\nimport random, cv2, os\nimport matplotlib.pyplot as plt\nimport numpy as np\nimport pycocotools.mask as mask_util\nimport torch\n\n# import some common detectron2 utilities\nfrom detectron2 import model_zoo\nfrom detectron2.engine import DefaultPredictor, DefaultTrainer\nfrom detectron2.config import get_cfg\nfrom detectron2.utils.visualizer import Visualizer, ColorMode\nfrom detectron2.data import MetadataCatalog, DatasetCatalog\nfrom detectron2.data.datasets import register_coco_instances\nfrom detectron2.utils.logger import setup_logger\nfrom detectron2.evaluation.evaluator import DatasetEvaluator\nfrom detectron2.projects import point_rend\nsetup_logger()","metadata":{"execution":{"iopub.status.busy":"2022-05-09T05:33:21.372792Z","iopub.execute_input":"2022-05-09T05:33:21.373047Z","iopub.status.idle":"2022-05-09T05:33:21.383464Z","shell.execute_reply.started":"2022-05-09T05:33:21.373016Z","shell.execute_reply":"2022-05-09T05:33:21.38258Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"cfg = get_cfg()\npoint_rend.add_pointrend_config(cfg)","metadata":{"execution":{"iopub.status.busy":"2022-05-09T05:33:21.384585Z","iopub.execute_input":"2022-05-09T05:33:21.384834Z","iopub.status.idle":"2022-05-09T05:33:21.400342Z","shell.execute_reply.started":"2022-05-09T05:33:21.384797Z","shell.execute_reply":"2022-05-09T05:33:21.399497Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"dataDir=Path('../input/sartorius-cell-instance-segmentation/')\ncfg.INPUT.MASK_FORMAT='bitmask'\nregister_coco_instances('sartorius_train',{}, '../input/sartorius-cell-instance-segmentation-coco/annotations_train.json', dataDir)\nregister_coco_instances('sartorius_val',{},'../input/sartorius-cell-instance-segmentation-coco/annotations_val.json', dataDir)\nmetadata = MetadataCatalog.get('sartorius_train')\ntrain_ds = DatasetCatalog.get('sartorius_train')","metadata":{"execution":{"iopub.status.busy":"2022-05-09T05:33:21.404221Z","iopub.execute_input":"2022-05-09T05:33:21.404425Z","iopub.status.idle":"2022-05-09T05:33:21.447233Z","shell.execute_reply.started":"2022-05-09T05:33:21.404402Z","shell.execute_reply":"2022-05-09T05:33:21.446227Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class_no = dict(zip(metadata.thing_classes, [0, 1, 2]))\nclass_no","metadata":{"execution":{"iopub.status.busy":"2022-05-09T05:33:34.242046Z","iopub.execute_input":"2022-05-09T05:33:34.242307Z","iopub.status.idle":"2022-05-09T05:33:34.247951Z","shell.execute_reply.started":"2022-05-09T05:33:34.242278Z","shell.execute_reply":"2022-05-09T05:33:34.247257Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"d = train_ds[42]\nimg = cv2.imread(d['file_name'])\nplt.imshow(img[:, :, ::-1])\nplt.imsave(\"astro_base.jpg\", img[:, :, ::-1])","metadata":{"execution":{"iopub.status.busy":"2022-05-09T05:33:34.501178Z","iopub.execute_input":"2022-05-09T05:33:34.501671Z","iopub.status.idle":"2022-05-09T05:33:34.787856Z","shell.execute_reply.started":"2022-05-09T05:33:34.501637Z","shell.execute_reply":"2022-05-09T05:33:34.78717Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"visualizer = Visualizer(img[:, :, ::-1], metadata=metadata)\nout = visualizer.draw_dataset_dict(d)\nplt.figure(figsize=(20, 15))\nplt.imshow(out.get_image()[:, :, ::-1])","metadata":{"execution":{"iopub.status.busy":"2022-05-09T05:33:34.789497Z","iopub.execute_input":"2022-05-09T05:33:34.789753Z","iopub.status.idle":"2022-05-09T05:33:35.839779Z","shell.execute_reply.started":"2022-05-09T05:33:34.789718Z","shell.execute_reply":"2022-05-09T05:33:35.835831Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class AxisError(Exception):\n    pass","metadata":{"execution":{"iopub.status.busy":"2022-05-09T05:33:35.841371Z","iopub.execute_input":"2022-05-09T05:33:35.841788Z","iopub.status.idle":"2022-05-09T05:33:35.845708Z","shell.execute_reply.started":"2022-05-09T05:33:35.841753Z","shell.execute_reply":"2022-05-09T05:33:35.845027Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def 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    pred_class = torch.mode(pred['instances'].pred_classes)[0]\n    take = pred['instances'].scores >= THRESHOLDS[pred_class]\n#     print(pred['instances'].pred_masks, pred['instances'].pred_masks.shape, pred['instances'].pred_masks.ndim)\n    pred_masks = pred['instances'].pred_masks[take]\n    pred_masks = pred_masks.cpu().numpy()\n#     print(pred_masks, pred_masks.shape, pred_masks.ndim)\n    res = []\n    for mask in pred_masks:\n        if mask.sum() >= MIN_PIXELS[pred_class]:\n            res.append(mask)\n    pred_masks = pred['instances'].pred_masks.cpu().numpy()\n    enc_preds = [mask_util.encode(np.asarray(p, order='F')) for p in pred_masks]\n    enc_targs = list(map(lambda x:x['segmentation'], targ))\n    ious = mask_util.iou(enc_preds, enc_targs, [0]*len(enc_targs))\n    prec = []\n    for t in np.arange(0.5, 1.0, 0.05):\n        try:\n            tp, fp, fn = precision_at(t, ious)\n            p = tp / (tp + fp + fn)\n        except :\n            print(\"AxisError\")\n            p = 0\n        prec.append(p)\n    return np.mean(prec)\n\nclass MAPIOUEvaluator(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 {\"MaP IoU\": np.mean(self.scores)}\n\nclass Trainer(DefaultTrainer):\n    @classmethod\n    def build_evaluator(cls, cfg, dataset_name, output_folder=None):\n        return MAPIOUEvaluator(dataset_name)","metadata":{"execution":{"iopub.status.busy":"2022-05-09T05:33:35.846952Z","iopub.execute_input":"2022-05-09T05:33:35.847183Z","iopub.status.idle":"2022-05-09T05:33:35.867288Z","shell.execute_reply.started":"2022-05-09T05:33:35.847153Z","shell.execute_reply":"2022-05-09T05:33:35.866573Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"\n#cfg.merge_from_file(\"../input/detectron-05/whls/detectron2-0.5/detectron2/projects/PointRend/configs/InstanceSegmentation/pointrend_rcnn_X_101_32x8d_FPN_3x_coco.yaml\")\ncfg.merge_from_file(\"../input/detectron-05/whls/detectron2-0.5/detectron2/projects/PointRend/configs/InstanceSegmentation/pointrend_rcnn_R_50_FPN_3x_coco.yaml\")\n#https://github.com/facebookresearch/detectron2/blob/main/configs/COCO-InstanceSegmentation/mask_rcnn_X_101_32x8d_FPN_3x.yaml\ncfg.DATASETS.TRAIN = (\"sartorius_train\",)\ncfg.DATASETS.TEST = (\"sartorius_val\",)\ncfg.DATALOADER.NUM_WORKERS = 2\n#cfg.MODEL.WEIGHTS = \"detectron2://PointRend/InstanceSegmentation/pointrend_rcnn_X_101_32x8d_FPN_3x_coco/28119989/model_final_ba17b9.pkl\"  # Let training initialize from model zoo\ncfg.MODEL.WEIGHTS = \"detectron2://PointRend/InstanceSegmentation/pointrend_rcnn_R_50_FPN_3x_coco/164955410/model_final_edd263.pkl\"\ncfg.SOLVER.IMS_PER_BATCH = 2\ncfg.SOLVER.BASE_LR = 0.0005\ncfg.SOLVER.MAX_ITER = 7000\ncfg.SOLVER.STEPS = []\ncfg.MODEL.ROI_HEADS.BATCH_SIZE_PER_IMAGE = 500\ncfg.MODEL.ROI_HEADS.NUM_CLASSES = 3\ncfg.MODEL.POINT_HEAD.NUM_CLASSES = 3\ncfg.MODEL.ROI_HEADS.SCORE_THRESH_TEST = .3\ncfg.TEST.EVAL_PERIOD = len(DatasetCatalog.get(\"sartorius_train\")) // cfg.SOLVER.IMS_PER_BATCH  # Once per epoch\ncfg.TEST.DETECTIONS_PER_IMAGE = 1000\ncfg.MODEL.POINT_HEAD.TRAIN_NUM_POINTS = 20 * 20\ncfg.MODEL.POINT_HEAD.SUBDIVISION_NUM_POINTS = 40 * 40\n\nTHRESHOLDS = [0.30, 0.35, 0.5]\nMIN_PIXELS = [70, 150, 75]\n\nos.makedirs(cfg.OUTPUT_DIR, exist_ok=True)\ntrainer = Trainer(cfg)\ntrainer.resume_or_load(resume=False)\ntrainer.train()","metadata":{"execution":{"iopub.status.busy":"2022-05-09T05:33:35.868953Z","iopub.execute_input":"2022-05-09T05:33:35.869552Z","iopub.status.idle":"2022-05-09T05:36:28.785956Z","shell.execute_reply.started":"2022-05-09T05:33:35.869518Z","shell.execute_reply":"2022-05-09T05:36:28.785032Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"cfg.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)\ndataset_dicts = DatasetCatalog.get('sartorius_val')\nouts = []\nfor d in random.sample(dataset_dicts, 3):\n    im = cv2.imread(d[\"file_name\"])\n    outputs = predictor(im)  # format is documented at https://detectron2.readthedocs.io/tutorials/models.html#model-output-format\n    v = Visualizer(im[:, :, ::-1],\n                   metadata = MetadataCatalog.get('sartorius_train'), \n                    \n                   instance_mode=ColorMode.IMAGE_BW   # remove the colors of unsegmented pixels. This option is only available for segmentation models\n    )\n    out_pred = v.draw_instance_predictions(outputs[\"instances\"].to(\"cpu\"))\n    visualizer = Visualizer(im[:, :, ::-1], metadata=MetadataCatalog.get('sartorius_train'))\n    out_target = visualizer.draw_dataset_dict(d)\n    outs.append(out_pred)\n    outs.append(out_target)\n_,axs = plt.subplots(len(outs)//2,2,figsize=(40,45))\nfor ax, out in zip(axs.reshape(-1), outs):\n    ax.imshow(out.get_image()[:, :, ::-1])","metadata":{"execution":{"iopub.status.busy":"2022-05-09T05:36:28.787666Z","iopub.execute_input":"2022-05-09T05:36:28.787948Z","iopub.status.idle":"2022-05-09T05:36:35.241149Z","shell.execute_reply.started":"2022-05-09T05:36:28.787905Z","shell.execute_reply":"2022-05-09T05:36:35.237424Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"!ls ./output/model_final.pth","metadata":{"execution":{"iopub.status.busy":"2022-05-09T05:36:35.242707Z","iopub.execute_input":"2022-05-09T05:36:35.243168Z","iopub.status.idle":"2022-05-09T05:36:35.989751Z","shell.execute_reply.started":"2022-05-09T05:36:35.243132Z","shell.execute_reply":"2022-05-09T05:36:35.988913Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]}]}