{"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":"!cp -r ../input/pytorch-segmentation-models-lib/ ./","metadata":{"execution":{"iopub.status.busy":"2022-07-26T10:14:33.717377Z","iopub.execute_input":"2022-07-26T10:14:33.718056Z","iopub.status.idle":"2022-07-26T10:14:34.516307Z","shell.execute_reply.started":"2022-07-26T10:14:33.718018Z","shell.execute_reply":"2022-07-26T10:14:34.514468Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"!pip config set global.disable-pip-version-check true","metadata":{"execution":{"iopub.status.busy":"2022-07-26T10:14:34.518895Z","iopub.execute_input":"2022-07-26T10:14:34.519319Z","iopub.status.idle":"2022-07-26T10:14:35.608119Z","shell.execute_reply.started":"2022-07-26T10:14:34.519275Z","shell.execute_reply":"2022-07-26T10:14:35.607023Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"!pip install -q ./pytorch-segmentation-models-lib/pretrainedmodels-0.7.4/pretrainedmodels-0.7.4\n!pip install -q ./pytorch-segmentation-models-lib/efficientnet_pytorch-0.6.3/efficientnet_pytorch-0.6.3\n!pip install -q ./pytorch-segmentation-models-lib/timm-0.4.12-py3-none-any.whl\n!pip install -q ./pytorch-segmentation-models-lib/segmentation_models_pytorch-0.2.0-py3-none-any.whl","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","execution":{"iopub.status.busy":"2022-07-26T10:14:35.609935Z","iopub.execute_input":"2022-07-26T10:14:35.611061Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# **Import Libraries**","metadata":{}},{"cell_type":"code","source":"import numpy as np\nimport pandas as pd\nimport time\nimport matplotlib.pyplot as plt\nimport cv2\nimport glob\nimport os\nimport shutil\nimport timm\nimport random\nimport torch\nimport torch.nn as nn\nimport albumentations as A\nfrom albumentations.pytorch import ToTensorV2\nimport transformers\nimport multiprocessing as mp\nimport segmentation_models_pytorch as smp\nimport copy\nfrom collections import defaultdict\nimport gc\nfrom tqdm import tqdm\nimport tifffile","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# **Config**","metadata":{}},{"cell_type":"code","source":"class CFG:\n    seed = 0\n    batch_size = 1\n    head = \"UNet\"\n    backbone = \"timm-efficientnet-b7\"\n    img_size = [768, 768]\n    device = torch.device(\"cuda:0\" if torch.cuda.is_available() else \"cpu\")\n    base_path = '../input/hubmap-organ-segmentation'\n    num_workers = mp.cpu_count()\n    num_classes = 1\n    threshold = 0.3","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# **Helper Functions**","metadata":{}},{"cell_type":"code","source":"# ref: https://www.kaggle.com/paulorzp/run-length-encode-and-decode\ndef rle_decode(mask_rle, shape):\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).T\n\n# ref.: https://www.kaggle.com/stainsby/fast-tested-rle\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\n#ref: https://www.kaggle.com/code/bguberfain/memory-aware-rle-encoding/notebook\ndef rle_encode_less_memory(img):\n    '''\n    img: numpy array, 1 - mask, 0 - background\n    Returns run length as string formated\n    This simplified method requires first and last pixel to be zero\n    '''\n    pixels = img.T.flatten()\n    \n    # This simplified method requires first and last pixel to be zero\n    pixels[0] = 0\n    pixels[-1] = 0\n    runs = np.where(pixels[1:] != pixels[:-1])[0] + 2\n    runs[1::2] -= runs[::2]\n    \n    return ' '.join(str(x) for x in runs)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def read_tiff(path, scale=None, verbose=0): #Modified from https://www.kaggle.com/code/abhinand05/hubmap-extensive-eda-what-are-we-hacking\n    image = tifffile.imread(path)\n    if len(image.shape) == 5:\n        image = image.squeeze().transpose(1, 2, 0)\n    \n    if verbose:\n        print(f\"[{path}] Image shape: {image.shape}\")\n    \n    if scale:\n        new_size = (image.shape[1] // scale, image.shape[0] // scale)\n        image = cv2.resize(image, new_size)\n        \n        if verbose:\n            print(f\"[{path}] Resized Image shape: {image.shape}\")\n        \n#     mx = np.max(image)\n#     image = image.astype(np.float32)\n#     if mx:\n#         image /= mx # scale image to [0, 1]\n    return image","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# **Grab Metadata**","metadata":{}},{"cell_type":"code","source":"df = pd.read_csv(\"../input/hubmap-organ-segmentation/test.csv\")\ndf['image_path'] = df['id'].apply(lambda x: os.path.join(CFG.base_path, 'test_images', str(x) + '.tiff'))\ndf.head()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# **Dataset**","metadata":{}},{"cell_type":"code","source":"class HuBMAP_Dataset(torch.utils.data.Dataset):\n    def __init__(self, df, transforms=None):\n        self.df = df\n        self.transforms = transforms\n        \n    def __len__(self):\n        return len(self.df)\n    \n    def __getitem__(self, index):\n        img_path = self.df.loc[index, 'image_path']\n        img_height = self.df.loc[index, 'img_height']\n        img_width = self.df.loc[index, 'img_width']\n        source = self.df.loc[index, 'data_source']\n        #pixel_size = self.df.loc[index, 'pixel_size']\n        #s = pixel_size / 0.4 * CFG.img_size[0]/3000\n        id_ = self.df.loc[index, 'id']\n        img = read_tiff(img_path)\n        #img = cv2.resize(img, dsize=None, fx=s, fy=s, interpolation=cv2.INTER_LINEAR)\n#         mx = np.max(img)\n#         img = img.astype(np.float32)\n#         if mx:\n#             img /= mx # scale image to [0, 1]\n            \n        if self.transforms:\n            data = self.transforms(image=img)\n            img  = data['image']\n\n#         img = np.transpose(img, (2, 0, 1))\n\n        return img, img_height, img_width, id_, source","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model_pths = [\n    '../input/exp007/exp007-bestdice-fold0.ckpt',\n    '../input/exp007/exp007-bestdice-fold1.ckpt',\n    '../input/exp007/exp007-bestdice-fold2.ckpt',\n    '../input/exp007/exp007-bestdice-fold3.ckpt',\n    '../input/exp007/exp007-bestdice-fold4.ckpt'\n]","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# **Augmentations**","metadata":{}},{"cell_type":"code","source":"data_transforms = {\n    \"inference\": A.Compose([\n        A.Resize(*CFG.img_size, interpolation=cv2.INTER_NEAREST),\n        A.Normalize(),\n        ToTensorV2()\n        ], p=1.0)\n}","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# **Models**","metadata":{}},{"cell_type":"code","source":"def build_model():\n    model = smp.Unet(\n        encoder_name=CFG.backbone,      \n        encoder_weights=None,     \n        in_channels=3,                  \n        classes=CFG.num_classes,\n        decoder_use_batchnorm=True,\n        decoder_attention_type='scse',\n        activation=None,\n    )\n    model.to(CFG.device)\n    return model\n\ndef load_model(path):\n    model = build_model()\n    state = torch.load(path)['state_dict']\n    nstate = {}\n    for k,v in state.items():\n        nstate[k[4:]] = v\n    model.load_state_dict(nstate)\n    model.eval()\n    return model","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"models = [load_model(pth) for pth in model_pths]\nlen(models)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# **Dataloader**","metadata":{}},{"cell_type":"code","source":"def prepare_loaders():\n\n    infer_dataset = HuBMAP_Dataset(df, transforms=data_transforms['inference'])\n\n    infer_loader = torch.utils.data.DataLoader(infer_dataset, batch_size=CFG.batch_size,\n                              num_workers=CFG.num_workers, shuffle=False, pin_memory=True, drop_last=False)\n    \n    return infer_loader","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# **Inference**","metadata":{}},{"cell_type":"code","source":"infer_loader = prepare_loaders()\n\npred_ids = []\npred_rles = []\nsource_lst = []\nwith torch.no_grad():\n    for (images, heights, widths, ids, sources) in infer_loader:\n        # images = images.to(CFG.device)\n        images = images.squeeze().to(CFG.device)\n        batch = {\n                'image':\n                    torch.stack([\n                        images,\n                        torch.flip(images, [1]),\n                        torch.flip(images, [2]),\n                    ]),  # simple TTA\n            }\n        pred = None\n        for model in models:\n            model.to(CFG.device)\n            #output = model(images)\n            output = model(batch['image'])\n            output = nn.Sigmoid()(output).detach()\n            output[1] = torch.flip(output[1], [1])\n            output[2] = torch.flip(output[2], [2])\n            output = output.unsqueeze(0).mean(0)\n            if pred is None: pred = output\n            else: pred += output\n        pred = pred / len(models)\n        # undo TTA\n#         pred[1] = torch.flip(pred[1], [1])\n#         pred[2] = torch.flip(pred[2], [2])\n        pred = pred.mean(0)\n        # msks = (pred.permute((0,2,3,1))>CFG.threshold).to(torch.uint8).cpu().detach().numpy()\n        msks = (pred>CFG.threshold).to(torch.uint8).cpu().detach().numpy()\n        #msks = msks.mean(0)\n        for idx in range(msks.shape[0]):\n            height = heights[idx].item()\n            width = widths[idx].item()\n            id_ = ids[idx].item()\n            source = sources[idx]\n            msk = cv2.resize(msks[idx].squeeze(), \n                             dsize=(width, height), \n                             interpolation=cv2.INTER_NEAREST)\n#             if source != 'Hubmap': # 'Hubmap' HPA\n#                 rle = rle_encode_less_memory(msk*0)\n#             else:\n#                 rle = rle_encode_less_memory(msk)\n            rle = rle_encode_less_memory(msk)\n            pred_rles.append(rle)\n            pred_ids.append(id_)\n            source_lst.append(source)\n\n        gc.collect()\n        torch.cuda.empty_cache()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"pred_df = pd.DataFrame({\n    \"id\":pred_ids,\n    \"rle\":pred_rles,\n    #\"data_source\":source_lst\n})\npred_df.to_csv('submission.csv',index=False)\ndisplay(pred_df.head(5))","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#pred_df.loc[pred_df.data_source == 'Hubmap'] = ''\n#pred_df.loc[pred_df.data_source == 'HPA'] = ''","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#pred_df.drop('data_source', axis=1, inplace=True)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#pred_df.head()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#pred_df.to_csv('submission.csv',index=False)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"m = read_tiff(\"../input/hubmap-organ-segmentation/test_images/10078.tiff\")","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"plt.imshow(m)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"public_testImg_pred = rle_decode(pred_df.loc[0, 'rle'], (2023,2023))","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"plt.imshow(public_testImg_pred)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]}]}