{"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":"# Intro\n\nCompetition home page: https://www.kaggle.com/c/sartorius-cell-instance-segmentation","metadata":{}},{"cell_type":"markdown","source":"# Import Libraries","metadata":{}},{"cell_type":"code","source":"# Install pycocotools\n!pip install pycocotools","metadata":{"execution":{"iopub.status.busy":"2022-03-02T20:28:24.335950Z","iopub.execute_input":"2022-03-02T20:28:24.336345Z","iopub.status.idle":"2022-03-02T20:28:57.293858Z","shell.execute_reply.started":"2022-03-02T20:28:24.336227Z","shell.execute_reply":"2022-03-02T20:28:57.293006Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Install detecton2\n# No pre-build for tocrch 1.9.1 and cuda 11.0. Consider cpu instead.\n#!pip install detectron2 -f \\\n#  https://dl.fbaipublicfiles.com/detectron2/wheels/cpu/torch1.9/index.html\n\n!python -m pip install 'git+https://github.com/facebookresearch/detectron2.git'","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","execution":{"iopub.status.busy":"2022-03-02T20:28:57.297414Z","iopub.execute_input":"2022-03-02T20:28:57.297629Z","iopub.status.idle":"2022-03-02T20:31:44.821760Z","shell.execute_reply.started":"2022-03-02T20:28:57.297601Z","shell.execute_reply":"2022-03-02T20:31:44.820887Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import os\nimport copy\nimport pickle\nimport argparse\nimport json\nimport random\nimport sys\nimport time\nimport datetime\nimport logging\nfrom tqdm.notebook import tqdm\nfrom joblib import Parallel, delayed\n\nimport pandas as pd\nimport numpy as np\n\nfrom PIL import Image\nimport cv2\nimport pydicom\nfrom pydicom.pixel_data_handlers.util import apply_voi_lut\nimport matplotlib.pyplot as plt\n\nfrom sklearn.model_selection import StratifiedKFold\n\nimport torch\nfrom detectron2 import model_zoo\nfrom detectron2.structures import BoxMode\nimport detectron2.data.transforms as T\nfrom detectron2.data import detection_utils as utils\nfrom detectron2.data import build_detection_test_loader, build_detection_train_loader\nfrom detectron2.engine import DefaultPredictor, DefaultTrainer, launch\nfrom detectron2.evaluation import COCOEvaluator, PascalVOCDetectionEvaluator\nfrom detectron2.config import CfgNode as CN\nfrom detectron2.config import get_cfg\nimport detectron2\nfrom detectron2 import model_zoo\nfrom detectron2.config import get_cfg\nfrom detectron2.data import DatasetCatalog, MetadataCatalog\nfrom detectron2.utils.logger import setup_logger, log_every_n_seconds\nfrom detectron2.utils.visualizer import Visualizer, ColorMode\nfrom detectron2.engine.hooks import HookBase\nimport detectron2.utils.comm as comm\nfrom detectron2.data.datasets import register_coco_instances\n\nfrom pycocotools import mask as maskUtils","metadata":{"execution":{"iopub.status.busy":"2022-03-02T20:31:44.823549Z","iopub.execute_input":"2022-03-02T20:31:44.823836Z","iopub.status.idle":"2022-03-02T20:31:46.895873Z","shell.execute_reply.started":"2022-03-02T20:31:44.823786Z","shell.execute_reply":"2022-03-02T20:31:46.895134Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Set configs","metadata":{}},{"cell_type":"code","source":"cfgDict = {\n    \"dicomPath\": None,\n    \"orgDataPath\": \"../input/sartorius-cell-instance-segmentation/\",\n    \"trainJsonPath\": \"../input/crossvalidationfold5/coco_cell_train_fold3.json\",\n    \"validJsonPath\": \"../input/crossvalidationfold5/coco_cell_valid_fold3.json\",\n    \"newDataPath\": None,\n    \"cachePath\": \"./\",\n    \"trainDataName\": \"sartoriusTrain\",\n    \"validDataName\": \"sartoriusValid\",\n    \"sampleSize\": 1000,\n    \"imSize\": None,\n    \"modelName\": \"COCO-InstanceSegmentation/mask_rcnn_R_50_FPN_3x.yaml\",\n    \"mask_format\": \"bitmask\",\n    \"debug\": False,\n    \"outdir\": \"./results/\",\n    \"logFile\": \"log.txt\",\n    \"splitMode\": True,\n    \"seed\": 111,\n    \"device\": \"cuda\",\n    \"iter\": 1000,\n    \"ims_per_batch\": 8,\n    \"roi_batch_size_per_image\": 128,\n    \"eval_period\": 50,\n    \"lr_scheduler_name\": \"WarmupCosineLR\",\n    \"base_lr\": 0.001,\n    \"checkpoint_period\":500,\n    \"num_workers\": 2,\n    \"score_thresh_test\": 0.5,\n    \"augKwargs\": {\n        \"RandomFlip\": {\"prob\": 0.5},\n        \"RandomRotation\": {\"angle\": [0,360]}\n    }\n}\n\nsetup_logger(os.path.join(cfgDict[\"outdir\"],cfgDict[\"logFile\"]))","metadata":{"execution":{"iopub.status.busy":"2022-03-02T20:31:46.897869Z","iopub.execute_input":"2022-03-02T20:31:46.898115Z","iopub.status.idle":"2022-03-02T20:31:46.911476Z","shell.execute_reply.started":"2022-03-02T20:31:46.898081Z","shell.execute_reply":"2022-03-02T20:31:46.910493Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Convert annotations to COCO format\n\nWe use the dataset https://www.kaggle.com/ammarnassanalhajali/crossvalidationfold5.\n\nExample code is provided below.","metadata":{}},{"cell_type":"code","source":"# Decode rle to binary mask\ndef rle2mask(rle,h,w):\n    # Reshape rle to (2, N) where 2 is for start and length\n    rleArray = np.fromiter(rle.split(), dtype = np.uint)\n    rleArray = rleArray.reshape((-1,2)).T\n    rleArray[0] = rleArray[0] - 1\n    # Decompress the rle length (eg, [3, 1, 10, 2] to [3, 4, 10, 11, 12]\n    starts, lenghts = rleArray\n    rleArray = np.concatenate([np.arange(s, s + l, dtype = np.uint) \n                                        for s, l in zip(starts, lenghts)])\n    # Create the binary mask\n    mask = np.zeros(h*w, dtype = np.uint8)\n    mask[rleArray] = 1\n    mask = mask.reshape((h,w))    \n    # Convert to obj that pycocotools can handle\n    mask = np.asfortranarray(mask) \n    \n    return mask","metadata":{"execution":{"iopub.status.busy":"2022-03-02T20:31:46.912770Z","iopub.execute_input":"2022-03-02T20:31:46.913207Z","iopub.status.idle":"2022-03-02T20:31:46.924367Z","shell.execute_reply.started":"2022-03-02T20:31:46.913170Z","shell.execute_reply":"2022-03-02T20:31:46.923659Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Encode the binary mask to COCO annotation with rle\ndef mask2annotation(idx, row, catIds):\n    # rle to binary mask\n    mask = rle2mask(row['annotation'],row['height'],row['width']) \n    # Encode to rle (coco format)\n    rle = maskUtils.encode(mask) \n    # Convert from binary to utf-8\n    rle['counts'] = rle['counts'].decode('utf-8')\n    # Calculate the area\n    area = maskUtils.area(rle).item()\n    # Calculate the bboxes\n    bbox = maskUtils.toBbox(rle).astype(int).tolist() \n    # Create COCO annotation\n    annotation = {  'segmentation': rle,\n                    'bbox': bbox,\n                    'area': area,\n                    'image_id':row['id'], \n                    'category_id':catIds[row['cell_type']], \n                    'iscrowd': 0, \n                    'id': idx }\n    \n    return annotation","metadata":{"execution":{"iopub.status.busy":"2022-03-02T20:31:46.927261Z","iopub.execute_input":"2022-03-02T20:31:46.927770Z","iopub.status.idle":"2022-03-02T20:31:46.936049Z","shell.execute_reply.started":"2022-03-02T20:31:46.927743Z","shell.execute_reply":"2022-03-02T20:31:46.935358Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Create COCO format JSON\ndef df2COCO(cfg,df,workers=4):\n    # Build header\n    catIds = {name:id+1 for id, name in enumerate(df.cell_type.unique())}    \n    cats =[{'name':name, 'id':id} for name,id in catIds.items()]\n    images = [{'id':id, 'width':row.width, 'height':row.height, \n               'file_name': f'train/{id}.png'} \n              for id,row in df.groupby('id').agg('first').iterrows()]\n    \n    # Build annotations\n    annotations = Parallel(n_jobs=workers)(delayed(mask2annotation)(idx, row, catIds) \n                                           for idx, row in tqdm(df.iterrows(), total = len(df)))\n        \n    return {'categories':cats, 'images':images, 'annotations':annotations}","metadata":{"execution":{"iopub.status.busy":"2022-03-02T20:31:46.939325Z","iopub.execute_input":"2022-03-02T20:31:46.940618Z","iopub.status.idle":"2022-03-02T20:31:46.949385Z","shell.execute_reply.started":"2022-03-02T20:31:46.940588Z","shell.execute_reply":"2022-03-02T20:31:46.948654Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Save to json\ndf = pd.read_csv(os.path.join(cfgDict[\"orgDataPath\"],\"train.csv\"))\ndf.head()\nroot = df2COCO(cfgDict,df[:cfgDict[\"sampleSize\"]])\nwith open('annotations_train.json', 'w', encoding='utf-8') as f:\n    json.dump(root, f, ensure_ascii=True, indent=4)","metadata":{"execution":{"iopub.status.busy":"2022-03-02T20:31:46.952376Z","iopub.execute_input":"2022-03-02T20:31:46.952884Z","iopub.status.idle":"2022-03-02T20:31:51.143761Z","shell.execute_reply.started":"2022-03-02T20:31:46.952858Z","shell.execute_reply":"2022-03-02T20:31:51.142991Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Prepare augmentation","metadata":{}},{"cell_type":"code","source":"class AugMapper:\n    \"\"\"Custom mapper class for augmentations\"\"\"\n\n    def __init__(self, cfg, isTrain=True):\n        augKwargs = cfg[\"augKwargs\"]\n        augList = []\n        # Define a sequence of augmentations\n        if isTrain:\n            augList.extend([getattr(T, name)(**kwargs) for name, kwargs in augKwargs.items()])\n        self.augmentations = T.AugmentationList(augList)\n        self.isTrain = isTrain\n        self.cfg = cfg\n\n    def __call__(self, datasetDict):\n        datasetDict = copy.deepcopy(datasetDict)  # it will be modified by code below\n        image = utils.read_image(datasetDict[\"file_name\"], format=\"BGR\")\n        augInput = T.AugInput(image) # the augmentation input\n        transforms = self.augmentations(augInput) # apply the augmentation\n        image = augInput.image # new image\n        imShape = image.shape[:2]  # h, w\n        datasetDict[\"image\"] = torch.as_tensor(image.transpose(2, 0, 1).astype(\"float32\")) # HWC to CHW\n        annos = [ utils.transform_instance_annotations(annotation, transforms, imShape) \n                    for annotation in datasetDict.pop(\"annotations\") \n                    if annotation.get(\"iscrowd\", 0) == 0 ] # apply the augmentation to annotation\n        instances = utils.annotations_to_instances(annos,imShape,mask_format=self.cfg.INPUT.MASK_FORMAT)\n        datasetDict[\"instances\"] = utils.filter_empty_instances(instances)\n        \n        return datasetDict","metadata":{"execution":{"iopub.status.busy":"2022-03-02T20:31:51.145276Z","iopub.execute_input":"2022-03-02T20:31:51.145555Z","iopub.status.idle":"2022-03-02T20:31:51.156309Z","shell.execute_reply.started":"2022-03-02T20:31:51.145519Z","shell.execute_reply":"2022-03-02T20:31:51.155527Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Prepare loss eval hook for validation","metadata":{}},{"cell_type":"code","source":"class LossEvalHook(HookBase):\n    def __init__(self, eval_period, model, data_loader):\n        self._model = model\n        self._period = eval_period\n        self._data_loader = data_loader\n    \n    def _do_loss_eval(self):\n        # Copying inference_on_dataset from evaluator.py\n        total = len(self._data_loader)\n        num_warmup = min(5, total - 1)\n            \n        start_time = time.perf_counter()\n        total_compute_time = 0\n        losses = []\n        for idx, inputs in enumerate(self._data_loader):            \n            if idx == num_warmup:\n                start_time = time.perf_counter()\n                total_compute_time = 0\n            start_compute_time = time.perf_counter()\n            if torch.cuda.is_available():\n                torch.cuda.synchronize()\n            total_compute_time += time.perf_counter() - start_compute_time\n            iters_after_start = idx + 1 - num_warmup * int(idx >= num_warmup)\n            seconds_per_img = total_compute_time / iters_after_start\n            if idx >= num_warmup * 2 or seconds_per_img > 5:\n                total_seconds_per_img = (time.perf_counter() - start_time) / iters_after_start\n                eta = datetime.timedelta(seconds=int(total_seconds_per_img * (total - idx - 1)))\n                log_every_n_seconds(\n                    logging.INFO,\n                    \"Loss on Validation  done {}/{}. {:.4f} s / img. ETA={}\".format(\n                        idx + 1, total, seconds_per_img, str(eta)\n                    ),\n                    n=5,\n                )\n            loss_batch = self._get_loss(inputs)\n            losses.append(loss_batch)\n        mean_loss = np.mean(losses)\n        comm.synchronize()\n\n        return mean_loss\n            \n    def _get_loss(self, data):\n        # How loss is calculated on train_loop \n        metrics_dict = self._model(data)\n        metrics_dict = {\n            k: v.detach().cpu().item() if isinstance(v, torch.Tensor) else float(v)\n            for k, v in metrics_dict.items()\n        }\n        total_losses_reduced = sum(loss for loss in metrics_dict.values())\n        return total_losses_reduced\n        \n        \n    def after_step(self):\n        next_iter = self.trainer.iter + 1\n        is_final = next_iter == self.trainer.max_iter\n        if is_final or (self._period > 0 and next_iter % self._period == 0):\n            mean_loss = self._do_loss_eval()\n            self.trainer.storage.put_scalars(validation_loss=mean_loss)\n            print(\"validation do loss eval\", mean_loss)","metadata":{"execution":{"iopub.status.busy":"2022-03-02T20:31:51.160320Z","iopub.execute_input":"2022-03-02T20:31:51.160613Z","iopub.status.idle":"2022-03-02T20:31:51.177532Z","shell.execute_reply.started":"2022-03-02T20:31:51.160577Z","shell.execute_reply":"2022-03-02T20:31:51.176316Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Custom DefaultTrainer","metadata":{}},{"cell_type":"code","source":"class MyTrainer(DefaultTrainer):\n    \"\"\"Overwrite DefaultTrainer methods\"\"\"\n    \n    @classmethod\n    def build_train_loader(cls, cfg, sampler=None):\n        return build_detection_train_loader(\n            cfg, mapper=AugMapper(cfg, True), sampler=sampler\n        )\n\n    @classmethod\n    def build_test_loader(cls, cfg, datasetName):\n        return build_detection_test_loader(\n            cfg, datasetName, mapper=AugMapper(cfg, False)\n        )\n\n    @classmethod\n    def build_evaluator(cls, cfg, datasetName, outputFolder=None):\n        if outputFolder is None:\n            outputFolder = os.path.join(cfg.OUTPUT_DIR, \"inference\")\n        return COCOEvaluator(datasetName, (\"bbox\",), False, output_dir=outputFolder)\n    \n    def build_hooks(self):\n        hooks = super(MyTrainer, self).build_hooks()\n        cfg = self.cfg\n        if len(cfg.DATASETS.TEST) > 0:\n            loss_eval_hook = LossEvalHook(\n                cfg.TEST.EVAL_PERIOD,\n                self.model,\n                MyTrainer.build_test_loader(cfg, cfg.DATASETS.TEST[0]),\n            )\n            hooks.insert(-1, loss_eval_hook)\n\n        return hooks","metadata":{"execution":{"iopub.status.busy":"2022-03-02T20:31:51.179390Z","iopub.execute_input":"2022-03-02T20:31:51.179684Z","iopub.status.idle":"2022-03-02T20:31:51.191749Z","shell.execute_reply.started":"2022-03-02T20:31:51.179643Z","shell.execute_reply":"2022-03-02T20:31:51.191005Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Load and register data","metadata":{}},{"cell_type":"code","source":"DatasetCatalog.clear()\nregister_coco_instances(cfgDict[\"trainDataName\"],{},cfgDict[\"trainJsonPath\"],cfgDict[\"orgDataPath\"])\nregister_coco_instances(cfgDict[\"validDataName\"],{},cfgDict[\"validJsonPath\"],cfgDict[\"orgDataPath\"])\n\nmetadata = MetadataCatalog.get(cfgDict[\"trainDataName\"])\ndatasetTrain = DatasetCatalog.get(cfgDict[\"trainDataName\"])\ndatasetValid = DatasetCatalog.get(cfgDict[\"validDataName\"])","metadata":{"execution":{"iopub.status.busy":"2022-03-02T20:31:51.193418Z","iopub.execute_input":"2022-03-02T20:31:51.193734Z","iopub.status.idle":"2022-03-02T20:31:54.978678Z","shell.execute_reply.started":"2022-03-02T20:31:51.193696Z","shell.execute_reply":"2022-03-02T20:31:54.977912Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Visualize data","metadata":{}},{"cell_type":"code","source":"d = datasetTrain[0]\nimg = cv2.imread(d[\"file_name\"])\nvisualizer = Visualizer(img[:, :, ::-1], metadata=metadata, scale=1, instance_mode=ColorMode.IMAGE_BW)\nout = visualizer.draw_dataset_dict(d)\nImage.fromarray(out.get_image()[:, :, ::-1])","metadata":{"execution":{"iopub.status.busy":"2022-03-02T20:31:54.979797Z","iopub.execute_input":"2022-03-02T20:31:54.980054Z","iopub.status.idle":"2022-03-02T20:31:57.147765Z","shell.execute_reply.started":"2022-03-02T20:31:54.980022Z","shell.execute_reply":"2022-03-02T20:31:57.146586Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Create Yacs config","metadata":{}},{"cell_type":"code","source":"cfg = get_cfg()\n\ncfg.augKwargs = CN(cfgDict[\"augKwargs\"])  # pass augKwargs to cfg as a CN\ncfg.merge_from_file(model_zoo.get_config_file(cfgDict[\"modelName\"]))\ncfg.MODEL.DEVICE = cfgDict[\"device\"]\ncfg.OUTPUT_DIR = cfgDict[\"outdir\"]\ncfg.DATASETS.TRAIN = (cfgDict[\"trainDataName\"],)\nif cfgDict[\"splitMode\"] is None:\n    cfg.DATASETS.TEST = ()\nelse:\n    cfg.DATASETS.TEST = (cfgDict[\"validDataName\"],)\n    cfg.TEST.EVAL_PERIOD = cfgDict[\"eval_period\"]\ncfg.DATALOADER.NUM_WORKERS = cfgDict[\"num_workers\"]\ncfg.MODEL.WEIGHTS = model_zoo.get_checkpoint_url(cfgDict[\"modelName\"])\ncfg.SOLVER.IMS_PER_BATCH = cfgDict[\"ims_per_batch\"]\ncfg.SOLVER.LR_SCHEDULER_NAME = cfgDict[\"lr_scheduler_name\"]\ncfg.SOLVER.BASE_LR = cfgDict[\"base_lr\"]\ncfg.SOLVER.MAX_ITER = cfgDict[\"iter\"]\ncfg.SOLVER.CHECKPOINT_PERIOD = cfgDict[\"checkpoint_period\"]\ncfg.MODEL.ROI_HEADS.BATCH_SIZE_PER_IMAGE = cfgDict[\"roi_batch_size_per_image\"]\ncfg.MODEL.ROI_HEADS.NUM_CLASSES = len(metadata.get(\"thing_classes\"))\ncfg.INPUT.MASK_FORMAT = cfgDict[\"mask_format\"]\ncfg.MODEL.ROI_HEADS.SCORE_THRESH_TEST = cfgDict[\"score_thresh_test\"]\n\nos.makedirs(cfg.OUTPUT_DIR, exist_ok=True)","metadata":{"execution":{"iopub.status.busy":"2022-03-02T20:31:57.148714Z","iopub.execute_input":"2022-03-02T20:31:57.148925Z","iopub.status.idle":"2022-03-02T20:31:57.182920Z","shell.execute_reply.started":"2022-03-02T20:31:57.148897Z","shell.execute_reply":"2022-03-02T20:31:57.182249Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Train model","metadata":{}},{"cell_type":"code","source":"trainer = MyTrainer(cfg)\ntrainer.resume_or_load(resume=False)\ntrainer.train()","metadata":{"execution":{"iopub.status.busy":"2022-03-02T20:31:57.184187Z","iopub.execute_input":"2022-03-02T20:31:57.184606Z","iopub.status.idle":"2022-03-02T22:16:03.645725Z","shell.execute_reply.started":"2022-03-02T20:31:57.184569Z","shell.execute_reply":"2022-03-02T22:16:03.644901Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Evaluation","metadata":{}},{"cell_type":"code","source":"dfMetrics = pd.read_json(os.path.join(cfgDict[\"outdir\"],\"metrics.json\"), orient=\"records\", lines=True)\ndfMetrics = dfMetrics.sort_values(\"iteration\")\ndfMetrics.head()","metadata":{"execution":{"iopub.status.busy":"2022-03-02T22:16:03.647497Z","iopub.execute_input":"2022-03-02T22:16:03.648035Z","iopub.status.idle":"2022-03-02T22:16:03.693962Z","shell.execute_reply.started":"2022-03-02T22:16:03.647993Z","shell.execute_reply":"2022-03-02T22:16:03.693136Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"dfTrainLoss = dfMetrics[~dfMetrics[\"total_loss\"].isna()]\nplt.plot(dfTrainLoss[\"iteration\"], dfTrainLoss[\"total_loss\"], c=\"C0\", label=\"train\")\nif \"validation_loss\" in dfMetrics.columns:\n    dfValidLoss = dfMetrics[~dfMetrics[\"validation_loss\"].isna()]\n    plt.plot(dfValidLoss[\"iteration\"], dfValidLoss[\"validation_loss\"], c=\"C1\", label=\"validation\")\n\nplt.legend()\nplt.title(\"Loss curve\")\nplt.xlabel(\"Iteration\")\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2022-03-02T22:16:03.695154Z","iopub.execute_input":"2022-03-02T22:16:03.695468Z","iopub.status.idle":"2022-03-02T22:16:03.891895Z","shell.execute_reply.started":"2022-03-02T22:16:03.695432Z","shell.execute_reply":"2022-03-02T22:16:03.891181Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Predict","metadata":{}},{"cell_type":"code","source":"# Same cfg from trainer and use the final model output to initialize the predictor\ncfg.MODEL.WEIGHTS = os.path.join(cfgDict[\"outdir\"],\"model_final.pth\")\npredictor = DefaultPredictor(cfg)\n\nd = datasetTrain[3]\nim = cv2.imread(d[\"file_name\"])\nif predictor.input_format == \"RGB\":\n    im = im[:, :, ::-1]\nheight, width = im.shape[:2]\nimage = torch.as_tensor(im.astype(\"float32\").transpose(2, 0, 1))\ninputs = [{\"image\": image, \"height\": height, \"width\": width}]\noutputs = predictor.model(inputs)\noutput = outputs[0]\n\nvisualizer = Visualizer(im,metadata=metadata, scale=1, instance_mode=ColorMode.IMAGE_BW)\nout = visualizer.draw_instance_predictions(output[\"instances\"].to(\"cpu\"))\nImage.fromarray(out.get_image()[:, :, ::-1])","metadata":{"execution":{"iopub.status.busy":"2022-03-02T22:16:03.893114Z","iopub.execute_input":"2022-03-02T22:16:03.893369Z","iopub.status.idle":"2022-03-02T22:16:05.155848Z","shell.execute_reply.started":"2022-03-02T22:16:03.893319Z","shell.execute_reply":"2022-03-02T22:16:05.155195Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# References\n\nhttps://www.kaggle.com/coldfir3/efficient-coco-dataset-generator\n\nhttps://cocodataset.org/#format-data\n\nhttps://github.com/cocodataset/cocoapi/blob/master/PythonAPI/pycocotools/mask.py","metadata":{}}]}