{"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":"nvidiaTeslaT4","dataSources":[{"sourceId":61446,"databundleVersionId":6962461,"sourceType":"competition"},{"sourceId":7453437,"sourceType":"datasetVersion","datasetId":4060087}],"dockerImageVersionId":30580,"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\nimport time\n\nimport cv2\nimport torch\nimport torch.nn as nn\nfrom torch.nn.parallel import DataParallel\nfrom torch.utils.data import Dataset, DataLoader\nfrom torch.optim import lr_scheduler\nfrom torch.cuda import amp\nimport torch.optim as optim\ndevice = torch.device('cuda' if torch.cuda.is_available() else 'cpu')","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","execution":{"iopub.status.busy":"2024-01-23T11:04:35.269065Z","iopub.execute_input":"2024-01-23T11:04:35.269916Z","iopub.status.idle":"2024-01-23T11:04:37.312965Z","shell.execute_reply.started":"2024-01-23T11:04:35.269882Z","shell.execute_reply":"2024-01-23T11:04:37.311961Z"},"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-23T11:04:37.314750Z","iopub.execute_input":"2024-01-23T11:04:37.315160Z","iopub.status.idle":"2024-01-23T11:04:37.325295Z","shell.execute_reply.started":"2024-01-23T11:04:37.315134Z","shell.execute_reply":"2024-01-23T11:04:37.324306Z"},"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-23T11:04:37.326812Z","iopub.execute_input":"2024-01-23T11:04:37.327121Z","iopub.status.idle":"2024-01-23T11:04:37.331343Z","shell.execute_reply.started":"2024-01-23T11:04:37.327095Z","shell.execute_reply":"2024-01-23T11:04:37.330262Z"},"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-23T11:04:37.333709Z","iopub.execute_input":"2024-01-23T11:04:37.334008Z","iopub.status.idle":"2024-01-23T11:04:37.430675Z","shell.execute_reply.started":"2024-01-23T11:04:37.333982Z","shell.execute_reply":"2024-01-23T11:04:37.429672Z"},"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().to(device)\n\n    net = ConvNeXt_U().to(device)\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-23T11:04:37.432407Z","iopub.execute_input":"2024-01-23T11:04:37.432803Z","iopub.status.idle":"2024-01-23T11:04:41.706358Z","shell.execute_reply.started":"2024-01-23T11:04:37.432765Z","shell.execute_reply":"2024-01-23T11:04:41.705096Z"},"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\", map_location = device))\nmodel1.eval()","metadata":{"execution":{"iopub.status.busy":"2024-01-23T11:04:41.708011Z","iopub.execute_input":"2024-01-23T11:04:41.708348Z","iopub.status.idle":"2024-01-23T11:04:45.605682Z","shell.execute_reply.started":"2024-01-23T11:04:41.708316Z","shell.execute_reply":"2024-01-23T11:04:45.604750Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model1 = model1.to(device)","metadata":{"execution":{"iopub.status.busy":"2024-01-23T11:04:45.607086Z","iopub.execute_input":"2024-01-23T11:04:45.607788Z","iopub.status.idle":"2024-01-23T11:04:45.708347Z","shell.execute_reply.started":"2024-01-23T11:04:45.607751Z","shell.execute_reply":"2024-01-23T11:04:45.707535Z"},"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().to(device)\n\n    net = ConvNeXt_U().to(device)\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-23T11:04:45.709804Z","iopub.execute_input":"2024-01-23T11:04:45.710090Z","iopub.status.idle":"2024-01-23T11:04:47.007879Z","shell.execute_reply.started":"2024-01-23T11:04:45.710065Z","shell.execute_reply":"2024-01-23T11:04:47.006866Z"},"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\", map_location = device))\nmodel2.eval()\nmodel2 = model2.to(device)","metadata":{"execution":{"iopub.status.busy":"2024-01-23T11:04:47.009161Z","iopub.execute_input":"2024-01-23T11:04:47.009460Z","iopub.status.idle":"2024-01-23T11:04:50.680591Z","shell.execute_reply.started":"2024-01-23T11:04:47.009434Z","shell.execute_reply":"2024-01-23T11:04:50.679633Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Model3","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 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\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        return x\n\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), nn.BatchNorm2d(24, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True), nn.ReLU(inplace=True))\n        self.stem1 = nn.Sequential(nn.Conv2d(in_channels=24, out_channels=48, kernel_size=3, stride=1, padding=1), nn.BatchNorm2d(48, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True), nn.ReLU(inplace=True))\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","metadata":{"execution":{"iopub.status.busy":"2024-01-23T11:04:50.684426Z","iopub.execute_input":"2024-01-23T11:04:50.684802Z","iopub.status.idle":"2024-01-23T11:04:50.708519Z","shell.execute_reply.started":"2024-01-23T11:04:50.684767Z","shell.execute_reply":"2024-01-23T11:04:50.707510Z"},"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-23T11:04:50.709512Z","iopub.execute_input":"2024-01-23T11:04:50.709816Z","iopub.status.idle":"2024-01-23T11:04:50.721689Z","shell.execute_reply.started":"2024-01-23T11:04:50.709791Z","shell.execute_reply":"2024-01-23T11:04:50.720858Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def make_prediction(predict, model, volume, shape, axes):\n    model = DataParallel(model)\n    for axis in axes:\n        loader = np.array_split(np.arange((D, H, W)[axis]), max(1, int((D, H, W)[axis] // 8)))\n        num_valid = len(loader)\n\n        B = 0 \n        for t in range(num_valid):\n\n            if axis == 0:\n                image = volume[loader[t].tolist()]\n            if axis == 1:\n                image = volume[:, loader[t].tolist()]\n                image = image.transpose(1, 0, 2)\n            if axis == 2:\n                image = volume[:, :, loader[t].tolist()]\n                image = image.transpose(2, 0, 1)\n\n            batch_size, bh, bw = image.shape\n            \n            images = np.zeros_like(image)\n\n            for i in range(batch_size):\n                img = image[i]\n                img = img.reshape(-1)\n                img = (img - img.min()) / (img.max() - img.min() + 0.0001)\n                img = img.reshape(bh, bw)\n                img = np.ascontiguousarray(img)\n                images[i] = img\n            image = torch.from_numpy(images).float().to(device).unsqueeze(1)\n\n            counter = 0\n            vessel1, kidney1 = 0, 0\n            vessel2, kidney2 = 0, 0\n            image = image.to(device)\n            with torch.cuda.amp.autocast():\n                with torch.no_grad():\n                    v1, k1 = model(image)\n                    vessel1 += v1\n                    kidney1 += k1\n                    counter += 1\n\n                    v1, k1 = model(torch.flip(image, dims=[2,]))\n                    vessel1 += torch.flip(v1, dims=[2,])\n                    kidney1 += torch.flip(k1, dims=[2,])\n                    counter += 1\n\n                    v1, k1 = model(torch.flip(image, dims=[3,]))\n                    vessel1 += torch.flip(v1, dims=[3,])\n                    kidney1 += torch.flip(k1, dims=[3,])\n                    counter += 1\n\n                    flipped_image = torch.flip(image, dims=[2, 3])\n                    v1, k1 = model(flipped_image)\n                    vessel1 += torch.flip(v1, dims=[2, 3])\n                    kidney1 += torch.flip(k1, dims=[2, 3])\n                    counter += 1\n\n            vessel1 = vessel1/counter   \n            kidney1 = kidney1/counter         \n\n            vessel1 = vessel1.float().data.cpu().numpy()\n            kidney1 = kidney1.float().data.cpu().numpy()\n            kidney1 = kidney1 > 0.5\n\n            batch_size = len(vessel1)\n            for b in range(batch_size):\n                mk1 = kidney1[b, 0]\n                mv1 = vessel1[b, 0]\n\n                p1 = (mv1 * mk1)\n                if axis == 0:\n                    predict[B + b] += (p1/3)\n                if axis == 1:\n                    predict[:, B + b] += (p1/3)\n                if axis == 2:\n                    predict[:, :, B + b] += (p1/3)\n            B += batch_size\n        \n    del model","metadata":{"execution":{"iopub.status.busy":"2024-01-23T11:04:50.722975Z","iopub.execute_input":"2024-01-23T11:04:50.723447Z","iopub.status.idle":"2024-01-23T11:04:50.743594Z","shell.execute_reply.started":"2024-01-23T11:04:50.723373Z","shell.execute_reply":"2024-01-23T11:04:50.742495Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"start = time.time()\nsubmission_df = []\nfor d in valid_meta:\n    predict = np.zeros(d['shape'], dtype=np.float32)\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    axes = [0,1,2]\n    \n    make_prediction(predict, model1, volume, (D, H, W), axes)\n    \n    torch.cuda.empty_cache()\n    gc.collect()\n    \n    make_prediction(predict, model2, volume, (D, H, W), axes)\n    \n    torch.cuda.empty_cache()\n    gc.collect()\n    \n    model3 = ConvNeXt_U()\n    model3.load_state_dict(torch.load(\"/kaggle/input/sennet-hoa-models/convnext_small-unet-16ylc1b5.pt\", map_location = device))\n    model3.eval()\n    model3 = model3.to(device)\n    \n    make_prediction(predict, model3, volume, (D, H, W), axes)\n    \n    torch.cuda.empty_cache()\n    gc.collect()\n\n    predict = (predict > 0.8).astype(np.uint8)\n    \n    rle = [rle_encode(p) for p in predict]\n    \n    submission_df.append(\n            pd.DataFrame(data={\n                'id'  : d['id'],\n                'rle' : rle,\n            })\n        )\n    \n    del volume, predict, rle\n    gc.collect()\n    torch.cuda.empty_cache()\nprint(time.time() - start)","metadata":{"execution":{"iopub.status.busy":"2024-01-23T11:04:50.745150Z","iopub.execute_input":"2024-01-23T11:04:50.745535Z","iopub.status.idle":"2024-01-23T11:15:00.802481Z","shell.execute_reply.started":"2024-01-23T11:04:50.745500Z","shell.execute_reply":"2024-01-23T11:15:00.801407Z"},"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-23T11:15:00.803774Z","iopub.execute_input":"2024-01-23T11:15:00.804090Z","iopub.status.idle":"2024-01-23T11:15:00.815271Z","shell.execute_reply.started":"2024-01-23T11:15:00.804063Z","shell.execute_reply":"2024-01-23T11:15:00.814358Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"submission.head()","metadata":{"execution":{"iopub.status.busy":"2024-01-23T11:15:00.816557Z","iopub.execute_input":"2024-01-23T11:15:00.816860Z","iopub.status.idle":"2024-01-23T11:15:00.834446Z","shell.execute_reply.started":"2024-01-23T11:15:00.816834Z","shell.execute_reply":"2024-01-23T11:15:00.833491Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"submission.to_csv('submission.csv', index=False)","metadata":{"execution":{"iopub.status.busy":"2024-01-23T11:15:00.835602Z","iopub.execute_input":"2024-01-23T11:15:00.835875Z","iopub.status.idle":"2024-01-23T11:15:00.841578Z","shell.execute_reply.started":"2024-01-23T11:15:00.835850Z","shell.execute_reply":"2024-01-23T11:15:00.840533Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]}]}