{"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":52254,"databundleVersionId":6863140,"sourceType":"competition"},{"sourceId":6089786,"sourceType":"datasetVersion","datasetId":3487378},{"sourceId":6267500,"sourceType":"datasetVersion","datasetId":3581068},{"sourceId":6665533,"sourceType":"datasetVersion","datasetId":3845991},{"sourceId":6682670,"sourceType":"datasetVersion","datasetId":3745884},{"sourceId":6713246,"sourceType":"datasetVersion","datasetId":3867724},{"sourceId":7914488,"sourceType":"datasetVersion","datasetId":4637376},{"sourceId":6676123,"sourceType":"datasetVersion","datasetId":3749004,"isSourceIdPinned":true},{"sourceId":8484157,"sourceType":"datasetVersion","datasetId":5060753},{"sourceId":135925962,"sourceType":"kernelVersion"},{"sourceId":143511308,"sourceType":"kernelVersion"}],"dockerImageVersionId":30559,"isInternetEnabled":false,"language":"python","sourceType":"notebook","isGpuEnabled":true}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"markdown","source":"## Initialization","metadata":{}},{"cell_type":"code","source":"!pip install -qqq /kaggle/input/rsna-abdomen-packages/{pydicom-2.4.3-py3-none-any.whl,pylibjpeg-1.4.0-py3-none-any.whl,python_gdcm-3.0.22-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl}\n!pip install -qqq /kaggle/input/rsna-abdomen-packages/dicomsdl-0.109.2-cp310-cp310-manylinux_2_12_x86_64.manylinux2010_x86_64.whl","metadata":{"_kg_hide-input":true,"_kg_hide-output":true,"execution":{"iopub.status.busy":"2024-05-22T08:21:48.57142Z","iopub.execute_input":"2024-05-22T08:21:48.571692Z","iopub.status.idle":"2024-05-22T08:22:54.213033Z","shell.execute_reply.started":"2024-05-22T08:21:48.571658Z","shell.execute_reply":"2024-05-22T08:22:54.211813Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"!pip install -qqq ../input/contrails-model-def1/einops-0.6.1-py3-none-any.whl\n!pip install -qqq --no-index --find-links /kaggle/input/contrails-wheels/ pretrainedmodels==0.7.4\n!pip install -qqq --no-index --find-links /kaggle/input/contrails-wheels/ efficientnet_pytorch==0.7.1","metadata":{"execution":{"iopub.status.busy":"2024-05-22T08:22:54.215063Z","iopub.execute_input":"2024-05-22T08:22:54.215881Z","iopub.status.idle":"2024-05-22T08:23:57.513354Z","shell.execute_reply.started":"2024-05-22T08:22:54.215848Z","shell.execute_reply":"2024-05-22T08:23:57.512266Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import os\nimport gc\nimport re\nimport sys\nimport glob\nimport json\nimport torch\nimport shutil\nimport warnings\nimport numpy as np\nimport pandas as pd\nimport matplotlib.pyplot as plt\nimport torch.nn.functional as F\n\nfrom tqdm.notebook import tqdm","metadata":{"_kg_hide-input":true,"execution":{"iopub.status.busy":"2024-05-22T08:23:57.514749Z","iopub.execute_input":"2024-05-22T08:23:57.515034Z","iopub.status.idle":"2024-05-22T08:24:00.888656Z","shell.execute_reply.started":"2024-05-22T08:23:57.515008Z","shell.execute_reply":"2024-05-22T08:24:00.887828Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"sys.path.append('/kaggle/input/rsna-abdomen-code/src')\n\nfrom inference.extract_features import Config\nfrom inference.lvl2 import predict as predict_2\nfrom inference.lvl2 import PatientFeatureInfDataset, to_sub_format\nfrom inference.crop import get_crops\n\nfrom util.torch import load_model_weights\nfrom util.plots import plot_mask\n\nfrom data.transforms import get_transfos\nfrom data.dataset import AbdominalCropDataset\n\nfrom inference.processing import process, restrict_imgs\nfrom inference.lvl1 import predict, AbdominalInfDataset\n\nsys.path.append('/kaggle/input/timm-smp/pytorch-image-models-main/pytorch-image-models-main')\nsys.path.append(\n    \"/kaggle/input/timm-smp/segmentation_models.pytorch-master/segmentation_models.pytorch-master\"\n)\n\nfrom model_zoo.models import define_model\n# from model_zoo.models_lvl2 import define_model as define_model_2\nfrom model_zoo.models_seg import define_model as define_model_seg\nfrom model_zoo.models_seg import convert_3d","metadata":{"_kg_hide-input":true,"execution":{"iopub.status.busy":"2024-05-22T08:24:00.890936Z","iopub.execute_input":"2024-05-22T08:24:00.891363Z","iopub.status.idle":"2024-05-22T08:24:20.691046Z","shell.execute_reply.started":"2024-05-22T08:24:00.891335Z","shell.execute_reply":"2024-05-22T08:24:20.690013Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import torch\nimport torch.nn as nn\n\n\ndef define_model_2(\n    name=\"rnn_att\",\n    ft_dim=2048,\n    layer_dim=64,\n    n_layers=1,\n    dense_dim=256,\n    p=0.1,\n    num_classes=2,\n    num_classes_aux=0,\n    n_fts=0,\n):\n    \"\"\"\n    Define the level 2 model.\n\n    Args:\n        name (str): The name of the model to define. Default is \"rnn_att\".\n        ft_dim (int): Dimension of input features. Default is 2048.\n        layer_dim (int): Dimension of LSTM layers. Default is 64.\n        n_layers (int): Number of LSTM layers. Default is 1.\n        dense_dim (int): Dimension of the dense layer. Default is 256.\n        p (float): Dropout probability. Default is 0.1.\n        num_classes (int): Number of main classes. Default is 2.\n        num_classes_aux (int): Number of auxiliary classes. Default is 0.\n        n_fts (int): Number of features to use. Default is 0.\n\n    Returns:\n        nn.Module: The defined model.\n    \"\"\"\n    if name == \"rnn_att\":\n        return RNNAttModel(\n            ft_dim=ft_dim,\n            lstm_dim=layer_dim,\n            n_lstm=n_layers,\n            dense_dim=dense_dim,\n            p=p,\n            num_classes=num_classes,\n            num_classes_aux=num_classes_aux,\n            n_fts=n_fts,\n        )\n    else:\n        raise NotImplementedError\n\n\nclass RNNAttModel(nn.Module):\n    \"\"\"\n    Recurrent Neural Network with attention.\n\n    Attributes:\n        ft_dim (int): The dimension of input features.\n        lstm_dim (int): The dimension of the LSTM layer.\n        n_lstm (int): The number of LSTM layers.\n        dense_dim (int): The dimension of the dense layer.\n        p (float): Dropout probability.\n        num_classes (int): The number of primary target classes.\n        num_classes_aux (int): The number of auxiliary target classes.\n        n_fts (int): The number of additional features.\n    \"\"\"\n    def __init__(\n        self,\n        ft_dim=64,\n        lstm_dim=64,\n        n_lstm=1,\n        dense_dim=64,\n        p=0.1,\n        num_classes=8,\n        num_classes_aux=0,\n        n_fts=0,\n    ):\n        \"\"\"\n        Constructor.\n\n        Args:\n            ft_dim (int): The dimension of input features. Defaults to 64.\n            lstm_dim (int): The dimension of the LSTM layer. Defaults to 64.\n            n_lstm (int): The number of LSTM layers. Defaults to 1.\n            dense_dim (int): The dimension of the dense layer. Defaults to 64.\n            p (float): Dropout probability. Defaults to 0.1.\n            num_classes (int): The number of primary target classes. Defaults to 8.\n            num_classes_aux (int): The number of auxiliary target classes. Defaults to 0.\n            n_fts (int): The number of additional features. Defaults to 0.\n\n        \"\"\"\n        super().__init__()\n        self.n_fts = n_fts\n        self.n_lstm = n_lstm\n        self.num_classes = num_classes\n        self.num_classes_aux = num_classes_aux\n\n        self.mlp = nn.Sequential(\n            nn.Linear(ft_dim, dense_dim),\n            nn.Mish(),\n        )\n\n        if n_fts > 0:\n            self.mlp_fts = nn.Sequential(\n                nn.Linear(n_fts, dense_dim),\n                nn.Dropout(p=p),\n                nn.Mish(),\n            )\n            n_fts = n_fts + dense_dim\n\n        self.lstm = nn.LSTM(dense_dim, lstm_dim, batch_first=True, bidirectional=True)\n\n#         self.logits_bowel = nn.Sequential(\n#             nn.Dropout(p=0),\n#             nn.Linear(2 * (lstm_dim * 2 + dense_dim) + 4, dense_dim),\n#             nn.Mish(),\n#             nn.Linear(dense_dim, 1),\n#         )\n#         self.logits_extrav = nn.Sequential(\n#             nn.Dropout(p=0),\n#             nn.Linear(2 * (lstm_dim * 2 + dense_dim) + 4, dense_dim),\n#             nn.Mish(),\n#             nn.Linear(dense_dim, 1),\n#         )\n        self.logits_spleen = nn.Sequential(\n            nn.Dropout(p=0),\n            nn.Linear(2 * (lstm_dim * 2 + dense_dim) + 8 + n_fts, dense_dim),\n            nn.Mish(),\n            nn.Linear(dense_dim, 3),\n        )\n#         self.logits_liver = nn.Sequential(\n#             nn.Dropout(p=0),\n#             nn.Linear(2 * (lstm_dim * 2 + dense_dim) + 8 + n_fts, dense_dim),\n#             nn.Mish(),\n#             nn.Linear(dense_dim, 3),\n#         )\n#         self.logits_kidney = nn.Sequential(\n#             nn.Dropout(p=0),\n#             nn.Linear(2 * (lstm_dim * 2 + dense_dim) + 8 + n_fts, dense_dim),\n#             nn.Mish(),\n#             nn.Linear(dense_dim, 3),\n#         )\n\n        if num_classes_aux:\n            raise NotImplementedError\n\n    def attention_pooling(self, x, w):\n        \"\"\"\n        Apply attention pooling to input features.\n\n        Args:\n            x (torch.Tensor): Input feature tensor.\n            w (torch.Tensor): Attention weights.\n\n        Returns:\n            torch.Tensor: The pooled result.\n        \"\"\"\n        return (x * w).sum(1) / (w.sum(1) + 1e-6), (x * w).amax(1)\n\n    def forward(self, x, ft=None):\n        \"\"\"\n        Forward pass of the RNN with attention model.\n\n        Args:\n            x (torch.Tensor): Input tensor of shape (batch_size, sequence_length, input_features).\n            ft (torch.Tensor, optional): Additional features tensor. Default is None.\n\n        Returns:\n            torch.Tensor: Model outputs as logits for different classes.\n            torch.Tensor: Placeholder for auxiliary outputs.\n        \"\"\"\n#         x[:, :, :1] = 0  # liver seg\n#         x[:, :, 2:5] = 0  # kidney & bowel seg\n        \n#         x[:, :, 5: 5 + 11 - 3] = 0  # model spleen\n#         x[:, :, 5 + 11: - 3] = 0  # model*seg not spleen\n        \n#         ft[:, 0] = 0  # kidney ft\n#         ft[:, 1] = 0  # liver ft\n        \n        ft = ft[:, 2:]\n        \n        x = torch.cat([\n            x[:, :, 1:2],\n            x[:, :, 5 + 11 - 3:5 + 11],\n            x[:, :, -3:],\n        ], -1)\n        \n\n        features = self.mlp(x)\n        features_lstm, _ = self.lstm(features)\n\n        features = torch.cat([features, features_lstm], -1)\n\n#         kidney = x[:, :, 2:4].amax(-1, keepdims=True)\n#         liver = x[:, :, :1]\n        spleen = x[:, :, :1]\n#         bowel = x[:, :, 4:5]\n\n#         att_bowel, max_bowel = self.attention_pooling(features, bowel)\n#         att_kidney, max_kidney = self.attention_pooling(features, kidney)\n#         att_liver, max_liver = self.attention_pooling(features, liver)\n        att_spleen, max_spleen = self.attention_pooling(features, spleen)\n\n        mean = features.mean(1)\n        max_ = features.amax(1)\n\n        scores = x[:, :, 1:]\n        scores = scores.view(x.size(0), x.size(1), -1, 3 * 2)\n        pooled_scores = scores.mean(2).view(x.size(0), x.size(1), 2, 3)\n        pooled_scores = torch.cat([pooled_scores.amax(1), pooled_scores.mean(1)], 1)\n\n\n#         pooled_scores_bowel = pooled_scores[:, :, :1].flatten(1, 2)\n#         pooled_scores_extrav = pooled_scores[:, :, 1:2].flatten(1, 2)\n#         pooled_scores_kidney = pooled_scores[:, :, 3:5].flatten(1, 2)\n#         pooled_scores_liver = pooled_scores[:, :, 6:8].flatten(1, 2)\n        pooled_scores_spleen = pooled_scores[:, :, 1:].flatten(1, 2)\n\n        if ft is None or self.n_fts == 0:\n            ft_kidney = torch.empty((x.size(0), 0)).to(x.device)\n            ft_liver = torch.empty((x.size(0), 0)).to(x.device)\n            ft_spleen = torch.empty((x.size(0), 0)).to(x.device)\n        else:\n            fts = self.mlp_fts(ft.flatten(1, 2))\n#             ft_kidney = torch.cat([fts, ft[:, 0]], -1)\n#             ft_liver = torch.cat([fts, ft[:, 1]], -1)\n            ft_spleen = torch.cat([fts, ft[:, 0]], -1)\n\n#         logits_bowel = self.logits_bowel(\n#             torch.cat([att_bowel, max_bowel, pooled_scores_bowel], -1)\n#         )\n#         logits_extrav = self.logits_extrav(\n#             torch.cat([mean, max_, pooled_scores_extrav], -1)\n#         )\n#         logits_kidney = self.logits_kidney(\n#             torch.cat([att_kidney, max_kidney, pooled_scores_kidney, ft_kidney], -1)\n#         )\n#         logits_liver = self.logits_liver(\n#             torch.cat([att_liver, max_liver, pooled_scores_liver, ft_liver], -1)\n#         )\n#         print(att_spleen.size(), max_spleen.size(), pooled_scores_spleen.size(), ft_spleen.size())\n        logits_spleen = self.logits_spleen(\n            torch.cat([att_spleen, max_spleen, pooled_scores_spleen, ft_spleen], -1)\n        )\n    \n        logits_bowel = torch.zeros(logits_spleen.size(), dtype=logits_spleen.dtype, device=logits_spleen.device)[:, :1]\n        logits_extrav = torch.zeros(logits_spleen.size(), dtype=logits_spleen.dtype, device=logits_spleen.device)[:, :1]\n        logits_kidney = torch.zeros(logits_spleen.size(), dtype=logits_spleen.dtype, device=logits_spleen.device)\n        logits_liver = torch.zeros(logits_spleen.size(), dtype=logits_spleen.dtype, device=logits_spleen.device)\n\n        logits = torch.cat(\n            [logits_bowel, logits_extrav, logits_kidney, logits_liver, logits_spleen],\n            -1,\n        )\n\n        return logits, torch.zeros((x.size(0)))\n","metadata":{"_kg_hide-input":true,"jupyter":{"source_hidden":true},"execution":{"iopub.status.busy":"2024-05-22T08:24:20.692517Z","iopub.execute_input":"2024-05-22T08:24:20.985374Z","iopub.status.idle":"2024-05-22T08:24:21.013306Z","shell.execute_reply.started":"2024-05-22T08:24:20.985325Z","shell.execute_reply":"2024-05-22T08:24:21.012245Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Params","metadata":{}},{"cell_type":"code","source":"EVAL = False","metadata":{"execution":{"iopub.status.busy":"2024-05-22T08:24:21.014562Z","iopub.execute_input":"2024-05-22T08:24:21.014861Z","iopub.status.idle":"2024-05-22T08:24:21.029471Z","shell.execute_reply.started":"2024-05-22T08:24:21.014836Z","shell.execute_reply":"2024-05-22T08:24:21.028484Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"DATA_PATH = \"/kaggle/input/rsna-2023-abdominal-trauma-detection/test_images/\"\nSAVE_FOLDER = \"/tmp/\"\n\nos.makedirs(SAVE_FOLDER, exist_ok=True)\n!rm -r $SAVE_FOLDER\nos.makedirs(SAVE_FOLDER, exist_ok=True)","metadata":{"execution":{"iopub.status.busy":"2024-05-22T08:24:21.030461Z","iopub.execute_input":"2024-05-22T08:24:21.030736Z","iopub.status.idle":"2024-05-22T08:24:22.021708Z","shell.execute_reply.started":"2024-05-22T08:24:21.030705Z","shell.execute_reply":"2024-05-22T08:24:22.020588Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"if len(os.listdir(DATA_PATH)) <= 3:\n    DATA_PATH = \"/tmp/data/\"\n    os.makedirs(DATA_PATH, exist_ok=True)\n    \n    for pid in [10082,10004, 10005, 10007]:\n        try:\n            shutil.copytree(f\"/kaggle/input/rsna-2023-abdominal-trauma-detection/train_images/{pid}\", DATA_PATH + f\"{pid}/\")\n        except FileExistsError:\n            pass\n#         break\n\nif EVAL:\n    df = pd.read_csv(\"/kaggle/input/rsna-weights-spleen/2024-02-19_3/df_val_0.csv\")\n    DATA_PATH = f\"/kaggle/input/rsna-2023-abdominal-trauma-detection/train_images/\"\n    patients = sorted(df['patient_id'].unique())[:10]\n    print(patients)","metadata":{"execution":{"iopub.status.busy":"2024-05-22T08:24:22.023419Z","iopub.execute_input":"2024-05-22T08:24:22.0238Z","iopub.status.idle":"2024-05-22T08:25:53.445064Z","shell.execute_reply.started":"2024-05-22T08:24:22.023762Z","shell.execute_reply":"2024-05-22T08:25:53.444093Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"BATCH_SIZE = 16\nBATCH_SIZE_2 = 512\nUSE_FP16 = True\nNUM_WORKERS = 2\n\nRESTRICT = True\nHALF = True","metadata":{"execution":{"iopub.status.busy":"2024-05-22T08:25:53.446305Z","iopub.execute_input":"2024-05-22T08:25:53.446588Z","iopub.status.idle":"2024-05-22T08:25:53.451319Z","shell.execute_reply.started":"2024-05-22T08:25:53.446562Z","shell.execute_reply":"2024-05-22T08:25:53.450397Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# FOLD = 0\nFOLD = \"fullfit_0\"\n\nEXP_FOLDERS = [\n    (\"/kaggle/input/rsna-abdomen-weights-1/2023-09-20_14/\", \"seg\", [FOLD]),\n#     (\"/kaggle/input/rsna-weights-spleen/2024-02-19_4/\", \"probas_2d\", [FOLD]),  # maxvit_tiny_tf_512 NO SMH\n    (\"/kaggle/input/rsna-weights-spleen-fix/2024-05-21_5/\", \"probas_2d\", [FOLD]),  # maxvit_tiny_tf_512 NO SMH\n]\n\nCROP_EXP_FOLDERS = [\n#     (\"/kaggle/input/rsna-weights-spleen/2024-03-21_4/\", \"crop\", [FOLD]),   # coatnet_1_rw_224 NO SMH\n    (\"/kaggle/input/rsna-weights-spleen-fix/2024-05-21_7/\", \"crop\", [FOLD]),   # coatnet_1_rw_224 NO SMH FIX\n]\n\"../logs/2024-03-21/4/\"\nEXP_FOLDERS_2 = [\n#     \"/kaggle/input/rsna-weights-spleen/2024-03-21_5/\",  # Spleen only, no SMH\n    \"/kaggle/input/rsna-weights-spleen-fix/2024-05-22_0/\",  # Spleen only, no SMH FIX\n]\n\nEXP_FOLDER_3D = \"/kaggle/input/rsna-abdomen-weights-1/2023-09-24_20/\"\n\nFOLDS_2 = [0, 1, 2, 3]\nif \"fullfit\" not in str(FOLD):\n    FOLDS_2 = [FOLD]\n    \nConfig(json.load(open(EXP_FOLDERS_2[0] + \"config.json\", 'r'))).exp_folders","metadata":{"execution":{"iopub.status.busy":"2024-05-22T08:30:25.393581Z","iopub.execute_input":"2024-05-22T08:30:25.393997Z","iopub.status.idle":"2024-05-22T08:30:25.410643Z","shell.execute_reply.started":"2024-05-22T08:30:25.393966Z","shell.execute_reply":"2024-05-22T08:30:25.409727Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Level 1","metadata":{}},{"cell_type":"code","source":"class Config3d:\n    size = 256\n    plot = (FOLD == 0) and (not EVAL)\n    margin = 5\n\nconfig = Config(json.load(open(EXP_FOLDER_3D + \"config.json\", \"r\")))\n\nmodel_seg = define_model_seg(\n    config.decoder_name,\n    config.name,\n    num_classes=config.num_classes,\n    num_classes_aux=config.num_classes_aux,\n    n_channels=config.n_channels,\n    increase_stride=config.increase_stride,\n    pretrained=False,\n)\n\nmodel_seg = convert_3d(model_seg)\nmodel_seg = load_model_weights(model_seg, EXP_FOLDER_3D + f\"{config.name}_{FOLD}.pt\")\nmodel_seg = model_seg.eval().cuda()","metadata":{"execution":{"iopub.status.busy":"2024-05-22T08:30:27.16605Z","iopub.execute_input":"2024-05-22T08:30:27.166406Z","iopub.status.idle":"2024-05-22T08:30:30.241343Z","shell.execute_reply.started":"2024-05-22T08:30:27.166377Z","shell.execute_reply":"2024-05-22T08:30:30.240552Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"models = []\nfor exp_folder, mode, folds in EXP_FOLDERS:\n    models_ = []\n    config = Config(json.load(open(exp_folder + \"config.json\", \"r\")))\n    \n    for fold in folds:\n        model = define_model(\n            config.name,\n            drop_rate=config.drop_rate,\n            drop_path_rate=config.drop_path_rate,\n            use_gem=config.use_gem,\n            head_3d=config.head_3d if hasattr(config, \"head_3d\") else \"\",\n            n_frames=config.n_frames if hasattr(config, \"n_frames\") else \"\",\n            replace_pad_conv=config.replace_pad_conv if hasattr(config, \"replace_pad_conv\") else False,\n            num_classes=config.num_classes,\n            num_classes_aux=config.num_classes_aux,\n            n_channels=config.n_channels,\n            reduce_stride=config.reduce_stride,\n            increase_stride=config.increase_stride if hasattr(config, \"increase_stride\") else False,\n            pretrained=False\n        )\n        model = model.cuda().eval()\n    \n        weights = exp_folder + f\"{config.name}_{fold}.pt\"\n        model = load_model_weights(model, weights, verbose=config.local_rank == 0)\n        models_.append(model)\n        \n    models.append(models_)","metadata":{"execution":{"iopub.status.busy":"2024-05-22T08:30:30.242843Z","iopub.execute_input":"2024-05-22T08:30:30.243101Z","iopub.status.idle":"2024-05-22T08:30:33.150372Z","shell.execute_reply.started":"2024-05-22T08:30:30.243078Z","shell.execute_reply":"2024-05-22T08:30:33.149227Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# %%time\n\ndfs = []\nfor patient in tqdm(sorted(os.listdir(DATA_PATH))):\n    if FOLD == 0:\n        if EVAL:\n            if int(patient) not in patients:\n                continue\n        else:\n            if patient != \"10082\":\n                continue\n\n    for series in sorted(os.listdir(DATA_PATH + patient)):\n        print(\"-> Patient\", patient, '- Series', series)        \n#         continue\n\n        imgs, paths, n_imgs = process(\n            patient,\n            series,\n            data_path=DATA_PATH,\n            on_gpu=True,\n            crop_size=384,\n            restrict=RESTRICT\n        )\n\n        # Seg & Crop\n        with torch.cuda.amp.autocast(enabled=True):\n            x = F.interpolate(imgs.unsqueeze(0).unsqueeze(0), size=(Config3d.size, Config3d.size, Config3d.size), mode=\"nearest\")\n            pred = model_seg(x)[0].argmax(1, keepdims=True).float()\n            pred = F.interpolate(pred, size=(len(imgs), 384, 384), mode=\"nearest\")\n            \n        seg = pred[0][0]\n        coords = get_crops(seg)\n\n        for (x0, x1, y0, y1, z0, z1), name in zip(coords, ['liver', 'spleen', 'kidney']):\n            x0, x1 = max(0, x0 - Config3d.margin), min(imgs.shape[0], x1 + Config3d.margin)\n            y0, y1 = max(0, y0 - Config3d.margin), min(imgs.shape[1], y1 + Config3d.margin)\n            z0, z1 = max(0, z0 - Config3d.margin), min(imgs.shape[2], z1 + Config3d.margin)\n\n            img_crop = (imgs[x0: x1, y0:y1, z0:z1].cpu().numpy() * 255).astype(np.uint8)\n            np.save(SAVE_FOLDER + f'{patient}_{series}_{name}.npy', img_crop.copy())\n\n        # Cls\n        df_series = pd.DataFrame({\"path\": paths})\n        df_series['patient_id'] = df_series['path'].apply(lambda x: x.split('_')[0])\n        df_series['patient'] = df_series['path'].apply(lambda x: x.split('_')[0])\n        df_series['series'] = df_series['path'].apply(lambda x: x.split('_')[1])\n        df_series['frame'] = df_series['path'].apply(lambda x: int(x.split('_')[2][:-4]))\n        dfs.append(df_series)\n\n        for models_list, (exp_folder, _, _) in zip(models, EXP_FOLDERS):\n            exp_name = \"_\".join(exp_folder.split('/')[-2:-1])\n#             if \"2023\" not in exp_name:  # locally\n#                 exp_name = \"_\".join(exp_folder.split('/')[-3:-1])\n            \n            config = Config(json.load(open(exp_folder + \"config.json\", \"r\")))\n            dataset = AbdominalInfDataset(\n                df_series,\n                frames_chanel=config.frames_chanel if hasattr(config, \"frames_chanel\") else 0,\n                n_frames=config.n_frames if hasattr(config, \"n_frames\") else 1,\n                stride=config.stride if hasattr(config, \"stride\") else 1,\n                imgs=imgs,\n                paths=paths,\n            )\n            if HALF:\n                dataset.info = dataset.info[::2]\n\n            preds = []\n            for model in models_list:\n                pred = predict(\n                    model,\n                    dataset,\n                    config.loss_config,\n                    batch_size=BATCH_SIZE,\n                    use_fp16=USE_FP16,\n                    num_workers=0,\n                    resize=config.resize if config.resize[0] != 384 else None\n                )\n                if HALF:\n                    pred = np.repeat(pred, 2, axis=0)[:len(df_series)]\n                preds.append(pred)\n\n                    \n            if RESTRICT:\n                pred_padded = np.zeros((n_imgs, pred.shape[-1]))\n                pred_padded[-len(pred):] = np.mean(preds, 0)\n            else:\n                pred_padded = np.mean(preds, 0)\n\n            np.save(SAVE_FOLDER + f\"{series}_{exp_name}.npy\", pred_padded)\n            \n            if FOLD == 0 and not RESTRICT:\n                ref = np.load(exp_folder + \"pred_val_0.npy\")\n                ref = ref[:len(pred)]\n                \n                plt.plot(ref - np.mean(preds, 0))\n                plt.title(np.abs(ref - np.mean(preds, 0)).max())\n                plt.show()\n\n#             break\n#     break\n\ndf = pd.concat(dfs, ignore_index=True)\ndf = df.groupby(['patient', 'series']).max().reset_index()\n\ndel model_seg, models, imgs, x, pred, seg, dataset\ntorch.cuda.empty_cache()\ngc.collect()","metadata":{"execution":{"iopub.status.busy":"2024-05-22T08:30:33.151974Z","iopub.execute_input":"2024-05-22T08:30:33.152318Z","iopub.status.idle":"2024-05-22T08:31:02.577355Z","shell.execute_reply.started":"2024-05-22T08:30:33.152288Z","shell.execute_reply":"2024-05-22T08:31:02.576372Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Crop Model","metadata":{}},{"cell_type":"code","source":"df_series = pd.DataFrame({\"img_path\": sorted(glob.glob(SAVE_FOLDER + f'*.npy'))})\ndf_series['patient_id'] = df_series['img_path'].apply(lambda x: x.split('/')[-1].split('_')[0])\ndf_series['series'] = df_series['img_path'].apply(lambda x: x.split('_')[-2])\ndf_series['organ'] = df_series['img_path'].apply(lambda x: x.split('_')[-1][:-4])\n\ndf_series['target'] = 0\ndf_series = df_series[df_series['organ'].isin(['kidney', 'liver', 'spleen'])].reset_index(drop=True)","metadata":{"execution":{"iopub.status.busy":"2024-05-22T08:31:02.580031Z","iopub.execute_input":"2024-05-22T08:31:02.580496Z","iopub.status.idle":"2024-05-22T08:31:02.593608Z","shell.execute_reply.started":"2024-05-22T08:31:02.580459Z","shell.execute_reply":"2024-05-22T08:31:02.592805Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"crop_fts = []\nfor exp_folder, mode, folds in tqdm(CROP_EXP_FOLDERS):\n    \n    config = Config(json.load(open(exp_folder + \"config.json\", \"r\")))\n\n    model = define_model(\n        config.name,\n        drop_rate=config.drop_rate,\n        drop_path_rate=config.drop_path_rate,\n        use_gem=config.use_gem,\n        head_3d=config.head_3d if hasattr(config, \"head_3d\") else \"\",\n        n_frames=config.n_frames if hasattr(config, \"n_frames\") else \"\",\n        replace_pad_conv=config.replace_pad_conv if hasattr(config, \"replace_pad_conv\") else False,\n        num_classes=config.num_classes,\n        num_classes_aux=config.num_classes_aux,\n        n_channels=config.n_channels,\n        reduce_stride=config.reduce_stride,\n        increase_stride=config.increase_stride if hasattr(config, \"increase_stride\") else False,\n        pretrained=False\n    )\n    model = model.cuda().eval()\n    \n    preds = []\n    for fold in folds:\n        weights = exp_folder + f\"{config.name}_{fold}.pt\"\n        model = load_model_weights(model, weights, verbose=config.local_rank == 0)\n        \n        transfos = get_transfos(\n            augment=False, resize=config.resize, crop=config.crop\n        )\n\n        dataset = AbdominalCropDataset(\n            None,\n            None,\n            transforms=transfos,\n            frames_chanel=config.frames_chanel,\n            n_frames=config.n_frames,\n            stride=config.stride,\n            use_mask=config.use_mask if hasattr(config, \"use_mask\") else False,\n            train=False,\n            df_series=df_series\n        )\n\n        pred = predict(\n            model,\n            dataset,\n            config.loss_config,\n            batch_size=BATCH_SIZE,\n            use_fp16=USE_FP16,\n            num_workers=NUM_WORKERS,\n        )\n        preds.append(pred)\n\n    preds = np.mean(preds, 0)\n    crop_fts.append(preds)\n    \n    del model, dataset\n    torch.cuda.empty_cache()\n    gc.collect()\n    \ncrop_fts = np.array(crop_fts) # n_models x 3*n_studies x n_classes\nnp.save(SAVE_FOLDER + \"crop_fts.npy\", crop_fts)","metadata":{"execution":{"iopub.status.busy":"2024-05-22T08:31:02.595084Z","iopub.execute_input":"2024-05-22T08:31:02.595458Z","iopub.status.idle":"2024-05-22T08:31:06.885577Z","shell.execute_reply.started":"2024-05-22T08:31:02.595426Z","shell.execute_reply":"2024-05-22T08:31:06.88435Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"crop_fts = np.load(SAVE_FOLDER + \"crop_fts.npy\")\n\ncrop_fts = crop_fts.reshape(crop_fts.shape[0], crop_fts.shape[1] // 3, 3, crop_fts.shape[2])  # n_models x n_studies x n_organs x 3\ncrop_fts = crop_fts.transpose(1, 2, 0, 3)  # n_studies x n_organs x n_models x 3\ncrop_fts = crop_fts.reshape(crop_fts.shape[0], crop_fts.shape[1], crop_fts.shape[2] * crop_fts.shape[3])  # n_studies x n_organs x 3 * n_models","metadata":{"execution":{"iopub.status.busy":"2024-05-22T08:31:06.88715Z","iopub.execute_input":"2024-05-22T08:31:06.887576Z","iopub.status.idle":"2024-05-22T08:31:06.895878Z","shell.execute_reply.started":"2024-05-22T08:31:06.887535Z","shell.execute_reply":"2024-05-22T08:31:06.894934Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Level 2","metadata":{}},{"cell_type":"code","source":"all_preds = []\n\nfor exp_folder in EXP_FOLDERS_2:\n    config_2 = Config(json.load(open(exp_folder + \"config.json\", \"r\")))\n#     config_2.exp_folders = [[f[:-3] + \"/\" if \"_r/\" in f else f, m] for f, m in config_2.exp_folders]\n    config_2.exp_folders = [[re.sub('_', '/', f[0]), f[1]] for f in config_2.exp_folders]\n\n    dataset = PatientFeatureInfDataset(\n        df['series'],\n        config_2.exp_folders,\n        crop_fts=crop_fts,\n        max_len=config_2.max_len,\n        restrict=config_2.restrict,\n        resize=config_2.resize,\n        save_folder=SAVE_FOLDER,\n        half=HALF,\n    )\n    \n    model = define_model_2(\n        config_2.name,\n        ft_dim=config_2.ft_dim,\n        layer_dim=config_2.layer_dim,\n        n_layers=config_2.n_layers,\n        dense_dim=config_2.dense_dim,\n        p=config_2.p,\n#         use_msd=config_2.use_msd if hasattr(config, \"use_msd\") else False,\n        num_classes=config_2.num_classes,\n        num_classes_aux=config_2.num_classes_aux,\n        n_fts=config_2.n_fts,\n    )\n    model = model.eval().cuda()\n\n    for fold in FOLDS_2:\n        weights = exp_folder + f\"{config_2.name}_{fold}.pt\"\n        model = load_model_weights(model, weights, verbose=config.local_rank == 0)\n    \n        preds = predict_2(\n            model,\n            dataset,\n            config_2.loss_config,\n            batch_size=BATCH_SIZE_2,\n            use_fp16=USE_FP16,\n            num_workers=NUM_WORKERS,\n        )\n        all_preds.append(preds)\n        \n    del model  # , dataset\n    torch.cuda.empty_cache()\n    gc.collect()","metadata":{"execution":{"iopub.status.busy":"2024-05-22T08:31:06.897108Z","iopub.execute_input":"2024-05-22T08:31:06.898036Z","iopub.status.idle":"2024-05-22T08:31:08.230712Z","shell.execute_reply.started":"2024-05-22T08:31:06.898002Z","shell.execute_reply":"2024-05-22T08:31:08.22959Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"preds = np.mean(all_preds, 0).astype(np.float64)\nfor i in range(preds.shape[1]):\n    df[f'pred_{i}'] = preds[:, i]\n\ndfg = df.drop(['series', 'path', 'frame', 'patient_id'], axis=1).groupby('patient').mean().reset_index()\nsub = to_sub_format(dfg)\n\nsub = sub[[\"patient_id\", \"spleen_healthy\", \"spleen_low\", \"spleen_high\"]]\n\nsub.to_csv(\"submission.csv\", index=False)\nsub.head()","metadata":{"execution":{"iopub.status.busy":"2024-05-22T08:31:11.165381Z","iopub.execute_input":"2024-05-22T08:31:11.165675Z","iopub.status.idle":"2024-05-22T08:31:11.194244Z","shell.execute_reply.started":"2024-05-22T08:31:11.165649Z","shell.execute_reply":"2024-05-22T08:31:11.193234Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Done ! ","metadata":{}}]}