{"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":"import os\nimport torch\nimport gc\nimport cv2\nimport time\nfrom torch import nn\nimport pandas as pd\nimport numpy as np\nimport collections\nimport torch.nn.functional as F\nfrom torch.utils.data import Dataset, DataLoader\nimport albumentations as albu\nfrom albumentations.pytorch import ToTensorV2\nimport torchvision\nfrom tqdm import tqdm_notebook as tqdm\nfrom skimage.color import label2rgb\nfrom torchvision.models.detection.faster_rcnn import FastRCNNPredictor\nfrom torchvision.models.detection.mask_rcnn import MaskRCNNPredictor\n%matplotlib inline","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","execution":{"iopub.status.busy":"2021-11-23T01:53:43.839743Z","iopub.execute_input":"2021-11-23T01:53:43.842519Z","iopub.status.idle":"2021-11-23T01:53:45.042375Z","shell.execute_reply.started":"2021-11-23T01:53:43.842451Z","shell.execute_reply":"2021-11-23T01:53:45.041529Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"ls ../input/sartorius-maskrcc-pytorch-exp001/","metadata":{"execution":{"iopub.status.busy":"2021-11-23T01:53:45.047013Z","iopub.execute_input":"2021-11-23T01:53:45.050238Z","iopub.status.idle":"2021-11-23T01:53:45.859669Z","shell.execute_reply.started":"2021-11-23T01:53:45.050196Z","shell.execute_reply":"2021-11-23T01:53:45.858852Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class CFG:\n    num_workers = 0\n    img_dir = '../input/sartorius-cell-instance-segmentation/test/'\n    model_pth = '../input/sartorius-maskrcc-pytorch-exp001/'\n    height = 520\n    width = 704\n    mask_threshold = 0.5\n    mean = np.array([0.485, 0.456, 0.406])\n    std = np.array([0.229, 0.224, 0.225])\n    box_detections_per_img = 539\n    min_score = 0.59\n    batch_size = 4","metadata":{"execution":{"iopub.status.busy":"2021-11-23T01:53:45.864097Z","iopub.execute_input":"2021-11-23T01:53:45.864377Z","iopub.status.idle":"2021-11-23T01:53:45.874670Z","shell.execute_reply.started":"2021-11-23T01:53:45.864339Z","shell.execute_reply":"2021-11-23T01:53:45.873838Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class TestDataset(Dataset):\n    def __init__(self, image_dir, transforms=None):\n        self.image_dir = image_dir\n        self.imgs = os.listdir(self.image_dir)\n        self.transforms = transforms\n    \n    def __len__(self):\n        return len(self.imgs)\n\n    def __getitem__(self, idx):\n        img_path = os.path.join(self.image_dir, self.imgs[idx])\n        img = cv2.imread(img_path)\n        img = img[:,:,::-1]\n\n        if self.transforms is not None:\n            augmented = self.transforms(image=img)     \n            img = augmented['image']\n        image_id = self.imgs[idx].split('.')[0]\n        \n        return {'image': img, 'image_id': image_id}","metadata":{"execution":{"iopub.status.busy":"2021-11-23T01:53:45.880434Z","iopub.execute_input":"2021-11-23T01:53:45.881535Z","iopub.status.idle":"2021-11-23T01:53:46.071404Z","shell.execute_reply.started":"2021-11-23T01:53:45.881497Z","shell.execute_reply":"2021-11-23T01:53:46.070569Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"transforms = albu.Compose([\n    albu.Normalize(),\n    ToTensorV2()\n    ], p=1.0)","metadata":{"execution":{"iopub.status.busy":"2021-11-23T01:53:46.075549Z","iopub.execute_input":"2021-11-23T01:53:46.075954Z","iopub.status.idle":"2021-11-23T01:53:46.081942Z","shell.execute_reply.started":"2021-11-23T01:53:46.075921Z","shell.execute_reply":"2021-11-23T01:53:46.081214Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def get_model():\n    # This is just a dummy value for the classification head\n    NUM_CLASSES = 2\n    model = torchvision.models.detection.maskrcnn_resnet50_fpn(pretrained=False, \n                                                               pretrained_backbone=False,\n                                                               box_detections_per_img=CFG.box_detections_per_img,\n                                                               image_mean=CFG.mean, \n                                                               image_std=CFG.std)\n\n    # get the number of input features for the classifier\n    in_features = model.roi_heads.box_predictor.cls_score.in_features\n    # replace the pre-trained head with a new one\n    model.roi_heads.box_predictor = FastRCNNPredictor(in_features, NUM_CLASSES)\n\n    # now get the number of input features for the mask classifier\n    in_features_mask = model.roi_heads.mask_predictor.conv5_mask.in_channels\n    hidden_layer = 256\n    # and replace the mask predictor with a new one\n    model.roi_heads.mask_predictor = MaskRCNNPredictor(in_features_mask, hidden_layer, NUM_CLASSES)\n    return model","metadata":{"execution":{"iopub.status.busy":"2021-11-23T01:53:46.083236Z","iopub.execute_input":"2021-11-23T01:53:46.083941Z","iopub.status.idle":"2021-11-23T01:53:46.092631Z","shell.execute_reply.started":"2021-11-23T01:53:46.083901Z","shell.execute_reply":"2021-11-23T01:53:46.091829Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"test_dataset = TestDataset(CFG.img_dir, transforms)\ntest_loader = DataLoader(test_dataset,\n                          batch_size=CFG.batch_size, \n                          shuffle=True,\n                          worker_init_fn=lambda id: np.random.seed(torch.initial_seed() // 2 ** 32 + id),\n                          #collate_fn=lambda x: tuple(zip(*x)),\n                          num_workers=CFG.num_workers, pin_memory=True, drop_last=False)","metadata":{"execution":{"iopub.status.busy":"2021-11-23T01:53:46.094876Z","iopub.execute_input":"2021-11-23T01:53:46.095149Z","iopub.status.idle":"2021-11-23T01:53:46.108606Z","shell.execute_reply.started":"2021-11-23T01:53:46.095108Z","shell.execute_reply":"2021-11-23T01:53:46.107749Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def rle_encoding(x):\n    dots = np.where(x.flatten() == 1)[0]\n    run_lengths = []\n    prev = -2\n    for b in dots:\n        if (b>prev+1): run_lengths.extend((b + 1, 0))\n        run_lengths[-1] += 1\n        prev = b\n    return ' '.join(map(str, run_lengths))\n\ndef remove_overlapping_pixels(mask, other_masks):\n    for other_mask in other_masks:\n        if np.sum(np.logical_and(mask, other_mask)) > 0:\n            mask[np.logical_and(mask, other_mask)] = 0\n    return mask","metadata":{"execution":{"iopub.status.busy":"2021-11-23T01:53:46.110675Z","iopub.execute_input":"2021-11-23T01:53:46.112226Z","iopub.status.idle":"2021-11-23T01:53:46.120618Z","shell.execute_reply.started":"2021-11-23T01:53:46.112185Z","shell.execute_reply":"2021-11-23T01:53:46.119899Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model = get_model()\nstate = torch.load(f'{CFG.model_pth}/001_best_fold0.pth')\nmodel.load_state_dict(state)\nmodel.eval();\nmodel.cuda()\nsubmission = []\nfor i, samples in enumerate(test_loader):\n    images = samples['image']\n    image_ids = samples['image_id']\n    images = list(image.cuda() for image in images)\n    with torch.no_grad():\n        result = model(images)\n    \n    previous_masks = []\n    for i in range(len(images)):\n        pred, image_id = result[i], image_ids[i]\n        for i, mask in enumerate(pred[\"masks\"]):\n            mask = mask.cpu().numpy()\n            # Keep only highly likely pixels\n            binary_mask = mask > CFG.mask_threshold\n            binary_mask = remove_overlapping_pixels(binary_mask, previous_masks)\n            previous_masks.append(binary_mask)\n            rle = rle_encoding(binary_mask)\n            submission.append((image_id, rle))\n\n        # Add empty prediction if no RLE was generated for this image\n        all_images_ids = [image_id for image_id, rle in submission]\n        if image_id not in all_images_ids:\n            submission.append((image_id, \"\"))\n\ndf_sub = pd.DataFrame(submission, columns=['id', 'predicted'])\ndf_sub.to_csv(\"submission.csv\", index=False)","metadata":{"execution":{"iopub.status.busy":"2021-11-23T01:53:46.122003Z","iopub.execute_input":"2021-11-23T01:53:46.122549Z","iopub.status.idle":"2021-11-23T01:55:39.531546Z","shell.execute_reply.started":"2021-11-23T01:53:46.122506Z","shell.execute_reply":"2021-11-23T01:55:39.530762Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df_sub.head()","metadata":{"execution":{"iopub.status.busy":"2021-11-23T01:55:39.532982Z","iopub.execute_input":"2021-11-23T01:55:39.533251Z","iopub.status.idle":"2021-11-23T01:55:39.549528Z","shell.execute_reply.started":"2021-11-23T01:55:39.533215Z","shell.execute_reply":"2021-11-23T01:55:39.548736Z"},"trusted":true},"execution_count":null,"outputs":[]}]}