{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.10.14","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"gpu","dataSources":[{"sourceType":"competition","sourceId":71549,"databundleVersionId":8561470},{"sourceType":"datasetVersion","sourceId":9570561,"datasetId":5782868,"databundleVersionId":9789697},{"sourceType":"datasetVersion","sourceId":9540790,"datasetId":5760109,"databundleVersionId":9756522},{"sourceType":"datasetVersion","sourceId":9471693,"datasetId":5760088,"databundleVersionId":9680482},{"sourceType":"datasetVersion","sourceId":9471406,"datasetId":5759884,"databundleVersionId":9680172},{"sourceType":"datasetVersion","sourceId":9576737,"datasetId":5834626,"databundleVersionId":9796428},{"sourceType":"datasetVersion","sourceId":9577005,"datasetId":5751560,"databundleVersionId":9796725},{"sourceType":"datasetVersion","sourceId":9540797,"datasetId":5795129,"databundleVersionId":9756529},{"sourceType":"datasetVersion","sourceId":9561530,"datasetId":5797040,"databundleVersionId":9779534},{"sourceType":"datasetVersion","sourceId":9567103,"datasetId":5783049,"databundleVersionId":9785825},{"sourceType":"kernelVersion","sourceId":198102119},{"sourceType":"kernelVersion","sourceId":199885993},{"sourceType":"kernelVersion","sourceId":199967358},{"sourceType":"kernelVersion","sourceId":199969364}],"dockerImageVersionId":30762,"isInternetEnabled":false,"language":"python","sourceType":"notebook","isGpuEnabled":true}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"! pip install -q segmentation_models_pytorch --no-index --find-links=/kaggle/input/pip-smp\n! pip install -q omegaconf --no-index --find-links=/kaggle/input/pip-smp\n! pip install -q timm==1.0.9 --no-index --find-links=/kaggle/input/pip-smp","metadata":{"execution":{"iopub.status.busy":"2024-10-08T13:52:47.717157Z","iopub.execute_input":"2024-10-08T13:52:47.717570Z","iopub.status.idle":"2024-10-08T13:53:36.930331Z","shell.execute_reply.started":"2024-10-08T13:52:47.717522Z","shell.execute_reply":"2024-10-08T13:53:36.929201Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"! mkdir /kaggle/tmp","metadata":{"execution":{"iopub.status.busy":"2024-10-08T13:53:36.931884Z","iopub.execute_input":"2024-10-08T13:53:36.932330Z","iopub.status.idle":"2024-10-08T13:53:37.910793Z","shell.execute_reply.started":"2024-10-08T13:53:36.932273Z","shell.execute_reply":"2024-10-08T13:53:37.909773Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"! cp -r /kaggle/input/rsna2024-main/rsna2024-main /kaggle/tmp/","metadata":{"execution":{"iopub.status.busy":"2024-10-08T13:53:37.913167Z","iopub.execute_input":"2024-10-08T13:53:37.913496Z","iopub.status.idle":"2024-10-08T13:53:39.837347Z","shell.execute_reply.started":"2024-10-08T13:53:37.913461Z","shell.execute_reply":"2024-10-08T13:53:39.836310Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import os\nos.chdir(\"/kaggle/tmp/rsna2024-main\")","metadata":{"execution":{"iopub.status.busy":"2024-10-08T13:53:39.838621Z","iopub.execute_input":"2024-10-08T13:53:39.838920Z","iopub.status.idle":"2024-10-08T13:53:39.843711Z","shell.execute_reply.started":"2024-10-08T13:53:39.838887Z","shell.execute_reply":"2024-10-08T13:53:39.842857Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"! ln -s /kaggle/input/rsna-2024-lumbar-spine-degenerative-classification input","metadata":{"execution":{"iopub.status.busy":"2024-10-08T13:53:39.844912Z","iopub.execute_input":"2024-10-08T13:53:39.845287Z","iopub.status.idle":"2024-10-08T13:53:40.833883Z","shell.execute_reply.started":"2024-10-08T13:53:39.845245Z","shell.execute_reply":"2024-10-08T13:53:40.832705Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"! python 05_create_test_axial_dataset.py --mode test --target axial","metadata":{"execution":{"iopub.status.busy":"2024-10-08T13:53:40.835578Z","iopub.execute_input":"2024-10-08T13:53:40.835893Z","iopub.status.idle":"2024-10-08T13:53:50.625558Z","shell.execute_reply.started":"2024-10-08T13:53:40.835859Z","shell.execute_reply":"2024-10-08T13:53:50.624585Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"! python 03_axial_test.py test.mode=test trainer.accelerator=gpu trainer.devices=[0] data.num_workers=2 task.img_size=128 task.in_channels=3 task.layer_num=1 model.resume_path=/kaggle/input/rsna2024-axial-depth-models","metadata":{"execution":{"iopub.status.busy":"2024-10-08T13:53:50.627315Z","iopub.execute_input":"2024-10-08T13:53:50.627752Z","iopub.status.idle":"2024-10-08T13:55:01.085383Z","shell.execute_reply.started":"2024-10-08T13:53:50.627702Z","shell.execute_reply":"2024-10-08T13:55:01.084204Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"! python 25_create_test_keypoint_dataset.py --mode test","metadata":{"execution":{"iopub.status.busy":"2024-10-08T13:55:01.086978Z","iopub.execute_input":"2024-10-08T13:55:01.087402Z","iopub.status.idle":"2024-10-08T13:55:05.062296Z","shell.execute_reply.started":"2024-10-08T13:55:01.087352Z","shell.execute_reply":"2024-10-08T13:55:05.061361Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"! python 23_axial_keypoint_test.py test.mode=test trainer.accelerator=gpu trainer.devices=[0] data.num_workers=2 data.batch_size=32 task.img_size=512 model.resume_path=/kaggle/input/rsna2024-axial-keypoint-models","metadata":{"execution":{"iopub.status.busy":"2024-10-08T13:55:05.066232Z","iopub.execute_input":"2024-10-08T13:55:05.066621Z","iopub.status.idle":"2024-10-08T13:55:53.440749Z","shell.execute_reply.started":"2024-10-08T13:55:05.066580Z","shell.execute_reply":"2024-10-08T13:55:53.439743Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"! head axial_test_keypoint_preds.csv","metadata":{"execution":{"iopub.status.busy":"2024-10-08T13:55:53.442528Z","iopub.execute_input":"2024-10-08T13:55:53.442952Z","iopub.status.idle":"2024-10-08T13:55:54.432186Z","shell.execute_reply.started":"2024-10-08T13:55:53.442904Z","shell.execute_reply":"2024-10-08T13:55:54.430543Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"! cp axial_test_keypoint_preds.csv /kaggle/working/","metadata":{"execution":{"iopub.status.busy":"2024-10-08T13:55:54.434589Z","iopub.execute_input":"2024-10-08T13:55:54.435767Z","iopub.status.idle":"2024-10-08T13:55:55.435664Z","shell.execute_reply.started":"2024-10-08T13:55:54.435711Z","shell.execute_reply":"2024-10-08T13:55:55.434450Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"! python 14_create_axial_cls_dataset_from_pred_v2.py --img_size 224 --channel_num 5 --mode test","metadata":{"execution":{"iopub.status.busy":"2024-10-08T13:55:55.437250Z","iopub.execute_input":"2024-10-08T13:55:55.437598Z","iopub.status.idle":"2024-10-08T13:55:59.528735Z","shell.execute_reply.started":"2024-10-08T13:55:55.437562Z","shell.execute_reply":"2024-10-08T13:55:59.527494Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"! python 18_axial_cls_test.py trainer.accelerator=gpu trainer.devices=[0] data.num_workers=2 data.batch_size=32 task.img_size=224 model.arch=2.5d model.in_channels=3 test.mode=test model.resume_path=/kaggle/input/rsna2024-axial-cls-models/axial_baseline","metadata":{"execution":{"iopub.status.busy":"2024-10-08T13:55:59.530481Z","iopub.execute_input":"2024-10-08T13:55:59.530935Z","iopub.status.idle":"2024-10-08T13:56:45.376755Z","shell.execute_reply.started":"2024-10-08T13:55:59.530866Z","shell.execute_reply":"2024-10-08T13:56:45.375761Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"! python 18_axial_cls_test.py --output_suffix swint trainer.accelerator=gpu trainer.devices=[0] data.num_workers=2 data.batch_size=32 task.img_size=224 model.arch=2.5d model.in_channels=3 test.mode=test model.backbone=swin_tiny_patch4_window7_224.ms_in22k_ft_in1k model.resume_path=/kaggle/input/rsna2024-axial-cls-models/axial_swint","metadata":{"execution":{"iopub.status.busy":"2024-10-08T13:56:45.378181Z","iopub.execute_input":"2024-10-08T13:56:45.378492Z","iopub.status.idle":"2024-10-08T13:57:32.025387Z","shell.execute_reply.started":"2024-10-08T13:56:45.378456Z","shell.execute_reply":"2024-10-08T13:57:32.024230Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"! rm -rf axial_test_dataset axial_keypoint_test_dataset # axial_cls_test_dataset","metadata":{"execution":{"iopub.status.busy":"2024-10-08T05:50:26.844884Z","iopub.execute_input":"2024-10-08T05:50:26.845204Z","iopub.status.idle":"2024-10-08T05:50:27.84594Z","shell.execute_reply.started":"2024-10-08T05:50:26.845159Z","shell.execute_reply":"2024-10-08T05:50:27.844864Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"! python 05_create_test_axial_dataset.py --mode test --target sagittal1","metadata":{"execution":{"iopub.status.busy":"2024-10-08T13:57:32.027025Z","iopub.execute_input":"2024-10-08T13:57:32.027418Z","iopub.status.idle":"2024-10-08T13:57:39.892971Z","shell.execute_reply.started":"2024-10-08T13:57:32.027361Z","shell.execute_reply":"2024-10-08T13:57:39.891789Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"! python 03_axial_test.py test.mode=test test.target=sagittal1 trainer.accelerator=gpu trainer.devices=[0] data.num_workers=2 task.img_size=128 task.in_channels=3 task.layer_num=1 model.resume_path=/kaggle/input/rsna2024-sagittal1-models/sagittal1/sagittal1/depth","metadata":{"execution":{"iopub.status.busy":"2024-10-08T13:57:39.894459Z","iopub.execute_input":"2024-10-08T13:57:39.894780Z","iopub.status.idle":"2024-10-08T13:58:37.663530Z","shell.execute_reply.started":"2024-10-08T13:57:39.894745Z","shell.execute_reply":"2024-10-08T13:58:37.662402Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"! python 27_create_test_sagittal1_keypoint_dataset.py --mode test","metadata":{"execution":{"iopub.status.busy":"2024-10-08T13:58:37.665272Z","iopub.execute_input":"2024-10-08T13:58:37.666166Z","iopub.status.idle":"2024-10-08T13:58:41.650279Z","shell.execute_reply.started":"2024-10-08T13:58:37.666112Z","shell.execute_reply":"2024-10-08T13:58:41.649341Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"! python 23_axial_keypoint_test.py test.mode=test test.target=sagittal1 trainer.accelerator=gpu trainer.devices=[0] data.num_workers=2 data.batch_size=32 task.img_size=512 model.resume_path=/kaggle/input/rsna2024-sagittal1-models/sagittal1/sagittal1/keypoint","metadata":{"execution":{"iopub.status.busy":"2024-10-08T13:58:41.651761Z","iopub.execute_input":"2024-10-08T13:58:41.652108Z","iopub.status.idle":"2024-10-08T13:59:29.871435Z","shell.execute_reply.started":"2024-10-08T13:58:41.652072Z","shell.execute_reply":"2024-10-08T13:59:29.870319Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"! python 31_create_sagittal1_cls_dataset_from_pred_v2.py --mode test","metadata":{"execution":{"iopub.status.busy":"2024-10-08T13:59:29.873079Z","iopub.execute_input":"2024-10-08T13:59:29.873425Z","iopub.status.idle":"2024-10-08T13:59:34.302582Z","shell.execute_reply.started":"2024-10-08T13:59:29.873387Z","shell.execute_reply":"2024-10-08T13:59:34.301544Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"! python 18_axial_cls_test.py trainer.accelerator=gpu trainer.devices=[0] data.num_workers=2 data.batch_size=32 task.img_size=224 model.arch=2.5d model.in_channels=3 test.mode=test test.target=sagittal1 model.resume_path=/kaggle/input/rsna2024-sagittal1-models/sagittal1/sagittal1/cls","metadata":{"execution":{"iopub.status.busy":"2024-10-08T13:59:34.304275Z","iopub.execute_input":"2024-10-08T13:59:34.304640Z","iopub.status.idle":"2024-10-08T14:00:20.468979Z","shell.execute_reply.started":"2024-10-08T13:59:34.304600Z","shell.execute_reply":"2024-10-08T14:00:20.467759Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"! python 18_axial_cls_test.py --output_suffix swint trainer.accelerator=gpu trainer.devices=[0] data.num_workers=2 data.batch_size=32 task.img_size=224 model.arch=2.5d model.in_channels=3 test.mode=test test.target=sagittal1 model.backbone=swin_tiny_patch4_window7_224.ms_in22k_ft_in1k model.resume_path=/kaggle/input/rsna2024-sagittal1-models/s1_swint","metadata":{"execution":{"iopub.status.busy":"2024-10-08T14:00:20.470522Z","iopub.execute_input":"2024-10-08T14:00:20.470885Z","iopub.status.idle":"2024-10-08T14:01:08.244524Z","shell.execute_reply.started":"2024-10-08T14:00:20.470846Z","shell.execute_reply":"2024-10-08T14:01:08.243450Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"! rm -rf sagittal1_test_dataset sagittal1_keypoint_test_dataset sagittal1_cls_test_dataset","metadata":{"execution":{"iopub.status.busy":"2024-10-08T05:54:11.687094Z","iopub.execute_input":"2024-10-08T05:54:11.687493Z","iopub.status.idle":"2024-10-08T05:54:12.698694Z","shell.execute_reply.started":"2024-10-08T05:54:11.687456Z","shell.execute_reply":"2024-10-08T05:54:12.697491Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"! python 42_create_test_sagittal2_keypoint_dataset.py --mode test","metadata":{"execution":{"iopub.status.busy":"2024-10-08T14:01:08.245969Z","iopub.execute_input":"2024-10-08T14:01:08.246331Z","iopub.status.idle":"2024-10-08T14:01:12.399081Z","shell.execute_reply.started":"2024-10-08T14:01:08.246294Z","shell.execute_reply":"2024-10-08T14:01:12.398066Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"! python 23_axial_keypoint_test.py test.mode=test test.target=sagittal2 trainer.accelerator=gpu trainer.devices=[0] data.num_workers=2 data.batch_size=32 task.img_size=512 model.resume_path=/kaggle/input/rsna2024-sagittal2-models/sagittal2/sagittal2/keypoint","metadata":{"execution":{"iopub.status.busy":"2024-10-08T14:01:12.400491Z","iopub.execute_input":"2024-10-08T14:01:12.400813Z","iopub.status.idle":"2024-10-08T14:02:01.391669Z","shell.execute_reply.started":"2024-10-08T14:01:12.400778Z","shell.execute_reply":"2024-10-08T14:02:01.390495Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"! python 43_create_sagittal2_cls_dataset_from_pred_v2.py --mode test --channel_num 9","metadata":{"execution":{"iopub.status.busy":"2024-10-08T14:02:01.393304Z","iopub.execute_input":"2024-10-08T14:02:01.393654Z","iopub.status.idle":"2024-10-08T14:02:05.920007Z","shell.execute_reply.started":"2024-10-08T14:02:01.393617Z","shell.execute_reply":"2024-10-08T14:02:05.919046Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"! python 18_axial_cls_test.py trainer.accelerator=gpu trainer.devices=[0] data.num_workers=2 data.batch_size=32 task.img_size=224 model.arch=2.5d model.in_channels=3 test.mode=test test.target=sagittal2 model.resume_path=/kaggle/input/rsna2024-sagittal2-models/sagittal2/sagittal2/cls","metadata":{"execution":{"iopub.status.busy":"2024-10-08T14:02:05.921476Z","iopub.execute_input":"2024-10-08T14:02:05.921825Z","iopub.status.idle":"2024-10-08T14:02:52.031681Z","shell.execute_reply.started":"2024-10-08T14:02:05.921788Z","shell.execute_reply":"2024-10-08T14:02:52.030727Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"! python 18_axial_cls_test.py --output_suffix swint trainer.accelerator=gpu trainer.devices=[0] data.num_workers=2 data.batch_size=32 task.img_size=224 model.arch=2.5d model.in_channels=3 test.mode=test test.target=sagittal2 model.backbone=swin_tiny_patch4_window7_224.ms_in22k_ft_in1k model.resume_path=/kaggle/input/rsna2024-sagittal2-models/s2_swint","metadata":{"execution":{"iopub.status.busy":"2024-10-08T14:02:52.033127Z","iopub.execute_input":"2024-10-08T14:02:52.033422Z","iopub.status.idle":"2024-10-08T14:03:39.114457Z","shell.execute_reply.started":"2024-10-08T14:02:52.033388Z","shell.execute_reply":"2024-10-08T14:03:39.113519Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"! python 18_axial_cls_test.py --output_suffix axial trainer.accelerator=gpu trainer.devices=[0] data.num_workers=2 data.batch_size=32 task.img_size=224 model.arch=2.5d model.in_channels=3 test.mode=test test.target=sagittal2 test.dirname=axial_cls_test_dataset model.backbone=swin_tiny_patch4_window7_224.ms_in22k_ft_in1k model.resume_path=/kaggle/input/rsna2024-sagittal2-models/s2_axial","metadata":{"execution":{"iopub.status.busy":"2024-10-08T14:03:39.120456Z","iopub.execute_input":"2024-10-08T14:03:39.120758Z","iopub.status.idle":"2024-10-08T14:04:25.427441Z","shell.execute_reply.started":"2024-10-08T14:03:39.120725Z","shell.execute_reply":"2024-10-08T14:04:25.426499Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"! ls","metadata":{"execution":{"iopub.status.busy":"2024-10-08T14:04:25.428754Z","iopub.execute_input":"2024-10-08T14:04:25.429062Z","iopub.status.idle":"2024-10-08T14:04:26.412831Z","shell.execute_reply.started":"2024-10-08T14:04:25.429027Z","shell.execute_reply":"2024-10-08T14:04:26.411808Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from collections import defaultdict\nimport numpy as np\nimport pandas as pd\nimport torch\n\nlevel_to_str = {0: \"l1_l2\", 1: \"l2_l3\", 2: \"l3_l4\", 3: \"l4_l5\", 4: \"l5_s1\"}\naxial_suffixes = [\"baseline\", \"swint\"]\ns1_suffixes = [\"baseline\", \"swint\"]\ns2_suffixes = [\"baseline\", \"swint\", \"axial\"]\n\n\ndef main():\n    # axial\n    for suffix in axial_suffixes:\n        results = []\n        csv_path = f\"axial_test_cls_preds_{suffix}.csv\"\n        df = pd.read_csv(csv_path)\n\n        for study_id, sub_df in df.groupby(\"study_id\"):\n            level_to_preds = defaultdict(list)\n\n            for _, row in sub_df.iterrows():\n                level = row[\"part_id\"]\n                pred = row[[\"left0\", \"left1\", \"left2\", \"right0\", \"right1\", \"right2\"]].values\n                level_to_preds[level].append(pred)\n\n            for level, preds in level_to_preds.items():\n                preds = np.stack(preds, 0)\n                pred = np.mean(preds, 0).reshape(2, 3)\n                pred = torch.softmax(torch.from_numpy(pred), -1).numpy()\n\n                for side, side_pred in zip([\"left\", \"right\"], pred):\n                    row_id = f\"{study_id}_{side}_subarticular_stenosis_{level_to_str[level]}\"\n                    results.append([row_id] + list(side_pred))\n\n        result_df = pd.DataFrame(results, columns=[\"row_id\", \"normal_mild\", \"moderate\", \"severe\"])\n        result_df.to_csv(f\"/kaggle/working/yu4u_axial_test_{suffix}_submission.csv\", index=False)\n\n    # sagittal1\n    for suffix in s1_suffixes:\n        results = []\n        csv_path = f\"sagittal1_test_cls_preds_{suffix}.csv\"\n        df = pd.read_csv(csv_path)\n    \n        for study_id, sub_df in df.groupby(\"study_id\"):\n            for side in [\"left\", \"right\"]:\n                level_to_preds = defaultdict(list)\n                side_df = sub_df[sub_df[\"side\"] == side]\n    \n                for _, row in side_df.iterrows():\n                    level = row[\"part_id\"]\n                    pred = row[[\"left0\", \"left1\", \"left2\"]].values.astype(np.float32)\n                    level_to_preds[level].append(pred)\n    \n                for level, preds in level_to_preds.items():\n                    preds = np.stack(preds, 0)\n                    pred = np.mean(preds, 0)\n                    pred = torch.softmax(torch.from_numpy(pred), -1).numpy()\n                    row_id = f\"{study_id}_{side}_neural_foraminal_narrowing_{level_to_str[level]}\"\n                    results.append([row_id] + list(pred))\n    \n        result_df = pd.DataFrame(results, columns=[\"row_id\", \"normal_mild\", \"moderate\", \"severe\"])\n        result_df.to_csv(f\"/kaggle/working/yu4u_sagittal1_test_{suffix}_submission.csv\", index=False)\n\n    # sagittal2\n    for suffix in s2_suffixes:\n        results = []\n        csv_path = f\"sagittal2_test_cls_preds_{suffix}.csv\"\n        df = pd.read_csv(csv_path)\n    \n        for study_id, sub_df in df.groupby(\"study_id\"):\n            level_to_preds = defaultdict(list)\n    \n            for _, row in sub_df.iterrows():\n                level = row[\"part_id\"]\n                pred = row[[\"left0\", \"left1\", \"left2\"]].values.astype(np.float32)\n                level_to_preds[level].append(pred)\n    \n            for level, preds in level_to_preds.items():\n                preds = np.stack(preds, 0)\n                pred = np.mean(preds, 0)\n                pred = torch.softmax(torch.from_numpy(pred), -1).numpy()\n                row_id = f\"{study_id}_spinal_canal_stenosis_{level_to_str[level]}\"\n                results.append([row_id] + list(pred))\n    \n        result_df = pd.DataFrame(results, columns=[\"row_id\", \"normal_mild\", \"moderate\", \"severe\"])\n        result_df.to_csv(f\"/kaggle/working/yu4u_sagittal2_test_{suffix}_submission.csv\", index=False)\n\n\nif __name__ == '__main__':\n    main()","metadata":{"execution":{"iopub.status.busy":"2024-10-08T14:04:26.414411Z","iopub.execute_input":"2024-10-08T14:04:26.414807Z","iopub.status.idle":"2024-10-08T14:04:28.551902Z","shell.execute_reply.started":"2024-10-08T14:04:26.414760Z","shell.execute_reply":"2024-10-08T14:04:28.551046Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"! ls /kaggle/working","metadata":{"execution":{"iopub.status.busy":"2024-10-08T14:04:28.553452Z","iopub.execute_input":"2024-10-08T14:04:28.553813Z","iopub.status.idle":"2024-10-08T14:04:29.587668Z","shell.execute_reply.started":"2024-10-08T14:04:28.553770Z","shell.execute_reply":"2024-10-08T14:04:29.586715Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"os.chdir(\"/kaggle/working/\")","metadata":{"execution":{"iopub.status.busy":"2024-10-08T14:04:29.589072Z","iopub.execute_input":"2024-10-08T14:04:29.589377Z","iopub.status.idle":"2024-10-08T14:04:29.594247Z","shell.execute_reply.started":"2024-10-08T14:04:29.589343Z","shell.execute_reply":"2024-10-08T14:04:29.593303Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"! cp -r /kaggle/input/rsna-2024-main-tattaka/rsna-2024-lumbar-spine-degenerative-classification-main .","metadata":{"execution":{"iopub.status.busy":"2024-10-08T14:04:29.595415Z","iopub.execute_input":"2024-10-08T14:04:29.595802Z","iopub.status.idle":"2024-10-08T14:04:32.258190Z","shell.execute_reply.started":"2024-10-08T14:04:29.595757Z","shell.execute_reply":"2024-10-08T14:04:32.257105Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"os.chdir(\"rsna-2024-lumbar-spine-degenerative-classification-main/src/stage2/exp076\")\n! ls ","metadata":{"execution":{"iopub.status.busy":"2024-10-08T14:04:32.259903Z","iopub.execute_input":"2024-10-08T14:04:32.260302Z","iopub.status.idle":"2024-10-08T14:04:33.251274Z","shell.execute_reply.started":"2024-10-08T14:04:32.260262Z","shell.execute_reply":"2024-10-08T14:04:33.250166Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"!python test_predict_keypoint.py --log_root /kaggle/input/rsna2024-weights/ \\\n--dicoms_root /kaggle/input/rsna-2024-lumbar-spine-degenerative-classification/test_images/ \\\n--series_description_df /kaggle/input/rsna-2024-lumbar-spine-degenerative-classification/test_series_descriptions.csv \\\n--out sagittal_keypoints_df.csv","metadata":{"execution":{"iopub.status.busy":"2024-10-08T14:04:33.253046Z","iopub.execute_input":"2024-10-08T14:04:33.253916Z","iopub.status.idle":"2024-10-08T14:07:52.891356Z","shell.execute_reply.started":"2024-10-08T14:04:33.253861Z","shell.execute_reply":"2024-10-08T14:07:52.890319Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"! head sagittal_keypoints_df.csv","metadata":{"execution":{"iopub.status.busy":"2024-10-08T14:07:52.893080Z","iopub.execute_input":"2024-10-08T14:07:52.893490Z","iopub.status.idle":"2024-10-08T14:07:53.894401Z","shell.execute_reply.started":"2024-10-08T14:07:52.893452Z","shell.execute_reply":"2024-10-08T14:07:53.893280Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"!python test_classification_v2.py --log_root /kaggle/input/rsna2024-weights/ \\\n--dicoms_root /kaggle/input/rsna-2024-lumbar-spine-degenerative-classification/test_images/ \\\n--stage2_logdirs caformer_s18_20x1x128x128_x1.0_20x1x128x128_x1.0_5x1x128x128_x1.0_mixup_mask0.1 resnetrs50_20x1x128x128_x1.0_20x1x128x128_x1.0_5x1x128x128_x1.0_mixup_mask0.1 \\\nswinv2_tiny_20x1x128x128_x1.0_20x1x128x128_x1.0_5x1x128x128_x1.0_mixup_mask0.1 \\\n--series_description_df /kaggle/input/rsna-2024-lumbar-spine-degenerative-classification/test_series_descriptions.csv \\\n--sagittal_keypoints_df sagittal_keypoints_df.csv \\\n--axial_keypint_df /kaggle/working/axial_test_keypoint_preds.csv\n\n!cp sagittal_keypoints_df.csv ../exp107/\n\nimport pandas as pd\nimport numpy as np\nlogdirs = [\n    \"caformer_s18_20x1x128x128_x1.0_20x1x128x128_x1.0_5x1x128x128_x1.0_mixup_mask0.1\",\n    \"resnetrs50_20x1x128x128_x1.0_20x1x128x128_x1.0_5x1x128x128_x1.0_mixup_mask0.1\",\n    \"swinv2_tiny_20x1x128x128_x1.0_20x1x128x128_x1.0_5x1x128x128_x1.0_mixup_mask0.1\",\n]\nfor logdir in logdirs:\n    submission = pd.read_csv(f\"submission_{logdir}_fold0.csv\")\n    submission.loc[:, [\"normal_mild\", \"moderate\", \"severe\"]] = np.stack([pd.read_csv(f\"submission_{logdir}_fold{i}.csv\").loc[:, [\"normal_mild\", \"moderate\", \"severe\"]].values for i in range(5)]).mean(0)\n    submission.to_csv(f\"/kaggle/working/tattaka_{logdir}.csv\", index=False)","metadata":{"execution":{"iopub.status.busy":"2024-10-08T14:07:53.896027Z","iopub.execute_input":"2024-10-08T14:07:53.896373Z","iopub.status.idle":"2024-10-08T14:09:55.281814Z","shell.execute_reply.started":"2024-10-08T14:07:53.896336Z","shell.execute_reply":"2024-10-08T14:09:55.280595Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"os.chdir(\"../exp107\")\n\n!python test_classification_v2.py --log_root /kaggle/input/rsna2024-weights/ \\\n--dicoms_root /kaggle/input/rsna-2024-lumbar-spine-degenerative-classification/test_images/ \\\n--stage2_logdirs rdnet_tiny_30x1x128x128_x1.0_30x1x128x128_x1.0_5x1x128x128_x1.0_mixup_mask0.1 maxxvitv2_nano_30x1x128x128_x1.0_30x1x128x128_x1.0_5x1x128x128_x1.0_mixup_mask0.1 \\\n--in_chans_st1 30 --in_chans_st2 30 \\\n--series_description_df /kaggle/input/rsna-2024-lumbar-spine-degenerative-classification/test_series_descriptions.csv \\\n--sagittal_keypoints_df sagittal_keypoints_df.csv \\\n--axial_keypint_df /kaggle/working/axial_test_keypoint_preds.csv\n\nimport pandas as pd\nimport numpy as np\nlogdirs = [\n    \"rdnet_tiny_30x1x128x128_x1.0_30x1x128x128_x1.0_5x1x128x128_x1.0_mixup_mask0.1\",\n    \"maxxvitv2_nano_30x1x128x128_x1.0_30x1x128x128_x1.0_5x1x128x128_x1.0_mixup_mask0.1\",\n]\nfor logdir in logdirs:\n    submission = pd.read_csv(f\"submission_{logdir}_fold0.csv\")\n    submission.loc[:, [\"normal_mild\", \"moderate\", \"severe\"]] = np.stack([pd.read_csv(f\"submission_{logdir}_fold{i}.csv\").loc[:, [\"normal_mild\", \"moderate\", \"severe\"]].values for i in range(5)]).mean(0)\n    submission.to_csv(f\"/kaggle/working/tattaka_{logdir}.csv\", index=False)","metadata":{"execution":{"iopub.status.busy":"2024-10-08T14:09:55.283699Z","iopub.execute_input":"2024-10-08T14:09:55.284674Z","iopub.status.idle":"2024-10-08T14:10:56.539771Z","shell.execute_reply.started":"2024-10-08T14:09:55.284624Z","shell.execute_reply":"2024-10-08T14:10:56.538604Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"os.chdir(\"/kaggle/working/\")","metadata":{"execution":{"iopub.status.busy":"2024-10-08T14:10:56.541515Z","iopub.execute_input":"2024-10-08T14:10:56.541888Z","iopub.status.idle":"2024-10-08T14:10:56.546709Z","shell.execute_reply.started":"2024-10-08T14:10:56.541848Z","shell.execute_reply":"2024-10-08T14:10:56.545752Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from glob import glob\n\nimport pytorch_lightning as pl\nimport torch\nfrom torch import nn","metadata":{"execution":{"iopub.status.busy":"2024-10-08T14:10:56.548046Z","iopub.execute_input":"2024-10-08T14:10:56.548407Z","iopub.status.idle":"2024-10-08T14:10:58.207635Z","shell.execute_reply.started":"2024-10-08T14:10:56.548374Z","shell.execute_reply":"2024-10-08T14:10:58.206865Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"tattaka_submissions = [\n    pd.read_csv(\"tattaka_caformer_s18_20x1x128x128_x1.0_20x1x128x128_x1.0_5x1x128x128_x1.0_mixup_mask0.1.csv\"),\n    pd.read_csv(\"tattaka_resnetrs50_20x1x128x128_x1.0_20x1x128x128_x1.0_5x1x128x128_x1.0_mixup_mask0.1.csv\"),\n    pd.read_csv(\"tattaka_swinv2_tiny_20x1x128x128_x1.0_20x1x128x128_x1.0_5x1x128x128_x1.0_mixup_mask0.1.csv\"),\n    pd.read_csv(\"tattaka_rdnet_tiny_30x1x128x128_x1.0_30x1x128x128_x1.0_5x1x128x128_x1.0_mixup_mask0.1.csv\"),\n    pd.read_csv(\"tattaka_maxxvitv2_nano_30x1x128x128_x1.0_30x1x128x128_x1.0_5x1x128x128_x1.0_mixup_mask0.1.csv\"),\n]\n\nyu4u_submissions_st1 = [\n    pd.read_csv(\"yu4u_sagittal1_test_baseline_submission.csv\"),\n    pd.read_csv(\"yu4u_sagittal1_test_swint_submission.csv\"),\n]\nyu4u_submissions_st2 = [\n    pd.read_csv(\"yu4u_sagittal2_test_baseline_submission.csv\"),\n    pd.read_csv(\"yu4u_sagittal2_test_swint_submission.csv\"),\n    pd.read_csv(\"yu4u_sagittal2_test_axial_submission.csv\"),\n]\nyu4u_submissions_ax = [\n    pd.read_csv(\"yu4u_axial_test_baseline_submission.csv\"),\n    pd.read_csv(\"yu4u_axial_test_swint_submission.csv\"),\n]","metadata":{"execution":{"iopub.status.busy":"2024-10-08T14:10:58.208756Z","iopub.execute_input":"2024-10-08T14:10:58.209231Z","iopub.status.idle":"2024-10-08T14:10:58.235142Z","shell.execute_reply.started":"2024-10-08T14:10:58.209193Z","shell.execute_reply":"2024-10-08T14:10:58.234420Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class MLPBlock(nn.Module):\n    def __init__(self, in_dim, mid_dim, dropout_p):\n        super().__init__()\n        self.linear1 = nn.Linear(in_dim, mid_dim)\n        self.act1 = nn.GELU()\n        self.dropout = nn.Dropout(dropout_p)\n        self.linear2 = nn.Linear(mid_dim, in_dim)\n        self.act2 = nn.GELU()\n\n    def forward(self, x):\n        return x + self.act2(self.linear2(self.dropout(self.act1(self.linear1(x)))))\n\n\nclass StackingModel(nn.Module):\n    def __init__(\n        self,\n        weight_foraminal,\n        weight_spinal,\n        weight_subarticular,\n    ):\n        super().__init__()\n        weight_foraminal = torch.tensor(weight_foraminal)[None, :, None, None].repeat(\n            1, 1, 10, 1\n        )\n        weight_spinal = torch.tensor(weight_spinal)[None, :, None, None].repeat(\n            1, 1, 5, 1\n        )\n        weight_subarticular = torch.tensor(weight_subarticular)[\n            None, :, None, None\n        ].repeat(1, 1, 10, 1)\n        self.register_buffer(\"nm_weight_foraminal\", weight_foraminal)\n        self.register_buffer(\"nm_weight_spinal\", weight_spinal)\n        self.register_buffer(\"nm_weight_subarticular\", weight_subarticular)\n\n        in_chans_scs = self.nm_weight_spinal.shape[1] * 5 * 3\n        self.mlps_scs = nn.Sequential(\n            MLPBlock(in_chans_scs, 512, 0.3),\n            MLPBlock(in_chans_scs, 512, 0.3),\n            MLPBlock(in_chans_scs, 512, 0.3),\n            MLPBlock(in_chans_scs, 512, 0.3),\n            nn.Linear(in_chans_scs, 5 * 3),\n        )\n\n    def forward(self, x_foraminal, x_spinal, x_subarticular):\n        bs = x_foraminal.shape[0]\n        nm_x_foraminal = (x_foraminal * self.nm_weight_foraminal).sum(1)  # (bs, 10, 3)\n        nm_x_spinal = (x_spinal * self.nm_weight_spinal).sum(1)  # (bs, 5, 3)\n        nm_x_subarticular = (x_subarticular * self.nm_weight_subarticular).sum(\n            1\n        )  # (bs, 5, 3)\n        nm_x = torch.log(torch.cat([nm_x_foraminal, nm_x_spinal, nm_x_subarticular], 1))\n\n        x_spinal = self.mlps_scs(x_spinal.reshape(bs, -1)).reshape((bs, 5, 3))\n\n        x = nm_x.clone()\n        x[:, 10:15] += x_spinal\n        return {\"logit\": x.float(), \"logit_debug\": nm_x.float()}\n\n\nclass SevereLoss(nn.Module):\n    \"\"\"\n    For RSNA 2024\n    criterion = SevereLoss()     # you can replace nn.CrossEntropyLoss\n    loss = criterion(y_pred, y)\n    \"\"\"\n    def __init__(self, temperature=1.0):\n        \"\"\"\n        Use max if temperature = 0\n        \"\"\"\n        super().__init__()\n        self.t = temperature\n        assert self.t >= 0\n        self.ce_loss = nn.CrossEntropyLoss(\n            weight=torch.tensor([1.0, 2.0, 4.0], dtype=torch.float), reduction=\"none\"\n        )\n        self.bce_loss = nn.BCELoss(reduction=\"none\")\n        \nclass StackingLightningModel(pl.LightningModule):\n    def __init__(\n        self,\n        weight_foraminal,\n        weight_spinal,\n        weight_subarticular,\n        lr: float = 1e-3,\n        weight_decay: float = 1e-2,\n    ) -> None:\n        super().__init__()\n        self.save_hyperparameters()\n        self.__build_model()\n        self.gt_val = []\n        self.logit_val = []\n\n    def __build_model(\n        self,\n    ):\n        self.model = StackingModel(\n            self.hparams.weight_foraminal,\n            self.hparams.weight_spinal,\n            self.hparams.weight_subarticular,\n        )\n        self.criterion = SevereLoss()\n        \n        \ndef get_condition(full_location: str) -> str:\n    # Given an input like spinal_canal_stenosis_l1_l2 extracts 'spinal'\n    for injury_condition in ['spinal', 'foraminal', 'subarticular']:\n        if injury_condition in full_location:\n            return injury_condition\n    raise ValueError(f'condition not found in {full_location}')\n\n\nsubmission = tattaka_submissions[0].copy()\nsubmission['condition'] = submission['row_id'].apply(get_condition)\n\ntattaka_preds_foraminal = [p[submission.condition == \"foraminal\"].loc[:, [\"normal_mild\", \"moderate\", \"severe\"]].values.reshape(-1, 10, 3) for p in tattaka_submissions]\nyu4u_preds_foraminal = [submission[submission.condition == \"foraminal\"].rename(columns={\"normal_mild\": \"normal_mild_tmp\", \"moderate\": \"moderate_tmp\", \"severe\": \"severe_tmp\"}).merge(ys, on=\"row_id\", how=\"left\").drop([\"normal_mild_tmp\", \"moderate_tmp\", \"severe_tmp\"],axis='columns').fillna(0).loc[:, [\"normal_mild\", \"moderate\", \"severe\"]].values.reshape(-1, 10, 3) for ys in yu4u_submissions_st1]\npreds_foraminal = np.stack(tattaka_preds_foraminal + yu4u_preds_foraminal, 0).transpose((1, 0, 2, 3))\n\ntattaka_preds_spinal = [p[submission.condition == \"spinal\"].loc[:, [\"normal_mild\", \"moderate\", \"severe\"]].values.reshape(-1, 5, 3) for p in tattaka_submissions]\nyu4u_preds_spinal = [submission[submission.condition == \"spinal\"].rename(columns={\"normal_mild\": \"normal_mild_tmp\", \"moderate\": \"moderate_tmp\", \"severe\": \"severe_tmp\"}).merge(ys, on=\"row_id\", how=\"left\").drop([\"normal_mild_tmp\", \"moderate_tmp\", \"severe_tmp\"],axis='columns').fillna(0).loc[:, [\"normal_mild\", \"moderate\", \"severe\"]].values.reshape(-1, 5, 3) for ys in yu4u_submissions_st2]\npreds_spinal = np.stack(tattaka_preds_spinal + yu4u_preds_spinal, 0).transpose((1, 0, 2, 3))\n\ntattaka_preds_subarticular = [p[submission.condition == \"subarticular\"].loc[:, [\"normal_mild\", \"moderate\", \"severe\"]].values.reshape(-1, 10, 3) for p in tattaka_submissions]\nyu4u_preds_subarticular= [submission[submission.condition == \"subarticular\"].rename(columns={\"normal_mild\": \"normal_mild_tmp\", \"moderate\": \"moderate_tmp\", \"severe\": \"severe_tmp\"}).merge(ys, on=\"row_id\", how=\"left\").drop([\"normal_mild_tmp\", \"moderate_tmp\", \"severe_tmp\"],axis='columns').fillna(0).loc[:, [\"normal_mild\", \"moderate\", \"severe\"]].values.reshape(-1, 10, 3) for ys in yu4u_submissions_ax]\npreds_subarticular = np.stack(tattaka_preds_subarticular + yu4u_preds_subarticular, 0).transpose((1, 0, 2, 3))\n\nckpt_paths = glob(f\"/kaggle/input/rsna2024-stacking/stacing_models/**/best_loss.ckpt\", recursive=True)\nprint(ckpt_paths)\nmodels = [StackingLightningModel.load_from_checkpoint(ckpt_path).model.eval() for ckpt_path in ckpt_paths]\nout = np.stack([model(torch.tensor(preds_foraminal).float(), torch.tensor(preds_spinal).float(), torch.tensor(preds_subarticular).float())[\"logit\"].detach().clone().cpu().softmax(-1).numpy() for model in models]).mean(0)\nsubmission.loc[submission.condition == \"foraminal\", [\"normal_mild\", \"moderate\", \"severe\"]] = out[:, :10].reshape(-1, 3)\nsubmission.loc[submission.condition == \"spinal\", [\"normal_mild\", \"moderate\", \"severe\"]] = out[:, 10:15].reshape(-1, 3)\nsubmission.loc[submission.condition == \"subarticular\", [\"normal_mild\", \"moderate\", \"severe\"]] = out[:, 15:25].reshape(-1, 3)\nsubmission = submission.sort_values(\"row_id\", ascending=True).reset_index(drop=True).drop(columns=[\"condition\"], inplace=False).copy()\nsubmission.to_csv(\"tattaka_stacking_scs.csv\", index=False)\n# submission.to_csv(\"submission.csv\", index=False)\nsubmission","metadata":{"execution":{"iopub.status.busy":"2024-10-08T14:10:58.236335Z","iopub.execute_input":"2024-10-08T14:10:58.236619Z","iopub.status.idle":"2024-10-08T14:10:59.063770Z","shell.execute_reply.started":"2024-10-08T14:10:58.236587Z","shell.execute_reply":"2024-10-08T14:10:59.062797Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class MLPBlock(nn.Module):\n    def __init__(self, in_dim, mid_dim, dropout_p):\n        super().__init__()\n        self.linear1 = nn.Linear(in_dim, mid_dim)\n        self.act1 = nn.GELU()\n        self.dropout = nn.Dropout(dropout_p)\n        self.linear2 = nn.Linear(mid_dim, in_dim)\n        self.act2 = nn.GELU()\n\n    def forward(self, x):\n        return x + self.act2(self.linear2(self.dropout(self.act1(self.linear1(x)))))\n\n\nclass StackingModel(nn.Module):\n    def __init__(\n        self,\n        weight_foraminal,\n        weight_spinal,\n        weight_subarticular,\n    ):\n        super().__init__()\n        weight_foraminal = torch.tensor(weight_foraminal)[None, :, None, None].repeat(\n            1, 1, 10, 1\n        )\n        weight_spinal = torch.tensor(weight_spinal)[None, :, None, None].repeat(\n            1, 1, 5, 1\n        )\n        weight_subarticular = torch.tensor(weight_subarticular)[\n            None, :, None, None\n        ].repeat(1, 1, 10, 1)\n        self.register_buffer(\"nm_weight_foraminal\", weight_foraminal)\n        self.register_buffer(\"nm_weight_spinal\", weight_spinal)\n        self.register_buffer(\"nm_weight_subarticular\", weight_subarticular)\n\n        in_chans_nfn = self.nm_weight_foraminal.shape[1] * 10 * 3 + self.nm_weight_spinal.shape[1] * 5 * 3 + self.nm_weight_subarticular.shape[1] * 10 * 3\n        self.mlps_nfn = nn.Sequential(\n            MLPBlock(in_chans_nfn, 512, 0.3),\n            nn.Linear(in_chans_nfn, 10 * 3)\n        )\n\n    def forward(self, x_foraminal, x_spinal, x_subarticular):\n        bs = x_foraminal.shape[0]\n        nm_x_foraminal = (x_foraminal * self.nm_weight_foraminal).sum(1) # (bs, 10, 3)\n        nm_x_spinal = (x_spinal * self.nm_weight_spinal).sum(1) # (bs, 5, 3)\n        nm_x_subarticular = (x_subarticular * self.nm_weight_subarticular).sum(1) # (bs, 5, 3)\n        nm_x = torch.log(torch.cat([nm_x_foraminal, nm_x_spinal, nm_x_subarticular], 1))\n        \n        x_foraminal = self.mlps_nfn(torch.cat([x_foraminal.reshape(bs, -1), x_spinal.reshape(bs, -1), x_subarticular.reshape(bs, -1)], -1)).reshape((bs, 10, 3))\n                \n        x = nm_x.clone()\n        x[:, :10] += x_foraminal\n        return {\"logit\": x.float(), \"logit_debug\": nm_x.float()}\n\n\nclass SevereLoss(nn.Module):\n    \"\"\"\n    For RSNA 2024\n    criterion = SevereLoss()     # you can replace nn.CrossEntropyLoss\n    loss = criterion(y_pred, y)\n    \"\"\"\n    def __init__(self, temperature=1.0):\n        \"\"\"\n        Use max if temperature = 0\n        \"\"\"\n        super().__init__()\n        self.t = temperature\n        assert self.t >= 0\n        self.ce_loss = nn.CrossEntropyLoss(\n            weight=torch.tensor([1.0, 2.0, 4.0], dtype=torch.float), reduction=\"none\"\n        )\n        self.bce_loss = nn.BCELoss(reduction=\"none\")\n        \nclass StackingLightningModel(pl.LightningModule):\n    def __init__(\n        self,\n        weight_foraminal,\n        weight_spinal,\n        weight_subarticular,\n        lr: float = 1e-3,\n        weight_decay: float = 1e-2,\n    ) -> None:\n        super().__init__()\n        self.save_hyperparameters()\n        self.__build_model()\n        self.gt_val = []\n        self.logit_val = []\n\n    def __build_model(\n        self,\n    ):\n        self.model = StackingModel(\n            self.hparams.weight_foraminal,\n            self.hparams.weight_spinal,\n            self.hparams.weight_subarticular,\n        )\n        self.criterion = SevereLoss()\n        \n        \ndef get_condition(full_location: str) -> str:\n    # Given an input like spinal_canal_stenosis_l1_l2 extracts 'spinal'\n    for injury_condition in ['spinal', 'foraminal', 'subarticular']:\n        if injury_condition in full_location:\n            return injury_condition\n    raise ValueError(f'condition not found in {full_location}')\n\n\nsubmission = tattaka_submissions[0].copy()\nsubmission['condition'] = submission['row_id'].apply(get_condition)\n\ntattaka_preds_foraminal = [p[submission.condition == \"foraminal\"].loc[:, [\"normal_mild\", \"moderate\", \"severe\"]].values.reshape(-1, 10, 3) for p in tattaka_submissions]\nyu4u_preds_foraminal = [submission[submission.condition == \"foraminal\"].rename(columns={\"normal_mild\": \"normal_mild_tmp\", \"moderate\": \"moderate_tmp\", \"severe\": \"severe_tmp\"}).merge(ys, on=\"row_id\", how=\"left\").drop([\"normal_mild_tmp\", \"moderate_tmp\", \"severe_tmp\"],axis='columns').fillna(0).loc[:, [\"normal_mild\", \"moderate\", \"severe\"]].values.reshape(-1, 10, 3) for ys in yu4u_submissions_st1]\npreds_foraminal = np.stack(tattaka_preds_foraminal + yu4u_preds_foraminal, 0).transpose((1, 0, 2, 3))\n\ntattaka_preds_spinal = [p[submission.condition == \"spinal\"].loc[:, [\"normal_mild\", \"moderate\", \"severe\"]].values.reshape(-1, 5, 3) for p in tattaka_submissions]\nyu4u_preds_spinal = [submission[submission.condition == \"spinal\"].rename(columns={\"normal_mild\": \"normal_mild_tmp\", \"moderate\": \"moderate_tmp\", \"severe\": \"severe_tmp\"}).merge(ys, on=\"row_id\", how=\"left\").drop([\"normal_mild_tmp\", \"moderate_tmp\", \"severe_tmp\"],axis='columns').fillna(0).loc[:, [\"normal_mild\", \"moderate\", \"severe\"]].values.reshape(-1, 5, 3) for ys in yu4u_submissions_st2]\npreds_spinal = np.stack(tattaka_preds_spinal + yu4u_preds_spinal, 0).transpose((1, 0, 2, 3))\n\ntattaka_preds_subarticular = [p[submission.condition == \"subarticular\"].loc[:, [\"normal_mild\", \"moderate\", \"severe\"]].values.reshape(-1, 10, 3) for p in tattaka_submissions]\nyu4u_preds_subarticular= [submission[submission.condition == \"subarticular\"].rename(columns={\"normal_mild\": \"normal_mild_tmp\", \"moderate\": \"moderate_tmp\", \"severe\": \"severe_tmp\"}).merge(ys, on=\"row_id\", how=\"left\").drop([\"normal_mild_tmp\", \"moderate_tmp\", \"severe_tmp\"],axis='columns').fillna(0).loc[:, [\"normal_mild\", \"moderate\", \"severe\"]].values.reshape(-1, 10, 3) for ys in yu4u_submissions_ax]\npreds_subarticular = np.stack(tattaka_preds_subarticular + yu4u_preds_subarticular, 0).transpose((1, 0, 2, 3))\n\nckpt_paths = glob(f\"/kaggle/input/rsna2024-stacking-nfn/stacing_models/**/best_loss.ckpt\", recursive=True)\nprint(ckpt_paths)\nmodels = [StackingLightningModel.load_from_checkpoint(ckpt_path).model.eval() for ckpt_path in ckpt_paths]\nout = np.stack([model(torch.tensor(preds_foraminal).float(), torch.tensor(preds_spinal).float(), torch.tensor(preds_subarticular).float())[\"logit\"].detach().clone().cpu().softmax(-1).numpy() for model in models]).mean(0)\nsubmission.loc[submission.condition == \"foraminal\", [\"normal_mild\", \"moderate\", \"severe\"]] = out[:, :10].reshape(-1, 3)\nsubmission.loc[submission.condition == \"spinal\", [\"normal_mild\", \"moderate\", \"severe\"]] = out[:, 10:15].reshape(-1, 3)\nsubmission.loc[submission.condition == \"subarticular\", [\"normal_mild\", \"moderate\", \"severe\"]] = out[:, 15:25].reshape(-1, 3)\nsubmission = submission.sort_values(\"row_id\", ascending=True).reset_index(drop=True).drop(columns=[\"condition\"], inplace=False).copy()\nsubmission.to_csv(\"tattaka_stacking_nfn.csv\", index=False)\n# submission.to_csv(\"submission.csv\", index=False)\nsubmission","metadata":{"execution":{"iopub.status.busy":"2024-10-08T14:10:59.065400Z","iopub.execute_input":"2024-10-08T14:10:59.065877Z","iopub.status.idle":"2024-10-08T14:10:59.783439Z","shell.execute_reply.started":"2024-10-08T14:10:59.065827Z","shell.execute_reply":"2024-10-08T14:10:59.782391Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class MLPBlock(nn.Module):\n    def __init__(self, in_dim, mid_dim, dropout_p):\n        super().__init__()\n        self.linear1 = nn.Linear(in_dim, mid_dim)\n        self.act1 = nn.GELU()\n        self.dropout = nn.Dropout(dropout_p)\n        self.linear2 = nn.Linear(mid_dim, in_dim)\n        self.act2 = nn.GELU()\n\n    def forward(self, x):\n        return x + self.act2(self.linear2(self.dropout(self.act1(self.linear1(x)))))\n\n\nclass StackingModel(nn.Module):\n    def __init__(\n        self,\n        weight_foraminal,\n        weight_spinal,\n        weight_subarticular,\n    ):\n        super().__init__()\n        weight_foraminal = torch.tensor(weight_foraminal)[None, :, None, None].repeat(\n            1, 1, 10, 1\n        )\n        weight_spinal = torch.tensor(weight_spinal)[None, :, None, None].repeat(\n            1, 1, 5, 1\n        )\n        weight_subarticular = torch.tensor(weight_subarticular)[\n            None, :, None, None\n        ].repeat(1, 1, 10, 1)\n        self.register_buffer(\"nm_weight_foraminal\", weight_foraminal)\n        self.register_buffer(\"nm_weight_spinal\", weight_spinal)\n        self.register_buffer(\"nm_weight_subarticular\", weight_subarticular)\n\n        in_chans_ss = self.nm_weight_subarticular.shape[1] * 10 * 3\n        self.mlps_ss = nn.Sequential(\n            MLPBlock(in_chans_ss, 512, 0.3),\n            nn.Linear(in_chans_ss, 10 * 3)\n        )\n\n    def forward(self, x_foraminal, x_spinal, x_subarticular):\n        bs = x_foraminal.shape[0]\n        nm_x_foraminal = (x_foraminal * self.nm_weight_foraminal).sum(1) # (bs, 10, 3)\n        nm_x_spinal = (x_spinal * self.nm_weight_spinal).sum(1) # (bs, 5, 3)\n        nm_x_subarticular = (x_subarticular * self.nm_weight_subarticular).sum(1) # (bs, 5, 3)\n        nm_x = torch.log(torch.cat([nm_x_foraminal, nm_x_spinal, nm_x_subarticular], 1))\n        \n        x_subarticular = self.mlps_ss(x_subarticular.reshape(bs, -1)).reshape((bs, 10, 3))\n                \n        x = nm_x.clone()\n        x[:, 15:] += x_subarticular\n        return {\"logit\": x.float(), \"logit_debug\": nm_x.float()}\n\n\nclass SevereLoss(nn.Module):\n    \"\"\"\n    For RSNA 2024\n    criterion = SevereLoss()     # you can replace nn.CrossEntropyLoss\n    loss = criterion(y_pred, y)\n    \"\"\"\n    def __init__(self, temperature=1.0):\n        \"\"\"\n        Use max if temperature = 0\n        \"\"\"\n        super().__init__()\n        self.t = temperature\n        assert self.t >= 0\n        self.ce_loss = nn.CrossEntropyLoss(\n            weight=torch.tensor([1.0, 2.0, 4.0], dtype=torch.float), reduction=\"none\"\n        )\n        self.bce_loss = nn.BCELoss(reduction=\"none\")\n        \nclass StackingLightningModel(pl.LightningModule):\n    def __init__(\n        self,\n        weight_foraminal,\n        weight_spinal,\n        weight_subarticular,\n        lr: float = 1e-3,\n        weight_decay: float = 1e-2,\n    ) -> None:\n        super().__init__()\n        self.save_hyperparameters()\n        self.__build_model()\n        self.gt_val = []\n        self.logit_val = []\n\n    def __build_model(\n        self,\n    ):\n        self.model = StackingModel(\n            self.hparams.weight_foraminal,\n            self.hparams.weight_spinal,\n            self.hparams.weight_subarticular,\n        )\n        self.criterion = SevereLoss()\n        \n        \ndef get_condition(full_location: str) -> str:\n    # Given an input like spinal_canal_stenosis_l1_l2 extracts 'spinal'\n    for injury_condition in ['spinal', 'foraminal', 'subarticular']:\n        if injury_condition in full_location:\n            return injury_condition\n    raise ValueError(f'condition not found in {full_location}')\n\n\nsubmission = tattaka_submissions[0].copy()\nsubmission['condition'] = submission['row_id'].apply(get_condition)\n\ntattaka_preds_foraminal = [p[submission.condition == \"foraminal\"].loc[:, [\"normal_mild\", \"moderate\", \"severe\"]].values.reshape(-1, 10, 3) for p in tattaka_submissions]\nyu4u_preds_foraminal = [submission[submission.condition == \"foraminal\"].rename(columns={\"normal_mild\": \"normal_mild_tmp\", \"moderate\": \"moderate_tmp\", \"severe\": \"severe_tmp\"}).merge(ys, on=\"row_id\", how=\"left\").drop([\"normal_mild_tmp\", \"moderate_tmp\", \"severe_tmp\"],axis='columns').fillna(0).loc[:, [\"normal_mild\", \"moderate\", \"severe\"]].values.reshape(-1, 10, 3) for ys in yu4u_submissions_st1]\npreds_foraminal = np.stack(tattaka_preds_foraminal + yu4u_preds_foraminal, 0).transpose((1, 0, 2, 3))\n\ntattaka_preds_spinal = [p[submission.condition == \"spinal\"].loc[:, [\"normal_mild\", \"moderate\", \"severe\"]].values.reshape(-1, 5, 3) for p in tattaka_submissions]\nyu4u_preds_spinal = [submission[submission.condition == \"spinal\"].rename(columns={\"normal_mild\": \"normal_mild_tmp\", \"moderate\": \"moderate_tmp\", \"severe\": \"severe_tmp\"}).merge(ys, on=\"row_id\", how=\"left\").drop([\"normal_mild_tmp\", \"moderate_tmp\", \"severe_tmp\"],axis='columns').fillna(0).loc[:, [\"normal_mild\", \"moderate\", \"severe\"]].values.reshape(-1, 5, 3) for ys in yu4u_submissions_st2]\npreds_spinal = np.stack(tattaka_preds_spinal + yu4u_preds_spinal, 0).transpose((1, 0, 2, 3))\n\ntattaka_preds_subarticular = [p[submission.condition == \"subarticular\"].loc[:, [\"normal_mild\", \"moderate\", \"severe\"]].values.reshape(-1, 10, 3) for p in tattaka_submissions]\nyu4u_preds_subarticular= [submission[submission.condition == \"subarticular\"].rename(columns={\"normal_mild\": \"normal_mild_tmp\", \"moderate\": \"moderate_tmp\", \"severe\": \"severe_tmp\"}).merge(ys, on=\"row_id\", how=\"left\").drop([\"normal_mild_tmp\", \"moderate_tmp\", \"severe_tmp\"],axis='columns').fillna(0).loc[:, [\"normal_mild\", \"moderate\", \"severe\"]].values.reshape(-1, 10, 3) for ys in yu4u_submissions_ax]\npreds_subarticular = np.stack(tattaka_preds_subarticular + yu4u_preds_subarticular, 0).transpose((1, 0, 2, 3))\n\nckpt_paths = glob(f\"/kaggle/input/rsna2024-stacking-ss/stacing_models/**/best_loss.ckpt\", recursive=True)\nprint(ckpt_paths)\nmodels = [StackingLightningModel.load_from_checkpoint(ckpt_path).model.eval() for ckpt_path in ckpt_paths]\nout = np.stack([model(torch.tensor(preds_foraminal).float(), torch.tensor(preds_spinal).float(), torch.tensor(preds_subarticular).float())[\"logit\"].detach().clone().cpu().softmax(-1).numpy() for model in models]).mean(0)\nsubmission.loc[submission.condition == \"foraminal\", [\"normal_mild\", \"moderate\", \"severe\"]] = out[:, :10].reshape(-1, 3)\nsubmission.loc[submission.condition == \"spinal\", [\"normal_mild\", \"moderate\", \"severe\"]] = out[:, 10:15].reshape(-1, 3)\nsubmission.loc[submission.condition == \"subarticular\", [\"normal_mild\", \"moderate\", \"severe\"]] = out[:, 15:25].reshape(-1, 3)\nsubmission = submission.sort_values(\"row_id\", ascending=True).reset_index(drop=True).drop(columns=[\"condition\"], inplace=False).copy()\nsubmission.to_csv(\"tattaka_stacking_ss.csv\", index=False)\n# submission.to_csv(\"submission.csv\", index=False)\nsubmission","metadata":{"execution":{"iopub.status.busy":"2024-10-08T14:10:59.786185Z","iopub.execute_input":"2024-10-08T14:10:59.786476Z","iopub.status.idle":"2024-10-08T14:11:00.274423Z","shell.execute_reply.started":"2024-10-08T14:10:59.786445Z","shell.execute_reply":"2024-10-08T14:11:00.273415Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"os.chdir(\"/kaggle/tmp/rsna2024-main\")","metadata":{"execution":{"iopub.status.busy":"2024-10-08T14:11:00.275883Z","iopub.execute_input":"2024-10-08T14:11:00.276357Z","iopub.status.idle":"2024-10-08T14:11:00.280891Z","shell.execute_reply.started":"2024-10-08T14:11:00.276311Z","shell.execute_reply":"2024-10-08T14:11:00.279477Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"! python 74_create_sep_stacking_dataset.py --mode test","metadata":{"execution":{"iopub.status.busy":"2024-10-08T14:11:00.282449Z","iopub.execute_input":"2024-10-08T14:11:00.282990Z","iopub.status.idle":"2024-10-08T14:11:02.113316Z","shell.execute_reply.started":"2024-10-08T14:11:00.282948Z","shell.execute_reply":"2024-10-08T14:11:02.112154Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"! python 82_test_lightgbm.py --checkpoint_dir /kaggle/input/rsna2024-lightgbm-models","metadata":{"execution":{"iopub.status.busy":"2024-10-08T14:11:02.114898Z","iopub.execute_input":"2024-10-08T14:11:02.115310Z","iopub.status.idle":"2024-10-08T14:11:07.869476Z","shell.execute_reply.started":"2024-10-08T14:11:02.115272Z","shell.execute_reply":"2024-10-08T14:11:07.868514Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"! python 84_test_xgboost.py --checkpoint_dir /kaggle/input/rsna2024-lightgbm-models","metadata":{"execution":{"iopub.status.busy":"2024-10-08T14:12:54.872802Z","iopub.execute_input":"2024-10-08T14:12:54.873207Z","iopub.status.idle":"2024-10-08T14:13:20.391510Z","shell.execute_reply.started":"2024-10-08T14:12:54.873169Z","shell.execute_reply":"2024-10-08T14:13:20.390410Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"! cp yu4u_*_test_stacking_submission.csv /kaggle/working/","metadata":{"execution":{"iopub.status.busy":"2024-10-08T14:15:30.126074Z","iopub.execute_input":"2024-10-08T14:15:30.127051Z","iopub.status.idle":"2024-10-08T14:15:31.123478Z","shell.execute_reply.started":"2024-10-08T14:15:30.127002Z","shell.execute_reply":"2024-10-08T14:15:31.122416Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"os.chdir(\"/kaggle/working/\")","metadata":{"execution":{"iopub.status.busy":"2024-10-08T14:15:31.125960Z","iopub.execute_input":"2024-10-08T14:15:31.126409Z","iopub.status.idle":"2024-10-08T14:15:31.131425Z","shell.execute_reply.started":"2024-10-08T14:15:31.126360Z","shell.execute_reply":"2024-10-08T14:15:31.130514Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"! ls","metadata":{"execution":{"iopub.status.busy":"2024-10-08T14:15:31.132682Z","iopub.execute_input":"2024-10-08T14:15:31.132982Z","iopub.status.idle":"2024-10-08T14:15:32.133480Z","shell.execute_reply.started":"2024-10-08T14:15:31.132951Z","shell.execute_reply":"2024-10-08T14:15:32.132492Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import pandas as pd\n\nlevel_to_str = {0: \"l1_l2\", 1: \"l2_l3\", 2: \"l3_l4\", 3: \"l4_l5\", 4: \"l5_s1\"}\n\n\ndef main():\n    mode = \"test\"\n    prefix = \"train\" if mode == \"val\" else \"test\"\n    series_df = pd.read_csv(f\"/kaggle/input/rsna-2024-lumbar-spine-degenerative-classification/{prefix}_series_descriptions.csv\")\n\n    # create row_ids\n    condition_to_row_ids = dict()\n\n    conditions = [\n        \"left_neural_foraminal_narrowing\",\n        \"left_subarticular_stenosis\",\n        \"right_neural_foraminal_narrowing\",\n        \"right_subarticular_stenosis\",\n        \"spinal_canal_stenosis\",\n    ]\n\n    levels = [\"l1_l2\", \"l2_l3\", \"l3_l4\", \"l4_l5\", \"l5_s1\"]\n\n    for condition in conditions:\n        row_ids = []\n        row_study_ids = []\n        row_levels = []\n\n        for study_id in series_df[\"study_id\"].unique():\n            for level in levels:\n                row_id = f\"{study_id}_{condition}_{level}\"\n                row_ids.append(row_id)\n                row_study_ids.append(study_id)\n                row_levels.append(level)\n\n        condition_to_row_ids[condition] = row_ids\n    \n    # subarticular_stenosis\n    axials = [\n        (0.33562216, \"yu4u_subarticular_stenosis_test_stacking_submission.csv\"),\n        (0.29930299, \"yu4u_subarticular_stenosis_xgboost_test_stacking_submission.csv\"),\n        (0.36507485, \"tattaka_stacking_ss.csv\"),\n    ]\n    print(sum([w[0] for w in axials]))\n    \n\n    # neural_foraminal_narrowing\n    s1s = [\n        (0.44973484, \"yu4u_neural_foraminal_narrowing_test_stacking_submission.csv\"),\n        (0.26700175, \"yu4u_neural_foraminal_narrowing_xgboost_test_stacking_submission.csv\"),\n        (0.28326341, \"tattaka_stacking_nfn.csv\"),\n    ]\n    print(sum([w[0] for w in s1s]))\n         \n    # spinal_canal_stenosis\n    s2s = [\n        (0.32523771, \"yu4u_spinal_canal_stenosis_test_stacking_submission.csv\"),\n        (-0.0240563, \"yu4u_spinal_canal_stenosis_xgboost_test_stacking_submission.csv\"),\n        (0.69881858, \"tattaka_stacking_scs.csv\"),\n    ]\n    print(sum([w[0] for w in s2s]))\n\n    condition_to_csv_filenames = {\n        \"left_neural_foraminal_narrowing\": s1s,\n        \"right_neural_foraminal_narrowing\": s1s,\n        \"left_subarticular_stenosis\": axials,\n        \"right_subarticular_stenosis\": axials,\n        \"spinal_canal_stenosis\": s2s,\n    }\n\n    condition_dfs = []\n\n    for condition, row_ids in condition_to_row_ids.items():\n        condition_df = pd.DataFrame(row_ids, columns=[\"row_id\"])\n        condition_df[[\"normal_mild\", \"moderate\", \"severe\"]] = 1e-5\n        csv_filenames = condition_to_csv_filenames[condition]\n\n        for w, csv_filename in csv_filenames:\n            df = pd.read_csv(csv_filename)\n            tmp_df = pd.DataFrame(row_ids, columns=[\"row_id\"])\n            tmp_df = tmp_df.merge(df, on=\"row_id\", how=\"left\")\n            tmp_df = tmp_df.fillna(0)\n            condition_df[[\"normal_mild\", \"moderate\", \"severe\"]] += w * tmp_df[[\"normal_mild\", \"moderate\", \"severe\"]]\n\n        condition_df[[\"normal_mild\", \"moderate\", \"severe\"]] /= condition_df[[\"normal_mild\", \"moderate\", \"severe\"]].values.sum(1, keepdims=True)\n        condition_dfs.append(condition_df)\n\n    submission_df = pd.concat(condition_dfs, axis=0)\n    submission_df = submission_df.sort_values(\"row_id\", ascending=True)\n    submission_df.to_csv(f\"submission.csv\", index=False)\n\n\nif __name__ == '__main__':\n    main()\n","metadata":{"execution":{"iopub.status.busy":"2024-10-08T14:23:46.725104Z","iopub.execute_input":"2024-10-08T14:23:46.725647Z","iopub.status.idle":"2024-10-08T14:23:47.526103Z","shell.execute_reply.started":"2024-10-08T14:23:46.725593Z","shell.execute_reply":"2024-10-08T14:23:47.524685Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"! head submission.csv","metadata":{"execution":{"iopub.status.busy":"2024-10-08T14:22:47.021021Z","iopub.execute_input":"2024-10-08T14:22:47.021860Z","iopub.status.idle":"2024-10-08T14:22:48.014342Z","shell.execute_reply.started":"2024-10-08T14:22:47.021816Z","shell.execute_reply":"2024-10-08T14:22:48.013133Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"! rm yu4u*.csv\n! rm tattaka*.csv\n! rm axial_test_keypoint_preds.csv\n! rm -rf rsna-2024-lumbar-spine-degenerative-classification-main\n! rm -rf /kaggle/tmp","metadata":{"execution":{"iopub.status.busy":"2024-10-08T14:22:52.865783Z","iopub.execute_input":"2024-10-08T14:22:52.866759Z","iopub.status.idle":"2024-10-08T14:22:57.919887Z","shell.execute_reply.started":"2024-10-08T14:22:52.866711Z","shell.execute_reply":"2024-10-08T14:22:57.918500Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"! ls","metadata":{"execution":{"iopub.status.busy":"2024-10-08T14:22:57.922576Z","iopub.execute_input":"2024-10-08T14:22:57.923039Z","iopub.status.idle":"2024-10-08T14:22:58.933786Z","shell.execute_reply.started":"2024-10-08T14:22:57.922970Z","shell.execute_reply":"2024-10-08T14:22:58.932762Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]}]}