{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"pygments_lexer":"ipython3","nbconvert_exporter":"python","version":"3.6.4","file_extension":".py","codemirror_mode":{"name":"ipython","version":3},"name":"python","mimetype":"text/x-python"}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"markdown","source":"## Imports","metadata":{}},{"cell_type":"code","source":"import numpy as np\nimport pandas as pd\nimport scipy as sp\nfrom sklearn.metrics import roc_auc_score, accuracy_score, f1_score, log_loss\nimport matplotlib.pyplot as plt\nimport sys\nimport os\nimport gc\nimport sys\nimport pickle\nimport warnings\nimport math\nimport time\nimport random\nimport argparse\nimport importlib\nfrom tqdm.auto import tqdm\nfrom functools import partial\n\nimport torch\nimport torch.nn as nn\nimport torch.nn.functional as F\nfrom torch.utils.data import DataLoader, Dataset\nfrom torch.cuda.amp import autocast, GradScaler\nfrom torch.optim import Adam, SGD, AdamW\nfrom torch.optim.lr_scheduler import CosineAnnealingWarmRestarts, CosineAnnealingLR, ReduceLROnPlateau\n# import segmentation_models_pytorch as smp\n# from warmup_scheduler import GradualWarmupScheduler\nimport cv2\n\nimport albumentations as A\nfrom albumentations.pytorch import ToTensorV2\nfrom albumentations import ImageOnlyTransform\n\nimport shutil\nfrom pathlib import Path\nfrom contextlib import contextmanager\nfrom collections import defaultdict, Counter\nimport datetime","metadata":{"execution":{"iopub.status.busy":"2023-06-08T18:14:21.150615Z","iopub.execute_input":"2023-06-08T18:14:21.151051Z","iopub.status.idle":"2023-06-08T18:14:28.090903Z","shell.execute_reply.started":"2023-06-08T18:14:21.151014Z","shell.execute_reply":"2023-06-08T18:14:28.08965Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"sys.path.append('/kaggle/input/pretrainedmodels/pretrainedmodels-0.7.4')\nsys.path.append('/kaggle/input/efficientnet-pytorch/EfficientNet-PyTorch-master')\nsys.path.append('/kaggle/input/timm-pytorch-image-models/pytorch-image-models-master')\n# sys.path.append('/kaggle/input/segmentation-models-pytorch/segmentation_models.pytorch-master')\nsys.path.append('/kaggle/input/d/vad13irt/segmentation-models-pytorch')\n\nimport segmentation_models_pytorch as smp\nfrom segmentation_models_pytorch.encoders.mix_transformer import MixVisionTransformerEncoder","metadata":{"execution":{"iopub.status.busy":"2023-06-08T18:14:28.093649Z","iopub.execute_input":"2023-06-08T18:14:28.094498Z","iopub.status.idle":"2023-06-08T18:14:31.222661Z","shell.execute_reply.started":"2023-06-08T18:14:28.094449Z","shell.execute_reply":"2023-06-08T18:14:31.221206Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Main Configuration Class","metadata":{}},{"cell_type":"code","source":"import os\nimport albumentations as A\nfrom albumentations.pytorch import ToTensorV2\n\nclass CFG:\n    # ============== comp exp name =============\n    comp_name = 'vesuvius'\n\n    # comp_dir_path = './'\n    comp_dir_path = '/kaggle/input/'\n    comp_folder_name = 'vesuvius-challenge-ink-detection'\n    comp_dataset_path = f'{comp_dir_path}{comp_folder_name}/'\n    \n    exp_name = 'sgm_effnb0'\n\n    # ============== pred target =============\n    target_size = 1\n\n    # ============== model cfg =============\n    model_name = 'Unet'\n    backbone = ['mit_b2', 'mit_b3', 'mit_b4', 'tu-regnety_064', 'tu-resnest50d_4s2x40d', 'resnet50', 'resnet34'] # 'tu-cs3se_edgenet_x', 'se_resnext50_32x4d', 'tu-seresnextaa101d_32x8d', 'vgg19_bn', 'mit_b0', 'mit_b1', 'mit_b2', 'mit_b3', 'mit_b4', 'mit_b5', 'tu-seresnext26d_32x4d'\n\n    in_chans = 8 # 65\n    # ============== training cfg =============\n    size = 224\n    tile_size = 224\n    stride = tile_size//4\n \n    batch_size = 32 # 32\n    use_amp = True\n\n    scheduler = 'GradualWarmupSchedulerV2'\n    # scheduler = 'CosineAnnealingLR'\n    epochs = 15\n\n    warmup_factor = 10\n    lr = 1e-4 / warmup_factor\n\n    # ============== fold =============\n    valid_id = 2\n\n    objective_cv = 'binary'  # 'binary', 'multiclass', 'regression'\n    metric_direction = 'maximize'  # maximize, 'minimize'\n    # metrics = 'dice_coef'\n\n    # ============== fixed =============\n    pretrained = True\n    inf_weight = 'best'  # 'best'\n\n    min_lr = 1e-6\n    weight_decay = 1e-6\n    max_grad_norm = 1000\n\n    print_freq = 50\n    num_workers = 2\n\n    seed = 42\n\n    # ============== augmentation =============\n    train_aug_list = [\n        # A.RandomResizedCrop(\n        #     size, size, scale=(0.85, 1.0)),\n        A.Resize(size, size),\n        A.HorizontalFlip(p=0.5),\n        A.VerticalFlip(p=0.5),\n        A.RandomBrightnessContrast(p=0.75),\n        A.ShiftScaleRotate(p=0.75),\n        A.OneOf([\n                A.GaussNoise(var_limit=[10, 50]),\n                A.GaussianBlur(),\n                A.MotionBlur(),\n                ], p=0.4),\n        A.GridDistortion(num_steps=5, distort_limit=0.3, p=0.5),\n        A.CoarseDropout(max_holes=1, max_width=int(size * 0.3), max_height=int(size * 0.3), \n                        mask_fill_value=0, p=0.5),\n        # A.Cutout(max_h_size=int(size * 0.6),\n        #          max_w_size=int(size * 0.6), num_holes=1, p=1.0),\n        A.Normalize(\n            mean= [0] * in_chans,\n            std= [1] * in_chans\n        ),\n        ToTensorV2(transpose_mask=True),\n    ]\n\n    valid_aug_list = [\n        A.Resize(size, size),\n        A.Normalize(\n            mean= [0] * in_chans,\n            std= [1] * in_chans\n        ),\n        ToTensorV2(transpose_mask=True),\n    ]","metadata":{"execution":{"iopub.status.busy":"2023-06-08T18:14:31.225657Z","iopub.execute_input":"2023-06-08T18:14:31.226546Z","iopub.status.idle":"2023-06-08T18:14:31.24807Z","shell.execute_reply.started":"2023-06-08T18:14:31.226488Z","shell.execute_reply":"2023-06-08T18:14:31.246366Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"IS_DEBUG = False\nmode = 'train' if IS_DEBUG else 'test'\n# top_TH = 0.5\n# bot_TH = 0.4\n# min_ar = 200\nTH=0.5","metadata":{"execution":{"iopub.status.busy":"2023-06-08T18:14:31.252193Z","iopub.execute_input":"2023-06-08T18:14:31.253102Z","iopub.status.idle":"2023-06-08T18:14:31.266072Z","shell.execute_reply.started":"2023-06-08T18:14:31.253053Z","shell.execute_reply":"2023-06-08T18:14:31.26469Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')","metadata":{"execution":{"iopub.status.busy":"2023-06-08T18:14:31.268593Z","iopub.execute_input":"2023-06-08T18:14:31.269607Z","iopub.status.idle":"2023-06-08T18:14:31.349773Z","shell.execute_reply.started":"2023-06-08T18:14:31.26956Z","shell.execute_reply":"2023-06-08T18:14:31.348194Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Helper Functions (as ususal)","metadata":{}},{"cell_type":"code","source":"# ref.: https://www.kaggle.com/stainsby/fast-tested-rle\ndef rle(img):\n    '''\n    img: numpy array, 1 - mask, 0 - background\n    Returns run length as string formated\n    '''\n    pixels = img.flatten()\n    # pixels = (pixels >= thr).astype(int)\n    \n    pixels = np.concatenate([[0], pixels, [0]])\n    runs = np.where(pixels[1:] != pixels[:-1])[0] + 1\n    runs[1::2] -= runs[::2]\n    return ' '.join(str(x) for x in runs)","metadata":{"execution":{"iopub.status.busy":"2023-06-08T18:14:31.352443Z","iopub.execute_input":"2023-06-08T18:14:31.353337Z","iopub.status.idle":"2023-06-08T18:14:31.364519Z","shell.execute_reply.started":"2023-06-08T18:14:31.353276Z","shell.execute_reply":"2023-06-08T18:14:31.363316Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## L1/Hessian Denoising","metadata":{}},{"cell_type":"code","source":"import cupy as cp\nxp = cp\n\ndelta_lookup = {\n    \"xx\": xp.array([[1, -2, 1]], dtype=float),\n    \"yy\": xp.array([[1], [-2], [1]], dtype=float),\n    \"xy\": xp.array([[1, -1], [-1, 1]], dtype=float),\n}\n\ndef operate_derivative(img_shape, pair):\n    assert len(img_shape) == 2\n    delta = delta_lookup[pair]\n    fft = xp.fft.fftn(delta, img_shape)\n    return fft * xp.conj(fft)\n\ndef soft_threshold(vector, threshold):\n    return xp.sign(vector) * xp.maximum(xp.abs(vector) - threshold, 0)\n\ndef back_diff(input_image, dim):\n    assert dim in (0, 1)\n    r, n = xp.shape(input_image)\n    size = xp.array((r, n))\n    position = xp.zeros(2, dtype=int)\n    temp1 = xp.zeros((r+1, n+1), dtype=float)\n    temp2 = xp.zeros((r+1, n+1), dtype=float)\n    \n    temp1[position[0]:size[0], position[1]:size[1]] = input_image\n    temp2[position[0]:size[0], position[1]:size[1]] = input_image\n    \n    size[dim] += 1\n    position[dim] += 1\n    temp2[position[0]:size[0], position[1]:size[1]] = input_image\n    temp1 -= temp2\n    size[dim] -= 1\n    return temp1[0:size[0], 0:size[1]]\n\ndef forward_diff(input_image, dim):\n    assert dim in (0, 1)\n    r, n = xp.shape(input_image)\n    size = xp.array((r, n))\n    position = xp.zeros(2, dtype=int)\n    temp1 = xp.zeros((r+1, n+1), dtype=float)\n    temp2 = xp.zeros((r+1, n+1), dtype=float)\n        \n    size[dim] += 1\n    position[dim] += 1\n\n    temp1[position[0]:size[0], position[1]:size[1]] = input_image\n    temp2[position[0]:size[0], position[1]:size[1]] = input_image\n    \n    size[dim] -= 1\n    temp2[0:size[0], 0:size[1]] = input_image\n    temp1 -= temp2\n    size[dim] += 1\n    return -temp1[position[0]:size[0], position[1]:size[1]]\n\ndef iter_deriv(input_image, b, scale, mu, dim1, dim2):\n    g = back_diff(forward_diff(input_image, dim1), dim2)\n    d = soft_threshold(g + b, 1 / mu)\n    b = b + (g - d)\n    L = scale * back_diff(forward_diff(d - b, dim2), dim1)\n    return L, b\n\ndef iter_xx(*args):\n    return iter_deriv(*args, dim1=1, dim2=1)\n\ndef iter_yy(*args):\n    return iter_deriv(*args, dim1=0, dim2=0)\n\ndef iter_xy(*args):\n    return iter_deriv(*args, dim1=0, dim2=1)\n\ndef iter_sparse(input_image, bsparse, scale, mu):\n    d = soft_threshold(input_image + bsparse, 1 / mu)\n    bsparse = bsparse + (input_image - d)\n    Lsparse = scale * (d - bsparse)\n    return Lsparse, bsparse\n\ndef denoise_image(input_image, iter_num=100, fidelity=150, sparsity_scale=10, continuity_scale=0.5, mu=1):\n    image_size = xp.shape(input_image)\n    #print(\"Initialize denoising\")\n    norm_array = (\n        operate_derivative(image_size, \"xx\") + \n        operate_derivative(image_size, \"yy\") + \n        2 * operate_derivative(image_size, \"xy\")\n    )\n    norm_array += (fidelity / mu) + sparsity_scale ** 2\n    b_arrays = {\n        \"xx\": xp.zeros(image_size, dtype=float),\n        \"yy\": xp.zeros(image_size, dtype=float),\n        \"xy\": xp.zeros(image_size, dtype=float),\n        \"L1\": xp.zeros(image_size, dtype=float),\n    }\n    g_update = xp.multiply(fidelity / mu, input_image)\n    for i in tqdm(range(iter_num), total=iter_num):\n        #print(f\"Starting iteration {i+1}\")\n        g_update = xp.fft.fftn(g_update)\n        if i == 0:\n            g = xp.fft.ifftn(g_update / (fidelity / mu)).real\n        else:\n            g = xp.fft.ifftn(xp.divide(g_update, norm_array)).real\n        g_update = xp.multiply((fidelity / mu), input_image)\n        \n        #print(\"XX update\")\n        L, b_arrays[\"xx\"] = iter_xx(g, b_arrays[\"xx\"], continuity_scale, mu)\n        g_update += L\n        \n        #print(\"YY update\")\n        L, b_arrays[\"yy\"] = iter_yy(g, b_arrays[\"yy\"], continuity_scale, mu)\n        g_update += L\n        \n        #print(\"XY update\")\n        L, b_arrays[\"xy\"] = iter_xy(g, b_arrays[\"xy\"], 2 * continuity_scale, mu)\n        g_update += L\n        \n        #print(\"L1 update\")\n        L, b_arrays[\"L1\"] = iter_sparse(g, b_arrays[\"L1\"], sparsity_scale, mu)\n        g_update += L\n        \n    g_update = xp.fft.fftn(g_update)\n    g = xp.fft.ifftn(xp.divide(g_update, norm_array)).real\n    \n    g[g < 0] = 0\n    g -= g.min()\n    g /= g.max()\n    return g","metadata":{"execution":{"iopub.status.busy":"2023-06-08T18:14:31.367223Z","iopub.execute_input":"2023-06-08T18:14:31.368273Z","iopub.status.idle":"2023-06-08T18:14:36.108245Z","shell.execute_reply.started":"2023-06-08T18:14:31.368225Z","shell.execute_reply":"2023-06-08T18:14:36.106977Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Dataset and Dataloader","metadata":{}},{"cell_type":"code","source":"def read_image(fragment_id):\n    images = []\n\n    # idxs = range(65)\n    mid = 30 # 65 // 2 , 28, 30\n    start = mid - CFG.in_chans // 2\n    end = mid + CFG.in_chans // 2\n    \n    if CFG.in_chans%2 != 0:\n        end+=1\n\n    idxs = range(start, end)\n\n    for i in tqdm(idxs):\n        \n        image = cv2.imread(CFG.comp_dataset_path + f\"{mode}/{fragment_id}/surface_volume/{i:02}.tif\", 0)\n\n        pad0 = (CFG.tile_size - image.shape[0] % CFG.tile_size)\n        pad1 = (CFG.tile_size - image.shape[1] % CFG.tile_size)\n\n        image = np.pad(image, [(0, pad0), (0, pad1)], constant_values=0)\n\n        images.append(image)\n    images = np.stack(images, axis=2)\n    \n    return images","metadata":{"execution":{"iopub.status.busy":"2023-06-08T18:14:36.110146Z","iopub.execute_input":"2023-06-08T18:14:36.110574Z","iopub.status.idle":"2023-06-08T18:14:36.125578Z","shell.execute_reply.started":"2023-06-08T18:14:36.110527Z","shell.execute_reply":"2023-06-08T18:14:36.124105Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def get_transforms(data, cfg):\n    if data == 'train':\n        aug = A.Compose(cfg.train_aug_list)\n    elif data == 'valid':\n        aug = A.Compose(cfg.valid_aug_list)\n\n    # print(aug)\n    return aug\n\nclass CustomDataset(Dataset):\n    def __init__(self, images, cfg, labels=None, transform=None):\n        self.images = images\n        self.cfg = cfg\n        self.labels = labels\n        self.transform = transform\n\n    def __len__(self):\n        # return len(self.xyxys)\n        return len(self.images)\n\n    def __getitem__(self, idx):\n        # x1, y1, x2, y2 = self.xyxys[idx]\n        image = self.images[idx]\n        data = self.transform(image=image)\n        image = data['image']\n        return image","metadata":{"execution":{"iopub.status.busy":"2023-06-08T18:14:36.127832Z","iopub.execute_input":"2023-06-08T18:14:36.128589Z","iopub.status.idle":"2023-06-08T18:14:36.14209Z","shell.execute_reply.started":"2023-06-08T18:14:36.128543Z","shell.execute_reply":"2023-06-08T18:14:36.140729Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def make_test_dataset(fragment_id):\n    test_images = read_image(fragment_id)\n    \n    x1_list = list(range(0, test_images.shape[1]-CFG.tile_size+1, CFG.stride))\n    y1_list = list(range(0, test_images.shape[0]-CFG.tile_size+1, CFG.stride))\n    \n    test_images_list = []\n    xyxys = []\n    for y1 in y1_list:\n        for x1 in x1_list:\n            y2 = y1 + CFG.tile_size\n            x2 = x1 + CFG.tile_size\n            \n            test_images_list.append(test_images[y1:y2, x1:x2])\n            xyxys.append((x1, y1, x2, y2))\n    xyxys = np.stack(xyxys)\n            \n    test_dataset = CustomDataset(test_images_list, CFG, transform=get_transforms(data='valid', cfg=CFG))\n    \n    test_loader = DataLoader(test_dataset,\n                          batch_size=CFG.batch_size,\n                          shuffle=False,\n                          num_workers=CFG.num_workers, pin_memory=True, drop_last=False)\n    \n    return test_loader, xyxys","metadata":{"execution":{"iopub.status.busy":"2023-06-08T18:14:36.148218Z","iopub.execute_input":"2023-06-08T18:14:36.148668Z","iopub.status.idle":"2023-06-08T18:14:36.163025Z","shell.execute_reply.started":"2023-06-08T18:14:36.148632Z","shell.execute_reply":"2023-06-08T18:14:36.161807Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Model (finally the good stuff)","metadata":{}},{"cell_type":"code","source":"class CustomModel(nn.Module):\n    def __init__(self, cfg, backb, weight=None):\n        super().__init__()\n        self.cfg = cfg\n        \n        if backb in ['mit_b0', 'mit_b1', 'mit_b2', 'mit_b3', 'mit_b4', 'mit_b5']:\n            in_chans = 3\n        else:\n            in_chans = 3\n        \n        if backb in ['mit_b2_s', 'mit_b3_s', 'mit_b4_s']:\n            x = backb[:6]\n            self.encoder = torch.load(f\"/kaggle/input/dad-mit-models/Unet___{x}_chans_27_30_fold_3_best.pth\")['encoder']\n        \n        elif backb in ['tu-seresnext26d_32x4d', 'tu-skresnext50_32x4d', 'tu-res2net50_26w_6s']:\n            self.encoder = smp.Unet(\n                encoder_name=backb, \n                encoder_weights=weight,\n                decoder_attention_type=None,\n                in_channels=in_chans,\n                classes=cfg.target_size,\n                activation=None,\n            )\n        else:\n            self.encoder = smp.Unet(\n                encoder_name=backb, \n                encoder_weights=weight,\n                in_channels=in_chans,\n                classes=cfg.target_size,\n                activation=None,\n            )\n\n    def forward(self, image):\n        output = self.encoder(image)\n        output = output.squeeze(-1)\n        return output","metadata":{"execution":{"iopub.status.busy":"2023-06-08T18:14:36.164974Z","iopub.execute_input":"2023-06-08T18:14:36.165337Z","iopub.status.idle":"2023-06-08T18:14:36.181572Z","shell.execute_reply.started":"2023-06-08T18:14:36.165303Z","shell.execute_reply":"2023-06-08T18:14:36.180253Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class conv_block(nn.Module):\n    '''\n    Block for convolutional layer of U-Net at the encoder end.\n    Args:\n        ch_in : number of input channels\n        ch_out : number of outut channels\n    Returns:\n        feature map of the giv\n    '''\n    def __init__(self,ch_in,ch_out):\n        super(conv_block,self).__init__()\n        self.conv = nn.Sequential(\n            nn.Conv2d(ch_in, ch_out, kernel_size=3,stride=1,padding=1,bias=True),\n            nn.BatchNorm2d(ch_out),\n            nn.ReLU(inplace=True),\n            nn.Conv2d(ch_out, ch_out, kernel_size=3,stride=1,padding=1,bias=True),\n            nn.BatchNorm2d(ch_out),\n            nn.ReLU(inplace=True)\n        )\n\n\n    def forward(self,x):\n        x = self.conv(x)\n        return x\n\nclass up_conv(nn.Module):\n    '''\n    Block for deconvolutional layer of U-Net at the decoder end\n    Args:\n        ch_in : number of input channels\n        ch_out : number of outut channels\n    Returns:\n        feature map of the given input\n    '''\n    def __init__(self,ch_in,ch_out):\n        super(up_conv,self).__init__()\n        self.up = nn.Sequential(\n            nn.Upsample(scale_factor=2),\n            nn.Conv2d(ch_in,ch_out,kernel_size=3,stride=1,padding=1,bias=True),\n            nn.BatchNorm2d(ch_out),\n            nn.ReLU(inplace=True)\n        )\n\n    def forward(self,x):\n        x = self.up(x)\n        return x\n\nclass Recurrent_block(nn.Module):\n    '''\n    Recurrent convolution block for RU-Net and R2U-Net\n    Args:\n        ch_out : number of outut channels\n        t: the number of recurrent convolution block to be used\n    Returns:\n        feature map of the given input\n    '''\n    def __init__(self,ch_out,t=2):\n        super(Recurrent_block,self).__init__()\n        self.t = t\n        self.ch_out = ch_out\n        self.conv = nn.Sequential(\n            nn.Conv2d(ch_out,ch_out,kernel_size=3,stride=1,padding=1,bias=True),\n            nn.BatchNorm2d(ch_out),\n            nn.ReLU(inplace=True)\n        )\n\n    def forward(self,x):\n        for i in range(self.t):\n\n            if i==0:\n                x1 = self.conv(x)\n            \n            x1 = self.conv(x+x1)\n        return x1\n        \nclass RRCNN_block(nn.Module):\n    '''\n    Recurrent Residual convolution block for R2U-Net\n    Args:\n        ch_in  : number of input channels\n        ch_out : number of outut channels\n        t\t: the number of recurrent residual convolution block to be used\n    Returns:\n        feature map of the given input\n    '''\n    def __init__(self,ch_in,ch_out,t=2):\n        super(RRCNN_block,self).__init__()\n        self.RCNN = nn.Sequential(\n            Recurrent_block(ch_out,t=t),\n            Recurrent_block(ch_out,t=t)\n        )\n        self.Conv_1x1 = nn.Conv2d(ch_in,ch_out,kernel_size=1,stride=1,padding=0)\n\n    def forward(self,x):\n        x = self.Conv_1x1(x)\n        x1 = self.RCNN(x)\n        return x+x1\t#residual learning\n\nclass RCNN_block(nn.Module):\n    '''\n    Recurrent convolution block for RU-Net\n    Args:\n        ch_in  : number of input channels\n        ch_out : number of outut channels\n        t\t: the number of recurrent residual convolution block to be used\n    Returns:\n        feature map of the given input\n    '''\n    def __init__(self,ch_in,ch_out,t=2):\n        super(RCNN_block,self).__init__()\n        self.RCNN = nn.Sequential(\n            Recurrent_block(ch_out,t=t),\n            Recurrent_block(ch_out,t=t)\n        )\n        self.Conv_1x1 = nn.Conv2d(ch_in,ch_out,kernel_size=1,stride=1,padding=0)\n\n    def forward(self,x):\n        x = self.Conv_1x1(x)\n        x = self.RCNN(x)\n        return x \n        \nclass ResCNN_block(nn.Module):\n    '''\n    Residual convolution block \n    Args:\n        ch_in  : number of input channels\n        ch_out : number of outut channels\n\n    Returns:\n        feature map of the given input\n    '''\n    def __init__(self,ch_in,ch_out):\n        super(ResCNN_block,self).__init__()\n        self.Conv = conv_block(ch_in, ch_out)\n        self.Conv_1x1 = nn.Conv2d(ch_in,ch_out,kernel_size=1,stride=1,padding=0)\n\n    def forward(self,x):\n        x1 = self.Conv_1x1(x)\n        x = self.Conv(x)\n        return x+x1 \n\nclass U_Net(nn.Module):\n    '''\n    U-Net Network.\n    Implements traditional U-Net with a compressive encoder and an expanding decoder\n\n    Args:\n        img_ch: Input image channels\n        output_ch: Number of channels expected in the output\n\n    Returns:\n        Feature map of input (batch_size, output_ch=1,h,w)\n    '''\n    def __init__(self,img_ch=3,output_ch=1):\n        super(U_Net,self).__init__()\n        \n        self.Maxpool = nn.MaxPool2d(kernel_size=2,stride=2)\n\n        self.Conv1 = conv_block(ch_in=img_ch,ch_out=64)\n        self.Conv2 = conv_block(ch_in=64,ch_out=128)\n        self.Conv3 = conv_block(ch_in=128,ch_out=256)\n        self.Conv4 = conv_block(ch_in=256,ch_out=512)\n        self.Conv5 = conv_block(ch_in=512,ch_out=1024)\n\n        self.Up5 = up_conv(ch_in=1024,ch_out=512)\n        self.Up_conv5 = conv_block(ch_in=1024, ch_out=512)\n\n        self.Up4 = up_conv(ch_in=512,ch_out=256)\n        self.Up_conv4 = conv_block(ch_in=512, ch_out=256)\n        \n        self.Up3 = up_conv(ch_in=256,ch_out=128)\n        self.Up_conv3 = conv_block(ch_in=256, ch_out=128)\n        \n        self.Up2 = up_conv(ch_in=128,ch_out=64)\n        self.Up_conv2 = conv_block(ch_in=128, ch_out=64)\n\n        self.Conv_1x1 = nn.Conv2d(64,output_ch,kernel_size=1,stride=1,padding=0)\n\n\n    def forward(self,x):\n        # encoding path\n        x1 = self.Conv1(x)\n\n        x2 = self.Maxpool(x1)\n        x2 = self.Conv2(x2)\n        \n        x3 = self.Maxpool(x2)\n        x3 = self.Conv3(x3)\n\n        x4 = self.Maxpool(x3)\n        x4 = self.Conv4(x4)\n\n        x5 = self.Maxpool(x4)\n        x5 = self.Conv5(x5)\n\n        # decoding + concat path\n        d5 = self.Up5(x5)\n        d5 = torch.cat((x4,d5),dim=1)\n        \n        d5 = self.Up_conv5(d5)\n        \n        d4 = self.Up4(d5)\n        d4 = torch.cat((x3,d4),dim=1)\n        d4 = self.Up_conv4(d4)\n\n        d3 = self.Up3(d4)\n        d3 = torch.cat((x2,d3),dim=1)\n        d3 = self.Up_conv3(d3)\n\n        d2 = self.Up2(d3)\n        d2 = torch.cat((x1,d2),dim=1)\n        d2 = self.Up_conv2(d2)\n\n        d1 = self.Conv_1x1(d2)\n\n        return d1\n\n\nclass R2U_Net(nn.Module):\n    '''\n    R2U-Net Network.\n    Implements U-Net with a RRCNN block.\n\n    Args:\n        img_ch: Input image channels\n        output_ch: Number of channels expected in the output\n        t: number of recurrent blocks expected\n\n    Returns:\n        Feature map of input (batch_size, output_ch=1,h,w)\n    '''\n    def __init__(self,img_ch=3,output_ch=1,t=2):\n        super(R2U_Net,self).__init__()\n        \n        self.Maxpool = nn.MaxPool2d(kernel_size=2,stride=2)\n        self.Upsample = nn.Upsample(scale_factor=2)\n\n        self.RRCNN1 = RRCNN_block(ch_in=img_ch,ch_out=64,t=t)\n\n        self.RRCNN2 = RRCNN_block(ch_in=64,ch_out=128,t=t)\n        \n        self.RRCNN3 = RRCNN_block(ch_in=128,ch_out=256,t=t)\n        \n        self.RRCNN4 = RRCNN_block(ch_in=256,ch_out=512,t=t)\n        \n        self.RRCNN5 = RRCNN_block(ch_in=512,ch_out=1024,t=t)\n        \n\n        self.Up5 = up_conv(ch_in=1024,ch_out=512)\n        self.Up_RRCNN5 = RRCNN_block(ch_in=1024, ch_out=512,t=t)\n        \n        self.Up4 = up_conv(ch_in=512,ch_out=256)\n        self.Up_RRCNN4 = RRCNN_block(ch_in=512, ch_out=256,t=t)\n        \n        self.Up3 = up_conv(ch_in=256,ch_out=128)\n        self.Up_RRCNN3 = RRCNN_block(ch_in=256, ch_out=128,t=t)\n        \n        self.Up2 = up_conv(ch_in=128,ch_out=64)\n        self.Up_RRCNN2 = RRCNN_block(ch_in=128, ch_out=64,t=t)\n\n        self.Conv_1x1 = nn.Conv2d(64,output_ch,kernel_size=1,stride=1,padding=0)\n\n\n    def forward(self,x):\n        # encoding path\n        x1 = self.RRCNN1(x)\n\n        x2 = self.Maxpool(x1)\n        x2 = self.RRCNN2(x2)\n        \n        x3 = self.Maxpool(x2)\n        x3 = self.RRCNN3(x3)\n\n        x4 = self.Maxpool(x3)\n        x4 = self.RRCNN4(x4)\n\n        x5 = self.Maxpool(x4)\n        x5 = self.RRCNN5(x5)\n\n        # decoding + concat path\n        d5 = self.Up5(x5)\n        d5 = torch.cat((x4,d5),dim=1)\n        d5 = self.Up_RRCNN5(d5)\n        \n        d4 = self.Up4(d5)\n        d4 = torch.cat((x3,d4),dim=1)\n        d4 = self.Up_RRCNN4(d4)\n\n        d3 = self.Up3(d4)\n        d3 = torch.cat((x2,d3),dim=1)\n        d3 = self.Up_RRCNN3(d3)\n\n        d2 = self.Up2(d3)\n        d2 = torch.cat((x1,d2),dim=1)\n        d2 = self.Up_RRCNN2(d2)\n\n        d1 = self.Conv_1x1(d2)\n\n        return d1\n\nclass RecU_Net(nn.Module):\n    '''\n    RU-Net Network.\n    Implements U-Net with a RCNN block.\n\n    Args:\n        img_ch: Input image channels\n        output_ch: Number of channels expected in the output\n        t: number of recurrent blocks expected\n\n    Returns:\n        Feature map of input (batch_size, output_ch=1,h,w)\t\n    '''\n    def __init__(self,img_ch=3,output_ch=1,t=2):\n        super(RecU_Net,self).__init__()\n        \n        self.Maxpool = nn.MaxPool2d(kernel_size=2,stride=2)\n        self.Upsample = nn.Upsample(scale_factor=2)\n\n        self.RCNN1 = RCNN_block(ch_in=img_ch,ch_out=64,t=t)\n\n        self.RCNN2 = RCNN_block(ch_in=64,ch_out=128,t=t)\n        \n        self.RCNN3 = RCNN_block(ch_in=128,ch_out=256,t=t)\n        \n        self.RCNN4 = RCNN_block(ch_in=256,ch_out=512,t=t)\n        \n        self.RCNN5 = RCNN_block(ch_in=512,ch_out=1024,t=t)\n        \n\n        self.Up5 = up_conv(ch_in=1024,ch_out=512)\n        self.Up_RCNN5 = RCNN_block(ch_in=1024, ch_out=512,t=t)\n        \n        self.Up4 = up_conv(ch_in=512,ch_out=256)\n        self.Up_RCNN4 = RCNN_block(ch_in=512, ch_out=256,t=t)\n        \n        self.Up3 = up_conv(ch_in=256,ch_out=128)\n        self.Up_RCNN3 = RCNN_block(ch_in=256, ch_out=128,t=t)\n        \n        self.Up2 = up_conv(ch_in=128,ch_out=64)\n        self.Up_RCNN2 = RCNN_block(ch_in=128, ch_out=64,t=t)\n\n        self.Conv_1x1 = nn.Conv2d(64,output_ch,kernel_size=1,stride=1,padding=0)\n\n\n    def forward(self,x):\n        # encoding path\n        x1 = self.RCNN1(x)\n\n        x2 = self.Maxpool(x1)\n        x2 = self.RCNN2(x2)\n        \n        x3 = self.Maxpool(x2)\n        x3 = self.RCNN3(x3)\n\n        x4 = self.Maxpool(x3)\n        x4 = self.RCNN4(x4)\n\n        x5 = self.Maxpool(x4)\n        x5 = self.RCNN5(x5)\n\n        # decoding + concat path\n        d5 = self.Up5(x5)\n        d5 = torch.cat((x4,d5),dim=1)\n        d5 = self.Up_RCNN5(d5)\n        \n        d4 = self.Up4(d5)\n        d4 = torch.cat((x3,d4),dim=1)\n        d4 = self.Up_RCNN4(d4)\n\n        d3 = self.Up3(d4)\n        d3 = torch.cat((x2,d3),dim=1)\n        d3 = self.Up_RCNN3(d3)\n\n        d2 = self.Up2(d3)\n        d2 = torch.cat((x1,d2),dim=1)\n        d2 = self.Up_RCNN2(d2)\n\n        d1 = self.Conv_1x1(d2)\n\n        return d1\n\nclass ResU_Net(nn.Module):\n    '''\n    Residual U-Net Network.\n    Implements U-Net with a ResCNN block.\n\n    Args:\n        img_ch: Input image channels\n        output_ch: Number of channels expected in the output\n\n    Returns:\n        Feature map of size (batch_size, output_ch,h,w)\n    '''\n    def __init__(self,img_ch=3,output_ch=1):\n        super(ResU_Net,self).__init__()\n        \n        self.Maxpool = nn.MaxPool2d(kernel_size=2,stride=2)\n        self.Upsample = nn.Upsample(scale_factor=2)\n\n        self.ResCNN1 = ResCNN_block(ch_in=img_ch,ch_out=64)\n\n        self.ResCNN2 = ResCNN_block(ch_in=64,ch_out=128)\n        \n        self.ResCNN3 = ResCNN_block(ch_in=128,ch_out=256)\n        \n        self.ResCNN4 = ResCNN_block(ch_in=256,ch_out=512)\n        \n        self.ResCNN5 = ResCNN_block(ch_in=512,ch_out=1024)\n        \n\n        self.Up5 = up_conv(ch_in=1024,ch_out=512)\n        self.Up_ResCNN5 = ResCNN_block(ch_in=1024, ch_out=512)\n        \n        self.Up4 = up_conv(ch_in=512,ch_out=256)\n        self.Up_ResCNN4 = ResCNN_block(ch_in=512, ch_out=256)\n        \n        self.Up3 = up_conv(ch_in=256,ch_out=128)\n        self.Up_ResCNN3 = ResCNN_block(ch_in=256, ch_out=128)\n        \n        self.Up2 = up_conv(ch_in=128,ch_out=64)\n        self.Up_ResCNN2 = ResCNN_block(ch_in=128, ch_out=64)\n\n        self.Conv_1x1 = nn.Conv2d(64,output_ch,kernel_size=1,stride=1,padding=0)\n\n\n    def forward(self,x):\n        # encoding path\n        x1 = self.ResCNN1(x)\n\n        x2 = self.Maxpool(x1)\n        x2 = self.ResCNN2(x2)\n        \n        x3 = self.Maxpool(x2)\n        x3 = self.ResCNN3(x3)\n\n        x4 = self.Maxpool(x3)\n        x4 = self.ResCNN4(x4)\n\n        x5 = self.Maxpool(x4)\n        x5 = self.ResCNN5(x5)\n\n        # decoding + concat path\n        d5 = self.Up5(x5)\n        d5 = torch.cat((x4,d5),dim=1)\n        d5 = self.Up_ResCNN5(d5)\n        \n        d4 = self.Up4(d5)\n        d4 = torch.cat((x3,d4),dim=1)\n        d4 = self.Up_ResCNN4(d4)\n\n        d3 = self.Up3(d4)\n        d3 = torch.cat((x2,d3),dim=1)\n        d3 = self.Up_ResCNN3(d3)\n\n        d2 = self.Up2(d3)\n        d2 = torch.cat((x1,d2),dim=1)\n        d2 = self.Up_ResCNN2(d2)\n\n        d1 = self.Conv_1x1(d2)\n\n        return d1","metadata":{"execution":{"iopub.status.busy":"2023-06-08T18:14:36.183957Z","iopub.execute_input":"2023-06-08T18:14:36.184739Z","iopub.status.idle":"2023-06-08T18:14:36.280969Z","shell.execute_reply.started":"2023-06-08T18:14:36.18469Z","shell.execute_reply":"2023-06-08T18:14:36.279455Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def build_model(cfg, backb, weight=\"None\"):\n    print('model_name', cfg.model_name)\n    print('backbone', backb)\n    \n    if backb == 'ResUNet':\n        model = ResU_Net(img_ch=6,output_ch=1)\n    else:\n        model = CustomModel(cfg, backb, weight)\n    \n    return model","metadata":{"execution":{"iopub.status.busy":"2023-06-08T18:14:36.283448Z","iopub.execute_input":"2023-06-08T18:14:36.283987Z","iopub.status.idle":"2023-06-08T18:14:36.295882Z","shell.execute_reply.started":"2023-06-08T18:14:36.283938Z","shell.execute_reply":"2023-06-08T18:14:36.294474Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Ensemble","metadata":{}},{"cell_type":"code","source":"class EnsembleModel:\n    def __init__(self, use_tta=False):\n        self.models = []\n        self.use_tta = use_tta\n\n    def __call__(self, x):\n#         outputs = [torch.sigmoid(model(x)).to('cpu').numpy()\n#                    for model in self.models]\n        outputs=[]\n        THR = 0.3\n        for model in self.models:\n            if type(model) == type(ResU_Net(img_ch=6,output_ch=1)):\n                outputs.append(torch.sigmoid(model(x)).to('cpu').numpy())\n            elif type(model.encoder.encoder) == MixVisionTransformerEncoder:\n                count=1\n                x_ = torch.sigmoid(model(x[:, 0:3, :, :]))\n#                 outputs.append(torch.sigmoid(model(x[:, 0:3, :, :])).to('cpu').numpy())\n                for i in range(4, CFG.in_chans):\n                    x_ += torch.sigmoid(model(x[:, i-3:i, :, :]))\n#                     outputs.append(torch.sigmoid(model(x[:, i-3:i, :, :])).to('cpu').numpy())\n                    count += 1\n                \n                outputs.append((x_/count).to('cpu').numpy())\n#                 outputs.append(((torch.sigmoid(model(x[:, 3:6, :, :]))+torch.sigmoid(model(x[:, 0:3, :, :]))+torch.sigmoid(model(x[:, 6:9, :, :])))/3).to('cpu').numpy())\n#                 outputs.append((torch.sigmoid(model(x[:, 3:6, :, :])).to('cpu').numpy() >=THR).astype(np.uint8))\n#                 outputs.append((torch.sigmoid(model(x[:, 0:3, :, :])).to('cpu').numpy() >=THR).astype(np.uint8))\n#                 outputs.append((torch.sigmoid(model(x[:, 5:8, :, :])).to('cpu').numpy() >=THR).astype(np.uint8))\n#                 outputs.append((torch.sigmoid(model(x[:, 3:6, :, :]))).cpu().numpy())\n            else:\n                count=1\n                x_ = torch.sigmoid(model(x[:, 0:3, :, :]))\n#                 outputs.append(torch.sigmoid(model(x[:, 0:3, :, :])).to('cpu').numpy())\n                for i in range(4, CFG.in_chans):\n                    x_ += torch.sigmoid(model(x[:, i-3:i, :, :]))\n#                     outputs.append(torch.sigmoid(model(x[:, i-3:i, :, :])).to('cpu').numpy())\n                    count += 1\n                \n                outputs.append((x_/count).to('cpu').numpy())\n#                 outputs.append(torch.sigmoid(model(x)).to('cpu').numpy())\n        avg_preds = np.mean(outputs, axis=0)\n#         avg_preds = np.amax(outputs, axis=0)\n#         avg_preds = np.amin(outputs, axis=0)\n        return avg_preds\n\n    def add_model(self, model):\n        self.models.append(model)\n\ndef build_ensemble_model():\n    model = EnsembleModel()\n    for backb in CFG.backbone:\n        ffolds = []\n        if backb in ['mit_b2', 'mit_b3', 'ResUNet', 'mit_b4', 'mit_b5']:\n            ffolds = [1, 2, 3]\n        else:\n            ffolds = [1, 2, 3]\n        \n        for fold in ffolds:\n            _model = build_model(CFG, backb, weight=None)\n            _model.to(device)\n            flag = False\n            \n            if backb == 'ResUNet':\n                model_path = f'/kaggle/input/vesuvius-models-6fold/ResUNet/Unet_fold{fold}_best.pth'\n            elif backb in ['tu-regnety_064', 'tu-resnest50d_4s2x40d', 'resnet50', 'resnet34']:\n                model_path = f'/kaggle/input/vesuvius-models-3/{backb}/Unet_fold{fold}_best.pth'\n            elif backb in ['mit_b2_s', 'mit_b3_s', 'mit_b4_s']:\n                x = backb[:6]\n                model_path = f'/kaggle/input/dad-mit-models/Unet___{x}_chans_27_30_fold_{fold}_best.pth'\n                flag = True\n            elif backb=='tu-seresnextaa101d_32x8d':\n                model_path = f'/kaggle/input/vesuvius-models/seresnextaa101d_32x8d/{CFG.model_name}_fold{fold}_best.pth'\n            elif backb.startswith(\"mit_b\") or backb=='se_resnext50_32x4d':\n                if backb in ['se_resnext50_32x4d', 'mit_b2', 'mit_b3', 'mit_b4', 'mit_b5']:\n                    model_path = f'/kaggle/input/vesuvius-models/{backb}_30/{CFG.model_name}_fold{fold}_best.pth'\n                else:\n                    model_path = f'/kaggle/input/vesuvius-models-6fold/{backb}/Unet_fold{fold}_best.pth'\n            elif backb == 'tu-seresnext26d_32x4d':\n                model_path = f'/kaggle/input/vesuvius-models/{backb}/{CFG.model_name}_fold{fold}_best.pth'\n            else:\n                model_path = f'/kaggle/input/vesuvius-models/{backb}/{CFG.model_name}_fold{fold}_best.pth'\n            \n            if flag:\n                state = torch.load(model_path)['weights']\n            else:\n                state = torch.load(model_path)['model']\n            \n            _model.load_state_dict(state)\n            _model.eval()\n\n            model.add_model(_model)\n    \n    return model","metadata":{"execution":{"iopub.status.busy":"2023-06-08T18:14:36.298034Z","iopub.execute_input":"2023-06-08T18:14:36.298926Z","iopub.status.idle":"2023-06-08T18:14:36.327809Z","shell.execute_reply.started":"2023-06-08T18:14:36.298865Z","shell.execute_reply":"2023-06-08T18:14:36.326439Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"if mode == 'test':\n    fragment_ids = sorted(os.listdir(CFG.comp_dataset_path + mode))\nelse:\n    fragment_ids = [1]","metadata":{"execution":{"iopub.status.busy":"2023-06-08T18:14:36.330035Z","iopub.execute_input":"2023-06-08T18:14:36.33053Z","iopub.status.idle":"2023-06-08T18:14:36.345359Z","shell.execute_reply.started":"2023-06-08T18:14:36.330485Z","shell.execute_reply":"2023-06-08T18:14:36.34351Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Initializing the model","metadata":{}},{"cell_type":"code","source":"model = build_ensemble_model()","metadata":{"execution":{"iopub.status.busy":"2023-06-08T18:14:36.347877Z","iopub.execute_input":"2023-06-08T18:14:36.349946Z","iopub.status.idle":"2023-06-08T18:15:38.736987Z","shell.execute_reply.started":"2023-06-08T18:14:36.349893Z","shell.execute_reply":"2023-06-08T18:15:38.735609Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def TTA(x:torch.Tensor,model:nn.Module):\n    # x.shape=(batch,c,h,w)\n    shape=x.shape\n    rot = [1, 3] # How much to rotate the fragments for TTA\n    x=[torch.rot90(x,k=i,dims=(-2,-1)) for i in rot]\n#     x = [x, torch.flip(x, dims=[2]), torch.flip(x, dims=[3])]\n    x=torch.cat(x,dim=0)\n    x=model(x)\n    x = torch.from_numpy(x).to(device)\n    # print(type(x))\n    x=x.reshape(len(rot),shape[0],1,*shape[-2:])\n#     x=x.reshape(3,shape[0],1,*shape[-2:])\n    x=[torch.rot90(x[count],k=-i,dims=(-2,-1)) for count, i in enumerate(rot)]\n    x=torch.stack(x,dim=0)\n    return x.mean(0)\n#     return x.max(0).values#[:, 0, :, :]","metadata":{"execution":{"iopub.status.busy":"2023-06-08T18:15:38.743168Z","iopub.execute_input":"2023-06-08T18:15:38.743558Z","iopub.status.idle":"2023-06-08T18:15:38.76065Z","shell.execute_reply.started":"2023-06-08T18:15:38.743521Z","shell.execute_reply":"2023-06-08T18:15:38.759297Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Main","metadata":{}},{"cell_type":"code","source":"results = []\nfor fragment_id in fragment_ids:\n    \n    test_loader, xyxys = make_test_dataset(fragment_id)\n    \n    binary_mask = cv2.imread(CFG.comp_dataset_path + f\"{mode}/{fragment_id}/mask.png\", 0)\n    binary_mask = (binary_mask / 255).astype(int)\n    \n    ori_h = binary_mask.shape[0]\n    ori_w = binary_mask.shape[1]\n    # mask = mask / 255\n\n    pad0 = (CFG.tile_size - binary_mask.shape[0] % CFG.tile_size)\n    pad1 = (CFG.tile_size - binary_mask.shape[1] % CFG.tile_size)\n\n    binary_mask = np.pad(binary_mask, [(0, pad0), (0, pad1)], constant_values=0)\n    \n    mask_pred = np.zeros(binary_mask.shape)\n    mask_count = np.zeros(binary_mask.shape)\n\n    for step, (images) in tqdm(enumerate(test_loader), total=len(test_loader)):\n#         print(images.shape)\n        images = images.to(device)\n        batch_size = images.size(0)\n\n        with torch.no_grad():\n            y_preds = TTA(images,model)\n#             print(y_preds.shape)\n\n        start_idx = step*CFG.batch_size\n        end_idx = start_idx + batch_size\n        for i, (x1, y1, x2, y2) in enumerate(xyxys[start_idx:end_idx]):\n            mask_pred[y1:y2, x1:x2] += y_preds[i].squeeze(0).cpu().numpy()\n            mask_count[y1:y2, x1:x2] += np.ones((CFG.tile_size, CFG.tile_size))\n    \n    plt.imshow(mask_count)\n    plt.show()\n    \n    print(f'mask_count_min: {mask_count.min()}')\n    mask_pred /= (mask_count)\n    \n    del y_preds, mask_count\n    gc.collect()\n    torch.cuda.empty_cache()\n    \n    mask_pred=xp.array(mask_pred)\n    mask_pred=denoise_image(mask_pred, iter_num=250)\n    mask_pred=mask_pred.get()\n    \n    mask_pred = mask_pred[:ori_h, :ori_w]\n    binary_mask = binary_mask[:ori_h, :ori_w]\n    \n    mask_pred = (mask_pred >= TH).astype(np.uint8)\n    mask_pred = mask_pred.astype(int)\n    mask_pred *= binary_mask\n    \n#     print(mask_pred.shape)\n    \n#     classification_mask = (mask_pred > top_TH).astype(int)\n#     mask = mask_pred.copy()\n#     mask[classification_mask.sum(axis=(1)) < min_ar, :] = np.zeros_like(mask_pred[0])\n#     mask = (mask > bot_TH).astype(int)\n    \n    plt.imshow(mask_pred)\n    plt.show()\n    \n    inklabels_rle = rle(mask_pred)\n    \n    results.append((fragment_id, inklabels_rle))\n    \n\n    del mask_pred\n    del test_loader\n    \n    gc.collect()\n    torch.cuda.empty_cache()","metadata":{"execution":{"iopub.status.busy":"2023-06-08T18:15:38.766565Z","iopub.execute_input":"2023-06-08T18:15:38.769894Z","iopub.status.idle":"2023-06-08T18:16:29.996446Z","shell.execute_reply.started":"2023-06-08T18:15:38.769827Z","shell.execute_reply":"2023-06-08T18:16:29.992749Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Submission","metadata":{}},{"cell_type":"code","source":"sub = pd.DataFrame(results, columns=['Id', 'Predicted'])","metadata":{"execution":{"iopub.status.busy":"2023-06-08T18:16:30.000289Z","iopub.status.idle":"2023-06-08T18:16:30.003089Z","shell.execute_reply.started":"2023-06-08T18:16:30.002772Z","shell.execute_reply":"2023-06-08T18:16:30.002802Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"sub","metadata":{"execution":{"iopub.status.busy":"2023-06-08T18:16:30.007193Z","iopub.status.idle":"2023-06-08T18:16:30.01118Z","shell.execute_reply.started":"2023-06-08T18:16:30.010806Z","shell.execute_reply":"2023-06-08T18:16:30.01084Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"sample_sub = pd.read_csv(CFG.comp_dataset_path + 'sample_submission.csv')\nsample_sub = pd.merge(sample_sub[['Id']], sub, on='Id', how='left')","metadata":{"execution":{"iopub.status.busy":"2023-06-08T18:16:30.013028Z","iopub.status.idle":"2023-06-08T18:16:30.014018Z","shell.execute_reply.started":"2023-06-08T18:16:30.013686Z","shell.execute_reply":"2023-06-08T18:16:30.013716Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"sample_sub","metadata":{"execution":{"iopub.status.busy":"2023-06-08T18:16:30.017248Z","iopub.status.idle":"2023-06-08T18:16:30.018218Z","shell.execute_reply.started":"2023-06-08T18:16:30.017939Z","shell.execute_reply":"2023-06-08T18:16:30.017968Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"sample_sub.to_csv(\"submission.csv\", index=False)","metadata":{"execution":{"iopub.status.busy":"2023-06-08T18:16:30.022124Z","iopub.status.idle":"2023-06-08T18:16:30.023091Z","shell.execute_reply.started":"2023-06-08T18:16:30.02278Z","shell.execute_reply":"2023-06-08T18:16:30.022809Z"},"trusted":true},"execution_count":null,"outputs":[]}],"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"}}