{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"pygments_lexer":"ipython3","nbconvert_exporter":"python","version":"3.6.4","file_extension":".py","codemirror_mode":{"name":"ipython","version":3},"name":"python","mimetype":"text/x-python"}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"!pip install -q ../input/for-pydicom/pylibjpeg-1.4.0-py3-none-any.whl\n!pip install -q ../input/for-pydicom/python_gdcm-3.0.14-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl\n!pip install -q ../input/for-pydicom/pylibjpeg_libjpeg-1.3.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl","metadata":{"execution":{"iopub.status.busy":"2022-10-26T14:49:09.245888Z","iopub.execute_input":"2022-10-26T14:49:09.246322Z","iopub.status.idle":"2022-10-26T14:50:39.384926Z","shell.execute_reply.started":"2022-10-26T14:49:09.246241Z","shell.execute_reply":"2022-10-26T14:50:39.383737Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import sys\nsys.path.append(\"../input/segmentation-models-pytorch/segmentation_models.pytorch-master\")\nsys.path.append('../input/timm-pytorch-image-models/pytorch-image-models-master')\nsys.path.append(\"../input/pretrainedmodels/pretrainedmodels-0.7.4\")\nsys.path.append(\"../input/efficientnet-pytorch/EfficientNet-PyTorch-master\")","metadata":{"execution":{"iopub.status.busy":"2022-10-26T14:50:39.38737Z","iopub.execute_input":"2022-10-26T14:50:39.388083Z","iopub.status.idle":"2022-10-26T14:50:39.39606Z","shell.execute_reply.started":"2022-10-26T14:50:39.388039Z","shell.execute_reply":"2022-10-26T14:50:39.395127Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import numpy as np\nimport pandas as pd\nfrom tqdm import tqdm\nimport os\nfrom glob import glob\nimport time\nimport sys\nimport ast\nimport math\nimport gc\ngc.enable()\nimport copy\n\nimport warnings\nwarnings.filterwarnings(\"ignore\")\n\nimport pydicom\nimport cv2\nfrom PIL import Image, ImageEnhance\n\nimport matplotlib as mpl\nimport matplotlib.pyplot as plt\n\nmpl.rcParams['figure.figsize'] = 12, 8\n\nimport albumentations as A\nfrom albumentations.pytorch import ToTensorV2\nfrom skimage import img_as_ubyte\n\nfrom sklearn.metrics import *\nfrom sklearn.model_selection import *\n\nimport torch\nfrom torch import nn, optim\nfrom torch.utils.data import Dataset, DataLoader\nimport pytorch_lightning as pl\nimport timm\nimport segmentation_models_pytorch as smp\n\nfrom skimage.measure import label, regionprops\n\nif torch.cuda.is_available(): device = 'cuda'\nelse: device = 'cpu'","metadata":{"execution":{"iopub.status.busy":"2022-10-26T14:50:39.397723Z","iopub.execute_input":"2022-10-26T14:50:39.398269Z","iopub.status.idle":"2022-10-26T14:50:48.271381Z","shell.execute_reply.started":"2022-10-26T14:50:39.398234Z","shell.execute_reply":"2022-10-26T14:50:48.27032Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def read_dicom(path, fix_monochrome = True):\n    dicom = pydicom.read_file(path)\n    \n    return dicom, 0\n    \n    data = dicom.pixel_array\n               \n    if fix_monochrome and dicom.PhotometricInterpretation == \"MONOCHROME1\":\n        data = np.amax(data) - data\n        \n    data = data - np.min(data)\n    data = data / np.max(data)\n    data = (data * 255).astype(np.uint8)\n    \n    meta = dicom.copy()\n    \n    del meta.PixelData\n    \n    return data, meta\n\ndef preprocess(img):\n    a = img.copy()\n    \n    if np.min(img)>0:\n        img -= np.min(img)\n    if np.min(img)<0:\n        img = img + abs(np.min(img))\n    \n    img = img / np.max(img)\n    \n    #RE: BECAUSE I DON'T KNOW WTF WAS WRONG\n    if np.min(img)<0:\n        img += abs(np.min(img))\n        img = img / np.max(img)\n    \n    b = img.copy()\n    \n    try:\n        return img_as_ubyte(img)\n    except:\n        print(img.shape)\n        print(img.dtype)\n        print(np.min(img), np.max(img))\n        \n        print(a.dtype)\n        print(np.min(a), np.max(a))\n        \n        print(b.dtype)\n        print(np.min(b), np.max(b))\n        \n\ndef read_dicom_image(path):\n    img = pydicom.dcmread(path).pixel_array.astype(np.float32)\n    return preprocess(img)\n\n\ndef load_dicom_array(f):\n   dicom_files = glob.glob(f\"{f}/*.dcm\")\n   dicoms = [pydicom.dcmread(d) for d in tqdm(dicom_files,total=len(dicom_files))]\n   M = float(dicoms[0].RescaleSlope)\n   B = float(dicoms[0].RescaleIntercept)\n   # Assume all images are axial\n   z_pos = np.array([float(d.ImagePositionPatient[-1]) for d in dicoms])#different from patients\n   z_inter = np.sort(z_pos)[3]-np.sort(z_pos)[2]\n\n   dicoms = np.asarray([d.pixel_array for d in dicoms])\n   dicoms = dicoms[np.argsort(-z_pos)]\n   dicoms = dicoms * M\n   dicoms = dicoms + B\n   return dicoms, np.asarray(dicom_files)[np.argsort(-z_pos)],z_inter\n\ndef read_dicom_images(paths):\n    dicoms = [pydicom.dcmread(path) for path in paths]\n    M = float(dicoms[0].RescaleSlope)\n    B = float(dicoms[0].RescaleIntercept)\n    \n    z_pos = np.array([float(dicom.ImagePositionPatient[-1]) for dicom in dicoms])\n    z_inter = np.sort(z_pos)[3] - np.sort(z_pos)[2]\n    \n    dicoms = np.asarray([d.pixel_array for d in dicoms])\n    dicoms = dicoms[np.argsort(-z_pos)]\n    dicoms = dicoms * M\n    dicoms = dicoms + B\n    dicoms = np.stack([preprocess(d) for d in dicoms])\n    return dicoms, np.asarray(paths)[np.argsort(-z_pos)]\n    \ndef read_meta(path):\n    meta = pydicom.dcmread(path, stop_before_pixels=True)\n    return [float(meta.SliceThickness)] + [float(x) for x in list(meta.ImagePositionPatient)]\n\nclass LoadDicoms(Dataset):\n    def __init__(self, files):\n        self.files = files\n    \n    def __len__(self):\n        return len(self.files)\n    \n    def __getitem__(self, i):\n        file = self.files[i]\n        \n        dicom = pydicom.dcmread(file)\n        \n        z_pos = float(dicom.ImagePositionPatient[-1])\n        \n        dicom = preprocess(dicom.pixel_array)\n        \n        return dicom, z_pos","metadata":{"execution":{"iopub.status.busy":"2022-10-26T14:50:48.275792Z","iopub.execute_input":"2022-10-26T14:50:48.276296Z","iopub.status.idle":"2022-10-26T14:50:48.29817Z","shell.execute_reply.started":"2022-10-26T14:50:48.276266Z","shell.execute_reply":"2022-10-26T14:50:48.297111Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"INPUT_DIR = '/kaggle/input/rsna-2022-cervical-spine-fracture-detection/test_images/'\n\nPATIENTS = glob(INPUT_DIR+\"*\")#[:1600]\n#PATIENTS = ['/kaggle/input/rsna-2022-cervical-spine-fracture-detection/train_images/1.2.826.0.1.3680043.128']\nPATIENTS[:5]","metadata":{"execution":{"iopub.status.busy":"2022-10-26T14:50:48.29983Z","iopub.execute_input":"2022-10-26T14:50:48.300262Z","iopub.status.idle":"2022-10-26T14:50:48.322117Z","shell.execute_reply.started":"2022-10-26T14:50:48.300228Z","shell.execute_reply":"2022-10-26T14:50:48.321282Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class SagSegModel(pl.LightningModule):\n    def __init__(self):\n        super(SagSegModel, self).__init__()\n        #tf_efficientnet_b0_ns resnest50d_4s2x40d seresnext50_32x4d tf_efficientnetv2_m_in21ft1k\n        self.feature_extractor = smp.Unet('tu-tf_efficientnet_b1_ns', in_channels=1, classes=8, encoder_weights=None)\n        self.sigmoid = nn.Sigmoid()\n        \n    def forward(self, inp):\n        masks = self.feature_extractor(inp)\n        return masks\n    \ndef SagInference(models, image, L):\n    with torch.no_grad():\n        img = cv2.resize(image, (256, 256)).astype(np.float32) / np.max(image)\n        \n        outputs = []\n        for model in models:\n            output = model.sigmoid(model(torch.as_tensor(img).unsqueeze(0).unsqueeze(0).to(device)))[0].detach().cpu().numpy().transpose(1, 2, 0)\n            output = cv2.resize(output, (image.shape[1], L)) #because odd and even numbers and // usage, this line will have to be written better and fixed, you get that\n            outputs.append(output)\n        \n        output = np.mean(outputs, 0)\n        \n        output[output>0.3] = 1\n        output[output<0.3] = 0\n        \n        preds = []\n        for _ in output:\n            classes = np.sum(_, 0)\n            if np.any(classes):\n                preds.append(np.argmax(classes)+1)\n            else:\n                preds.append(100)\n                \n    return preds","metadata":{"execution":{"iopub.status.busy":"2022-10-26T14:50:48.323365Z","iopub.execute_input":"2022-10-26T14:50:48.323795Z","iopub.status.idle":"2022-10-26T14:50:48.333739Z","shell.execute_reply.started":"2022-10-26T14:50:48.323762Z","shell.execute_reply":"2022-10-26T14:50:48.332673Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"folders = ['/kaggle/input/try2-seg-b1v10-sagview-full/',]# '/kaggle/input/try7-seresnext50-v7-full/'] #['/kaggle/input/try7-b1-v8-full/', '/kaggle/input/try7-seresnext50-v7-full/']\nmodel_funcs = [SagSegModel,]\nsag_models = []\nfor model_func, folder in zip(model_funcs, folders):\n    for file in sorted(glob(folder+\"/*\"), key=lambda x: x.split('/')[-1]):\n        sag_model = SagSegModel()\n        sag_model.eval()\n        sag_model.to(device)\n        st = torch.load(f\"{file}\", map_location=device)['state_dict']\n        sag_model.load_state_dict(st, strict=False)\n        sag_models.append(copy.deepcopy(sag_model))\n\nsag_models = sag_models#[:1]\n\nlen(sag_models)","metadata":{"execution":{"iopub.status.busy":"2022-10-26T14:50:48.334898Z","iopub.execute_input":"2022-10-26T14:50:48.33594Z","iopub.status.idle":"2022-10-26T14:51:00.470301Z","shell.execute_reply.started":"2022-10-26T14:50:48.335905Z","shell.execute_reply":"2022-10-26T14:51:00.46938Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class BoneSegModel(pl.LightningModule):\n    def __init__(self):\n        super(BoneSegModel, self).__init__()\n        #tf_efficientnet_b0_ns resnest50d_4s2x40d seresnext50_32x4d tf_efficientnetv2_m_in21ft1k\n        self.feature_extractor = smp.Unet('tu-tf_efficientnet_b1_ns', in_channels=3, classes=8, encoder_weights=None)\n        self.sigmoid = nn.Sigmoid()\n        \n    def forward(self, inp):\n        masks = self.feature_extractor(inp)\n        return masks\n    \ndef BoneInference(models, images, sz, bs):\n    with torch.no_grad():\n        \n        images = nn.functional.interpolate(torch.as_tensor(images).unsqueeze(1), (sz, sz))\n        \n        images = torch.cat([images]*3, 1)\n        \n        outputs = []\n        \n        N = images.shape[0]/bs\n        if not str(N).endswith('.0'): N += 1\n        N = int(N)\n        \n        OUTS = []\n        for i in range(N):\n            outs = []\n            for model in models:\n                with torch.no_grad():\n                    inputs = images[i*bs:(i+1)*bs].to(device)\n                    \n                    inputs = inputs.float() / 255\n                    \n                    outputs = model(inputs)\n                    outputs = model.sigmoid(outputs)\n                    outputs = outputs.detach().cpu().numpy().transpose(0, 2, 3, 1)\n                    \n                    #print(outputs.shape)\n                    \n                    outs.append(outputs)\n                    \n            outs = np.stack(outs)\n            \n            #print(outs.shape)\n            \n            outs = np.mean(outs, 0)\n            \n            outs[outs>0.5] = 1\n            outs[outs<=0.5] = 0\n            \n            outs = outs.astype(np.uint8)\n            \n            #print(outs.shape)\n            \n            outs = np.stack(outs)\n            OUTS.extend(outs)\n    \n    OUTS = np.stack(OUTS)\n    \n    return OUTS","metadata":{"execution":{"iopub.status.busy":"2022-10-26T14:51:00.471831Z","iopub.execute_input":"2022-10-26T14:51:00.472176Z","iopub.status.idle":"2022-10-26T14:51:00.486367Z","shell.execute_reply.started":"2022-10-26T14:51:00.472142Z","shell.execute_reply":"2022-10-26T14:51:00.485483Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"folders = ['/kaggle/input/try2-seg-b1v1-full/',]# '/kaggle/input/try7-seresnext50-v7-full/'] #['/kaggle/input/try7-b1-v8-full/', '/kaggle/input/try7-seresnext50-v7-full/']\nmodel_funcs = [BoneSegModel,]\nbone_models = []\nfor model_func, folder in zip(model_funcs, folders):\n    for file in sorted(glob(folder+\"/*\"), key=lambda x: x.split('/')[-1]):\n        bone_model = BoneSegModel()\n        bone_model.eval()\n        bone_model.to(device)\n        st = torch.load(f\"{file}\", map_location=device)['state_dict']\n        bone_model.load_state_dict(st, strict=False)\n        bone_models.append(copy.deepcopy(bone_model))\n\nbone_models = bone_models#[:1]\n\nlen(bone_models)","metadata":{"execution":{"iopub.status.busy":"2022-10-26T14:51:00.488018Z","iopub.execute_input":"2022-10-26T14:51:00.488391Z","iopub.status.idle":"2022-10-26T14:51:09.857639Z","shell.execute_reply.started":"2022-10-26T14:51:00.488359Z","shell.execute_reply":"2022-10-26T14:51:09.855668Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class Model(pl.LightningModule):\n    def __init__(self):\n        super(Model, self).__init__()\n        self.feature_extractor = timm.models.tf_efficientnet_b5_ns(in_chans=3, pretrained=False, num_classes=0, global_pool='')\n        \n        f = self.feature_extractor.num_features\n        \n        self.avgpool = nn.AdaptiveAvgPool2d(1)\n        self.classifier = nn.Linear(f, 1)\n        self.flatten = nn.Flatten()\n        self.sigmoid = nn.Sigmoid()\n        \n    def forward(self, inp):\n        features = self.feature_extractor(inp)\n        features = self.avgpool(features)\n        features = self.flatten(features)\n        logits = self.classifier(features)\n        \n        return logits, features\n    \nclass Model2(pl.LightningModule):\n    def __init__(self):\n        super(Model2, self).__init__()\n        self.feature_extractor = timm.models.seresnext50_32x4d(in_chans=3, pretrained=False, num_classes=0, global_pool='')\n        \n        f = self.feature_extractor.num_features\n        \n        self.avgpool = nn.AdaptiveAvgPool2d(1)\n        self.classifier = nn.Linear(f, 1)\n        self.flatten = nn.Flatten()\n        self.sigmoid = nn.Sigmoid()\n        \n    def forward(self, inp):\n        features = self.feature_extractor(inp)\n        features = self.avgpool(features)\n        features = self.flatten(features)\n        logits = self.classifier(features)\n        \n        return logits, features\n\nclass Model3(pl.LightningModule):\n    def __init__(self):\n        super(Model3, self).__init__()\n        self.feature_extractor = timm.models.tf_efficientnetv2_m_in21k(in_chans=3, pretrained=False, num_classes=0, global_pool='')\n        \n        f = self.feature_extractor.num_features\n        \n        self.avgpool = nn.AdaptiveAvgPool2d(1)\n        self.classifier = nn.Linear(f, 1)\n        self.flatten = nn.Flatten()\n        self.sigmoid = nn.Sigmoid()\n        \n    def forward(self, inp):\n        features = self.feature_extractor(inp)\n        features = self.avgpool(features)\n        features = self.flatten(features)\n        logits = self.classifier(features)\n        \n        return logits, features\n    \ndef CLSInference(models, images, bs):\n    with torch.no_grad():\n        outputs = []\n        \n        N = images.shape[0]/bs\n        if not str(N).endswith('.0'): N += 1\n        N = int(N)\n        \n        OUTS = []\n        FEATS = []\n        for i in range(N):\n            outs = []\n            feats = []\n            for model in models:\n                with torch.no_grad():\n                    inputs = images[i*bs:(i+1)*bs].to(device)\n                    \n                    inputs = inputs.float() / 255\n                    \n                    outputs, features = model(inputs)\n                    outputs = model.sigmoid(outputs)\n                    outputs = outputs.detach().cpu().numpy()\n                    \n                    features = features.detach().cpu().numpy()\n                    \n                    feats.append(features)\n                    \n                    outs.append(outputs)\n                    \n            outs = np.stack(outs)\n            feats = np.stack(feats)\n            \n            #print(outs.shape)\n            \n            outs = np.mean(outs, 0)\n            feats = np.mean(feats, 0)\n            \n            OUTS.extend(outs)\n            FEATS.extend(feats)\n    \n    OUTS = np.stack(OUTS)\n    FEATS = np.stack(FEATS)\n    \n    return OUTS, FEATS","metadata":{"execution":{"iopub.status.busy":"2022-10-26T14:51:09.863213Z","iopub.execute_input":"2022-10-26T14:51:09.863742Z","iopub.status.idle":"2022-10-26T14:51:09.902658Z","shell.execute_reply.started":"2022-10-26T14:51:09.863699Z","shell.execute_reply":"2022-10-26T14:51:09.901238Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"folders = ['/kaggle/input/try17-b5-v5-t4-pseudo-round1/', '/kaggle/input/try17-seresnext50-v1-t4-pseudo-round1/', '/kaggle/input/try17-v2m-v1-t4-pseudo-round1/',]# '/kaggle/input/v2s-v6-full-plus-v6-full-tuned']# '/kaggle/input/try7-seresnext50-v7-full/']\nmodel_funcs = [Model, Model2, Model3,]\ncls_models = []\nfor model_func, folder in tqdm(zip(model_funcs, folders)):\n    for file in sorted(glob(folder+\"/*\"), key=lambda x: x.split('/')[-1]):\n        cls_model = model_func()\n        cls_model.eval()\n        cls_model.to(device)\n        st = torch.load(f\"{file}\", map_location=device)#['state_dict']\n        cls_model.load_state_dict(st, )#strict=False)\n        cls_models.append(copy.deepcopy(cls_model))\n\ncls_models = cls_models#[1:2]\n\nlen(cls_models)","metadata":{"execution":{"iopub.status.busy":"2022-10-26T14:52:52.806263Z","iopub.execute_input":"2022-10-26T14:52:52.806655Z","iopub.status.idle":"2022-10-26T14:53:31.339882Z","shell.execute_reply.started":"2022-10-26T14:52:52.806623Z","shell.execute_reply":"2022-10-26T14:53:31.338724Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class Attention(nn.Module):\n    def __init__(self, feature_dim, step_dim, bias=True, **kwargs):\n        super(Attention, self).__init__(**kwargs)\n        \n        self.supports_masking = True\n\n        self.bias = bias\n        self.feature_dim = feature_dim\n        self.step_dim = step_dim\n        self.features_dim = 0\n        \n        weight = torch.zeros(feature_dim, 1)\n        nn.init.xavier_uniform_(weight)\n        self.weight = nn.Parameter(weight)\n        \n        if bias:\n            self.b = nn.Parameter(torch.zeros(step_dim))\n        \n    def forward(self, x, mask=None):\n        feature_dim = self.feature_dim\n        step_dim = self.step_dim\n\n        eij = torch.mm(\n            x.contiguous().view(-1, feature_dim), \n            self.weight\n        ).view(-1, step_dim)\n        \n        if self.bias:\n            eij = eij + self.b\n            \n        eij = torch.tanh(eij)\n        a = torch.exp(eij)\n        \n        if mask is not None:\n            a = a * mask\n\n        a = a / torch.sum(a, 1, keepdim=True) + 1e-10\n\n        weighted_input = x * torch.unsqueeze(a, -1)\n        return torch.sum(weighted_input, 1)\n\nclass BaseBlock(nn.Module):\n    def __init__(self, base=1280, c=512, seq_dim=21):\n        super(BaseBlock, self).__init__()\n        \n        m = 1\n        \n        base = base# + 1280 + 1280\n        c = c\n        \n        self.c = c\n        \n        self.lstm1 = nn.GRU(base*m, c*m, bidirectional=True, batch_first=True)\n        self.lstm2 = nn.GRU(c*2*m, c*m, bidirectional=True, batch_first=True)\n        \n        self.attention1 = Attention(c * m * 2, seq_dim)\n        #self.attention2 = UFOAttention(d_model=512*m*2, d_k=512*m*2, d_v=512*m*2, h=8)\n        \n        self.conv1 = nn.Conv1d(seq_dim, 1, 1)\n        \n        self.lstm_bn1 = nn.BatchNorm1d(seq_dim)\n        self.lstm_bn2 = nn.BatchNorm1d(seq_dim)\n        \n        self.att_bn1 = nn.BatchNorm1d(c*2*m)\n        \n        self.flatten = nn.Flatten()\n        self.relu = nn.ReLU()\n        self.tanh = nn.Tanh()\n        self.avgpool = nn.AdaptiveAvgPool1d(1)\n        \n        self.dropout = nn.Dropout(0.2)\n        \n        self.final_classifier = nn.Linear(c*2*2*7, 8)\n        \n        self.sigmoid = nn.Sigmoid()\n        \n    def forward(self, inp):\n        x, _ = self.lstm1(inp)\n        x = self.tanh(x)\n        \n        #x = self.dropout(x)\n        \n        x = self.lstm_bn1(x)\n        \n        x, _ = self.lstm2(x)\n        x = self.tanh(x)\n        \n        x = self.lstm_bn2(x)\n        x_ = self.sigmoid(x)\n        \n        #x = self.dropout(x)\n        \n        x_conv = self.conv1(x_)\n        x_conv = x_conv[:, 0]\n        \n        #x, _ = self.lstm2(x)\n        #print(x.shape)\n        \n        #max_pool, _ = torch.max(x, 1)\n        #max_pool = self.avgpool(x.transpose(1, 2))[:, :, 0]\n        #print(max_pool.shape)\n        \n        #x = self.attention2(x, x, x)\n        att_pool = self.attention1(x_, mask=None)\n        #print(att_pool.shape)\n        #print(att_pool.shape)\n        \n        x = att_pool#torch.cat([max_pool, att_pool], -1)\n        \n        x = self.att_bn1(x)\n        x = self.relu(x)\n        \n        x = torch.cat([x, x_conv], -1)\n        \n        x = self.dropout(x)\n        \n        #logits = self.clf(x)\n        \n        features = x.reshape(x.shape[0]//7, 7, self.c*2*2)\n        features = nn.Flatten(1, 2)(features)\n        \n        return features\n\nclass SeqModel(nn.Module):\n    def __init__(self, seq_dim=21):\n        super(SeqModel, self).__init__()\n        \n        m = 1\n        \n        base = 1280# + 1280 + 1280\n        c = 512\n        \n        self.base_b5 = BaseBlock(2048, 512, seq_dim)\n        self.base_seres = BaseBlock(2048, 512, seq_dim)\n        #self.base_v2m = BaseBlock(1280, 512, seq_dim)\n        \n        self.final_classifier_b5 = nn.Linear(c*2*2*7, 8)\n        self.final_classifier_seres = nn.Linear(c*2*2*7, 8)\n        #self.final_classifier_v2m = nn.Linear(c*2*2*7, 8)\n        self.final_classifier = nn.Linear(c*2*2*7*2, 8)\n        \n        self.sigmoid = nn.Sigmoid()\n        \n    def forward(self, inp):\n        features_b5 = self.base_b5(inp[0])\n        features_seres = self.base_seres(inp[1])\n        #features_v2m = self.base_v2m(inp[2])\n        \n        #print(features_b5.shape)\n        #print(features_seres.shape)\n        #print(features_v2m.shape)\n        \n        logits_b5 = self.final_classifier_b5(features_b5)\n        logits_seres = self.final_classifier_seres(features_seres)\n        #logits_v2m = self.final_classifier_v2m(features_v2m)\n        \n        #features = torch.cat([features_b5, features_seres, features_v2m], -1)\n        features = torch.cat([features_b5, features_seres,], -1)\n        \n        logits = self.final_classifier(features)\n        \n        #return (logits_b5 + logits_seres + logits_v2m + logits) / 4\n        return (logits_b5 + logits_seres + logits) / 3","metadata":{"execution":{"iopub.status.busy":"2022-10-26T14:59:50.351879Z","iopub.execute_input":"2022-10-26T14:59:50.352249Z","iopub.status.idle":"2022-10-26T14:59:50.376697Z","shell.execute_reply.started":"2022-10-26T14:59:50.352216Z","shell.execute_reply":"2022-10-26T14:59:50.375668Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"folders = ['/kaggle/input/ens-v5/',]# '/kaggle/input/v2s-v6-full-plus-v6-full-tuned']# '/kaggle/input/try7-seresnext50-v7-full/'] #['/kaggle/input/try7-b1-v8-full/',]\nmodel_funcs = [SeqModel]\ndims = [32,]\nseq_models = []\nfor model_func, folder, d in tqdm(zip(model_funcs, folders, dims)):\n    for file in sorted(glob(folder+\"/*\"), key=lambda x: x.split('/')[-1]):\n        seq_model = model_func(d)\n        seq_model.eval()\n        seq_model.to(device)\n        st = torch.load(f\"{file}\", map_location=device)#['state_dict']\n        seq_model.load_state_dict(st, strict=False)\n        seq_models.append(copy.deepcopy(seq_model))\n\nseq_models = seq_models#[1:2]\n\nlen(seq_models)","metadata":{"execution":{"iopub.status.busy":"2022-10-26T15:00:21.798699Z","iopub.execute_input":"2022-10-26T15:00:21.799278Z","iopub.status.idle":"2022-10-26T15:00:27.366353Z","shell.execute_reply.started":"2022-10-26T15:00:21.799232Z","shell.execute_reply":"2022-10-26T15:00:27.36536Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"row_ids = []\nfractured = []\n\naugs = A.Compose([\n    #A.Resize(CFG.SZ_H, CFG.SZ_W),\n    A.LongestMaxSize(1024),\n    A.PadIfNeeded(1024, 1024, border_mode=0, p=1),\n    ToTensorV2()\n])\n\nmeans = [0.4760, 0.0723, 0.1412, 0.0362, 0.0535, 0.0802, 0.1372, 0.1947]\n\nfor patient in tqdm(PATIENTS[:]):\n    study_id = patient.split('/')[-1]\n    \n    try:\n    #if 1:\n    \n        t = time.time()\n    \n        dl = DataLoader(LoadDicoms(glob(patient + \"/*\")), batch_size=32, num_workers=4, shuffle=False)\n\n        #FAST LOAD ALL IMAGES\n\n        images = []\n        z_pos = []\n        for batch in dl:\n            images.extend(batch[0])\n            z_pos.extend(batch[1])\n        images = torch.stack(images).numpy()\n        z_pos = torch.stack(z_pos).numpy()\n\n        z_inter = np.sort(z_pos)[3] - np.sort(z_pos)[2]\n\n        images = images[np.argsort(-z_pos)]\n\n        #print(\"Time to load images:\", time.time() - t)\n        \n        #SAG VIEW, SELECTS IMPORTANT ONLY IMAGES AND THEIR KEYS\n        \n        t = time.time()\n\n        sag = images[:, :, images.shape[-1]//2]\n\n        keys = np.array(SagInference(sag_models, sag, images.shape[0]))\n        selec_idxs = np.where(np.logical_and(keys!=100, keys!=8))\n\n        images = images[selec_idxs]\n        keys = keys[selec_idxs]\n\n        #print(\"Time to get keys:\", time.time() - t)\n        \n        #GET MASKS, AND ONLY THOSE WHICH HAVE MASKS\n\n        t = time.time()\n        \n        masks = BoneInference(bone_models, images, 256, 32)\n\n        masks = np.max(masks, -1)\n\n        selec_idxs = [i for i, m in enumerate(masks) if np.max(m)]\n\n        masks = masks[selec_idxs]\n        images = images[selec_idxs]\n        keys = keys[selec_idxs]\n\n        #print(\"Time to load masks:\", time.time() - t)\n        \n        #PREPROCESSING FOR IMAGES, INCLUDES ROI, AND 1:-1 TO MAKE SURE ALL 2.5D IS CORRECT, DID SAME WITH KEYS FOR MAKING SURE ITS GOOD FOR THE UPCOMING STEP\n\n        t = time.time()\n        \n        inputs = []\n        for i in range(1, len(images)-1):\n            image_curr = images[i]\n            image_last = images[i-1]\n            image_next = images[i+1]\n\n            image = np.stack([image_last, image_curr, image_next], -1)\n\n            mask = masks[i]\n\n            try:\n                ymin, ymax = np.min(np.where(mask)[0])/mask.shape[1], np.max(np.where(mask)[0])/mask.shape[1]\n                xmin, xmax = np.min(np.where(mask)[1])/mask.shape[0], np.max(np.where(mask)[1])/mask.shape[0]\n\n                xmin = xmin * .95#np.random.choice(np.arange(0.9, 1., 0.01))#* 0.95\n                ymin = ymin * .95#np.random.choice(np.arange(0.9, 1., 0.01))#* 0.95\n                xmax = xmax * 1.05#np.random.choice(np.arange(1., 1.1, 0.01))#* 1.05\n                ymax = ymax * 1.05#np.random.choice(np.arange(1., 1.1, 0.01))#* 1.05\n\n                image = image[int(ymin*image.shape[0]):int(ymax*image.shape[0]), int(xmin*image.shape[1]):int(xmax*image.shape[1])]\n            except:\n                pass\n\n            #print(image.shape)\n\n            image = augs(image=image)['image']\n\n            inputs.append(image)\n\n        images = torch.stack(inputs)\n\n        keys = keys[1:-1]\n        \n        #FEED RESIZE IMAGES TO MODELS TO GET FEATURES AND PREDS\n        \n        #print(\"Time to get inputs:\", time.time() - t)\n        \n        t = time.time()\n        '''\n        x = 0\n        selec_idxs1 = [i for i in range(len(images)) if i%3==x and i!=0]\n        inputs = nn.functional.interpolate(images[selec_idxs1], (456, 456))\n        preds1, features1 = CLSInference(cls_models[:5], inputs, 32)\n        keys1 = keys[selec_idxs1]\n        \n        x = 1\n        selec_idxs2 = [i for i in range(len(images)) if i%3==x and i!=0]\n        inputs = nn.functional.interpolate(images[selec_idxs2], (512, 512))\n        preds2, features2 = CLSInference(cls_models[5:10], inputs, 32)\n        keys2 = keys[selec_idxs2]\n        \n        x = 2\n        selec_idxs3 = [i for i in range(len(images)) if i%3==x and i!=0]\n        inputs = nn.functional.interpolate(images[selec_idxs3], (384, 384))\n        preds3, features3 = CLSInference(cls_models[10:15], inputs, 32)\n        keys3 = keys[selec_idxs3]\n        '''\n        \n        x = 0\n        selec_idxs1 = [i for i in range(len(images)) if i%2==x]\n        inputs = nn.functional.interpolate(images[selec_idxs1], (456, 456))\n        preds1, features1 = CLSInference(cls_models[:5], inputs, 32)\n        keys1 = keys[selec_idxs1]\n        \n        x = 1\n        selec_idxs2 = [i for i in range(len(images)) if i%2==x]\n        inputs = nn.functional.interpolate(images[selec_idxs2], (512, 512))\n        preds2, features2 = CLSInference(cls_models[5:10], inputs, 32)\n        keys2 = keys[selec_idxs2]\n        \n        #print(\"Time to get preds:\", time.time() - t)\n        \n        #inputs = nn.functional.interpolate(images, (384, 384))\n        #preds2, features2 = CLSInference(cls_models[5:], inputs, 32)\n\n        #MAP PREDS TO BONES AND DO POST\n\n        t = time.time()\n        \n        bone_features1 = []\n        bone_features2 = []\n        #bone_features3 = []\n        \n        dim = 32\n        \n        for bone in range(1, 8):\n            #row_ids.append(f\"{study_id}_C{bone}\")\n\n            _features1 = np.zeros((dim, 2048))\n            _features2 = np.zeros((dim, 2048))\n            #_features3 = np.zeros((dim, 1280))\n            \n            if np.sum(keys1==bone):\n                feats = features1[keys1==bone]\n                _features1[:min(len(feats), dim)] = feats[:min(len(feats), dim)]\n            \n            if np.sum(keys2==bone):\n                feats = features2[keys2==bone]\n                _features2[:min(len(feats), dim)] = feats[:min(len(feats), dim)]\n                \n            #if np.sum(keys3==bone):\n            #    feats = features3[keys3==bone]\n            #    _features3[:min(len(feats), dim)] = feats[:min(len(feats), dim)]\n                \n            bone_features1.append(_features1)\n            bone_features2.append(_features2)\n            #bone_features3.append(_features3)\n            \n            \n            #CONTINUE\n            continue\n            \n            '''\n            if np.sum(keys==bone):\n                p = torch.tensor(preds[keys==bone])[:, 0]\n                ks = 5\n                p = nn.functional.max_pool1d(p.unsqueeze(0).unsqueeze(0), kernel_size=ks, stride=1, padding=ks//2)\n                ks = 7\n                p = nn.functional.avg_pool1d(p, kernel_size=ks, stride=1, padding=ks//2)\n                ks = 5\n                p = nn.functional.avg_pool1d(p, kernel_size=ks, stride=1, padding=ks//2)\n                ks = 3\n                p = nn.functional.avg_pool1d(p, kernel_size=ks, stride=1, padding=ks//2)\n\n                p = p[0][0]\n                p = p.max().item()\n                \n                feats = features[keys==bone]\n                features_ = np.zeros((dim, 2048))\n                features_[:min(len(feats), dim)] = feats[:min(len(feats), dim)]\n\n                features_ = torch.as_tensor(features_).unsqueeze(0).float().to(device)\n                \n                sps = []\n                for seq_model in seq_models[:]:\n                    sp = seq_model.sigmoid(seq_model(features_)).item()\n                    sps.append(sp)\n                sp = np.mean(sps)\n\n                #print(feats.shape)\n                #print(features_.shape)\n\n                fractured.append((p*0.5) + (sp*0.5))\n            else:\n                fractured.append(means[bone])\n                \n            '''\n\n            #I mean, If you really want to crash it \n            #if bone==3:\n            #    sadklfjklasdf\n        \n        bone_features = [torch.as_tensor(np.stack(bone_features1)).float().cuda(), torch.as_tensor(np.stack(bone_features2)).float().cuda(), ]#torch.as_tensor(np.stack(bone_features3)).float().cuda()]\n        sps = []\n        for seq_model in seq_models[:5]:\n            sp = seq_model.sigmoid(seq_model(bone_features)).detach().cpu().numpy()\n            sps.append(sp)\n        sp = np.mean(sps, 0)[0]\n        '''\n        sps = []\n        for seq_model in seq_models[5:]:\n            sp = seq_model.sigmoid(seq_model(bone_features[:, :, 1280:])[0]).detach().cpu().numpy()\n            sps.append(sp)\n        sp2 = np.mean(sps, 0)\n        \n        sp = (sp1 + sp2) / 2\n        '''\n        \n        for _ in range(1, 8):\n            row_ids.append(f\"{study_id}_C{_}\")\n            fractured.append(sp[_])\n        \n        row_ids.append(f\"{study_id}_patient_overall\")\n        fractured.append(sp[0])\n        \n        #print(\"Time to finish up:\", time.time() - t)\n        \n        #row_ids.append(f\"{study_id}_patient_overall\")\n        #fractured.append(np.max(fractured[-7:]))\n\n        import gc\n        gc.enable()\n\n        del preds1, features1, preds2, features2, images, inputs, masks\n\n        gc.collect()\n    \n    #'''\n    except:\n        \n        L = len(fractured)\n        if L%8:\n            row_ids = row_ids[:L - (L%8)]\n            #fractured = fractured[:L - (L%8)]\n        \n        for bone in range(1, 8):\n            row_ids.append(f\"{study_id}_C{bone}\")\n        \n        row_ids.append(f\"{study_id}_patient_overall\")\n        \n        fractured.extend(means[1:][L%8:])\n        fractured.append(means[0])\n    #'''\n    #break","metadata":{"execution":{"iopub.status.busy":"2022-10-26T15:00:39.778915Z","iopub.execute_input":"2022-10-26T15:00:39.779533Z","iopub.status.idle":"2022-10-26T15:02:19.010928Z","shell.execute_reply.started":"2022-10-26T15:00:39.77949Z","shell.execute_reply":"2022-10-26T15:02:19.009634Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"sub = pd.DataFrame({'row_id': row_ids, 'fractured': fractured})\nsub.fractured = sub.fractured.clip(0.001, 0.999)\n#sub.fractured = sub.fractured.clip(0.1, 0.9)\nsub.head(8)","metadata":{"execution":{"iopub.status.busy":"2022-10-26T15:02:19.014258Z","iopub.execute_input":"2022-10-26T15:02:19.014576Z","iopub.status.idle":"2022-10-26T15:02:19.031797Z","shell.execute_reply.started":"2022-10-26T15:02:19.014546Z","shell.execute_reply":"2022-10-26T15:02:19.030341Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"sub.to_csv('submission.csv', index=False)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]}]}