{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.10.12","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"gpu","dataSources":[{"sourceId":61446,"databundleVersionId":6962461,"sourceType":"competition"},{"sourceId":7338501,"sourceType":"datasetVersion","datasetId":4060087}],"dockerImageVersionId":30579,"isInternetEnabled":false,"language":"python","sourceType":"notebook","isGpuEnabled":true}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"import os\nimport random\nfrom tqdm import tqdm\nimport pandas as pd\nimport numpy as np\nfrom glob import glob\nimport gc\nfrom collections import defaultdict\n\nimport cv2\nimport torch\nimport torch.nn as nn\nfrom torch.utils.data import Dataset, DataLoader\nfrom torch.optim import lr_scheduler\nfrom torch.cuda import amp\nimport torch.optim as optim","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","execution":{"iopub.status.busy":"2024-01-06T05:03:00.501543Z","iopub.execute_input":"2024-01-06T05:03:00.502320Z","iopub.status.idle":"2024-01-06T05:03:04.437498Z","shell.execute_reply.started":"2024-01-06T05:03:00.502289Z","shell.execute_reply":"2024-01-06T05:03:04.436305Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def set_seed(seed = 42):\n    '''Sets the seed of the entire notebook so results are the same every time we run.\n    This is for REPRODUCIBILITY.'''\n    np.random.seed(seed)\n    random.seed(seed)\n    torch.manual_seed(seed)\n    torch.cuda.manual_seed(seed)\n    # When running on the CuDNN backend, two further options must be set\n    torch.backends.cudnn.deterministic = True\n    torch.backends.cudnn.benchmark = False\n    # Set a fixed value for the hash seed\n    os.environ['PYTHONHASHSEED'] = str(seed)\nset_seed(42)","metadata":{"execution":{"iopub.status.busy":"2024-01-06T05:03:04.439446Z","iopub.execute_input":"2024-01-06T05:03:04.439961Z","iopub.status.idle":"2024-01-06T05:03:04.452267Z","shell.execute_reply.started":"2024-01-06T05:03:04.439921Z","shell.execute_reply":"2024-01-06T05:03:04.450263Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# DataLoader","metadata":{}},{"cell_type":"code","source":"data_dir = \\\n    '/kaggle/input/blood-vessel-segmentation'","metadata":{"execution":{"iopub.status.busy":"2024-01-06T05:03:04.453576Z","iopub.execute_input":"2024-01-06T05:03:04.454226Z","iopub.status.idle":"2024-01-06T05:03:04.465386Z","shell.execute_reply.started":"2024-01-06T05:03:04.454193Z","shell.execute_reply":"2024-01-06T05:03:04.464332Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def file_to_id(f):\n    s = f.split('/')\n    return s[-3]+'_' + s[-1][:-4]\n\nvalid_meta = []\nvalid_folder = sorted(glob(f'{data_dir}/test/*'))\nfor image_folder in valid_folder:\n    file = sorted(glob(f'{image_folder}/images/*.tif'))\n    H, W = cv2.imread(file[0], cv2.IMREAD_ANYDEPTH).shape\n    valid_meta.append(dict({\n        'name':image_folder,\n        'file':file,\n        'shape':(len(file), H, W),\n        'id':[file_to_id(f) for f in file],\n    }))\n        \n        \nprint('len(valid_file) :', len(valid_meta))","metadata":{"execution":{"iopub.status.busy":"2024-01-06T05:03:04.468727Z","iopub.execute_input":"2024-01-06T05:03:04.469109Z","iopub.status.idle":"2024-01-06T05:03:04.611111Z","shell.execute_reply.started":"2024-01-06T05:03:04.469077Z","shell.execute_reply":"2024-01-06T05:03:04.609998Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Model1","metadata":{}},{"cell_type":"code","source":"import torch\nimport torch.nn as nn\nimport torch.nn.functional as F\nimport numpy as np\nfrom timm.models import create_model\n\n\nclass sSE(nn.Module):\n    def __init__(self, out_channels):\n        super(sSE, self).__init__()\n        self.conv = nn.Sequential(nn.Conv2d(out_channels, 1, kernel_size=1,padding=0),\n                                  nn.BatchNorm2d(1),\n                                  nn.Sigmoid())\n    def forward(self,x):\n        x=self.conv(x)\n        return x\n\nclass cSE(nn.Module):\n    def __init__(self, out_channels):\n        super(cSE, self).__init__()\n        self.conv1 = nn.Sequential(nn.Conv2d(out_channels, int(out_channels/2), kernel_size=1,padding=0),\n                                   nn.BatchNorm2d(int(out_channels/2)),\n                                   nn.ReLU(inplace=True),\n                                   )\n                        \n        self.conv2 = nn.Sequential(nn.Conv2d(int(out_channels/2), out_channels, kernel_size=1,padding=0),\n                                   nn.BatchNorm2d(out_channels),\n                                   nn.Sigmoid(),\n                                   )\n    def forward(self,x):\n        x=nn.AvgPool2d(x.size()[2:])(x)\n        x=self.conv1(x)\n        x=self.conv2(x)\n        return x\n    \nclass MyDecoderBlock(nn.Module):\n    def __init__(\n        self,\n        in_channel,\n        skip_channel,\n        out_channel,\n    ):\n        super().__init__()\n        self.conv1 = nn.Sequential(\n            nn.Conv2d(in_channel + skip_channel, out_channel, kernel_size=3, padding=1,),\n            nn.BatchNorm2d(out_channel),\n            nn.ReLU(inplace=True),\n        )\n\n        self.conv2 = nn.Sequential(\n            nn.Conv2d(out_channel,out_channel,kernel_size=3, padding=1,),\n            nn.BatchNorm2d(out_channel),\n            nn.ReLU(inplace=True),\n        )\n        self.spatial_gate = sSE(out_channel)\n        self.channel_gate = cSE(out_channel)\n\n\n    def forward(self, x, skip=None):\n        x = F.interpolate(x, scale_factor=2, mode='bilinear')\n        if skip is not None:\n            x = torch.cat([x, skip], dim=1)\n        x = self.conv1(x)\n        x = self.conv2(x)\n        g1 = self.spatial_gate(x)\n        g2 = self.channel_gate(x)\n        x = g1*x + g2*x\n        return x\n\nclass MyUnetDecoder(nn.Module):\n    def __init__(self,\n                 in_channel,\n                 skip_channel,\n                 out_channel,\n                 ):\n        super().__init__()\n\n        self.center = nn.Identity()\n\n        i_channel = [in_channel, ] + out_channel[:-1]\n        s_channel = skip_channel\n        o_channel = out_channel\n        block = [\n            MyDecoderBlock(i, s, o,)\n            for i, s, o in zip(i_channel, s_channel, o_channel)\n        ]\n        self.block = nn.ModuleList(block)\n\n    def forward(self, feature, skip):\n        d = self.center(feature)\n\n        for i, block in enumerate(self.block):\n            s = skip[i]\n            d = block(d, s)\n            \n        last = d\n        return last\n\n\nclass ConvNeXt_U(nn.Module):\n    def __init__(self):\n        super().__init__() \n        encoder_dim = [24, 48, 96, 192, 384, 768]\n        decoder_dim = [384, 192, 96, 48, 24]\n\n        self.encoder = create_model('convnext_small.fb_in22k', pretrained=False, in_chans=1)\n\n        self.decoder = MyUnetDecoder(\n            in_channel  = encoder_dim[-1],\n            skip_channel= encoder_dim[:-1][::-1],\n            out_channel = decoder_dim,\n        )\n        self.vessel = nn.Conv2d(decoder_dim[-1], 1, kernel_size=1)\n        self.kidney = nn.Conv2d(decoder_dim[-1], 1, kernel_size=1)\n        self.stem0 = nn.Sequential(nn.Conv2d(in_channels=1, out_channels=24, kernel_size=3, stride=1, padding=1), \n                                   nn.BatchNorm2d(24, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True), \n                                   nn.ReLU(inplace=True),\n                                   nn.Conv2d(in_channels=24, out_channels=24, kernel_size=3, stride=1, padding=1), \n                                   nn.BatchNorm2d(24, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True), \n                                   nn.ReLU(inplace=True),\n                                  )\n        self.stem1 = nn.Sequential(nn.Conv2d(in_channels=24, out_channels=48, kernel_size=3, stride=1, padding=1), \n                                   nn.BatchNorm2d(48, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True), \n                                   nn.ReLU(inplace=True),\n                                   nn.Conv2d(in_channels=48, out_channels=48, kernel_size=3, stride=1, padding=1), \n                                   nn.BatchNorm2d(48, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True), \n                                   nn.ReLU(inplace=True),\n                                  )\n\n    def forward(self, image):\n        B, C, H, W = image.shape\n        H_pad = (32 - H % 32) % 32\n        W_pad = (32 - W % 32) % 32\n        x = F.pad(image, (0, W_pad, 0, H_pad), 'constant', 0)\n        # x = x.expand(-1, 3, -1, -1)\n\n        encode = []\n        xx = self.stem0(x); encode.append(xx)\n        xx = F.avg_pool2d(xx,kernel_size=2,stride=2)\n        xx = self.stem1(xx); encode.append(xx)\n\n        e = self.encoder\n        x = e.stem(x);\n\n        x = e.stages[0](x); encode.append(x)\n        x = e.stages[1](x); encode.append(x)\n        x = e.stages[2](x); encode.append(x)\n        x = e.stages[3](x); encode.append(x)\n        #[print(f'encode_{i}', e.shape) for i,e in enumerate(encode)]\n        last = self.decoder(\n            feature=encode[-1], skip=encode[:-1][::-1]\n        )\n\n        vessel = self.vessel(last).float()\n        vessel = F.logsigmoid(vessel).exp()\n        vessel = vessel[:, :, :H, :W].contiguous()\n        \n        kidney = self.kidney(last).float()\n        kidney = F.logsigmoid(kidney).exp()\n        kidney = kidney[:, :, :H, :W].contiguous()\n        \n        return vessel, kidney\n    \ndef run_check_net():\n    height, width = 260, 256\n    batch_size = 2\n\n    image = torch.from_numpy(np.random.uniform(0, 1, (batch_size, 1, height, width))).float().cuda()\n\n    net = ConvNeXt_U().cuda()\n\n    with torch.no_grad():\n        with torch.cuda.amp.autocast(enabled=True):\n            v, k = net(image)\n\n    print('image', image.shape)\n    print('vessel', v.shape)\n    print('kidney', k.shape)\n\nif __name__ == '__main__':\n    run_check_net()\n    torch.cuda.empty_cache()","metadata":{"execution":{"iopub.status.busy":"2024-01-06T05:03:04.612937Z","iopub.execute_input":"2024-01-06T05:03:04.613545Z","iopub.status.idle":"2024-01-06T05:03:08.592249Z","shell.execute_reply.started":"2024-01-06T05:03:04.613510Z","shell.execute_reply":"2024-01-06T05:03:08.591285Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model1 = ConvNeXt_U()\nmodel1.load_state_dict(torch.load(\"/kaggle/input/sennet-hoa-models/convnext_small-unet-1ltuf51v.pt\",))\nmodel1.eval()","metadata":{"execution":{"iopub.status.busy":"2024-01-06T05:03:08.593662Z","iopub.execute_input":"2024-01-06T05:03:08.594348Z","iopub.status.idle":"2024-01-06T05:03:13.473041Z","shell.execute_reply.started":"2024-01-06T05:03:08.594313Z","shell.execute_reply":"2024-01-06T05:03:13.472067Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model1 = model1.cuda()","metadata":{"execution":{"iopub.status.busy":"2024-01-06T05:03:13.474272Z","iopub.execute_input":"2024-01-06T05:03:13.474648Z","iopub.status.idle":"2024-01-06T05:03:13.569763Z","shell.execute_reply.started":"2024-01-06T05:03:13.474623Z","shell.execute_reply":"2024-01-06T05:03:13.568754Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Model2","metadata":{}},{"cell_type":"code","source":"import torch\nimport torch.nn as nn\nimport torch.nn.functional as F\nimport numpy as np\nfrom timm.models import create_model\n\n\nclass sSE(nn.Module):\n    def __init__(self, out_channels):\n        super(sSE, self).__init__()\n        self.conv = nn.Sequential(nn.Conv2d(out_channels, 1, kernel_size=1,padding=0),\n                                  nn.BatchNorm2d(1),\n                                  nn.Sigmoid())\n    def forward(self,x):\n        x=self.conv(x)\n        return x\n\nclass cSE(nn.Module):\n    def __init__(self, out_channels):\n        super(cSE, self).__init__()\n        self.conv1 = nn.Sequential(nn.Conv2d(out_channels, int(out_channels/2), kernel_size=1,padding=0),\n                                   nn.BatchNorm2d(int(out_channels/2)),\n                                   nn.ReLU(inplace=True),\n                                   )\n                        \n        self.conv2 = nn.Sequential(nn.Conv2d(int(out_channels/2), out_channels, kernel_size=1,padding=0),\n                                   nn.BatchNorm2d(out_channels),\n                                   nn.Sigmoid(),\n                                   )\n    def forward(self,x):\n        x=nn.AvgPool2d(x.size()[2:])(x)\n        x=self.conv1(x)\n        x=self.conv2(x)\n        return x\n    \nclass MyDecoderBlock(nn.Module):\n    def __init__(\n        self,\n        in_channel,\n        skip_channel,\n        out_channel,\n    ):\n        super().__init__()\n        self.conv1 = nn.Sequential(\n            nn.Conv2d(in_channel + skip_channel, out_channel, kernel_size=3, padding=1,),\n            nn.BatchNorm2d(out_channel),\n            nn.ReLU(inplace=True),\n        )\n\n        self.conv2 = nn.Sequential(\n            nn.Conv2d(out_channel,out_channel,kernel_size=3, padding=1,),\n            nn.BatchNorm2d(out_channel),\n            nn.ReLU(inplace=True),\n        )\n        self.spatial_gate = sSE(out_channel)\n        self.channel_gate = cSE(out_channel)\n\n\n    def forward(self, x, skip=None):\n        x = F.interpolate(x, scale_factor=2, mode='bilinear')\n        if skip is not None:\n            x = torch.cat([x, skip], dim=1)\n        x = self.conv1(x)\n        x = self.conv2(x)\n        g1 = self.spatial_gate(x)\n        g2 = self.channel_gate(x)\n        x = g1*x + g2*x\n        return x\n\nclass MyUnetDecoder(nn.Module):\n    def __init__(self,\n                 in_channel,\n                 skip_channel,\n                 out_channel,\n                 ):\n        super().__init__()\n\n        self.center = nn.Identity()\n\n        i_channel = [in_channel, ] + out_channel[:-1]\n        s_channel = skip_channel\n        o_channel = out_channel\n        block = [\n            MyDecoderBlock(i, s, o,)\n            for i, s, o in zip(i_channel, s_channel, o_channel)\n        ]\n        self.block = nn.ModuleList(block)\n\n    def forward(self, feature, skip):\n        d = self.center(feature)\n\n        for i, block in enumerate(self.block):\n            s = skip[i]\n            d = block(d, s)\n            \n        last = d\n        return last\n\n\nclass ConvNeXt_U(nn.Module):\n    def __init__(self):\n        super().__init__() \n        encoder_dim = [24, 48, 96, 192, 384, 768]\n        decoder_dim = [384, 192, 96, 48, 24]\n\n        self.encoder = create_model('convnext_small.fb_in22k', pretrained=False, in_chans=3)\n\n        self.decoder = MyUnetDecoder(\n            in_channel  = encoder_dim[-1],\n            skip_channel= encoder_dim[:-1][::-1],\n            out_channel = decoder_dim,\n        )\n        self.vessel = nn.Conv2d(decoder_dim[-1], 1, kernel_size=1)\n        self.kidney = nn.Conv2d(decoder_dim[-1], 1, kernel_size=1)\n        self.stem0 = nn.Sequential(nn.Conv2d(in_channels=3, out_channels=24, kernel_size=3, stride=1, padding=1), \n                                   nn.BatchNorm2d(24, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True), \n                                   nn.ReLU(inplace=True),\n                                   nn.Conv2d(in_channels=24, out_channels=24, kernel_size=3, stride=1, padding=1), \n                                   nn.BatchNorm2d(24, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True), \n                                   nn.ReLU(inplace=True),\n                                  )\n        self.stem1 = nn.Sequential(nn.Conv2d(in_channels=24, out_channels=48, kernel_size=3, stride=1, padding=1), \n                                   nn.BatchNorm2d(48, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True), \n                                   nn.ReLU(inplace=True),\n                                   nn.Conv2d(in_channels=48, out_channels=48, kernel_size=3, stride=1, padding=1), \n                                   nn.BatchNorm2d(48, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True), \n                                   nn.ReLU(inplace=True),\n                                  )\n\n    def forward(self, image):\n        B, C, H, W = image.shape\n        H_pad = (32 - H % 32) % 32\n        W_pad = (32 - W % 32) % 32\n        x = F.pad(image, (0, W_pad, 0, H_pad), 'constant', 0)\n        x = x.expand(-1, 3, -1, -1)\n\n        encode = []\n        xx = self.stem0(x); encode.append(xx)\n        xx = F.avg_pool2d(xx,kernel_size=2,stride=2)\n        xx = self.stem1(xx); encode.append(xx)\n\n        e = self.encoder\n        x = e.stem(x);\n\n        x = e.stages[0](x); encode.append(x)\n        x = e.stages[1](x); encode.append(x)\n        x = e.stages[2](x); encode.append(x)\n        x = e.stages[3](x); encode.append(x)\n        #[print(f'encode_{i}', e.shape) for i,e in enumerate(encode)]\n        last = self.decoder(\n            feature=encode[-1], skip=encode[:-1][::-1]\n        )\n\n        vessel = self.vessel(last).float()\n        vessel = F.logsigmoid(vessel).exp()\n        vessel = vessel[:, :, :H, :W].contiguous()\n        \n        kidney = self.kidney(last).float()\n        kidney = F.logsigmoid(kidney).exp()\n        kidney = kidney[:, :, :H, :W].contiguous()\n        \n        return vessel, kidney\n    \ndef run_check_net():\n    height, width = 260, 256\n    batch_size = 2\n\n    image = torch.from_numpy(np.random.uniform(0, 1, (batch_size, 1, height, width))).float().cuda()\n\n    net = ConvNeXt_U().cuda()\n\n    with torch.no_grad():\n        with torch.cuda.amp.autocast(enabled=True):\n            v, k = net(image)\n\n    print('image', image.shape)\n    print('vessel', v.shape)\n    print('kidney', k.shape)\n\nif __name__ == '__main__':\n    run_check_net()\n    torch.cuda.empty_cache()","metadata":{"execution":{"iopub.status.busy":"2024-01-06T05:03:13.571391Z","iopub.execute_input":"2024-01-06T05:03:13.571962Z","iopub.status.idle":"2024-01-06T05:03:14.944677Z","shell.execute_reply.started":"2024-01-06T05:03:13.571928Z","shell.execute_reply":"2024-01-06T05:03:14.943715Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model2 = ConvNeXt_U()\nmodel2.load_state_dict(torch.load(\"/kaggle/input/sennet-hoa-models/convnext_small-unet-1cbx0ckf.pt\",))\nmodel2.eval()\nmodel2 = model2.cuda()","metadata":{"execution":{"iopub.status.busy":"2024-01-06T05:03:14.946206Z","iopub.execute_input":"2024-01-06T05:03:14.946788Z","iopub.status.idle":"2024-01-06T05:03:19.166439Z","shell.execute_reply.started":"2024-01-06T05:03:14.946760Z","shell.execute_reply":"2024-01-06T05:03:19.165311Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def rle_encode(mask):\n    pixel = mask.flatten()\n    pixel = np.concatenate([[0], pixel, [0]])\n    run = np.where(pixel[1:] != pixel[:-1])[0] + 1\n    run[1::2] -= run[::2]\n    rle = ' '.join(str(r) for r in run)\n    if rle == '':\n        rle = '1 0'\n    return rle","metadata":{"execution":{"iopub.status.busy":"2024-01-06T05:03:19.169449Z","iopub.execute_input":"2024-01-06T05:03:19.169769Z","iopub.status.idle":"2024-01-06T05:03:19.176841Z","shell.execute_reply.started":"2024-01-06T05:03:19.169742Z","shell.execute_reply":"2024-01-06T05:03:19.175681Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"submission_df = []\nfor d in valid_meta:\n    volume = [cv2.imread(f, cv2.IMREAD_ANYDEPTH).astype(np.float32) for f in d['file']]\n    volume = np.stack(volume)\n    D, H, W = volume.shape\n\n    predict1 = np.zeros(d['shape'], dtype=np.float32)\n    predict2 = np.zeros(d['shape'], dtype=np.float32)\n    axes = [0,1,2]\n    for axis in axes:\n        loader = np.array_split(np.arange((D, H, W)[axis]), max(1, int((D, H, W)[axis] // 2)))\n        num_valid = len(loader)\n\n        B = 0 \n        for t in range(num_valid):\n            if axis == 0:\n                image = volume[loader[t].tolist()]\n            elif axis == 1:\n                image = volume[:, loader[t].tolist()].transpose(1, 0, 2)\n            else:\n                image = volume[:, :, loader[t].tolist()].transpose(2, 0, 1)\n\n            batch_size, bh, bw = image.shape\n            image = ((image - image.min()) / (image.ptp() + 0.0001)).astype(np.float32)\n            image = torch.from_numpy(image).unsqueeze(1).cuda()\n\n            counter = 0\n            vessel_sum, kidney_sum = [0, 0], [0, 0]\n            for model in [model1, model2]:\n                for dims in [[], [2], [3], [2, 3]]:\n                    flipped_image = torch.flip(image, dims=dims) if dims else image\n                    with torch.cuda.amp.autocast():\n                        with torch.no_grad():\n                            v, k = model(flipped_image)\n                    reversed_v = torch.flip(v, dims=dims) if dims else v\n                    reversed_k = torch.flip(k, dims=dims) if dims else k\n                    vessel_sum[model == model2] += reversed_v\n                    kidney_sum[model == model2] += reversed_k\n                    counter += 1\n                    \n                    torch.cuda.empty_cache()\n                    gc.collect()\n\n            for i in range(2):\n                vessel = (vessel_sum[i]/counter).float().data.cpu().numpy()\n                kidney = (kidney_sum[i]/counter).float().data.cpu().numpy()\n                kidney = kidney > 0.5\n\n                for b in range(batch_size):\n                    mk = kidney[b, 0]\n                    mv = vessel[b, 0]\n                    p = (mv * mk)\n                    if axis == 0:\n                        predict1[B + b] += p\n                        predict2[B + b] += p\n                    elif axis == 1:\n                        predict1[:, B + b] += p\n                        predict2[:, B + b] += p\n                    else:\n                        predict1[:, :, B + b] += p\n                        predict2[:, :, B + b] += p\n\n            B += batch_size\n\n    predict1 = predict1 / len(axes)\n    predict2 = predict2 / len(axes)\n    predict1 = (predict1 > 0.1).astype(np.uint8)\n    predict2 = (predict2 > 0.4).astype(np.uint8)\n    predict1 = np.logical_and(predict1, predict2).astype(np.uint8)\n    \n    rle = [rle_encode(p) for p in predict1]\n    \n    submission_df.append(\n            pd.DataFrame(data={\n                'id'  : d['id'],\n                'rle' : rle,\n            })\n        )","metadata":{"execution":{"iopub.status.busy":"2024-01-06T05:06:55.218445Z","iopub.execute_input":"2024-01-06T05:06:55.219190Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"submission = pd.concat(submission_df)\nsubmission.to_csv('submission.csv', index=False)","metadata":{"execution":{"iopub.status.busy":"2024-01-06T05:03:20.681510Z","iopub.status.idle":"2024-01-06T05:03:20.681990Z","shell.execute_reply.started":"2024-01-06T05:03:20.681739Z","shell.execute_reply":"2024-01-06T05:03:20.681761Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"submission.head()","metadata":{"execution":{"iopub.status.busy":"2024-01-06T05:03:20.683466Z","iopub.status.idle":"2024-01-06T05:03:20.683913Z","shell.execute_reply.started":"2024-01-06T05:03:20.683676Z","shell.execute_reply":"2024-01-06T05:03:20.683698Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"submission.to_csv('submission.csv', index=False)","metadata":{"execution":{"iopub.status.busy":"2024-01-06T05:03:20.685603Z","iopub.status.idle":"2024-01-06T05:03:20.686035Z","shell.execute_reply.started":"2024-01-06T05:03:20.685802Z","shell.execute_reply":"2024-01-06T05:03:20.685820Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]}]}