{"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":"This notebook is based on Slawek Biel's notebook (https://www.kaggle.com/slawekbiel/positive-score-with-detectron-3-3-inference)","metadata":{}},{"cell_type":"markdown","source":"Please UPVOTE !!","metadata":{}},{"cell_type":"markdown","source":"## Inference and submission\nNow, we have trained model ([train with livecell](https://www.kaggle.com/markunys/sartorius-transfer-learning-train-with-livecell), [train](https://www.kaggle.com/markunys/sartorius-transfer-learning-train)). Let's inference with the model !!","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-input":true,"_kg_hide-output":true,"execution":{"iopub.status.busy":"2021-11-04T07:54:20.949446Z","iopub.execute_input":"2021-11-04T07:54:20.950218Z","iopub.status.idle":"2021-11-04T07:57:44.167042Z","shell.execute_reply.started":"2021-11-04T07:54:20.950129Z","shell.execute_reply":"2021-11-04T07:57:44.166157Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import detectron2\nimport torch\nfrom detectron2 import model_zoo\nfrom detectron2.engine import DefaultPredictor\nfrom detectron2.config import get_cfg\nfrom PIL import Image\nimport cv2\nimport pandas as pd\nimport matplotlib.pyplot as plt\nimport numpy as np\nfrom fastcore.all import *","metadata":{"execution":{"iopub.status.busy":"2021-11-04T07:57:44.169062Z","iopub.execute_input":"2021-11-04T07:57:44.169324Z","iopub.status.idle":"2021-11-04T07:57:45.464392Z","shell.execute_reply.started":"2021-11-04T07:57:44.169289Z","shell.execute_reply":"2021-11-04T07:57:45.463409Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"dataDir=Path('../input/sartorius-cell-instance-segmentation')","metadata":{"execution":{"iopub.status.busy":"2021-11-04T08:02:17.609941Z","iopub.execute_input":"2021-11-04T08:02:17.610596Z","iopub.status.idle":"2021-11-04T08:02:17.614843Z","shell.execute_reply.started":"2021-11-04T08:02:17.610558Z","shell.execute_reply":"2021-11-04T08:02:17.614069Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# From https://www.kaggle.com/stainsby/fast-tested-rle\ndef rle_decode(mask_rle, shape=(520, 704)):\n    '''\n    mask_rle: run-length as string formated (start length)\n    shape: (height,width) of array to return \n    Returns numpy array, 1 - mask, 0 - background\n\n    '''\n    s = mask_rle.split()\n    starts, lengths = [np.asarray(x, dtype=int) for x in (s[0:][::2], s[1:][::2])]\n    starts -= 1\n    ends = starts + lengths\n    img = np.zeros(shape[0]*shape[1], dtype=np.uint8)\n    for lo, hi in zip(starts, ends):\n        img[lo:hi] = 1\n    return img.reshape(shape)  # Needed to align to RLE direction\n\ndef rle_encode(img):\n    '''\n    img: numpy array, 1 - mask, 0 - background\n    Returns run length as string formated\n    '''\n    pixels = img.flatten()\n    pixels = np.concatenate([[0], pixels, [0]])\n    runs = np.where(pixels[1:] != pixels[:-1])[0] + 1\n    runs[1::2] -= runs[::2]\n    return ' '.join(str(x) for x in runs)\n\ndef get_masks(fn, predictor):\n    im = cv2.imread(str(fn))\n    pred = predictor(im)\n    pred_class = torch.mode(pred['instances'].pred_classes)[0]\n    take = pred['instances'].scores >= THRESHOLDS[pred_class]\n    pred_masks = pred['instances'].pred_masks[take]\n    pred_masks = pred_masks.cpu().numpy()\n    res = []\n    used = np.zeros(im.shape[:2], dtype=int)\n    print(pred)\n    for mask in pred_masks:\n        mask = mask * (1-used)\n        if mask.sum() >= MIN_PIXELS[pred_class]: # skip predictions with small area\n            used += mask\n            res.append(rle_encode(mask))\n    return res\n","metadata":{"execution":{"iopub.status.busy":"2021-11-04T08:06:29.552913Z","iopub.execute_input":"2021-11-04T08:06:29.553633Z","iopub.status.idle":"2021-11-04T08:06:29.56534Z","shell.execute_reply.started":"2021-11-04T08:06:29.553597Z","shell.execute_reply":"2021-11-04T08:06:29.56459Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"ids, masks=[],[]\ntest_names = (dataDir/'test').ls()","metadata":{"execution":{"iopub.status.busy":"2021-11-04T08:06:29.963189Z","iopub.execute_input":"2021-11-04T08:06:29.96343Z","iopub.status.idle":"2021-11-04T08:06:29.969831Z","shell.execute_reply.started":"2021-11-04T08:06:29.963403Z","shell.execute_reply":"2021-11-04T08:06:29.96909Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Initiate a Predictor from our trained model","metadata":{}},{"cell_type":"code","source":"cfg = get_cfg()\ncfg.merge_from_file(model_zoo.get_config_file(\"COCO-InstanceSegmentation/mask_rcnn_R_50_FPN_3x.yaml\"))\ncfg.INPUT.MASK_FORMAT='bitmask'\ncfg.MODEL.ROI_HEADS.NUM_CLASSES = 3 \ncfg.MODEL.WEIGHTS = os.path.join('../input/sartorius-transfer-learning-model', \"model_0009679.pth\")  \ncfg.TEST.DETECTIONS_PER_IMAGE = 1000\npredictor = DefaultPredictor(cfg)\nTHRESHOLDS = [.15, .35, .55]\nMIN_PIXELS = [75, 150, 75]","metadata":{"execution":{"iopub.status.busy":"2021-11-04T08:06:34.837508Z","iopub.execute_input":"2021-11-04T08:06:34.838089Z","iopub.status.idle":"2021-11-04T08:06:35.685193Z","shell.execute_reply.started":"2021-11-04T08:06:34.838049Z","shell.execute_reply":"2021-11-04T08:06:35.684452Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Look at the outputs on a sample test file to sanity check\nI'm encoding here in the competition format and decoding back to bit mask just to make sure everything is fine","metadata":{}},{"cell_type":"code","source":"encoded_masks = get_masks(test_names[0], predictor)","metadata":{"execution":{"iopub.status.busy":"2021-11-04T08:06:37.581826Z","iopub.execute_input":"2021-11-04T08:06:37.582078Z","iopub.status.idle":"2021-11-04T08:06:38.125907Z","shell.execute_reply.started":"2021-11-04T08:06:37.58205Z","shell.execute_reply":"2021-11-04T08:06:38.125218Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"encoded_masks = get_masks(test_names[0], predictor)\n\n_, axs = plt.subplots(1,2, figsize=(40,15))\naxs[1].imshow(cv2.imread(str(test_names[0])))\nfor enc in encoded_masks:\n    dec = rle_decode(enc)\n    axs[0].imshow(np.ma.masked_where(dec==0, dec))","metadata":{"execution":{"iopub.status.busy":"2021-11-04T08:02:33.316931Z","iopub.execute_input":"2021-11-04T08:02:33.317388Z","iopub.status.idle":"2021-11-04T08:03:10.408177Z","shell.execute_reply.started":"2021-11-04T08:02:33.317348Z","shell.execute_reply":"2021-11-04T08:03:10.407442Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"encoded_masks","metadata":{"execution":{"iopub.status.busy":"2021-11-04T08:03:32.568343Z","iopub.execute_input":"2021-11-04T08:03:32.568605Z","iopub.status.idle":"2021-11-04T08:03:32.578475Z","shell.execute_reply.started":"2021-11-04T08:03:32.568575Z","shell.execute_reply":"2021-11-04T08:03:32.577818Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Looks good, so lets generate masks for all the files and create a submission","metadata":{}},{"cell_type":"code","source":"for fn in test_names:\n    encoded_masks = get_masks(fn, predictor)\n    for enc in encoded_masks:\n        ids.append(fn.stem)\n        masks.append(enc)","metadata":{"execution":{"iopub.status.busy":"2021-10-31T13:17:53.139432Z","iopub.execute_input":"2021-10-31T13:17:53.139782Z","iopub.status.idle":"2021-10-31T13:17:53.856328Z","shell.execute_reply.started":"2021-10-31T13:17:53.139715Z","shell.execute_reply":"2021-10-31T13:17:53.8556Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"pd.DataFrame({'id':ids, 'predicted':masks}).to_csv('submission.csv', index=False)\npd.read_csv('submission.csv').head()","metadata":{"execution":{"iopub.status.busy":"2021-10-31T13:17:53.858316Z","iopub.execute_input":"2021-10-31T13:17:53.85857Z","iopub.status.idle":"2021-10-31T13:17:53.891884Z","shell.execute_reply.started":"2021-10-31T13:17:53.858536Z","shell.execute_reply":"2021-10-31T13:17:53.891164Z"},"trusted":true},"execution_count":null,"outputs":[]}]}