{"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 sys\n# from IPython.display import FileLink\n# !pip download timm==0.4.12\n#FileLink(\"timm-0.5.4-py3-none-any.whl\")\n#FileLink(\"timm-0.4.12-py3-none-any.whl\")\n#!pip download segmentation-models-pytorch\n#FileLink(\"segmentation_models_pytorch-0.2.1-py3-none-any.whl\")\n#FileLink(\"pretrainedmodels-0.7.4.tar.gz\")\n#FileLink(\"efficientnet_pytorch-0.6.3.tar.gz\")\n#!pip download staintools\n#FileLink(\"staintools-2.1.2.tar.gz\")\n#!pip download spams\n#FileLink(\"spams-2.6.5.4.tar.gz\")\n!cp -R /kaggle/input/jph-hubmap2022-wheels/* ./\n!cp -R /kaggle/input/einops-030/* ./\n# !ls\n#!pip install 'timm-0.5.4-py3-none-any.whl'\n!pip install 'timm-0.4.12-py3-none-any.whl'\n# !pip install 'pretrainedmodels-0.7.4/pretrainedmodels-0.7.4'\n!pip install 'efficientnet_pytorch-0.6.3/efficientnet_pytorch-0.6.3'\n!pip install 'einops-0.3.0-py2.py3-none-any.whl'\nsys.path.append(\"../input/pretrained-models-pytorch\")\n# sys.path.append(\"../input/efficientnet-pytorch\")\nsys.path.append(\"../input/segmentation-models-pytorch\")\n# !pip install 'segmentation_models_pytorch-0.2.1-py3-none-any.whl'\n!pip install 'spams-2.6.1/spams-2.6.1'\n!pip install 'staintools-2.1.2/staintools-2.1.2'\nsys.path.append(\"../input/timm-pytorch-image-models/pytorch-image-models-master\")\n","metadata":{"execution":{"iopub.status.busy":"2022-09-20T12:42:07.744521Z","iopub.execute_input":"2022-09-20T12:42:07.745145Z","iopub.status.idle":"2022-09-20T12:46:03.110773Z","shell.execute_reply.started":"2022-09-20T12:42:07.745059Z","shell.execute_reply":"2022-09-20T12:46:03.109573Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import os\nimport cv2\nimport shutil\nimport random\nimport tifffile\nimport staintools\nimport numpy as np\nimport pandas as pd\nimport albumentations as A\n\nfrom glob import glob\n\nimport torch\nimport torch.nn as nn\nimport torch.nn.functional as F\nimport segmentation_models_pytorch as smp\nfrom tqdm import tqdm\nfrom transformers import SegformerForSemanticSegmentation, SegformerConfig\nfrom transformers.modeling_outputs import SemanticSegmenterOutput","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","execution":{"iopub.status.busy":"2022-09-20T12:47:36.034132Z","iopub.execute_input":"2022-09-20T12:47:36.034513Z","iopub.status.idle":"2022-09-20T12:47:36.041063Z","shell.execute_reply.started":"2022-09-20T12:47:36.034478Z","shell.execute_reply":"2022-09-20T12:47:36.040047Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# https://github.com/mlpc-ucsd/CoaT/blob/main/src/models/coat.py\nfrom functools import partial\nfrom einops import rearrange\nfrom timm.data import IMAGENET_DEFAULT_MEAN, IMAGENET_DEFAULT_STD\nfrom timm.models.layers import DropPath, to_2tuple, trunc_normal_\nfrom torch import nn, einsum\n\n# ---------------------------------------------\n# https://github.com/facebookresearch/ConvNeXt/blob/main/models/convnext.py#L15\nclass LayerNorm2d(nn.Module):\n    def __init__(self, dim, eps=1e-6):\n        super().__init__()\n        self.dim = dim\n        self.weight = nn.Parameter(torch.ones(dim))\n        self.bias = nn.Parameter(torch.zeros(dim))\n        self.eps = eps\n\n    def forward(self, x):\n        batch_size, C, H, W = x.shape\n        # assert C==self.dim, 'C=%d, self.dim=%d'%(C,self.dim)\n        # print('C=%d, self.dim=%d'%(C,self.dim))\n\n        u = x.mean(1, keepdim=True)\n        s = (x - u).pow(2).mean(1, keepdim=True)\n        x = (x - u) / torch.sqrt(s + self.eps)\n        x = self.weight[:, None, None] * x + self.bias[:, None, None]\n        return x\n\n\n# ---------------------------------------------\n\ndef _cfg_coat(url='', **kwargs):\n    return {\n        'url': url,\n        'num_classes': 1000, 'input_size': (3, 224, 224), 'pool_size': None,\n        'crop_pct': .9, 'interpolation': 'bicubic',\n        'mean': IMAGENET_DEFAULT_MEAN, 'std': IMAGENET_DEFAULT_STD,\n        'first_conv': 'patch_embed.proj', 'classifier': 'head',\n        **kwargs\n    }\n\n\nclass Mlp(nn.Module):\n    \"\"\" Feed-forward network (FFN, a.k.a. MLP) class. \"\"\"\n\n    def __init__(self, in_features, hidden_features=None, out_features=None, act_layer=nn.GELU, drop=0.):\n        super().__init__()\n        out_features = out_features or in_features\n        hidden_features = hidden_features or in_features\n        self.fc1 = nn.Linear(in_features, hidden_features)\n        self.act = act_layer()\n        self.fc2 = nn.Linear(hidden_features, out_features)\n        self.drop = nn.Dropout(drop)\n\n    def forward(self, x):\n        x = self.fc1(x)\n        x = self.act(x)\n        x = self.drop(x)\n        x = self.fc2(x)\n        x = self.drop(x)\n        return x\n\n\nclass ConvRelPosEnc(nn.Module):\n    \"\"\" Convolutional relative position encoding. \"\"\"\n\n    def __init__(self, Ch, h, window):\n        \"\"\"\n        Initialization.\n            Ch: Channels per head.\n            h: Number of heads.\n            window: Window size(s) in convolutional relative positional encoding. It can have two forms:\n                    1. An integer of window size, which assigns all attention heads with the same window size in ConvRelPosEnc.\n                    2. A dict mapping window size to #attention head splits (e.g. {window size 1: #attention head split 1, window size 2: #attention head split 2})\n                       It will apply different window size to the attention head splits.\n        \"\"\"\n        super().__init__()\n\n        if isinstance(window, int):\n            window = {window: h}  # Set the same window size for all attention heads.\n            self.window = window\n        elif isinstance(window, dict):\n            self.window = window\n        else:\n            raise ValueError()\n\n        self.conv_list = nn.ModuleList()\n        self.head_splits = []\n        for cur_window, cur_head_split in window.items():\n            dilation = 1  # Use dilation=1 at default.\n            padding_size = (cur_window + (cur_window - 1) * (\n                    dilation - 1)) // 2  # Determine padding size. Ref: https://discuss.pytorch.org/t/how-to-keep-the-shape-of-input-and-output-same-when-dilation-conv/14338\n            cur_conv = nn.Conv2d(cur_head_split * Ch, cur_head_split * Ch,\n                                 kernel_size=(cur_window, cur_window),\n                                 padding=(padding_size, padding_size),\n                                 dilation=(dilation, dilation),\n                                 groups=cur_head_split * Ch,\n                                 )\n            self.conv_list.append(cur_conv)\n            self.head_splits.append(cur_head_split)\n        self.channel_splits = [x * Ch for x in self.head_splits]\n\n    def forward(self, q, v, size):\n        B, h, N, Ch = q.shape\n        H, W = size\n        assert N == 1 + H * W\n\n        # Convolutional relative position encoding.\n        q_img = q[:, :, 1:, :]  # Shape: [B, h, H*W, Ch].\n        v_img = v[:, :, 1:, :]  # Shape: [B, h, H*W, Ch].\n\n        v_img = rearrange(v_img, 'B h (H W) Ch -> B (h Ch) H W', H=H, W=W)  # Shape: [B, h, H*W, Ch] -> [B, h*Ch, H, W].\n        v_img_list = torch.split(v_img, self.channel_splits, dim=1)  # Split according to channels.\n        conv_v_img_list = [conv(x) for conv, x in zip(self.conv_list, v_img_list)]\n        conv_v_img = torch.cat(conv_v_img_list, dim=1)\n        conv_v_img = rearrange(conv_v_img, 'B (h Ch) H W -> B h (H W) Ch',\n                               h=h)  # Shape: [B, h*Ch, H, W] -> [B, h, H*W, Ch].\n\n        EV_hat_img = q_img * conv_v_img\n        zero = torch.zeros((B, h, 1, Ch), dtype=q.dtype, layout=q.layout, device=q.device)\n        EV_hat = torch.cat((zero, EV_hat_img), dim=2)  # Shape: [B, h, N, Ch].\n\n        return EV_hat\n\n\nclass FactorAtt_ConvRelPosEnc(nn.Module):\n    \"\"\" Factorized attention with convolutional relative position encoding class. \"\"\"\n\n    def __init__(self, dim, num_heads=8, qkv_bias=False, qk_scale=None, attn_drop=0., proj_drop=0., shared_crpe=None):\n        super().__init__()\n        self.num_heads = num_heads\n        head_dim = dim // num_heads\n        self.scale = qk_scale or head_dim ** -0.5\n\n        self.qkv = nn.Linear(dim, dim * 3, bias=qkv_bias)\n        self.attn_drop = nn.Dropout(attn_drop)  # Note: attn_drop is actually not used.\n        self.proj = nn.Linear(dim, dim)\n        self.proj_drop = nn.Dropout(proj_drop)\n\n        # Shared convolutional relative position encoding.\n        self.crpe = shared_crpe\n\n    def forward(self, x, size):\n        B, N, C = x.shape\n\n        # Generate Q, K, V.\n        qkv = self.qkv(x).reshape(B, N, 3, self.num_heads, C // self.num_heads).permute(2, 0, 3, 1,\n                                                                                        4)  # Shape: [3, B, h, N, Ch].\n        q, k, v = qkv[0], qkv[1], qkv[2]  # Shape: [B, h, N, Ch].\n\n        # Factorized attention.\n        k_softmax = k.softmax(dim=2)  # Softmax on dim N.\n        k_softmax_T_dot_v = einsum('b h n k, b h n v -> b h k v', k_softmax, v)  # Shape: [B, h, Ch, Ch].\n        factor_att = einsum('b h n k, b h k v -> b h n v', q, k_softmax_T_dot_v)  # Shape: [B, h, N, Ch].\n\n        # Convolutional relative position encoding.\n        crpe = self.crpe(q, v, size=size)  # Shape: [B, h, N, Ch].\n\n        # Merge and reshape.\n        x = self.scale * factor_att + crpe\n        x = x.transpose(1, 2).reshape(B, N, C)  # Shape: [B, h, N, Ch] -> [B, N, h, Ch] -> [B, N, C].\n\n        # Output projection.\n        x = self.proj(x)\n        x = self.proj_drop(x)\n\n        return x  # Shape: [B, N, C].\n\n\nclass ConvPosEnc(nn.Module):\n    \"\"\" Convolutional Position Encoding.\n        Note: This module is similar to the conditional position encoding in CPVT.\n    \"\"\"\n\n    def __init__(self, dim, k=3):\n        super(ConvPosEnc, self).__init__()\n        self.proj = nn.Conv2d(dim, dim, k, 1, k // 2, groups=dim)\n\n    def forward(self, x, size):\n        B, N, C = x.shape\n        H, W = size\n        assert N == 1 + H * W\n\n        # Extract CLS token and image tokens.\n        cls_token, img_tokens = x[:, :1], x[:, 1:]  # Shape: [B, 1, C], [B, H*W, C].\n\n        # Depthwise convolution.\n        feat = img_tokens.transpose(1, 2).view(B, C, H, W)\n        x = self.proj(feat) + feat\n        x = x.flatten(2).transpose(1, 2)\n\n        # Combine with CLS token.\n        x = torch.cat((cls_token, x), dim=1)\n\n        return x\n\n\nclass SerialBlock(nn.Module):\n    \"\"\" Serial block class.\n        Note: In this implementation, each serial block only contains a conv-attention and a FFN (MLP) module. \"\"\"\n\n    def __init__(self, dim, num_heads, mlp_ratio=4., qkv_bias=False, qk_scale=None, drop=0., attn_drop=0.,\n                 drop_path=0., act_layer=nn.GELU, norm_layer=nn.LayerNorm,\n                 shared_cpe=None, shared_crpe=None):\n        super().__init__()\n\n        # Conv-Attention.\n        self.cpe = shared_cpe\n\n        self.norm1 = norm_layer(dim)\n        self.factoratt_crpe = FactorAtt_ConvRelPosEnc(\n            dim, num_heads=num_heads, qkv_bias=qkv_bias, qk_scale=qk_scale, attn_drop=attn_drop, proj_drop=drop,\n            shared_crpe=shared_crpe)\n        self.drop_path = DropPath(drop_path) if drop_path > 0. else nn.Identity()\n\n        # MLP.\n        self.norm2 = norm_layer(dim)\n        mlp_hidden_dim = int(dim * mlp_ratio)\n        self.mlp = Mlp(in_features=dim, hidden_features=mlp_hidden_dim, act_layer=act_layer, drop=drop)\n\n    def forward(self, x, size):\n        # Conv-Attention.\n        x = self.cpe(x, size)  # Apply convolutional position encoding.\n        cur = self.norm1(x)\n        cur = self.factoratt_crpe(cur, size)  # Apply factorized attention and convolutional relative position encoding.\n        x = x + self.drop_path(cur)\n\n        # MLP.\n        cur = self.norm2(x)\n        cur = self.mlp(cur)\n        x = x + self.drop_path(cur)\n\n        return x\n\n\nclass ParallelBlock(nn.Module):\n    \"\"\" Parallel block class. \"\"\"\n\n    def __init__(self, dims, num_heads, mlp_ratios=[], qkv_bias=False, qk_scale=None, drop=0., attn_drop=0.,\n                 drop_path=0., act_layer=nn.GELU, norm_layer=nn.LayerNorm,\n                 shared_cpes=None, shared_crpes=None):\n        super().__init__()\n\n        # Conv-Attention.\n        self.cpes = shared_cpes\n\n        self.norm12 = norm_layer(dims[1])\n        self.norm13 = norm_layer(dims[2])\n        self.norm14 = norm_layer(dims[3])\n        self.norm15 = norm_layer(dims[4])\n\n        self.factoratt_crpe2 = FactorAtt_ConvRelPosEnc(\n            dims[1], num_heads=num_heads, qkv_bias=qkv_bias, qk_scale=qk_scale, attn_drop=attn_drop, proj_drop=drop,\n            shared_crpe=shared_crpes[1]\n        )\n        self.factoratt_crpe3 = FactorAtt_ConvRelPosEnc(\n            dims[2], num_heads=num_heads, qkv_bias=qkv_bias, qk_scale=qk_scale, attn_drop=attn_drop, proj_drop=drop,\n            shared_crpe=shared_crpes[2]\n        )\n        self.factoratt_crpe4 = FactorAtt_ConvRelPosEnc(\n            dims[3], num_heads=num_heads, qkv_bias=qkv_bias, qk_scale=qk_scale, attn_drop=attn_drop, proj_drop=drop,\n            shared_crpe=shared_crpes[3]\n        )\n        self.factoratt_crpe5 = FactorAtt_ConvRelPosEnc(\n            dims[4], num_heads=num_heads, qkv_bias=qkv_bias, qk_scale=qk_scale, attn_drop=attn_drop, proj_drop=drop,\n            shared_crpe=shared_crpes[4]\n        )\n\n        self.drop_path = DropPath(drop_path) if drop_path > 0. else nn.Identity()\n\n        # MLP.\n        self.norm22 = norm_layer(dims[1])\n        self.norm23 = norm_layer(dims[2])\n        self.norm24 = norm_layer(dims[3])\n        self.norm25 = norm_layer(dims[4])\n\n        assert dims[1] == dims[2] == dims[3] == dims[\n            4]  # In parallel block, we assume dimensions are the same and share the linear transformation.\n        assert mlp_ratios[1] == mlp_ratios[2] == mlp_ratios[3]\n        mlp_hidden_dim = int(dims[1] * mlp_ratios[1])\n        self.mlp2 = self.mlp3 = self.mlp4 = self.mlp5 = Mlp(in_features=dims[1], hidden_features=mlp_hidden_dim,\n                                                            act_layer=act_layer, drop=drop)\n\n    def upsample(self, x, output_size, size):\n        \"\"\" Feature map up-sampling. \"\"\"\n        return self.interpolate(x, output_size=output_size, size=size)\n\n    def downsample(self, x, output_size, size):\n        \"\"\" Feature map down-sampling. \"\"\"\n        return self.interpolate(x, output_size=output_size, size=size)\n\n    def interpolate(self, x, output_size, size):\n        \"\"\" Feature map interpolation. \"\"\"\n        B, N, C = x.shape\n        H, W = size\n        assert N == 1 + H * W\n\n        cls_token = x[:, :1, :]\n        img_tokens = x[:, 1:, :]\n\n        img_tokens = img_tokens.transpose(1, 2).reshape(B, C, H, W)\n        img_tokens = F.interpolate(img_tokens, size=output_size, mode='bilinear')  # FIXME: May have alignment issue.\n        img_tokens = img_tokens.reshape(B, C, -1).transpose(1, 2)\n\n        out = torch.cat((cls_token, img_tokens), dim=1)\n\n        return out\n\n    def forward(self, x1, x2, x3, x4, x5, sizes):\n        _, (H2, W2), (H3, W3), (H4, W4), (H5, W5) = sizes\n\n        # Conv-Attention.\n        x2 = self.cpes[1](x2, size=(H2, W2))  # Note: x1 is ignored.\n        x3 = self.cpes[2](x3, size=(H3, W3))\n        x4 = self.cpes[3](x4, size=(H4, W4))\n        x5 = self.cpes[4](x5, size=(H5, W5))\n\n        cur2 = self.norm12(x2)\n        cur3 = self.norm13(x3)\n        cur4 = self.norm14(x4)\n        cur5 = self.norm15(x5)\n\n        cur2 = self.factoratt_crpe2(cur2, size=(H2, W2))\n        cur3 = self.factoratt_crpe3(cur3, size=(H3, W3))\n        cur4 = self.factoratt_crpe4(cur4, size=(H4, W4))\n        cur5 = self.factoratt_crpe4(cur5, size=(H5, W5))\n\n        upsample3_2 = self.upsample(cur3, output_size=(H2, W2), size=(H3, W3))\n        upsample4_3 = self.upsample(cur4, output_size=(H3, W3), size=(H4, W4))\n        upsample4_2 = self.upsample(cur4, output_size=(H2, W2), size=(H4, W4))\n        downsample2_3 = self.downsample(cur2, output_size=(H3, W3), size=(H2, W2))\n        downsample3_4 = self.downsample(cur3, output_size=(H4, W4), size=(H3, W3))\n        downsample2_4 = self.downsample(cur2, output_size=(H4, W4), size=(H2, W2))\n        upsample5_2 = self.upsample(cur5, output_size=(H2, W2), size=(H5, W5))\n        upsample5_3 = self.upsample(cur5, output_size=(H3, W3), size=(H5, W5))\n        downsample3_5 = self.downsample(cur3, output_size=(H5, W5), size=(H3, W3))\n        upsample5_4 = self.upsample(cur5, output_size=(H4, W4), size=(H5, W5))\n        downsample2_5 = self.downsample(cur2, output_size=(H5, W5), size=(H2, W2))\n        downsample4_5 = self.downsample(cur4, output_size=(H5, W5), size=(H4, W4))\n\n        # cur2 = cur2  + upsample3_2   + upsample4_2+  upsample5_2\n        # cur3 = cur3  + upsample4_3   + downsample2_3 + upsample5_3\n        # cur4 = cur4  + downsample3_4 + downsample2_4 + upsample5_4\n        # cur5 = cur5  + downsample3_5 + downsample2_5 + downsample4_5 4\n        # not use all connetction\n        cur2 = cur2 + upsample3_2 + upsample4_2\n        cur3 = cur3 + upsample4_3 + downsample2_3\n        cur4 = cur4 + upsample5_4 + downsample2_4\n        cur5 = cur5 + downsample4_5 + downsample2_5\n\n        x2 = x2 + self.drop_path(cur2)\n        x3 = x3 + self.drop_path(cur3)\n        x4 = x4 + self.drop_path(cur4)\n        x5 = x5 + self.drop_path(cur5)\n\n        # MLP.\n        cur2 = self.norm22(x2)\n        cur3 = self.norm23(x3)\n        cur4 = self.norm24(x4)\n        cur5 = self.norm25(x5)\n\n        cur2 = self.mlp2(cur2)\n        cur3 = self.mlp3(cur3)\n        cur4 = self.mlp4(cur4)\n        cur5 = self.mlp5(cur5)\n\n        x2 = x2 + self.drop_path(cur2)\n        x3 = x3 + self.drop_path(cur3)\n        x4 = x4 + self.drop_path(cur4)\n        x5 = x5 + self.drop_path(cur5)\n\n        return x1, x2, x3, x4, x5\n\nclass PatchEmbed(nn.Module):\n    \"\"\" Image to Patch Embedding \"\"\"\n\n    def __init__(self, patch_size=16, in_chans=3, embed_dim=768):\n        super().__init__()\n        patch_size = to_2tuple(patch_size)\n\n        self.patch_size = patch_size\n        self.proj = nn.Conv2d(in_chans, embed_dim, kernel_size=patch_size, stride=patch_size)\n        self.norm = nn.LayerNorm(embed_dim)\n\n    def forward(self, x):\n        _, _, H, W = x.shape\n        out_H, out_W = H // self.patch_size[0], W // self.patch_size[1]\n\n        x = self.proj(x).flatten(2).transpose(1, 2)\n        out = self.norm(x)\n\n        return out, (out_H, out_W)\n\n\nclass CoaT(nn.Module):\n    \"\"\" CoaT class. \"\"\"\n\n    def __init__(self, patch_size=16, in_chans=3, embed_dims=[0, 0, 0, 0],\n                 serial_depths=[0, 0, 0, 0], parallel_depth=0,\n                 num_heads=0, mlp_ratios=[0, 0, 0, 0], qkv_bias=True, qk_scale=None, drop_rate=0., attn_drop_rate=0.,\n                 drop_path_rate=0.,\n                 norm_layer=partial(nn.LayerNorm, eps=1e-6),\n                 return_interm_layers=True,\n                 # out_features=['x1_nocls','x2_nocls','x3_nocls','x4_nocls',],\n                 crpe_window={3: 2, 5: 3, 7: 3},\n                 pretrain=None,\n                 out_norm=nn.Identity,  # use nn.Identity, nn.BatchNorm2d, LayerNorm2d\n                 **kwargs):\n        super().__init__()\n        self.return_interm_layers = return_interm_layers\n        self.pretrain = pretrain\n        self.embed_dims = embed_dims\n        # self.out_features = out_features\n        # self.num_classes  = num_classes\n\n        # Patch embeddings.\n        self.patch_embed1 = PatchEmbed(patch_size=patch_size, in_chans=in_chans, embed_dim=embed_dims[0])\n        self.patch_embed2 = PatchEmbed(patch_size=2, in_chans=embed_dims[0], embed_dim=embed_dims[1])\n        self.patch_embed3 = PatchEmbed(patch_size=2, in_chans=embed_dims[1], embed_dim=embed_dims[2])\n        self.patch_embed4 = PatchEmbed(patch_size=2, in_chans=embed_dims[2], embed_dim=embed_dims[3])\n\n        # Class tokens.\n        self.cls_token1 = nn.Parameter(torch.zeros(1, 1, embed_dims[0]))\n        self.cls_token2 = nn.Parameter(torch.zeros(1, 1, embed_dims[1]))\n        self.cls_token3 = nn.Parameter(torch.zeros(1, 1, embed_dims[2]))\n        self.cls_token4 = nn.Parameter(torch.zeros(1, 1, embed_dims[3]))\n\n        # Convolutional position encodings.\n        self.cpe1 = ConvPosEnc(dim=embed_dims[0], k=3)\n        self.cpe2 = ConvPosEnc(dim=embed_dims[1], k=3)\n        self.cpe3 = ConvPosEnc(dim=embed_dims[2], k=3)\n        self.cpe4 = ConvPosEnc(dim=embed_dims[3], k=3)\n\n        # Convolutional relative position encodings.\n        self.crpe1 = ConvRelPosEnc(Ch=embed_dims[0] // num_heads, h=num_heads, window=crpe_window)\n        self.crpe2 = ConvRelPosEnc(Ch=embed_dims[1] // num_heads, h=num_heads, window=crpe_window)\n        self.crpe3 = ConvRelPosEnc(Ch=embed_dims[2] // num_heads, h=num_heads, window=crpe_window)\n        self.crpe4 = ConvRelPosEnc(Ch=embed_dims[3] // num_heads, h=num_heads, window=crpe_window)\n\n        # Enable stochastic depth.\n        dpr = drop_path_rate\n\n        # Serial blocks 1.\n        self.serial_blocks1 = nn.ModuleList([\n            SerialBlock(\n                dim=embed_dims[0], num_heads=num_heads, mlp_ratio=mlp_ratios[0], qkv_bias=qkv_bias, qk_scale=qk_scale,\n                drop=drop_rate, attn_drop=attn_drop_rate, drop_path=dpr, norm_layer=norm_layer,\n                shared_cpe=self.cpe1, shared_crpe=self.crpe1\n            )\n            for _ in range(serial_depths[0])]\n        )\n\n        # Serial blocks 2.\n        self.serial_blocks2 = nn.ModuleList([\n            SerialBlock(\n                dim=embed_dims[1], num_heads=num_heads, mlp_ratio=mlp_ratios[1], qkv_bias=qkv_bias, qk_scale=qk_scale,\n                drop=drop_rate, attn_drop=attn_drop_rate, drop_path=dpr, norm_layer=norm_layer,\n                shared_cpe=self.cpe2, shared_crpe=self.crpe2\n            )\n            for _ in range(serial_depths[1])]\n        )\n\n        # Serial blocks 3.\n        self.serial_blocks3 = nn.ModuleList([\n            SerialBlock(\n                dim=embed_dims[2], num_heads=num_heads, mlp_ratio=mlp_ratios[2], qkv_bias=qkv_bias, qk_scale=qk_scale,\n                drop=drop_rate, attn_drop=attn_drop_rate, drop_path=dpr, norm_layer=norm_layer,\n                shared_cpe=self.cpe3, shared_crpe=self.crpe3\n            )\n            for _ in range(serial_depths[2])]\n        )\n\n        # Serial blocks 4.\n        self.serial_blocks4 = nn.ModuleList([\n            SerialBlock(\n                dim=embed_dims[3], num_heads=num_heads, mlp_ratio=mlp_ratios[3], qkv_bias=qkv_bias, qk_scale=qk_scale,\n                drop=drop_rate, attn_drop=attn_drop_rate, drop_path=dpr, norm_layer=norm_layer,\n                shared_cpe=self.cpe4, shared_crpe=self.crpe4\n            )\n            for _ in range(serial_depths[3])]\n        )\n\n        # Parallel blocks.\n        self.parallel_depth = parallel_depth\n        if self.parallel_depth > 0:\n            self.parallel_blocks = nn.ModuleList([\n                ParallelBlock(\n                    dims=embed_dims, num_heads=num_heads, mlp_ratios=mlp_ratios, qkv_bias=qkv_bias, qk_scale=qk_scale,\n                    drop=drop_rate, attn_drop=attn_drop_rate, drop_path=dpr, norm_layer=norm_layer,\n                    shared_cpes=[self.cpe1, self.cpe2, self.cpe3, self.cpe4],\n                    shared_crpes=[self.crpe1, self.crpe2, self.crpe3, self.crpe4]\n                )\n                for _ in range(parallel_depth)]\n            )\n\n        # add a norm layer for each output\n        self.out_norm = nn.ModuleList(\n            [out_norm(embed_dims[i]) for i in range(4)]\n        )\n\n        # Initialize weights.\n        trunc_normal_(self.cls_token1, std=.02)\n        trunc_normal_(self.cls_token2, std=.02)\n        trunc_normal_(self.cls_token3, std=.02)\n        trunc_normal_(self.cls_token4, std=.02)\n        self.apply(self._init_weights)\n\n    def _init_weights(self, m):\n        if isinstance(m, nn.Linear):\n            trunc_normal_(m.weight, std=.02)\n            if isinstance(m, nn.Linear) and m.bias is not None:\n                nn.init.constant_(m.bias, 0)\n        elif isinstance(m, nn.LayerNorm):\n            nn.init.constant_(m.bias, 0)\n            nn.init.constant_(m.weight, 1.0)\n\n    @torch.jit.ignore\n    def no_weight_decay(self):\n        return {'cls_token1', 'cls_token2', 'cls_token3', 'cls_token4'}\n\n    def insert_cls(self, x, cls_token):\n        \"\"\" Insert CLS token. \"\"\"\n        cls_tokens = cls_token.expand(x.shape[0], -1, -1)\n        x = torch.cat((cls_tokens, x), dim=1)\n        return x\n\n    def remove_cls(self, x):\n        \"\"\" Remove CLS token. \"\"\"\n        return x[:, 1:, :]\n\n    def forward(self, x0):\n        B = x0.shape[0]\n\n        # Serial blocks 1.\n        x1, (H1, W1) = self.patch_embed1(x0)\n        cls = self.cls_token1  # torch.zeros_like(self.cls_token1)#self.cls_token1\n        x1 = self.insert_cls(x1, cls)\n        for blk in self.serial_blocks1:\n            x1 = blk(x1, size=(H1, W1))\n        x1_nocls = self.remove_cls(x1)\n        x1_nocls = x1_nocls.reshape(B, H1, W1, -1).permute(0, 3, 1, 2).contiguous()\n\n        # Serial blocks 2.\n        x2, (H2, W2) = self.patch_embed2(x1_nocls)\n        cls = self.cls_token2  # torch.zeros_like(self.cls_token2)#self.cls_token2#\n        x2 = self.insert_cls(x2, cls)\n        for blk in self.serial_blocks2:\n            x2 = blk(x2, size=(H2, W2))\n        x2_nocls = self.remove_cls(x2)\n        x2_nocls = x2_nocls.reshape(B, H2, W2, -1).permute(0, 3, 1, 2).contiguous()\n\n        # Serial blocks 3.\n        x3, (H3, W3) = self.patch_embed3(x2_nocls)\n        cls = self.cls_token3  # torch.zeros_like(self.cls_token3)# self.cls_token3\n        x3 = self.insert_cls(x3, cls)\n        for blk in self.serial_blocks3:\n            x3 = blk(x3, size=(H3, W3))\n        x3_nocls = self.remove_cls(x3)\n        x3_nocls = x3_nocls.reshape(B, H3, W3, -1).permute(0, 3, 1, 2).contiguous()\n\n        # Serial blocks 4.\n        x4, (H4, W4) = self.patch_embed4(x3_nocls)\n        cls = self.cls_token4  # torch.zeros_like(self.cls_token4)#self.cls_token4\n        x4 = self.insert_cls(x4, cls)\n        for blk in self.serial_blocks4:\n            x4 = blk(x4, size=(H4, W4))\n        x4_nocls = self.remove_cls(x4)\n        x4_nocls = x4_nocls.reshape(B, H4, W4, -1).permute(0, 3, 1, 2).contiguous()\n\n        # Only serial blocks: Early return. ------------------------\n        if self.parallel_depth == 0:\n            x1_nocls = self.out_norm[0](x1_nocls)\n            x2_nocls = self.out_norm[1](x2_nocls)\n            x3_nocls = self.out_norm[2](x3_nocls)\n            x4_nocls = self.out_norm[3](x4_nocls)\n            return [x1_nocls, x2_nocls, x3_nocls, x4_nocls]\n\n        # Parallel blocks. ------------------------------------------\n        if self.parallel_depth > 0:\n\n            for blk in self.parallel_blocks:\n                x1, x2, x3, x4 = blk(x1, x2, x3, x4, sizes=[(H1, W1), (H2, W2), (H3, W3), (H4, W4)])\n\n            x1_nocls = self.remove_cls(x1)\n            x1_nocls = x1_nocls.reshape(B, H1, W1, -1).permute(0, 3, 1, 2).contiguous()\n            x1_nocls = self.out_norm[0](x1_nocls)\n\n            x2_nocls = self.remove_cls(x2)\n            x2_nocls = x2_nocls.reshape(B, H2, W2, -1).permute(0, 3, 1, 2).contiguous()\n            x2_nocls = self.out_norm[1](x2_nocls)\n\n            x3_nocls = self.remove_cls(x3)\n            x3_nocls = x3_nocls.reshape(B, H3, W3, -1).permute(0, 3, 1, 2).contiguous()\n            x3_nocls = self.out_norm[2](x3_nocls)\n\n            x4_nocls = self.remove_cls(x4)\n            x4_nocls = x4_nocls.reshape(B, H4, W4, -1).permute(0, 3, 1, 2).contiguous()\n            x4_nocls = self.out_norm[3](x4_nocls)\n\n            return [x1_nocls, x2_nocls, x3_nocls, x4_nocls]\n\nclass coat_lite_small(CoaT):\n    def __init__(self, **kwargs):\n        super(coat_lite_small, self).__init__(\n            patch_size=4,\n            embed_dims=[64, 128, 320, 512],\n            serial_depths=[3, 4, 6, 3],\n            parallel_depth=0,\n            num_heads=8,\n            mlp_ratios=[8, 8, 4, 4],\n            **kwargs)\n\n\n# @register_model\nclass coat_lite_medium(CoaT):\n    def __init__(self, **kwargs):\n        super(coat_lite_medium, self).__init__(\n            patch_size=4,\n            embed_dims=[128, 256, 320, 512],\n            serial_depths=[3, 6, 10, 8],\n            parallel_depth=0,\n            num_heads=8,\n            mlp_ratios=[4, 4, 4, 4],\n            pretrain='coat_lite_medium_384x384_f9129688.pth',\n            **kwargs)\n\n\nclass coat_parallel_small_plus1(CoaT):\n    def __init__(self, **kwargs):\n        super(coat_parallel_small_plus1, self).__init__(\n            patch_size=4,\n            embed_dims=[152, 320, 320, 320, 320],\n            serial_depths=[2, 2, 2, 2, 2],\n            parallel_depth=6,\n            num_heads=8,\n            mlp_ratios=[4, 4, 4, 4, 4],\n            pretrain='coat_small_7479cf9b.pth',\n            **kwargs)\n\n\nclass MixUpSample(nn.Module):\n    def __init__(self, scale_factor=2):\n        super().__init__()\n        assert (scale_factor != 1)\n\n        self.mixing = nn.Parameter(torch.tensor(0.5))\n        self.scale_factor = scale_factor\n\n    def forward(self, x):\n        x = self.mixing * F.interpolate(x, scale_factor=self.scale_factor, mode='bilinear', align_corners=False) \\\n            + (1 - self.mixing) * F.interpolate(x, scale_factor=self.scale_factor, mode='nearest')\n        return x\n\n\n# https://github.com/lhoyer/DAFormer/blob/master/mmseg/models/decode_heads/daformer_head.py\ndef Conv2dBnReLU(in_channel, out_channel, kernel_size=3, padding=1, stride=1, dilation=1):\n    return nn.Sequential(\n        nn.Conv2d(in_channel, out_channel, kernel_size=kernel_size, padding=padding, stride=stride, dilation=dilation,\n                  bias=False),\n        nn.BatchNorm2d(out_channel),\n        nn.ReLU(inplace=True),\n    )\n\n\nclass ASPP(nn.Module):\n\n    def __init__(self,\n                 in_channel,\n                 channel,\n                 dilation,\n                 ):\n        super(ASPP, self).__init__()\n\n        self.conv = nn.ModuleList()\n        for d in dilation:\n            self.conv.append(\n                Conv2dBnReLU(\n                    in_channel,\n                    channel,\n                    kernel_size=1 if d == 1 else 3,\n                    dilation=d,\n                    padding=0 if d == 1 else d,\n                )\n            )\n\n        self.out = Conv2dBnReLU(\n            len(dilation) * channel,\n            channel,\n            kernel_size=3,\n            padding=1,\n        )\n\n    def forward(self, x):\n        aspp = []\n        for conv in self.conv:\n            aspp.append(conv(x))\n        aspp = torch.cat(aspp, dim=1)\n        out = self.out(aspp)\n        return out\n\n\n# DepthwiseSeparable\nclass DSConv2d(nn.Module):\n    def __init__(self,\n                 in_channel,\n                 out_channel,\n                 kernel_size,\n                 stride=1,\n                 padding=0,\n                 dilation=1\n                 ):\n        super().__init__()\n\n        self.depthwise = nn.Sequential(\n            nn.Conv2d(in_channel, in_channel, kernel_size, stride=stride, padding=padding, dilation=dilation),\n            nn.BatchNorm2d(in_channel),\n            nn.ReLU(inplace=True)\n        )\n\n        self.pointwise = nn.Sequential(\n            nn.Conv2d(in_channel, out_channel, kernel_size=1, stride=1, padding=0),\n            nn.BatchNorm2d(out_channel),\n            nn.ReLU(inplace=True)\n        )\n\n    def forward(self, x):\n        x = self.depthwise(x)\n        x = self.pointwise(x)\n        return x\n\n\nclass DSASPP(nn.Module):\n\n    def __init__(self,\n                 in_channel,\n                 channel,\n                 dilation,\n                 ):\n        super(DSASPP, self).__init__()\n\n        self.conv = nn.ModuleList()\n        for d in dilation:\n            if d == 1:\n                self.conv.append(\n                    Conv2dBnReLU(\n                        in_channel,\n                        channel,\n                        kernel_size=1 if d == 1 else 3,\n                        dilation=d,\n                        padding=0 if d == 1 else d,\n                    )\n                )\n            else:\n                self.conv.append(\n                    DSConv2d(\n                        in_channel,\n                        channel,\n                        kernel_size=3,\n                        dilation=d,\n                        padding=d,\n                    )\n                )\n\n        self.out = Conv2dBnReLU(\n            len(dilation) * channel,\n            channel,\n            kernel_size=3,\n            padding=1,\n        )\n\n    def forward(self, x):\n        aspp = []\n        for conv in self.conv:\n            aspp.append(conv(x))\n        aspp = torch.cat(aspp, dim=1)\n        out = self.out(aspp)\n        return out\n\n\n##############################################################################################33\n\nclass DaformerDecoder(nn.Module):\n    def __init__(\n            self,\n            encoder_dim=[32, 64, 160, 256],\n            decoder_dim=256,\n            dilation=[1, 6, 12, 18],\n            use_bn_mlp=True,\n            fuse='conv3x3',\n    ):\n        super().__init__()\n        self.mlp = nn.ModuleList([\n            nn.Sequential(\n                # Conv2dBnReLU(dim, decoder_dim, 1, padding=0), #follow mmseg to use conv-bn-relu\n                *(\n                    (nn.Conv2d(dim, decoder_dim, 1, padding=0, bias=False),\n                     nn.BatchNorm2d(decoder_dim),\n                     nn.ReLU(inplace=True),\n                     ) if use_bn_mlp else\n                    (nn.Conv2d(dim, decoder_dim, 1, padding=0, bias=True),)\n                ),\n\n                MixUpSample(2 ** i) if i != 0 else nn.Identity(),\n            ) for i, dim in enumerate(encoder_dim)])\n\n        if fuse == 'conv1x1':\n            self.fuse = nn.Sequential(\n                nn.Conv2d(len(encoder_dim) * decoder_dim, decoder_dim, 1, padding=0, bias=False),\n                nn.BatchNorm2d(decoder_dim),\n                nn.ReLU(inplace=True),\n            )\n\n        if fuse == 'conv3x3':\n            self.fuse = nn.Sequential(\n                nn.Conv2d(len(encoder_dim) * decoder_dim, decoder_dim, 3, padding=1, bias=False),\n                nn.BatchNorm2d(decoder_dim),\n                nn.ReLU(inplace=True),\n            )\n\n        if fuse == 'aspp':\n            self.fuse = ASPP(\n                decoder_dim * len(encoder_dim),\n                decoder_dim,\n                dilation,\n            )\n\n        if fuse == 'ds-aspp':\n            self.fuse = DSASPP(\n                decoder_dim * len(encoder_dim),\n                decoder_dim,\n                dilation,\n            )\n\n    def forward(self, feature):\n\n        out = []\n        for i, f in enumerate(feature):\n            f = self.mlp[i](f)\n            out.append(f)\n        # print(f.shape)\n        x = self.fuse(torch.cat(out, dim=1))\n        return x, out\n\n\nclass daformer_conv3x3(DaformerDecoder):\n    def __init__(self, **kwargs):\n        super(daformer_conv3x3, self).__init__(\n            fuse='conv3x3',\n            **kwargs\n        )\n\n\nclass daformer_conv1x1(DaformerDecoder):\n    def __init__(self, **kwargs):\n        super(daformer_conv1x1, self).__init__(\n            fuse='conv1x1',\n            **kwargs\n        )\n\n\nclass daformer_aspp(DaformerDecoder):\n    def __init__(self, **kwargs):\n        super(daformer_aspp, self).__init__(\n            fuse='aspp',\n            **kwargs\n        )\n        \nclass CoatDaformer(nn.Module):\n\n    def __init__(self,\n                 encoder,\n                 decoder,\n                 encoder_cfg={},\n                 decoder_cfg={},\n                 ):\n        super(CoatDaformer, self).__init__()\n        decoder_dim = decoder_cfg.get('decoder_dim', 320)\n\n        self.encoder = encoder\n\n        encoder_dim = self.encoder.embed_dims\n        # [64, 128, 320, 512]\n\n        self.decoder = decoder(\n            encoder_dim=encoder_dim,\n            decoder_dim=decoder_dim,\n        )\n        self.logit = nn.Sequential(\n            nn.Conv2d(decoder_dim, 1, kernel_size=1),\n            nn.Upsample(scale_factor=4, mode='bilinear', align_corners=False),\n        )\n\n    def forward(self, x):\n        # B, C, H, W = x.shape\n        encoder = self.encoder(x)\n\n        last, decoder = self.decoder(encoder)\n        logit = self.logit(last)\n\n        # output = {}\n        # probability_from_logit = torch.sigmoid(logit)\n        # output['probability'] = probability_from_logit\n\n        return logit","metadata":{"execution":{"iopub.status.busy":"2022-09-20T12:47:36.139967Z","iopub.execute_input":"2022-09-20T12:47:36.140744Z","iopub.status.idle":"2022-09-20T12:47:36.274162Z","shell.execute_reply.started":"2022-09-20T12:47:36.140707Z","shell.execute_reply":"2022-09-20T12:47:36.273184Z"},"jupyter":{"source_hidden":true},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"INFERENCE_DIR = '../input/hubmap-organ-segmentation/test_images'\nSUBMISSION_CSV_PATH = '../input/hubmap-organ-segmentation/sample_submission.csv'\nMETADATA_CSV_PATH = '../input/hubmap-organ-segmentation/test.csv'\n\nMEAN = [0.78054955, 0.7566257, 0.7735184]\nSTD = [0.25334089, 0.26656769, 0.26202731]\nTTAS = [[-1],[-2],[-2,-1]]\nREF_PIXEL_SIZE = 0.4\nREL_UPSCALE = 1\n\nDEFAULT_STRIDE = 512\nDEFAULT_TRIM = 0.1  # Proportion of 'native_tile_size'\nADD = [0.025, 0, 0, 0, 0]\n# ADD = [0] * 5\n\nUPSAMPLE_METHOD = cv2.INTER_CUBIC  # cv2.INTER_CUBIC\nDOWNSAMPLE_METHOD = cv2.INTER_AREA  # cv2.INTER_AREA\nTORCH_INTERP = 'bicubic'\n\nTHRESHOLDS = {\n#     \"HPA\": {\n#         \"lung\": 0.1,\n#         \"kidney\": 0.5,\n#         \"largeintestine\": 0.5,\n#         \"prostate\": 0.5,\n#         \"spleen\": 0.5\n#     },\n    \"HPA\": {\n        \"lung\": 10,\n        \"kidney\": 10,\n        \"largeintestine\": 10,\n        \"prostate\": 10,\n        \"spleen\": 10\n    },\n    \"Hubmap\": {\n        \"lung\": 0.05 + ADD[0],  # 211: 0.075 > 0.1\n        \"kidney\": 0.45 + ADD[1],     # 211: 0.45 > 0.4 & 0.5\n        \"largeintestine\": 0.3 + ADD[2],  # 211 0.3 > 0.25 & 0.35\n        \"prostate\": 0.25 + ADD[3],   # 211: 0.25 > 0.2 & 0.3\n        \"spleen\": 0.25 + ADD[4] # 211: 0.25 > 0.2 & 0.3 \n    }\n}\n\nprint(THRESHOLDS)\n\nDEVICE = torch.device('cuda' if torch.cuda.is_available() else 'cpu')\n\nSETTINGS_AND_MODELS = [\n#     # 202 - DL-B4x4 stainaug 1536/1792 HBMP @ 0.1/0.2 (version 8/17) -> 0.57\n#     {\"native_tile_size\": 1792*2,\n#      \"native_down_sample\": 2,\n#      \"model_params\": [{\"type\": \"smp\",\n#                        \"arch\": \"deeplabv3plus\",\n#                        \"encoder\": \"timm-efficientnet-b4\",\n#                        \"weights\": \"last-v1.ckpt\",\n#                        \"activation\": \"sigmoid\",\n#                        \"model_dir\": \"/kaggle/input/jphhubmap2022models\"}]},\n#     {\"native_tile_size\": 1792*2,\n#      \"native_down_sample\": 2,\n#      \"model_params\": [{\"type\": \"smp\",\n#                        \"arch\": \"deeplabv3plus\",\n#                        \"encoder\": \"timm-efficientnet-b4\",\n#                        \"weights\": \"last-v2.ckpt\",\n#                        \"activation\": \"sigmoid\",\n#                        \"model_dir\": \"/kaggle/input/jphhubmap2022models\"}]},\n#     {\"native_tile_size\": 1792*2,\n#      \"native_down_sample\": 2,\n#      \"model_params\": [{\"type\": \"smp\",\n#                        \"arch\": \"deeplabv3plus\",\n#                        \"encoder\": \"timm-efficientnet-b4\",\n#                        \"weights\": \"last-v3.ckpt\",\n#                        \"activation\": \"sigmoid\",\n#                        \"model_dir\": \"/kaggle/input/jphhubmap2022models\"}]},\n#     {\"native_tile_size\": 1792*2,\n#      \"native_down_sample\": 2,\n#      \"model_params\": [{\"type\": \"smp\",\n#                        \"arch\": \"deeplabv3plus\",\n#                        \"encoder\": \"timm-efficientnet-b4\",\n#                        \"weights\": \"last-v4.ckpt\",\n#                        \"activation\": \"sigmoid\",\n#                        \"model_dir\": \"/kaggle/input/jphhubmap2022models\"}]},\n#     # 203 - SegB1x4 stainaug 1536/1792 HBMP @ 0.1/0.2 -> 0.54\n#     {\"native_tile_size\": 1792,\n#      \"native_down_sample\": 2,\n#      \"native_tile_stride\": 512,\n#      \"model_params\": [{\"type\": \"segformer\",\n#                        \"path\": \"203_seg_b1_512_1536/f1\",\n#                        \"activation\": \"softmax\",\n#                        \"model_dir\": \"/kaggle/input/jphhubmap2022models\"}]},\n#     {\"native_tile_size\": 1792,\n#      \"native_down_sample\": 2,\n#      \"native_tile_stride\": 512,\n#      \"model_params\": [{\"type\": \"segformer\",\n#                        \"path\": \"203_seg_b1_512_1536/f2\",\n#                        \"activation\": \"softmax\",\n#                        \"model_dir\": \"/kaggle/input/jphhubmap2022models\"}]},\n#     {\"native_tile_size\": 1792,\n#      \"native_down_sample\": 2,\n#      \"native_tile_stride\": 512,\n#      \"model_params\": [{\"type\": \"segformer\",\n#                        \"path\": \"203_seg_b1_512_1536/f3\",\n#                        \"activation\": \"softmax\",\n#                        \"model_dir\": \"/kaggle/input/jphhubmap2022models\"}]},\n#     {\"native_tile_size\": 1792,\n#      \"native_down_sample\": 2,\n#      \"native_tile_stride\": 512,\n#      \"model_params\": [{\"type\": \"segformer\",\n#                        \"path\": \"203_seg_b1_512_1536/f4\",\n#                        \"activation\": \"softmax\",\n#                        \"model_dir\": \"/kaggle/input/jphhubmap2022models\"}]}\n#     # 204 - DL-B5x4 stainaug 1536/1792 HBMP @ 0.1/0.2 -> 0.57\n#     {\"native_tile_size\": 1536*2,\n#      \"native_down_sample\": 2,\n#      \"model_params\": [{\"type\": \"smp\",\n#                        \"arch\": \"deeplabv3plus\",\n#                        \"encoder\": \"timm-efficientnet-b5\",\n#                        \"weights\": \"last.ckpt\",\n#                        \"activation\": \"sigmoid\",\n#                        \"model_dir\": \"/kaggle/input/jphhubmap2022models/204_dl_eb5_1792\"}]},\n#     {\"native_tile_size\": 1536*2,\n#      \"native_down_sample\": 2,\n#      \"model_params\": [{\"type\": \"smp\",\n#                        \"arch\": \"deeplabv3plus\",\n#                        \"encoder\": \"timm-efficientnet-b5\",\n#                        \"weights\": \"last-v1.ckpt\",\n#                        \"activation\": \"sigmoid\",\n#                        \"model_dir\": \"/kaggle/input/jphhubmap2022models/204_dl_eb5_1792\"}]},\n#     {\"native_tile_size\": 1536*2,\n#      \"native_down_sample\": 2,\n#      \"model_params\": [{\"type\": \"smp\",\n#                        \"arch\": \"deeplabv3plus\",\n#                        \"encoder\": \"timm-efficientnet-b5\",\n#                        \"weights\": \"last-v2.ckpt\",\n#                        \"activation\": \"sigmoid\",\n#                        \"model_dir\": \"/kaggle/input/jphhubmap2022models/204_dl_eb5_1792\"}]},\n#     {\"native_tile_size\": 1536*2,\n#      \"native_down_sample\": 2,\n#      \"model_params\": [{\"type\": \"smp\",\n#                        \"arch\": \"deeplabv3plus\",\n#                        \"encoder\": \"timm-efficientnet-b5\",\n#                        \"weights\": \"last-v3.ckpt\",\n#                        \"activation\": \"sigmoid\",\n#                        \"model_dir\": \"/kaggle/input/jphhubmap2022models/204_dl_eb5_1792\"}]},\n#     # 206 - DL-B4x4 stainaug 2048/2304/2 HBMP @ 0.1/0.2 -> ?\n#     {\"native_tile_size\": 2304,\n#      \"native_down_sample\": 2,\n#      \"native_tile_stride\": 512,\n#      \"model_params\": [{\"type\": \"smp\",\n#                        \"arch\": \"deeplabv3plus\",\n#                        \"encoder\": \"timm-efficientnet-b4\",\n#                        \"weights\": \"last-v1.ckpt\",\n#                        \"activation\": \"sigmoid\",\n#                        \"model_dir\": \"/kaggle/input/jphhubmap2022models/206_dl_eb4_2304\"}]},\n#     {\"native_tile_size\": 2304,\n#      \"native_down_sample\": 2,\n#      \"native_tile_stride\": 512,\n#      \"model_params\": [{\"type\": \"smp\",\n#                        \"arch\": \"deeplabv3plus\",\n#                        \"encoder\": \"timm-efficientnet-b4\",\n#                        \"weights\": \"last-v2.ckpt\",\n#                        \"activation\": \"sigmoid\",\n#                        \"model_dir\": \"/kaggle/input/jphhubmap2022models/206_dl_eb4_2304\"}]},\n#     {\"native_tile_size\": 2304,\n#      \"native_down_sample\": 2,\n#      \"native_tile_stride\": 512,\n#      \"model_params\": [{\"type\": \"smp\",\n#                        \"arch\": \"deeplabv3plus\",\n#                        \"encoder\": \"timm-efficientnet-b4\",\n#                        \"weights\": \"last-v3.ckpt\",\n#                        \"activation\": \"sigmoid\",\n#                        \"model_dir\": \"/kaggle/input/jphhubmap2022models/206_dl_eb4_2304\"}]},\n#     {\"native_tile_size\": 2304,\n#      \"native_down_sample\": 2,\n#      \"native_tile_stride\": 512,\n#      \"model_params\": [{\"type\": \"smp\",\n#                        \"arch\": \"deeplabv3plus\",\n#                        \"encoder\": \"timm-efficientnet-b4\",\n#                        \"weights\": \"last-v4.ckpt\",\n#                        \"activation\": \"sigmoid\",\n#                        \"model_dir\": \"/kaggle/input/jphhubmap2022models/206_dl_eb4_2304\"}]}\n#     # 208 - Unet-ResNext101x4 stainaug 1536/1792\n#     {\"native_tile_size\": 1792,\n#      \"native_down_sample\": 2,\n#      \"model_params\": [{\"type\": \"smp\",\n#                        \"arch\": \"unet\",\n#                        \"encoder\": \"resnext101_32x4d\",\n#                        \"weights\": \"last.ckpt\",\n#                        \"activation\": \"sigmoid\",\n#                        \"model_dir\": \"/kaggle/input/jphhubmap2022models/208_unet_resnext101_1792\"}]},\n#     {\"native_tile_size\": 1792,\n#      \"native_down_sample\": 2,\n#      \"model_params\": [{\"type\": \"smp\",\n#                        \"arch\": \"unet\",\n#                        \"encoder\": \"resnext101_32x4d\",\n#                        \"weights\": \"last-v2.ckpt\",\n#                        \"activation\": \"sigmoid\",\n#                        \"model_dir\": \"/kaggle/input/jphhubmap2022models/208_unet_resnext101_1792\"}]},\n#     {\"native_tile_size\": 1792,\n#      \"native_down_sample\": 2,\n#      \"model_params\": [{\"type\": \"smp\",\n#                        \"arch\": \"unet\",\n#                        \"encoder\": \"resnext101_32x4d\",\n#                        \"weights\": \"last-v3.ckpt\",\n#                        \"activation\": \"sigmoid\",\n#                        \"model_dir\": \"/kaggle/input/jphhubmap2022models/208_unet_resnext101_1792\"}]},\n#     {\"native_tile_size\": 1792,\n#      \"native_down_sample\": 2,\n#      \"model_params\": [{\"type\": \"smp\",\n#                        \"arch\": \"unet\",\n#                        \"encoder\": \"resnext101_32x4d\",\n#                        \"weights\": \"last-v4.ckpt\",\n#                        \"activation\": \"sigmoid\",\n#                        \"model_dir\": \"/kaggle/input/jphhubmap2022models/208_unet_resnext101_1792\"}]},\n#     # 209 - DL-ResNext101x4 stainaug 1536/1792 - 209 DL-RN101 SA 1536/1792 HBMP @ 0.1/0.25 -> 0.55\n#     {\"native_tile_size\": 1792,\n#      \"native_down_sample\": 2,\n#      \"model_params\": [{\"type\": \"smp\",\n#                        \"arch\": \"deeplabv3plus\",\n#                        \"encoder\": \"resnext101_32x4d\",\n#                        \"weights\": \"last.ckpt\",\n#                        \"activation\": \"sigmoid\",\n#                        \"model_dir\": \"/kaggle/input/jphhubmap2022models/209_dl_resnext101_1792\"}]},\n#     {\"native_tile_size\": 1792,\n#      \"native_down_sample\": 2,\n#      \"model_params\": [{\"type\": \"smp\",\n#                        \"arch\": \"deeplabv3plus\",\n#                        \"encoder\": \"resnext101_32x4d\",\n#                        \"weights\": \"last-v1.ckpt\",\n#                        \"activation\": \"sigmoid\",\n#                        \"model_dir\": \"/kaggle/input/jphhubmap2022models/209_dl_resnext101_1792\"}]},\n#     {\"native_tile_size\": 1792,\n#      \"native_down_sample\": 2,\n#      \"model_params\": [{\"type\": \"smp\",\n#                        \"arch\": \"deeplabv3plus\",\n#                        \"encoder\": \"resnext101_32x4d\",\n#                        \"weights\": \"last-v2.ckpt\",\n#                        \"activation\": \"sigmoid\",\n#                        \"model_dir\": \"/kaggle/input/jphhubmap2022models/209_dl_resnext101_1792\"}]},\n#     {\"native_tile_size\": 1792,\n#      \"native_down_sample\": 2,\n#      \"model_params\": [{\"type\": \"smp\",\n#                        \"arch\": \"deeplabv3plus\",\n#                        \"encoder\": \"resnext101_32x4d\",\n#                        \"weights\": \"last-v3.ckpt\",\n#                        \"activation\": \"sigmoid\",\n#                        \"model_dir\": \"/kaggle/input/jphhubmap2022models/209_dl_resnext101_1792\"}]},\n#     # 210 - DL-B6x4 stainaug 1536/1792 HBMP\n#     {\"native_tile_size\": 1792*2,\n#      \"native_down_sample\": 2,\n#      \"model_params\": [{\"type\": \"smp\",\n#                        \"arch\": \"deeplabv3plus\",\n#                        \"encoder\": \"timm-efficientnet-b6\",\n#                        \"weights\": \"last-v1.ckpt\",\n#                        \"activation\": \"sigmoid\",\n#                        \"model_dir\": \"/kaggle/input/jphhubmap2022models/210_dl_eb6_1792\"}]},\n#     {\"native_tile_size\": 1792*2,\n#      \"native_down_sample\": 2,\n#      \"model_params\": [{\"type\": \"smp\",\n#                        \"arch\": \"deeplabv3plus\",\n#                        \"encoder\": \"timm-efficientnet-b6\",\n#                        \"weights\": \"last-v2.ckpt\",\n#                        \"activation\": \"sigmoid\",\n#                        \"model_dir\": \"/kaggle/input/jphhubmap2022models/210_dl_eb6_1792\"}]},\n#     {\"native_tile_size\": 1792*2,\n#      \"native_down_sample\": 2,\n#      \"model_params\": [{\"type\": \"smp\",\n#                        \"arch\": \"deeplabv3plus\",\n#                        \"encoder\": \"timm-efficientnet-b6\",\n#                        \"weights\": \"last-v3.ckpt\",\n#                        \"activation\": \"sigmoid\",\n#                        \"model_dir\": \"/kaggle/input/jphhubmap2022models/210_dl_eb6_1792\"}]},\n#     {\"native_tile_size\": 1792*2,\n#      \"native_down_sample\": 2,\n#      \"model_params\": [{\"type\": \"smp\",\n#                        \"arch\": \"deeplabv3plus\",\n#                        \"encoder\": \"timm-efficientnet-b6\",\n#                        \"weights\": \"last-v4.ckpt\",\n#                        \"activation\": \"sigmoid\",\n#                        \"model_dir\": \"/kaggle/input/jphhubmap2022models/210_dl_eb6_1792\"}]},\n#     # 211 - UNet MitB3 1024/1280 @ 0.075/0.25/0.3/0.25/0.025 -> 0.59\n#     {\"native_tile_size\": 1280*3,\n#      \"native_down_sample\": 3,\n#      \"model_params\": [{\"type\": \"smp\",\n#                        \"arch\": \"unet\",\n#                        \"encoder\": \"mit_b3\",\n#                        \"weights\": \"last-v1.ckpt\",\n#                        \"activation\": \"sigmoid\",\n#                        \"model_dir\": \"/kaggle/input/jphhubmap2022models/211_unet_mitb3_1280\"}]},\n#     {\"native_tile_size\": 1280*3,\n#      \"native_down_sample\": 3,\n#      \"model_params\": [{\"type\": \"smp\",\n#                        \"arch\": \"unet\",\n#                        \"encoder\": \"mit_b3\",\n#                        \"weights\": \"last-v2.ckpt\",\n#                        \"activation\": \"sigmoid\",\n#                        \"model_dir\": \"/kaggle/input/jphhubmap2022models/211_unet_mitb3_1280\"}]},\n#     {\"native_tile_size\": 1280*3,\n#      \"native_down_sample\": 3,\n#      \"model_params\": [{\"type\": \"smp\",\n#                        \"arch\": \"unet\",\n#                        \"encoder\": \"mit_b3\",\n#                        \"weights\": \"last.ckpt\",\n#                        \"activation\": \"sigmoid\",\n#                        \"model_dir\": \"/kaggle/input/jphhubmap2022models/211_unet_mitb3_1280\"}]},\n#     {\"native_tile_size\": 1280*3,\n#      \"native_down_sample\": 3,\n#      \"model_params\": [{\"type\": \"smp\",\n#                        \"arch\": \"unet\",\n#                        \"encoder\": \"mit_b3\",\n#                        \"weights\": \"last-v3.ckpt\",\n#                        \"activation\": \"sigmoid\",\n#                        \"model_dir\": \"/kaggle/input/jphhubmap2022models/211_unet_mitb3_1280\"}]},\n#     # 211 @ 2.5\n#     {\"native_tile_size\": 1280*2.5,\n#      \"native_down_sample\": 2.5,\n#      \"model_params\": [{\"type\": \"smp\",\n#                        \"arch\": \"unet\",\n#                        \"encoder\": \"mit_b3\",\n#                        \"weights\": \"last-v1.ckpt\",\n#                        \"activation\": \"sigmoid\",\n#                        \"model_dir\": \"/kaggle/input/jphhubmap2022models/211_unet_mitb3_1280\"}]},\n#     {\"native_tile_size\": 1280*2.5,\n#      \"native_down_sample\": 2.5,\n#      \"model_params\": [{\"type\": \"smp\",\n#                        \"arch\": \"unet\",\n#                        \"encoder\": \"mit_b3\",\n#                        \"weights\": \"last-v2.ckpt\",\n#                        \"activation\": \"sigmoid\",\n#                        \"model_dir\": \"/kaggle/input/jphhubmap2022models/211_unet_mitb3_1280\"}]},\n#     {\"native_tile_size\": 1280*2.5,\n#      \"native_down_sample\": 2.5,\n#      \"model_params\": [{\"type\": \"smp\",\n#                        \"arch\": \"unet\",\n#                        \"encoder\": \"mit_b3\",\n#                        \"weights\": \"last.ckpt\",\n#                        \"activation\": \"sigmoid\",\n#                        \"model_dir\": \"/kaggle/input/jphhubmap2022models/211_unet_mitb3_1280\"}]},\n#     {\"native_tile_size\": 1280*2.5,\n#      \"native_down_sample\": 2.5,\n#      \"model_params\": [{\"type\": \"smp\",\n#                        \"arch\": \"unet\",\n#                        \"encoder\": \"mit_b3\",\n#                        \"weights\": \"last-v3.ckpt\",\n#                        \"activation\": \"sigmoid\",\n#                        \"model_dir\": \"/kaggle/input/jphhubmap2022models/211_unet_mitb3_1280\"}]},\n#     # 211 @ 3.5\n#     {\"native_tile_size\": 960*3.5,\n#      \"native_down_sample\": 3.5,\n#      \"model_params\": [{\"type\": \"smp\",\n#                        \"arch\": \"unet\",\n#                        \"encoder\": \"mit_b3\",\n#                        \"weights\": \"last-v1.ckpt\",\n#                        \"activation\": \"sigmoid\",\n#                        \"model_dir\": \"/kaggle/input/jphhubmap2022models/211_unet_mitb3_1280\"}]},\n#     {\"native_tile_size\": 960*3.5,\n#      \"native_down_sample\": 3.5,\n#      \"model_params\": [{\"type\": \"smp\",\n#                        \"arch\": \"unet\",\n#                        \"encoder\": \"mit_b3\",\n#                        \"weights\": \"last-v2.ckpt\",\n#                        \"activation\": \"sigmoid\",\n#                        \"model_dir\": \"/kaggle/input/jphhubmap2022models/211_unet_mitb3_1280\"}]},\n#     {\"native_tile_size\": 960*3.5,\n#      \"native_down_sample\": 3.5,\n#      \"model_params\": [{\"type\": \"smp\",\n#                        \"arch\": \"unet\",\n#                        \"encoder\": \"mit_b3\",\n#                        \"weights\": \"last.ckpt\",\n#                        \"activation\": \"sigmoid\",\n#                        \"model_dir\": \"/kaggle/input/jphhubmap2022models/211_unet_mitb3_1280\"}]},\n#     {\"native_tile_size\": 960*3.5,\n#      \"native_down_sample\": 3.5,\n#      \"model_params\": [{\"type\": \"smp\",\n#                        \"arch\": \"unet\",\n#                        \"encoder\": \"mit_b3\",\n#                        \"weights\": \"last-v3.ckpt\",\n#                        \"activation\": \"sigmoid\",\n#                        \"model_dir\": \"/kaggle/input/jphhubmap2022models/211_unet_mitb3_1280\"}]},\n#     # 213 - UNet MitB1 1536/1536 @ 0.25 -> 0.55\n#     {\"native_tile_size\": 1536*2,\n#      \"native_down_sample\": 2,\n#      \"model_params\": [{\"type\": \"smp\",\n#                        \"arch\": \"unet\",\n#                        \"encoder\": \"mit_b1\",\n#                        \"weights\": \"last-v1.ckpt\",\n#                        \"activation\": \"sigmoid\",\n#                        \"model_dir\": \"/kaggle/input/jphhubmap2022models/213_unet_mitb1_1536\"}]},\n#     {\"native_tile_size\": 1536*2,\n#      \"native_down_sample\": 2,\n#      \"model_params\": [{\"type\": \"smp\",\n#                        \"arch\": \"unet\",\n#                        \"encoder\": \"mit_b1\",\n#                        \"weights\": \"last-v2.ckpt\",\n#                        \"activation\": \"sigmoid\",\n#                        \"model_dir\": \"/kaggle/input/jphhubmap2022models/213_unet_mitb1_1536\"}]},\n#     {\"native_tile_size\": 1536*2,\n#      \"native_down_sample\": 2,\n#      \"model_params\": [{\"type\": \"smp\",\n#                        \"arch\": \"unet\",\n#                        \"encoder\": \"mit_b1\",\n#                        \"weights\": \"last-v3.ckpt\",\n#                        \"activation\": \"sigmoid\",\n#                        \"model_dir\": \"/kaggle/input/jphhubmap2022models/213_unet_mitb1_1536\"}]},\n#     {\"native_tile_size\": 1536*2,\n#      \"native_down_sample\": 2,\n#      \"model_params\": [{\"type\": \"smp\",\n#                        \"arch\": \"unet\",\n#                        \"encoder\": \"mit_b1\",\n#                        \"weights\": \"last-v4.ckpt\",\n#                        \"activation\": \"sigmoid\",\n#                        \"model_dir\": \"/kaggle/input/jphhubmap2022models/213_unet_mitb1_1536\"}]},\n#     # 214 - UNet MitB4 1024/1280 @ 0.4 -> 0.58\n#     {\"native_tile_size\": 1280*3,\n#      \"native_down_sample\": 3,\n#      \"model_params\": [{\"type\": \"smp\",\n#                        \"arch\": \"unet\",\n#                        \"encoder\": \"mit_b4\",\n#                        \"weights\": \"last-v1.ckpt\",\n#                        \"activation\": \"sigmoid\",\n#                        \"model_dir\": \"/kaggle/input/jphhubmap2022models/214_unet_mitb4_1280\"}]},\n#     {\"native_tile_size\": 1280*3,\n#      \"native_down_sample\": 3,\n#      \"model_params\": [{\"type\": \"smp\",\n#                        \"arch\": \"unet\",\n#                        \"encoder\": \"mit_b4\",\n#                        \"weights\": \"last-v2.ckpt\",\n#                        \"activation\": \"sigmoid\",\n#                        \"model_dir\": \"/kaggle/input/jphhubmap2022models/214_unet_mitb4_1280\"}]},\n#     {\"native_tile_size\": 1280*3,\n#      \"native_down_sample\": 3,\n#      \"model_params\": [{\"type\": \"smp\",\n#                        \"arch\": \"unet\",\n#                        \"encoder\": \"mit_b4\",\n#                        \"weights\": \"last.ckpt\",\n#                        \"activation\": \"sigmoid\",\n#                        \"model_dir\": \"/kaggle/input/jphhubmap2022models/214_unet_mitb4_1280\"}]},\n#     {\"native_tile_size\": 1280*3,\n#      \"native_down_sample\": 3,\n#      \"model_params\": [{\"type\": \"smp\",\n#                        \"arch\": \"unet\",\n#                        \"encoder\": \"mit_b4\",\n#                        \"weights\": \"last-v3.ckpt\",\n#                        \"activation\": \"sigmoid\",\n#                        \"model_dir\": \"/kaggle/input/jphhubmap2022models/214_unet_mitb4_1280\"}]},\n#     # 215 - MANet MitB3 1024/1280 @ 0.25\n#     {\"native_tile_size\": 1280*3,\n#      \"native_down_sample\": 3,\n#      \"model_params\": [{\"type\": \"smp\",\n#                        \"arch\": \"manet\",\n#                        \"encoder\": \"mit_b3\",\n#                        \"weights\": \"last.ckpt\",\n#                        \"activation\": \"sigmoid\",\n#                        \"model_dir\": \"/kaggle/input/jphhubmap2022models/215_manet_mitb4_1280\"}]},\n#     {\"native_tile_size\": 1280*3,\n#      \"native_down_sample\": 3,\n#      \"model_params\": [{\"type\": \"smp\",\n#                        \"arch\": \"manet\",\n#                        \"encoder\": \"mit_b3\",\n#                        \"weights\": \"last-v1.ckpt\",\n#                        \"activation\": \"sigmoid\",\n#                        \"model_dir\": \"/kaggle/input/jphhubmap2022models/215_manet_mitb4_1280\"}]},\n#     {\"native_tile_size\": 1280*3,\n#      \"native_down_sample\": 3,\n#      \"model_params\": [{\"type\": \"smp\",\n#                        \"arch\": \"manet\",\n#                        \"encoder\": \"mit_b3\",\n#                        \"weights\": \"last-v2.ckpt\",\n#                        \"activation\": \"sigmoid\",\n#                        \"model_dir\": \"/kaggle/input/jphhubmap2022models/215_manet_mitb4_1280\"}]},\n#     {\"native_tile_size\": 1280*3,\n#      \"native_down_sample\": 3,\n#      \"model_params\": [{\"type\": \"smp\",\n#                        \"arch\": \"manet\",\n#                        \"encoder\": \"mit_b3\",\n#                        \"weights\": \"last-v3.ckpt\",\n#                        \"activation\": \"sigmoid\",\n#                        \"model_dir\": \"/kaggle/input/jphhubmap2022models/215_manet_mitb4_1280\"}]},\n#     # 216 - Unet Mid B3 1280\n#     {\"native_tile_size\": 1280*3,\n#      \"native_down_sample\": 3,\n#      \"model_params\": [{\"type\": \"smp\",\n#                        \"arch\": \"unet\",\n#                        \"encoder\": \"mit_b3\",\n#                        \"weights\": \"last.ckpt\",\n#                        \"activation\": \"sigmoid\",\n#                        \"model_dir\": \"/kaggle/input/jphhubmap2022models/216_unet_mitb3_1280_5f_ds\"}]},\n#     {\"native_tile_size\": 1280*3,\n#      \"native_down_sample\": 3,\n#      \"model_params\": [{\"type\": \"smp\",\n#                        \"arch\": \"unet\",\n#                        \"encoder\": \"mit_b3\",\n#                        \"weights\": \"last-v1.ckpt\",\n#                        \"activation\": \"sigmoid\",\n#                        \"model_dir\": \"/kaggle/input/jphhubmap2022models/216_unet_mitb3_1280_5f_ds\"}]},\n#     {\"native_tile_size\": 1280*3,\n#      \"native_down_sample\": 3,\n#      \"model_params\": [{\"type\": \"smp\",\n#                        \"arch\": \"unet\",\n#                        \"encoder\": \"mit_b3\",\n#                        \"weights\": \"last-v2.ckpt\",\n#                        \"activation\": \"sigmoid\",\n#                        \"model_dir\": \"/kaggle/input/jphhubmap2022models/216_unet_mitb3_1280_5f_ds\"}]},\n#     {\"native_tile_size\": 1280*3,\n#      \"native_down_sample\": 3,\n#      \"model_params\": [{\"type\": \"smp\",\n#                        \"arch\": \"unet\",\n#                        \"encoder\": \"mit_b3\",\n#                        \"weights\": \"last-v3.ckpt\",\n#                        \"activation\": \"sigmoid\",\n#                        \"model_dir\": \"/kaggle/input/jphhubmap2022models/216_unet_mitb3_1280_5f_ds\"}]},\n#     {\"native_tile_size\": 1280*3,\n#      \"native_down_sample\": 3,\n#      \"model_params\": [{\"type\": \"smp\",\n#                        \"arch\": \"unet\",\n#                        \"encoder\": \"mit_b3\",\n#                        \"weights\": \"last-v4.ckpt\",\n#                        \"activation\": \"sigmoid\",\n#                        \"model_dir\": \"/kaggle/input/jphhubmap2022models/216_unet_mitb3_1280_5f_ds\"}]},\n#     # 218 - UNet MitB5\n#     {\"native_tile_size\": 1280*3,\n#      \"native_down_sample\": 3,\n#      \"model_params\": [{\"type\": \"smp\",\n#                        \"arch\": \"unet\",\n#                        \"encoder\": \"mit_b5\",\n#                        \"weights\": \"last.ckpt\",\n#                        \"activation\": \"sigmoid\",\n#                        \"model_dir\": \"/kaggle/input/jphhubmap2022models/218_unet_mitb5_1280\"}]},\n#     {\"native_tile_size\": 1280*3,\n#      \"native_down_sample\": 3,\n#      \"model_params\": [{\"type\": \"smp\",\n#                        \"arch\": \"unet\",\n#                        \"encoder\": \"mit_b5\",\n#                        \"weights\": \"last-v1.ckpt\",\n#                        \"activation\": \"sigmoid\",\n#                        \"model_dir\": \"/kaggle/input/jphhubmap2022models/218_unet_mitb5_1280\"}]},\n#     {\"native_tile_size\": 1280*3,\n#      \"native_down_sample\": 3,\n#      \"model_params\": [{\"type\": \"smp\",\n#                        \"arch\": \"unet\",\n#                        \"encoder\": \"mit_b5\",\n#                        \"weights\": \"last-v2.ckpt\",\n#                        \"activation\": \"sigmoid\",\n#                        \"model_dir\": \"/kaggle/input/jphhubmap2022models/218_unet_mitb5_1280\"}]},\n#     {\"native_tile_size\": 1280*3,\n#      \"native_down_sample\": 3,\n#      \"model_params\": [{\"type\": \"smp\",\n#                        \"arch\": \"unet\",\n#                        \"encoder\": \"mit_b5\",\n#                        \"weights\": \"last-v3.ckpt\",\n#                        \"activation\": \"sigmoid\",\n#                        \"model_dir\": \"/kaggle/input/jphhubmap2022models/218_unet_mitb5_1280\"}]},\n#     # 220 - UNet MitB5 1024/1280 \n#     {\"native_tile_size\": 1280*3,\n#      \"native_down_sample\": 3,\n#      \"model_params\": [{\"type\": \"smp\",\n#                        \"arch\": \"unet\",\n#                        \"encoder\": \"mit_b5\",\n#                        \"weights\": \"last.ckpt\",\n#                        \"activation\": \"sigmoid\",\n#                        \"model_dir\": \"/kaggle/input/jphhubmap2022models/220_unet_mitb5_1280\"}]},\n#     {\"native_tile_size\": 1280*3,\n#      \"native_down_sample\": 3,\n#      \"model_params\": [{\"type\": \"smp\",\n#                        \"arch\": \"unet\",\n#                        \"encoder\": \"mit_b5\",\n#                        \"weights\": \"last-v1.ckpt\",\n#                        \"activation\": \"sigmoid\",\n#                        \"model_dir\": \"/kaggle/input/jphhubmap2022models/220_unet_mitb5_1280\"}]},\n#     {\"native_tile_size\": 1280*3,\n#      \"native_down_sample\": 3,\n#      \"model_params\": [{\"type\": \"smp\",\n#                        \"arch\": \"unet\",\n#                        \"encoder\": \"mit_b5\",\n#                        \"weights\": \"last-v2.ckpt\",\n#                        \"activation\": \"sigmoid\",\n#                        \"model_dir\": \"/kaggle/input/jphhubmap2022models/220_unet_mitb5_1280\"}]},\n#     {\"native_tile_size\": 1280*3,\n#      \"native_down_sample\": 3,\n#      \"model_params\": [{\"type\": \"smp\",\n#                        \"arch\": \"unet\",\n#                        \"encoder\": \"mit_b5\",\n#                        \"weights\": \"last-v3.ckpt\",\n#                        \"activation\": \"sigmoid\",\n#                        \"model_dir\": \"/kaggle/input/jphhubmap2022models/220_unet_mitb5_1280\"}]},\n#     # 224 - UNet MitB5 1024 @ scale 1\n#     {\"native_tile_size\": 1280,\n#      \"native_down_sample\": 1,\n#      \"model_params\": [{\"type\": \"smp\",\n#                        \"arch\": \"unet\",\n#                        \"encoder\": \"mit_b5\",\n#                        \"weights\": \"last-v2.ckpt\",\n#                        \"activation\": \"sigmoid\",\n#                        \"model_dir\": \"/kaggle/input/jphhubmap2022models/224_unet_mitb5_1024_sc1\"},\n#                      {\"type\": \"smp\",\n#                        \"arch\": \"unet\",\n#                        \"encoder\": \"mit_b5\",\n#                        \"weights\": \"last-v3.ckpt\",\n#                        \"activation\": \"sigmoid\",\n#                        \"model_dir\": \"/kaggle/input/jphhubmap2022models/224_unet_mitb5_1024_sc1\"},\n#                       {\"type\": \"smp\",\n#                        \"arch\": \"unet\",\n#                        \"encoder\": \"mit_b5\",\n#                        \"weights\": \"last-v4.ckpt\",\n#                        \"activation\": \"sigmoid\",\n#                        \"model_dir\": \"/kaggle/input/jphhubmap2022models/224_unet_mitb5_1024_sc1\"},\n#                       {\"type\": \"smp\",\n#                        \"arch\": \"unet\",\n#                        \"encoder\": \"mit_b5\",\n#                        \"weights\": \"last-v5.ckpt\",\n#                        \"activation\": \"sigmoid\",\n#                        \"model_dir\": \"/kaggle/input/jphhubmap2022models/224_unet_mitb5_1024_sc1\"}\n#                      ]}\n    \n#     # 229 - CoatMed Da3x3 @ 1024/1280\n#     {\"native_tile_size\": 1280*3,\n#      \"native_down_sample\": 3,\n#      \"model_params\": [{\"type\": \"smp\",\n#                        \"arch\": \"coat_daformer\",\n#                        \"encoder\": \"coat_lite_medium\",\n#                        \"decoder\": \"daformer_conv3x3\",\n#                        \"weights\": \"last.ckpt\",\n#                        \"activation\": \"sigmoid\",\n#                        \"model_dir\": \"/kaggle/input/jphhubmap2022models/229_coat_med_daformer3_1024_1280\"}]},\n#     {\"native_tile_size\": 1280*3,\n#      \"native_down_sample\": 3,\n#      \"model_params\": [{\"type\": \"smp\",\n#                        \"arch\": \"coat_daformer\",\n#                        \"encoder\": \"coat_lite_medium\",\n#                        \"decoder\": \"daformer_conv3x3\",\n#                        \"weights\": \"last-v1.ckpt\",\n#                        \"activation\": \"sigmoid\",\n#                        \"model_dir\": \"/kaggle/input/jphhubmap2022models/229_coat_med_daformer3_1024_1280\"}]},\n#     {\"native_tile_size\": 1280*3,\n#      \"native_down_sample\": 3,\n#      \"model_params\": [{\"type\": \"smp\",\n#                        \"arch\": \"coat_daformer\",\n#                        \"encoder\": \"coat_lite_medium\",\n#                        \"decoder\": \"daformer_conv3x3\",\n#                        \"weights\": \"last-v2.ckpt\",\n#                        \"activation\": \"sigmoid\",\n#                        \"model_dir\": \"/kaggle/input/jphhubmap2022models/229_coat_med_daformer3_1024_1280\"}]},\n#     {\"native_tile_size\": 1280*3,\n#      \"native_down_sample\": 3,\n#      \"model_params\": [{\"type\": \"smp\",\n#                        \"arch\": \"coat_daformer\",\n#                        \"encoder\": \"coat_lite_medium\",\n#                        \"decoder\": \"daformer_conv3x3\",\n#                        \"weights\": \"last-v3.ckpt\",\n#                        \"activation\": \"sigmoid\",\n#                        \"model_dir\": \"/kaggle/input/jphhubmap2022models/229_coat_med_daformer3_1024_1280\"}]},\n#     {\"native_tile_size\": 1280*3,\n#      \"native_down_sample\": 3,\n#      \"model_params\": [{\"type\": \"smp\",\n#                        \"arch\": \"coat_daformer\",\n#                        \"encoder\": \"mit_b3\",\n#                        \"weights\": \"last-v2.ckpt\",\n#                        \"activation\": \"sigmoid\",\n#                        \"model_dir\": \"/kaggle/input/jphhubmap2022models/211_unet_mitb3_1280\"}]},\n#     {\"native_tile_size\": 1280*3,\n#      \"native_down_sample\": 3,\n#      \"model_params\": [{\"type\": \"smp\",\n#                        \"arch\": \"coat_daformer\",\n#                        \"encoder\": \"mit_b3\",\n#                        \"weights\": \"last.ckpt\",\n#                        \"activation\": \"sigmoid\",\n#                        \"model_dir\": \"/kaggle/input/jphhubmap2022models/211_unet_mitb3_1280\"}]},\n#     {\"native_tile_size\": 1280*3,\n#      \"native_down_sample\": 3,\n#      \"model_params\": [{\"type\": \"smp\",\n#                        \"arch\": \"coat_daformer\",\n#                        \"encoder\": \"mit_b3\",\n#                        \"weights\": \"last-v3.ckpt\",\n#                        \"activation\": \"sigmoid\",\n#                        \"model_dir\": \"/kaggle/input/jphhubmap2022models/211_unet_mitb3_1280\"}]},\n    \n    \n    \n    # ORGAN SPECIFIC\n    # 202 - DL-B4x4 stainaug 1536/1792 HBMP @ 0.1/0.2 (version 8/17) -> 0.57\n    {\"native_tile_size\": 1536*2,\n     \"native_down_sample\": 2,\n     \"organs\": [\"lung\"],\n     \"model_params\": [{\"type\": \"smp\",\n                       \"arch\": \"deeplabv3plus\",\n                       \"encoder\": \"timm-efficientnet-b4\",\n                       \"weights\": \"last-v1.ckpt\",\n                       \"activation\": \"sigmoid\",\n                       \"model_dir\": \"/kaggle/input/jphhubmap2022models\"}]},\n    {\"native_tile_size\": 1536*2,\n     \"native_down_sample\": 2,\n     \"organs\": [\"lung\"],\n     \"model_params\": [{\"type\": \"smp\",\n                       \"arch\": \"deeplabv3plus\",\n                       \"encoder\": \"timm-efficientnet-b4\",\n                       \"weights\": \"last-v2.ckpt\",\n                       \"activation\": \"sigmoid\",\n                       \"model_dir\": \"/kaggle/input/jphhubmap2022models\"}]},\n    {\"native_tile_size\": 1536*2,\n     \"native_down_sample\": 2,\n     \"organs\": [\"lung\"],\n     \"model_params\": [{\"type\": \"smp\",\n                       \"arch\": \"deeplabv3plus\",\n                       \"encoder\": \"timm-efficientnet-b4\",\n                       \"weights\": \"last-v3.ckpt\",\n                       \"activation\": \"sigmoid\",\n                       \"model_dir\": \"/kaggle/input/jphhubmap2022models\"}]},\n    {\"native_tile_size\": 1536*2,\n     \"native_down_sample\": 2,\n     \"organs\": [\"lung\"],\n     \"model_params\": [{\"type\": \"smp\",\n                       \"arch\": \"deeplabv3plus\",\n                       \"encoder\": \"timm-efficientnet-b4\",\n                       \"weights\": \"last-v4.ckpt\",\n                       \"activation\": \"sigmoid\",\n                       \"model_dir\": \"/kaggle/input/jphhubmap2022models\"}]},\n    # 204 - DL-B5x4 stainaug 1536/1792 HBMP @ 0.1/0.2 -> 0.57\n    {\"native_tile_size\": 1536*2,\n     \"native_down_sample\": 2,\n     \"organs\": [\"lung\"],\n     \"model_params\": [{\"type\": \"smp\",\n                       \"arch\": \"deeplabv3plus\",\n                       \"encoder\": \"timm-efficientnet-b5\",\n                       \"weights\": \"last.ckpt\",\n                       \"activation\": \"sigmoid\",\n                       \"model_dir\": \"/kaggle/input/jphhubmap2022models/204_dl_eb5_1792\"}]},\n    {\"native_tile_size\": 1536*2,\n     \"native_down_sample\": 2,\n     \"organs\": [\"lung\"],\n     \"model_params\": [{\"type\": \"smp\",\n                       \"arch\": \"deeplabv3plus\",\n                       \"encoder\": \"timm-efficientnet-b5\",\n                       \"weights\": \"last-v1.ckpt\",\n                       \"activation\": \"sigmoid\",\n                       \"model_dir\": \"/kaggle/input/jphhubmap2022models/204_dl_eb5_1792\"}]},\n    {\"native_tile_size\": 1536*2,\n     \"native_down_sample\": 2,\n     \"organs\": [\"lung\"],\n     \"model_params\": [{\"type\": \"smp\",\n                       \"arch\": \"deeplabv3plus\",\n                       \"encoder\": \"timm-efficientnet-b5\",\n                       \"weights\": \"last-v2.ckpt\",\n                       \"activation\": \"sigmoid\",\n                       \"model_dir\": \"/kaggle/input/jphhubmap2022models/204_dl_eb5_1792\"}]},\n    {\"native_tile_size\": 1536*2,\n     \"native_down_sample\": 2,\n     \"organs\": [\"lung\"],\n     \"model_params\": [{\"type\": \"smp\",\n                       \"arch\": \"deeplabv3plus\",\n                       \"encoder\": \"timm-efficientnet-b5\",\n                       \"weights\": \"last-v3.ckpt\",\n                       \"activation\": \"sigmoid\",\n                       \"model_dir\": \"/kaggle/input/jphhubmap2022models/204_dl_eb5_1792\"}]},\n# #     # 211 - UNet MitB3 1024/1280 @ 0.075/0.25/0.3/0.25/0.025 -> 0.59\n# #     {\"native_tile_size\": 1280*3,\n# #      \"native_down_sample\": 3,\n# #      \"organs\": [\"kidney\",\"largeintestine\",\"prostate\",\"spleen\"],\n# #      \"model_params\": [{\"type\": \"smp\",\n# #                        \"arch\": \"unet\",\n# #                        \"encoder\": \"mit_b3\",\n# #                        \"weights\": \"last-v1.ckpt\",\n# #                        \"activation\": \"sigmoid\",\n# #                        \"model_dir\": \"/kaggle/input/jphhubmap2022models/211_unet_mitb3_1280\"}]},\n# #     {\"native_tile_size\": 1280*3,\n# #      \"native_down_sample\": 3,\n# #      \"organs\": [\"kidney\",\"largeintestine\",\"prostate\",\"spleen\"],\n# #      \"model_params\": [{\"type\": \"smp\",\n# #                        \"arch\": \"unet\",\n# #                        \"encoder\": \"mit_b3\",\n# #                        \"weights\": \"last-v2.ckpt\",\n# #                        \"activation\": \"sigmoid\",\n# #                        \"model_dir\": \"/kaggle/input/jphhubmap2022models/211_unet_mitb3_1280\"}]},\n# #     {\"native_tile_size\": 1280*3,\n# #      \"native_down_sample\": 3,\n# #      \"organs\": [\"kidney\",\"largeintestine\",\"prostate\",\"spleen\"],\n# #      \"model_params\": [{\"type\": \"smp\",\n# #                        \"arch\": \"unet\",\n# #                        \"encoder\": \"mit_b3\",\n# #                        \"weights\": \"last.ckpt\",\n# #                        \"activation\": \"sigmoid\",\n# #                        \"model_dir\": \"/kaggle/input/jphhubmap2022models/211_unet_mitb3_1280\"}]},\n# #     {\"native_tile_size\": 1280*3,\n# #      \"native_down_sample\": 3,\n# #      \"organs\": [\"kidney\",\"largeintestine\",\"prostate\",\"spleen\"],\n# #      \"model_params\": [{\"type\": \"smp\",\n# #                        \"arch\": \"unet\",\n# #                        \"encoder\": \"mit_b3\",\n# #                        \"weights\": \"last-v3.ckpt\",\n# #                        \"activation\": \"sigmoid\",\n# #                        \"model_dir\": \"/kaggle/input/jphhubmap2022models/211_unet_mitb3_1280\"}]},\n# #     # 215 - MANet MitB3 1024/1280 @ 0.25\n# #     {\"native_tile_size\": 1280*3,\n# #      \"native_down_sample\": 3,\n# #      \"organs\": [\"kidney\",\"largeintestine\",\"prostate\",\"spleen\"],\n# #      \"model_params\": [{\"type\": \"smp\",\n# #                        \"arch\": \"manet\",\n# #                        \"encoder\": \"mit_b3\",\n# #                        \"weights\": \"last.ckpt\",\n# #                        \"activation\": \"sigmoid\",\n# #                        \"model_dir\": \"/kaggle/input/jphhubmap2022models/215_manet_mitb4_1280\"}]},\n# #     {\"native_tile_size\": 1280*3,\n# #      \"native_down_sample\": 3,\n# #      \"organs\": [\"kidney\",\"largeintestine\",\"prostate\",\"spleen\"],\n# #      \"model_params\": [{\"type\": \"smp\",\n# #                        \"arch\": \"manet\",\n# #                        \"encoder\": \"mit_b3\",\n# #                        \"weights\": \"last-v1.ckpt\",\n# #                        \"activation\": \"sigmoid\",\n# #                        \"model_dir\": \"/kaggle/input/jphhubmap2022models/215_manet_mitb4_1280\"}]},\n# #     {\"native_tile_size\": 1280*3,\n# #      \"native_down_sample\": 3,\n# #      \"organs\": [\"kidney\",\"largeintestine\",\"prostate\",\"spleen\"],\n# #      \"model_params\": [{\"type\": \"smp\",\n# #                        \"arch\": \"manet\",\n# #                        \"encoder\": \"mit_b3\",\n# #                        \"weights\": \"last-v2.ckpt\",\n# #                        \"activation\": \"sigmoid\",\n# #                        \"model_dir\": \"/kaggle/input/jphhubmap2022models/215_manet_mitb4_1280\"}]},\n# #     {\"native_tile_size\": 1280*3,\n# #      \"native_down_sample\": 3,\n# #      \"organs\": [\"kidney\",\"largeintestine\",\"prostate\",\"spleen\"],\n# #      \"model_params\": [{\"type\": \"smp\",\n# #                        \"arch\": \"manet\",\n# #                        \"encoder\": \"mit_b3\",\n# #                        \"weights\": \"last-v3.ckpt\",\n# #                        \"activation\": \"sigmoid\",\n# #                        \"model_dir\": \"/kaggle/input/jphhubmap2022models/215_manet_mitb4_1280\"}]},\n#     # 220 - UNet MitB5 1024/1280 \n#     {\"native_tile_size\": 1280*3,\n#      \"native_down_sample\": 3,\n#      \"organs\": [\"kidney\",\"largeintestine\",\"prostate\",\"spleen\"],\n#      \"model_params\": [{\"type\": \"smp\",\n#                        \"arch\": \"unet\",\n#                        \"encoder\": \"mit_b5\",\n#                        \"weights\": \"last.ckpt\",\n#                        \"activation\": \"sigmoid\",\n#                        \"model_dir\": \"/kaggle/input/jphhubmap2022models/220_unet_mitb5_1280\"}]},\n#     {\"native_tile_size\": 1280*3,\n#      \"native_down_sample\": 3,\n#      \"organs\": [\"kidney\",\"largeintestine\",\"prostate\",\"spleen\"],\n#      \"model_params\": [{\"type\": \"smp\",\n#                        \"arch\": \"unet\",\n#                        \"encoder\": \"mit_b5\",\n#                        \"weights\": \"last-v1.ckpt\",\n#                        \"activation\": \"sigmoid\",\n#                        \"model_dir\": \"/kaggle/input/jphhubmap2022models/220_unet_mitb5_1280\"}]},\n#     {\"native_tile_size\": 1280*3,\n#      \"native_down_sample\": 3,\n#      \"organs\": [\"kidney\",\"largeintestine\",\"prostate\",\"spleen\"],\n#      \"model_params\": [{\"type\": \"smp\",\n#                        \"arch\": \"unet\",\n#                        \"encoder\": \"mit_b5\",\n#                        \"weights\": \"last-v2.ckpt\",\n#                        \"activation\": \"sigmoid\",\n#                        \"model_dir\": \"/kaggle/input/jphhubmap2022models/220_unet_mitb5_1280\"}]},\n#     {\"native_tile_size\": 1280*3,\n#      \"native_down_sample\": 3,\n#      \"organs\": [\"kidney\",\"largeintestine\",\"prostate\",\"spleen\"],\n#      \"model_params\": [{\"type\": \"smp\",\n#                        \"arch\": \"unet\",\n#                        \"encoder\": \"mit_b5\",\n#                        \"weights\": \"last-v3.ckpt\",\n#                        \"activation\": \"sigmoid\",\n#                        \"model_dir\": \"/kaggle/input/jphhubmap2022models/220_unet_mitb5_1280\"}]},\n#     # 226 - FPN MitB5 1024/1280 \n#     {\"native_tile_size\": 1280*3,\n#      \"native_down_sample\": 3,\n#      \"organs\": [\"kidney\",\"largeintestine\",\"prostate\",\"spleen\"],\n#      \"model_params\": [{\"type\": \"smp\",\n#                        \"arch\": \"fpn\",\n#                        \"encoder\": \"mit_b4\",\n#                        \"weights\": \"last-v1.ckpt\",\n#                        \"activation\": \"sigmoid\",\n#                        \"model_dir\": \"/kaggle/input/jphhubmap2022models/226_fpn_mitb5_1280\"}]},\n#     {\"native_tile_size\": 1280*3,\n#      \"native_down_sample\": 3,\n#      \"organs\": [\"kidney\",\"largeintestine\",\"prostate\",\"spleen\"],\n#      \"model_params\": [{\"type\": \"smp\",\n#                        \"arch\": \"fpn\",\n#                        \"encoder\": \"mit_b4\",\n#                        \"weights\": \"last-v2.ckpt\",\n#                        \"activation\": \"sigmoid\",\n#                        \"model_dir\": \"/kaggle/input/jphhubmap2022models/226_fpn_mitb5_1280\"}]},\n#     {\"native_tile_size\": 1280*3,\n#      \"native_down_sample\": 3,\n#      \"organs\": [\"kidney\",\"largeintestine\",\"prostate\",\"spleen\"],\n#      \"model_params\": [{\"type\": \"smp\",\n#                        \"arch\": \"fpn\",\n#                        \"encoder\": \"mit_b4\",\n#                        \"weights\": \"last-v3.ckpt\",\n#                        \"activation\": \"sigmoid\",\n#                        \"model_dir\": \"/kaggle/input/jphhubmap2022models/226_fpn_mitb5_1280\"}]},\n#     {\"native_tile_size\": 1280*3,\n#      \"native_down_sample\": 3,\n#      \"organs\": [\"kidney\",\"largeintestine\",\"prostate\",\"spleen\"],\n#      \"model_params\": [{\"type\": \"smp\",\n#                        \"arch\": \"fpn\",\n#                        \"encoder\": \"mit_b4\",\n#                        \"weights\": \"last-v4.ckpt\",\n#                        \"activation\": \"sigmoid\",\n#                        \"model_dir\": \"/kaggle/input/jphhubmap2022models/226_fpn_mitb5_1280\"}]},\n    # 229 - CoatMed Da3x3 @ 1024/1280\n    {\"native_tile_size\": 1280*3,\n     \"native_down_sample\": 3,\n     \"organs\": [\"kidney\",\"largeintestine\",\"prostate\",\"spleen\"],\n     \"model_params\": [{\"type\": \"smp\",\n                       \"arch\": \"coat_daformer\",\n                       \"encoder\": \"coat_lite_medium\",\n                       \"decoder\": \"daformer_conv3x3\",\n                       \"weights\": \"last.ckpt\",\n                       \"activation\": \"sigmoid\",\n                       \"model_dir\": \"/kaggle/input/jphhubmap2022models/229_coat_med_daformer3_1024_1280\"}]},\n    {\"native_tile_size\": 1280*3,\n     \"native_down_sample\": 3,\n     \"organs\": [\"kidney\",\"largeintestine\",\"prostate\",\"spleen\"],\n     \"model_params\": [{\"type\": \"smp\",\n                       \"arch\": \"coat_daformer\",\n                       \"encoder\": \"coat_lite_medium\",\n                       \"decoder\": \"daformer_conv3x3\",\n                       \"weights\": \"last-v1.ckpt\",\n                       \"activation\": \"sigmoid\",\n                       \"model_dir\": \"/kaggle/input/jphhubmap2022models/229_coat_med_daformer3_1024_1280\"}]},\n    {\"native_tile_size\": 1280*3,\n     \"native_down_sample\": 3,\n     \"organs\": [\"kidney\",\"largeintestine\",\"prostate\",\"spleen\"],\n     \"model_params\": [{\"type\": \"smp\",\n                       \"arch\": \"coat_daformer\",\n                       \"encoder\": \"coat_lite_medium\",\n                       \"decoder\": \"daformer_conv3x3\",\n                       \"weights\": \"last-v2.ckpt\",\n                       \"activation\": \"sigmoid\",\n                       \"model_dir\": \"/kaggle/input/jphhubmap2022models/229_coat_med_daformer3_1024_1280\"}]},\n    {\"native_tile_size\": 1280*3,\n     \"native_down_sample\": 3,\n     \"organs\": [\"kidney\",\"largeintestine\",\"prostate\",\"spleen\"],\n     \"model_params\": [{\"type\": \"smp\",\n                       \"arch\": \"coat_daformer\",\n                       \"encoder\": \"coat_lite_medium\",\n                       \"decoder\": \"daformer_conv3x3\",\n                       \"weights\": \"last-v3.ckpt\",\n                       \"activation\": \"sigmoid\",\n                       \"model_dir\": \"/kaggle/input/jphhubmap2022models/229_coat_med_daformer3_1024_1280\"}]},\n    # 229 - CoatMed Da3x3 @ 1024/1280 @ 2.5\n    {\"native_tile_size\": 1280*2.5,\n     \"native_down_sample\": 2.5,\n     \"organs\": [\"kidney\",\"largeintestine\",\"prostate\",\"spleen\"],\n     \"model_params\": [{\"type\": \"smp\",\n                       \"arch\": \"coat_daformer\",\n                       \"encoder\": \"coat_lite_medium\",\n                       \"decoder\": \"daformer_conv3x3\",\n                       \"weights\": \"last.ckpt\",\n                       \"activation\": \"sigmoid\",\n                       \"model_dir\": \"/kaggle/input/jphhubmap2022models/229_coat_med_daformer3_1024_1280\"}]},\n    {\"native_tile_size\": 1280*2.5,\n     \"native_down_sample\": 2.5,\n     \"organs\": [\"kidney\",\"largeintestine\",\"prostate\",\"spleen\"],\n     \"model_params\": [{\"type\": \"smp\",\n                       \"arch\": \"coat_daformer\",\n                       \"encoder\": \"coat_lite_medium\",\n                       \"decoder\": \"daformer_conv3x3\",\n                       \"weights\": \"last-v1.ckpt\",\n                       \"activation\": \"sigmoid\",\n                       \"model_dir\": \"/kaggle/input/jphhubmap2022models/229_coat_med_daformer3_1024_1280\"}]},\n    {\"native_tile_size\": 1280*2.5,\n     \"native_down_sample\": 2.5,\n     \"organs\": [\"kidney\",\"largeintestine\",\"prostate\",\"spleen\"],\n     \"model_params\": [{\"type\": \"smp\",\n                       \"arch\": \"coat_daformer\",\n                       \"encoder\": \"coat_lite_medium\",\n                       \"decoder\": \"daformer_conv3x3\",\n                       \"weights\": \"last-v2.ckpt\",\n                       \"activation\": \"sigmoid\",\n                       \"model_dir\": \"/kaggle/input/jphhubmap2022models/229_coat_med_daformer3_1024_1280\"}]},\n    {\"native_tile_size\": 1280*2.5,\n     \"native_down_sample\": 2.5,\n     \"organs\": [\"kidney\",\"largeintestine\",\"prostate\",\"spleen\"],\n     \"model_params\": [{\"type\": \"smp\",\n                       \"arch\": \"coat_daformer\",\n                       \"encoder\": \"coat_lite_medium\",\n                       \"decoder\": \"daformer_conv3x3\",\n                       \"weights\": \"last-v3.ckpt\",\n                       \"activation\": \"sigmoid\",\n                       \"model_dir\": \"/kaggle/input/jphhubmap2022models/229_coat_med_daformer3_1024_1280\"}]},\n]","metadata":{"execution":{"iopub.status.busy":"2022-09-20T12:47:36.277027Z","iopub.execute_input":"2022-09-20T12:47:36.277418Z","iopub.status.idle":"2022-09-20T12:47:36.352606Z","shell.execute_reply.started":"2022-09-20T12:47:36.277377Z","shell.execute_reply":"2022-09-20T12:47:36.351494Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def get_largest_tile_size():\n    largest = max([d['native_tile_size'] for d in SETTINGS_AND_MODELS])\n    assert largest == int(largest)\n    return int(largest)\n\ndef load_tiff(file_path) -> np.ndarray:\n    image = tifffile.imread(file_path)\n    if len(image.shape) == 5:\n        image = image.squeeze().transpose(1, 2, 0)\n    return image\n\n\ndef load_models(model_list):\n    mdls = []\n\n    for model_dict in model_list:\n        if model_dict['type'] == 'smp':\n            weights = os.path.join(model_dict['model_dir'], model_dict['weights'])\n            arch, encoder = model_dict['arch'], model_dict['encoder']\n            print('!'+arch+'!'+encoder)\n            if arch == 'deeplabv3plus':\n                _model = smp.DeepLabV3Plus(encoder_name=encoder, encoder_weights=None, in_channels=3, classes=1)\n            elif arch == 'unet':\n                _model = smp.Unet(encoder_name=encoder, encoder_weights=None, in_channels=3, classes=1)\n            elif arch == 'manet':\n                _model = smp.MAnet(encoder_name=encoder, encoder_weights=None, in_channels=3, classes=1)\n            elif arch == 'fpn':\n                _model = smp.FPN(encoder_name=encoder, encoder_weights=None, in_channels=3, classes=1)\n            elif arch == 'coat_daformer':\n                if encoder == 'coat_lite_medium':\n                    encoder = coat_lite_medium()\n                else:\n                    raise ValueError()\n                    \n                if model_dict['decoder'] == 'daformer_conv3x3':\n                    decoder = daformer_conv3x3\n                else:\n                    raise ValueError()\n                    \n                _model = CoatDaformer(encoder=encoder, decoder=decoder)\n            else:\n                raise ValueError(f\"Unknown arch {arch}\")\n            _model.load_state_dict({key.replace(\"model.\", \"\"): value for key, value in\n                                    torch.load(weights, map_location=torch.device(DEVICE))['state_dict'].items()})\n        elif model_dict['type'] == 'segformer':\n            model_dir = os.path.join(model_dict['model_dir'], model_dict['path'])\n            temp_dir = os.path.join(\"/kaggle/working\", os.path.basename(model_dir))\n            os.makedirs(temp_dir, exist_ok=True)\n            torch.save({key.replace(\"model.\", \"\"): value for key, value in\n                        torch.load(os.path.join(model_dir, \"pytorch_model.bin\"))['state_dict'].items()},\n                       os.path.join(temp_dir, \"pytorch_model.bin\"))\n            shutil.copy(os.path.join(model_dir, \"config.json\"),\n                        os.path.join(temp_dir, \"config.json\"))\n            _model = SegformerForSemanticSegmentation.from_pretrained(temp_dir, local_files_only=True)\n        elif model_dict['type'] == 'UneXt50':\n            weights = os.path.join(model_dict['model_dir'], model_dict['weights'])\n            _model = UneXt50()\n            _model.load_state_dict(torch.load(weights))\n        else:\n            raise ValueError(f\"Unknown network type {model_dict['type']}\")\n\n        _model = _model.to(DEVICE).half()\n        _model = _model.eval()\n        mdls.append({'model': _model,\n                     'weight': model_dict.get('weight', 1),\n                     'activation': model_dict['activation']})\n\n    print(f\"Loaded {len(mdls)} models\")\n\n    return mdls\n\n\ndef load_tiff_and_pad_if_needed(tiff_path, tile_size, tiff_pixel_size, ref_pixel_size=None):\n    img = load_tiff(tiff_path)\n    img_h, img_w = img.shape[:2]\n    img = staintools.LuminosityStandardizer.standardize(img)\n    if img.max() <= 1.0:\n        img = (img*255).astype(np.uint8)\n    else:\n        img = img.astype(np.uint8)\n    \n    if tiff_pixel_size and tiff_pixel_size != ref_pixel_size:\n        assert ref_pixel_size\n        scale = tiff_pixel_size / ref_pixel_size\n        img = cv2.resize(img,dsize=None,fx=scale,fy=scale,interpolation=UPSAMPLE_METHOD if scale > 1 else DOWNSAMPLE_METHOD)\n    \n    if img.shape[0] < tile_size or img.shape[1] < tile_size:\n        print(f\"h {img.shape[0]}, w {img.shape[1]} but tile size is {tile_size} -> padding\")\n        new_h, new_w = max(tile_size, img.shape[0]), max(tile_size, img.shape[1])\n        print(f\"news h/w {new_h}/{new_w}\")\n        img_full_ = np.full((tile_size, tile_size, 3), 255)\n        print(f\"full is {img_full_.shape}\")\n        img_full_[:img.shape[0], :img.shape[1]] = img\n        padded = new_h - img.shape[0], new_w - img.shape[1]\n        print(f\"padded is {padded}\")\n        img = img_full_\n        return img, padded[0], padded[1], (img_h, img_w)\n    else:\n        return img, 0, 0, (img_h, img_w)\n\n\ndef coord_generator(image: np.ndarray, tile_size: int, stride: int):\n    img_h, img_w = image.shape[:2]\n    if img_h < tile_size or img_w < tile_size:\n        raise ValueError(f\"Asking for a tile of size {tile_size} bigger than the image! ({image.shape})\")\n\n    def get_starts(img_dim, seq_len, strd):\n        last_valid_start = img_dim - seq_len\n        if last_valid_start == 0:\n            return [0]\n        else:\n            starts = np.arange(0, last_valid_start, strd)\n        if starts[-1] != last_valid_start:\n            starts = np.append(starts, last_valid_start)\n        return starts\n\n    x_starts = get_starts(img_w, tile_size, stride)\n    y_starts = get_starts(img_h, tile_size, stride)\n    for x in x_starts:\n        for y in y_starts:\n            yield int(x), int(y)\n\n\ndef interp_image_tensor(img: torch.Tensor, scale_factor):\n    img = img.unsqueeze(0)  # Add batch dim\n    img = F.interpolate(img.permute(0, 3, 1, 2),\n                        scale_factor=scale_factor,\n                        mode=TORCH_INTERP,\n                        align_corners=False)[0].permute(1, 2, 0)  # Channels last at end\n    return img\n\n\ndef apply_activation_on_preds(pred: torch.Tensor, activation: str):\n    # Receives B*C*H*W\n    # Returned B*H*W*1\n    if activation == 'sigmoid':\n        pred = torch.sigmoid(pred)\n    elif activation == 'softmax':\n        pred = torch.softmax(pred, dim=1)[:,1].unsqueeze(1)  # Remove the 1th of the 2 channel dims, then readd as a single dim for upsampling\n    else:\n        raise ValueError(f\"Unknown activation function {activation}\")\n    return pred\n        \n\ndef upsample_if_needed(y_pred, target_dim):\n    if isinstance(y_pred, SemanticSegmenterOutput):\n        y_pred = F.interpolate(y_pred.logits,\n                               size=target_dim,\n                               mode=TORCH_INTERP,\n                               align_corners=False)  # Take the 1st channel (0=bg)\n    return y_pred\n\n\ndef infer_image_at_coords(img, x_from, y_from, tile_size, model, down_sample, transforms, activation: str, tta):\n    tile = img[y_from:y_from + tile_size, x_from:x_from + tile_size]\n    assert tile.shape[:2] == (tile_size, tile_size)\n    tile = transforms(image=tile)['image']\n    x = torch.from_numpy(tile).to(DEVICE)\n    x = interp_image_tensor(x, scale_factor=1 / down_sample)\n    x = x.permute(2,0,1).half().unsqueeze(0)  # H*W*C -> 1*C*H*W\n    \n    with torch.no_grad():\n        \n        if tta:\n            x = x.repeat(len(tta)+1, 1, 1, 1)  # N_TTA*H*W*C\n            \n            for i_tta, flip_axes in enumerate(tta):\n                x[i_tta+1] = x[i_tta+1].flip(flip_axes)\n                \n            y = upsample_if_needed(model(x), x.shape[-2:])\n            \n            for i_tta, flip_axes in enumerate(tta):\n                y[i_tta+1] = y[i_tta+1].flip(flip_axes)\n                \n        else:\n            y = upsampled_if_needed(model(x), x.shape[-2:])\n            \n        y = apply_activation_on_preds(y, activation).permute(0,2,3,1)  # B*C*H*W -> B*H*W*C;  although C==1, we need it for interp.\n        \n        if tta:  # Average across our batch (TTA) dimension\n            y = torch.mean(y, dim=0)\n            \n    return interp_image_tensor(y.float(), scale_factor=down_sample).squeeze()  # H*W\n\n\ndef get_transforms(mean, std):\n    return A.Compose([\n        A.Normalize(mean=mean, std=std)\n    ])\n\n\ndef rle_encode_less_memory(img):\n    pixels = img.T.flatten()\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    return ' '.join(str(x) for x in runs)","metadata":{"execution":{"iopub.status.busy":"2022-09-20T12:47:36.354671Z","iopub.execute_input":"2022-09-20T12:47:36.355049Z","iopub.status.idle":"2022-09-20T12:47:36.393247Z","shell.execute_reply.started":"2022-09-20T12:47:36.355011Z","shell.execute_reply":"2022-09-20T12:47:36.392002Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"transforms = get_transforms(MEAN, STD)\n\ndf_sample = pd.read_csv(SUBMISSION_CSV_PATH)\ndf_metadata = pd.read_csv(METADATA_CSV_PATH)\n\nfor i_setting, setting_dict in enumerate(SETTINGS_AND_MODELS):\n    SETTINGS_AND_MODELS[i_setting]['models'] = load_models(setting_dict['model_params'])\n\nnames,preds = [],[]\n    \nwith torch.no_grad():\n\n    for idx,row in df_sample.iterrows():\n\n        idx = str(row['id'])\n        native_pixel_size = df_metadata.loc[df_metadata['id']==row['id'], 'pixel_size'].values[0]\n        organ = df_metadata.loc[df_metadata['id']==row['id'], 'organ'].values[0]\n        data_source = df_metadata.loc[df_metadata['id']==row['id'], 'data_source'].values[0]\n\n        # Load the image at full res\n        img_path = os.path.join(INFERENCE_DIR, f\"{idx}.tiff\")\n        \n        img_full, padded_h, padded_w, orig_dim = load_tiff_and_pad_if_needed(img_path, get_largest_tile_size(), native_pixel_size, REF_PIXEL_SIZE/REL_UPSCALE)\n        preds_full = torch.zeros(img_full.shape[:2], device=DEVICE, dtype=torch.half)\n        preds_count = torch.zeros_like(preds_full, dtype=torch.int32)\n\n        for setting_dict in SETTINGS_AND_MODELS:\n            # Work through each model set\n            native_tile_size = setting_dict['native_tile_size']\n            native_down_sample = setting_dict['native_down_sample']\n            native_tile_stride = setting_dict.get('native_tile_stride', DEFAULT_STRIDE)\n            native_window_trim = setting_dict.get('native_window_trim', None)\n            if setting_dict.get('organs'):\n                if organ not in setting_dict['organs']:\n                    print(f\"Skipping {setting_dict['model_params'][0]['arch']} / {setting_dict['model_params'][0]['encoder']}\")\n                    continue\n            \n            assert native_tile_size == int(native_tile_size)\n            native_tile_size = int(native_tile_size)\n            \n            if native_window_trim is None:\n                native_window_trim = int(native_tile_size * DEFAULT_TRIM)\n            \n            models = setting_dict['models']\n\n            for i_tile, (x_from, y_from) in enumerate(tqdm(coord_generator(img_full, native_tile_size, native_tile_stride))):\n                model_dict = models[i_tile % len(models)]\n                \n                pred_tile_native = infer_image_at_coords(img_full,\n                                                         x_from,\n                                                         y_from,\n                                                         native_tile_size,\n                                                         model_dict['model'],\n                                                         native_down_sample,\n                                                         transforms,\n                                                         model_dict['activation'],\n                                                         tta=TTAS)\n                                                \n                x_to = x_from + native_tile_size\n                y_to = y_from + native_tile_size\n                if native_window_trim:\n                    # x_pred_from\n                    if x_from == 0:  # If far left...\n                        x_pred_from = 0\n                    else:\n                        x_from += native_window_trim\n                        x_pred_from = native_window_trim\n                        \n                    # x_pred_to\n                    if x_to == preds_count.shape[0]:  # If far right...\n                        x_pred_to = native_tile_size\n                    else:\n                        x_to -= native_window_trim\n                        x_pred_to = native_tile_size - native_window_trim\n                        \n                    # x_pred_from\n                    if y_from == 0:  # If top...\n                        y_pred_from = 0\n                    else:\n                        y_from += native_window_trim\n                        y_pred_from = native_window_trim\n                        \n                    # x_pred_to\n                    if y_to == preds_count.shape[0]:  # If bottom...\n                        y_pred_to = native_tile_size\n                    else:\n                        y_to -= native_window_trim\n                        y_pred_to = native_tile_size - native_window_trim\n                \n                preds_full[y_from:y_to, x_from:x_to]  += (pred_tile_native[y_pred_from:y_pred_to, x_pred_from:x_pred_to] * model_dict['weight'])\n                preds_count[y_from:y_to, x_from:x_to] += model_dict['weight']\n\n        if padded_w or padded_h:\n            preds_full = preds_full[:-padded_h, :-padded_w]\n            preds_count = preds_count[:-padded_h, :-padded_w]\n            img_unpadded = img_full[:-padded_h, :-padded_w]\n        else:\n            img_unpadded = img_full\n            \n        preds_full.div_(preds_count)\n        preds_full = preds_full.float().cpu().numpy()\n            \n        if preds_full.shape != orig_dim:\n            shrink = orig_dim[0] < preds_full.shape[0]\n            preds_full = cv2.resize(preds_full, orig_dim, interpolation=DOWNSAMPLE_METHOD if shrink else UPSAMPLE_METHOD)\n            \n        assert orig_dim[0] == preds_full.shape[0]\n        assert orig_dim[1] == preds_full.shape[1]\n            \n        preds_full = preds_full >= THRESHOLDS[data_source][organ]\n        rle_pred = rle_encode_less_memory(preds_full)\n        \n        names.append(idx)\n        preds.append(rle_pred)","metadata":{"execution":{"iopub.status.busy":"2022-09-20T12:47:36.397203Z","iopub.execute_input":"2022-09-20T12:47:36.398221Z","iopub.status.idle":"2022-09-20T12:47:57.188640Z","shell.execute_reply.started":"2022-09-20T12:47:36.398180Z","shell.execute_reply":"2022-09-20T12:47:57.187635Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df = pd.DataFrame({'id':names,'rle':preds})\ndf.to_csv('submission.csv',index=False)","metadata":{"execution":{"iopub.status.busy":"2022-09-20T12:47:57.190040Z","iopub.execute_input":"2022-09-20T12:47:57.190412Z","iopub.status.idle":"2022-09-20T12:47:57.198493Z","shell.execute_reply.started":"2022-09-20T12:47:57.190374Z","shell.execute_reply":"2022-09-20T12:47:57.197244Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"try:\n    import matplotlib.pyplot as plt\n\n    if img_unpadded.shape[:2] != orig_dim:\n        shrink = orig_dim[0] < preds_full.shape[0]\n        img_unpadded = cv2.resize(img_unpadded.astype(np.uint8), orig_dim, interpolation=DOWNSAMPLE_METHOD if shrink else UPSAMPLE_METHOD)\n\n    fig, axes = plt.subplots(1,3, figsize=(20, 10))\n    axes[0].imshow(img_full)\n    axes[1].imshow(img_unpadded)\n    axes[1].imshow(preds_full, alpha=0.5, cmap='gray')\n    im = axes[2].imshow(preds_count.cpu().numpy(), cmap='plasma')\n    fig.colorbar(im, ax=axes[2])\n    plt.show()\n    raise ValueError()\nexcept Exception as e:\n    pass","metadata":{"execution":{"iopub.status.busy":"2022-09-20T12:47:57.199995Z","iopub.execute_input":"2022-09-20T12:47:57.200455Z","iopub.status.idle":"2022-09-20T12:48:00.752945Z","shell.execute_reply.started":"2022-09-20T12:47:57.200391Z","shell.execute_reply":"2022-09-20T12:48:00.751834Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"preds_count.max()","metadata":{"execution":{"iopub.status.busy":"2022-09-20T12:48:00.754411Z","iopub.execute_input":"2022-09-20T12:48:00.754877Z","iopub.status.idle":"2022-09-20T12:48:00.762495Z","shell.execute_reply.started":"2022-09-20T12:48:00.754839Z","shell.execute_reply":"2022-09-20T12:48:00.761658Z"},"trusted":true},"execution_count":null,"outputs":[]}]}