{"metadata":{"kaggle":{"accelerator":"none","dataSources":[{"sourceId":71549,"databundleVersionId":8561470,"sourceType":"competition"},{"sourceId":9071670,"sourceType":"datasetVersion","datasetId":5471909},{"sourceId":116992,"sourceType":"modelInstanceVersion","modelInstanceId":98349,"modelId":122526},{"sourceId":116996,"sourceType":"modelInstanceVersion","modelInstanceId":98352,"modelId":122529},{"sourceId":116998,"sourceType":"modelInstanceVersion","modelInstanceId":98354,"modelId":122531},{"sourceId":119391,"sourceType":"modelInstanceVersion","isSourceIdPinned":true,"modelInstanceId":100401,"modelId":124567},{"sourceId":119438,"sourceType":"modelInstanceVersion","isSourceIdPinned":true,"modelInstanceId":100447,"modelId":124616},{"sourceId":120097,"sourceType":"modelInstanceVersion","isSourceIdPinned":true,"modelInstanceId":101014,"modelId":125186},{"sourceId":120800,"sourceType":"modelInstanceVersion","isSourceIdPinned":true,"modelInstanceId":101621,"modelId":125821},{"sourceId":122325,"sourceType":"modelInstanceVersion","isSourceIdPinned":true,"modelInstanceId":102932,"modelId":127166},{"sourceId":122337,"sourceType":"modelInstanceVersion","isSourceIdPinned":true,"modelInstanceId":102941,"modelId":127175},{"sourceId":122588,"sourceType":"modelInstanceVersion","isSourceIdPinned":true,"modelInstanceId":103164,"modelId":127395}],"dockerImageVersionId":30761,"isInternetEnabled":false,"language":"python","sourceType":"notebook","isGpuEnabled":false},"kernelspec":{"name":"python3","display_name":"Python 3","language":"python"},"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"}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"import pandas as pd\nimport numpy as np","metadata":{"execution":{"iopub.status.busy":"2024-09-28T09:39:05.218588Z","iopub.execute_input":"2024-09-28T09:39:05.218967Z","iopub.status.idle":"2024-09-28T09:39:05.658720Z","shell.execute_reply.started":"2024-09-28T09:39:05.218921Z","shell.execute_reply":"2024-09-28T09:39:05.657527Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"data_dir = '/kaggle/input/rsna-2024-lumbar-spine-degenerative-classification'\n#data_dir = '/kaggle/input/rsna-lsdc-2024-submission-debug-dataset/debug'\ntest = pd.read_csv(f'{data_dir}/test_series_descriptions.csv')\n#test = test.head(9)\n#test = test.head(3150)\n#test","metadata":{"execution":{"iopub.status.busy":"2024-09-28T09:39:05.660896Z","iopub.execute_input":"2024-09-28T09:39:05.661400Z","iopub.status.idle":"2024-09-28T09:39:05.685575Z","shell.execute_reply.started":"2024-09-28T09:39:05.661360Z","shell.execute_reply":"2024-09-28T09:39:05.684286Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"test.head()","metadata":{"execution":{"iopub.status.busy":"2024-09-28T09:39:05.687776Z","iopub.execute_input":"2024-09-28T09:39:05.688306Z","iopub.status.idle":"2024-09-28T09:39:05.712421Z","shell.execute_reply.started":"2024-09-28T09:39:05.688228Z","shell.execute_reply":"2024-09-28T09:39:05.711052Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import os\nimport glob\nimport random\nimport math\n\nimport pandas as pd\nimport numpy as np\nimport matplotlib.pyplot as plt\nimport matplotlib.gridspec as gridspec\nfrom tqdm import tqdm\nfrom types import SimpleNamespace\nimport albumentations as A\nimport cv2\n\nimport torch\nimport timm\nimport pydicom\n\ndef set_seed(seed=1234):\n    random.seed(seed)\n    os.environ[\"PYTHONHASHSEED\"] = str(seed)\n    np.random.seed(seed)\n    torch.manual_seed(seed)\n    torch.cuda.manual_seed(seed)\n    torch.backends.cudnn.deterministic = False\n    torch.backends.cudnn.benchmark = True","metadata":{"execution":{"iopub.status.busy":"2024-09-28T09:39:05.715641Z","iopub.execute_input":"2024-09-28T09:39:05.716161Z","iopub.status.idle":"2024-09-28T09:39:34.363863Z","shell.execute_reply.started":"2024-09-28T09:39:05.716106Z","shell.execute_reply":"2024-09-28T09:39:34.362562Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"study_ids = list(test['study_id'].unique())\n#study_ids = list(test['series_id'].unique())\n\n#study_ids","metadata":{"execution":{"iopub.status.busy":"2024-09-28T09:39:34.366080Z","iopub.execute_input":"2024-09-28T09:39:34.366465Z","iopub.status.idle":"2024-09-28T09:39:34.376015Z","shell.execute_reply.started":"2024-09-28T09:39:34.366424Z","shell.execute_reply":"2024-09-28T09:39:34.374325Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"len(study_ids)","metadata":{"execution":{"iopub.status.busy":"2024-09-28T09:39:34.377456Z","iopub.execute_input":"2024-09-28T09:39:34.377876Z","iopub.status.idle":"2024-09-28T09:39:34.389731Z","shell.execute_reply.started":"2024-09-28T09:39:34.377837Z","shell.execute_reply":"2024-09-28T09:39:34.388449Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"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\nLEVELS = [\n    'l1_l2',\n    'l2_l3',\n    'l3_l4',\n    'l4_l5',\n    'l5_s1',\n]\n\nLABELS = ['normal_mild', 'moderate', 'severe']","metadata":{"execution":{"iopub.status.busy":"2024-09-28T09:39:34.391011Z","iopub.execute_input":"2024-09-28T09:39:34.391448Z","iopub.status.idle":"2024-09-28T09:39:34.400809Z","shell.execute_reply.started":"2024-09-28T09:39:34.391408Z","shell.execute_reply":"2024-09-28T09:39:34.399647Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"row_names = []\n#i=0\nfor i in range(len(study_ids)):\n    for cond in CONDITIONS:\n        for level in LEVELS:\n            row_names.append(str(study_ids[i]) + '_' + cond + '_' + level)\n\n","metadata":{"execution":{"iopub.status.busy":"2024-09-28T09:39:34.402721Z","iopub.execute_input":"2024-09-28T09:39:34.403610Z","iopub.status.idle":"2024-09-28T09:39:34.413658Z","shell.execute_reply.started":"2024-09-28T09:39:34.403553Z","shell.execute_reply":"2024-09-28T09:39:34.412295Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print(len(row_names))\n#row_names","metadata":{"execution":{"iopub.status.busy":"2024-09-28T09:39:34.415354Z","iopub.execute_input":"2024-09-28T09:39:34.416709Z","iopub.status.idle":"2024-09-28T09:39:34.426935Z","shell.execute_reply.started":"2024-09-28T09:39:34.416646Z","shell.execute_reply":"2024-09-28T09:39:34.425717Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"\ny_preds = np.ones((len(row_names), 3)) * 0.33\n#y_preds","metadata":{"execution":{"iopub.status.busy":"2024-09-28T09:39:34.432059Z","iopub.execute_input":"2024-09-28T09:39:34.432790Z","iopub.status.idle":"2024-09-28T09:39:34.439446Z","shell.execute_reply.started":"2024-09-28T09:39:34.432735Z","shell.execute_reply":"2024-09-28T09:39:34.438125Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"sub = pd.DataFrame()\nsub['row_id'] = row_names\nsub[LABELS] = y_preds","metadata":{"execution":{"iopub.status.busy":"2024-09-28T09:39:34.441709Z","iopub.execute_input":"2024-09-28T09:39:34.442661Z","iopub.status.idle":"2024-09-28T09:39:34.454960Z","shell.execute_reply.started":"2024-09-28T09:39:34.442606Z","shell.execute_reply":"2024-09-28T09:39:34.453766Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"sub.shape","metadata":{"execution":{"iopub.status.busy":"2024-09-28T09:39:34.457675Z","iopub.execute_input":"2024-09-28T09:39:34.458524Z","iopub.status.idle":"2024-09-28T09:39:34.469353Z","shell.execute_reply.started":"2024-09-28T09:39:34.458466Z","shell.execute_reply":"2024-09-28T09:39:34.468047Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Config\ncfg= SimpleNamespace(\n    img_dir= f\"{data_dir}/test_images\",\n    device= torch.device(\"cuda\" if torch.cuda.is_available() else \"mps\" if torch.backends.mps.is_available() else \"cpu\"),\n    n_frames=3,\n    epochs=10,\n    lr=0.0005,\n    batch_size=64,\n    backbone=\"resnet18\",\n    seed= 0,\n)\nset_seed(seed=cfg.seed) # Makes results reproducable\nprint(cfg.device)","metadata":{"execution":{"iopub.status.busy":"2024-09-28T09:39:34.471038Z","iopub.execute_input":"2024-09-28T09:39:34.471495Z","iopub.status.idle":"2024-09-28T09:39:34.489782Z","shell.execute_reply.started":"2024-09-28T09:39:34.471448Z","shell.execute_reply":"2024-09-28T09:39:34.488270Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def convert_to_8bit(x):\n    lower, upper = np.percentile(x, (1, 99))\n    x = np.clip(x, lower, upper)\n    x = x - np.min(x)\n    x = x / np.max(x) \n    return (x * 255).astype(\"uint8\")\n\n\ndef load_dicom_stack(dicom_folder, plane, reverse_sort=False):\n    dicom_files = glob.glob(os.path.join(dicom_folder, \"*.dcm\"))\n    dicoms = [pydicom.dcmread(f) for f in dicom_files]\n    plane = {\"sagittal\": 0, \"coronal\": 1, \"axial\": 2}[plane.lower()]\n    positions = np.asarray([float(d.ImagePositionPatient[plane]) for d in dicoms])\n    # if reverse_sort=False, then increasing array index will be from RIGHT->LEFT and CAUDAL->CRANIAL\n    # thus we do reverse_sort=True for axial so increasing array index is craniocaudal\n    idx = np.argsort(-positions if reverse_sort else positions)\n    ipp = np.asarray([d.ImagePositionPatient for d in dicoms]).astype(\"float\")[idx]\n    array = np.stack([d.pixel_array.astype(\"float32\") for d in dicoms])\n    array = array[idx]\n    return {\"array\": convert_to_8bit(array), \"positions\": ipp, \"pixel_spacing\": np.asarray(dicoms[0].PixelSpacing).astype(\"float\")}\n\ndef load_weights_skip_mismatch(model, weights_path, device):\n    # Load Weights\n    state_dict = torch.load(weights_path, map_location=device)\n    model_dict = model.state_dict()\n    \n    # Iter models\n    params = {}\n    for (sdk, sfv), (mdk, mdv) in zip(state_dict.items(), model_dict.items()):\n        if sfv.size() == mdv.size():\n            params[sdk] = sfv\n        else:\n            print(\"Skipping param: {}, {} != {}\".format(sdk, sfv.size(), mdv.size()))\n    \n    # Reload + Skip\n    model.load_state_dict(params, strict=False)\n    print(\"Loaded weights from:\", weights_path)","metadata":{"execution":{"iopub.status.busy":"2024-09-28T09:39:34.491822Z","iopub.execute_input":"2024-09-28T09:39:34.493098Z","iopub.status.idle":"2024-09-28T09:39:34.505532Z","shell.execute_reply.started":"2024-09-28T09:39:34.493043Z","shell.execute_reply":"2024-09-28T09:39:34.504202Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"f= \"/kaggle/input/resnet18_0_rsna_r_21/pytorch/default/1/resnet18_0_RSNA_R_21.pt\".format(cfg.backbone, cfg.seed)\n# Load backbone for RSNA 2024 task\nmodel = timm.create_model('resnet18', pretrained=False, num_classes=10)\nmodel = model.to(cfg.device)\nload_weights_skip_mismatch(model, f, cfg.device)","metadata":{"execution":{"iopub.status.busy":"2024-09-28T09:39:34.507058Z","iopub.execute_input":"2024-09-28T09:39:34.507644Z","iopub.status.idle":"2024-09-28T09:39:35.435508Z","shell.execute_reply.started":"2024-09-28T09:39:34.507592Z","shell.execute_reply":"2024-09-28T09:39:35.434073Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"f= \"/kaggle/input/resnet18_0_rsna_l_21/pytorch/default/1/resnet18_0_RSNA_L_21.pt\".format(cfg.backbone, cfg.seed)\n# Load backbone for RSNA 2024 task\nmodel_L = timm.create_model('resnet18', pretrained=False, num_classes=10)\nmodel_L = model_L.to(cfg.device)\nload_weights_skip_mismatch(model_L, f, cfg.device)","metadata":{"execution":{"iopub.status.busy":"2024-09-28T09:39:35.437073Z","iopub.execute_input":"2024-09-28T09:39:35.437493Z","iopub.status.idle":"2024-09-28T09:39:36.180485Z","shell.execute_reply.started":"2024-09-28T09:39:35.437449Z","shell.execute_reply":"2024-09-28T09:39:36.179288Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"preprocessed_path = 'preprocessed_test_data'\nimport os\nif not os.path.exists(preprocessed_path):\n    os.makedirs(preprocessed_path)","metadata":{"execution":{"iopub.status.busy":"2024-09-28T09:39:36.182149Z","iopub.execute_input":"2024-09-28T09:39:36.182678Z","iopub.status.idle":"2024-09-28T09:39:36.189943Z","shell.execute_reply.started":"2024-09-28T09:39:36.182624Z","shell.execute_reply":"2024-09-28T09:39:36.188613Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"resize_transform= A.Compose([\n    A.LongestMaxSize(max_size=256, interpolation=cv2.INTER_CUBIC, always_apply=True),\n    #A.PadIfNeeded(min_height=256, min_width=256, border_mode=cv2.BORDER_CONSTANT, value=(0, 0, 0), always_apply=True),\n    A.Resize(256, 256, interpolation=cv2.INTER_CUBIC)\n])\n\ndef angle_of_line(x1, y1, x2, y2):\n    return math.degrees(math.atan2(-(y2-y1), x2-x1))\n\ndef plot_img(img, coords_temp):\n    # Plot img\n    fig, ax = plt.subplots()\n    ax.imshow(img, cmap='gray')\n    h, w = img.shape\n    \n    # Kepoints as pairs\n    p= coords_temp.groupby(\"level\") \\\n                  .apply(lambda g: list(zip(g['relative_x'], g['relative_y'])), include_groups=False) \\\n                  .reset_index(drop=False, name=\"vals\")\n    \n    \n    # Plot keypoints\n    for _, row in p.iterrows():\n        level = row['level']\n        x = [_[0]*w for _ in row[\"vals\"]]\n        y = [_[1]*h for _ in row[\"vals\"]]\n        ax.plot(x, y, marker='o')\n    ax.axis('off')\n    plt.show()\n\ndef plot_5_crops_3D_and_save(img, coords_temp, df_row, path):\n\n    # transpose\n\n    img = np.transpose(img, (1,2,0))\n    \n    # Create a figure and axis for the grid\n    #fig = plt.figure(figsize=(10, 10))\n    #gs = gridspec.GridSpec(1, 5, width_ratios=[1]*5)\n\n    \n    # Plot the crops\n    p= coords_temp.groupby(\"level\").apply(lambda g: list(zip(g['relative_x'], g['relative_y'])), include_groups=False).reset_index(drop=False, name=\"vals\")\n    for idx, (_, row) in enumerate(p.iterrows()):\n        # Copy of img\n        img_copy= img.copy()\n        h, w, d = img.shape\n\n        # Extract Keypoints\n        level = row['level']\n        vals = sorted(row[\"vals\"], key=lambda x: x[0])\n        a,b= vals\n        a= (a[0]*w, a[1]*h)\n        b= (b[0]*w, b[1]*h)\n        \n        # Rotate\n        rotate_angle= angle_of_line(a[0], a[1], b[0], b[1])\n        transform = A.Compose([\n            A.Rotate(limit=(-rotate_angle, -rotate_angle), p=1.0),\n        ], keypoint_params= A.KeypointParams(format='xy', remove_invisible=False),\n        )\n\n        t= transform(image=img_copy, keypoints=[a,b])\n        img_copy= t[\"image\"]\n        a,b= t[\"keypoints\"]\n\n        # Crop + Resize\n        img_copy= crop_between_keypoints(img_copy, a, b)\n        img_copy= resize_transform(image=img_copy)[\"image\"]\n\n        # Transpose and save\n        img_copy = np.transpose(img_copy, (2,0,1))\n        saving_path = f'{path}/{str(df_row.study_id)}_{str(df_row.series_id)}_{level.replace(\"/\",\"_\").lower()}'\n        print(saving_path)\n        np.save(saving_path, img_copy)\n        \n        \n        # Plot\n        #ax = plt.subplot(gs[idx])\n        #ax.imshow(img_copy[1, :,:], cmap='gray')\n        #ax.set_title(level)\n        #ax.axis('on')\n    #plt.show()\n\ndef crop_between_keypoints(img, keypoint1, keypoint2):\n    h, w, d = img.shape\n    x1, y1 = int(keypoint1[0]), int(keypoint1[1])\n    x2, y2 = int(keypoint2[0]), int(keypoint2[1])\n    \n    # Calculate bounding box around the keypoints\n    left = int(min(x1, x2) - 0.05*w)\n    right = int(max(x1, x2) + 0.05*w)\n    top = int(min(y1, y2) - (h * 0.1))\n    bottom = int(max(y1, y2) + (h * 0.1))\n\n    if left < 0: left = 0\n    if top < 0: top = 0 \n    if right > (w-1): right = (w-1) \n    if bottom > (h-1): bottom = (h-1) \n            \n    # Crop the image\n    return img[top:bottom, left:right,:]","metadata":{"execution":{"iopub.status.busy":"2024-09-28T09:39:36.191535Z","iopub.execute_input":"2024-09-28T09:39:36.191933Z","iopub.status.idle":"2024-09-28T09:39:36.215033Z","shell.execute_reply.started":"2024-09-28T09:39:36.191892Z","shell.execute_reply":"2024-09-28T09:39:36.213495Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import torch","metadata":{"execution":{"iopub.status.busy":"2024-09-28T09:39:36.216399Z","iopub.execute_input":"2024-09-28T09:39:36.216811Z","iopub.status.idle":"2024-09-28T09:39:36.234433Z","shell.execute_reply.started":"2024-09-28T09:39:36.216774Z","shell.execute_reply":"2024-09-28T09:39:36.232991Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class RSNADatasetTest(torch.utils.data.Dataset):\n    def __init__(self, df, cfg):\n        self.cfg= cfg\n        self.df= df\n\n    def pad_image(self, img):\n        n= img.shape[0]\n        if n >= self.cfg.n_frames:\n            start_idx = (n - self.cfg.n_frames) // 2\n            return img[start_idx:start_idx + self.cfg.n_frames, :, :]\n        else:\n            pad_left = (self.cfg.n_frames - n) // 2\n            pad_right = self.cfg.n_frames - n - pad_left\n            return np.pad(img, ((pad_left, pad_right), (0,0), (0,0)), 'constant', constant_values=0)\n    \n    def load_img(self, study_id, series_id):\n        #img = np.load(f'/Users/azanella/Documents/Perso/kaggle_RSNA_lumbar_spine_challenge/kaggle/input/rsna-2024-lumbar-spine-degenerative-classification/train_sag2_npy/{study_id}_{series_id}.npy')\n        #return img\n        fname= os.path.join(self.cfg.img_dir, str(study_id), str(series_id))\n        print(fname)\n        sag_t2 = load_dicom_stack(fname, plane=\"sagittal\")\n        img= sag_t2[\"array\"]\n        img= self.pad_image(img)\n        res0 = cv2.resize(img[0], dsize=(256, 256), interpolation=cv2.INTER_CUBIC)\n        res1 = cv2.resize(img[1], dsize=(256, 256), interpolation=cv2.INTER_CUBIC)\n        res2 = cv2.resize(img[2], dsize=(256, 256), interpolation=cv2.INTER_CUBIC)\n        img = np.array([res0,res1,res2])\n        \n        img= (img / 255.0)\n        return img\n        \n        \n    def __getitem__(self, idx):\n        df= self.df\n        #label= d[\"label\"]\n        study_id = df[\"study_id\"].values[idx]\n        series_id = df[\"series_id\"].values[idx]  \n        img = self.load_img(study_id, series_id)\n                \n        #img, sag_t2= self.load_img(study_id, series_id)\n        \n        return {\n            'img': img.astype(np.float32), \n            'series_id': series_id,\n            #'sag_t2': sag_t2,\n            }\n    \n    def __len__(self,):\n        return len(self.df)\n","metadata":{"execution":{"iopub.status.busy":"2024-09-28T09:39:36.236000Z","iopub.execute_input":"2024-09-28T09:39:36.236518Z","iopub.status.idle":"2024-09-28T09:39:36.252558Z","shell.execute_reply.started":"2024-09-28T09:39:36.236470Z","shell.execute_reply":"2024-09-28T09:39:36.251306Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"SEED= 10\nN= 2\n\nfrom tqdm import tqdm\n\ncfg.img_dir = f'{data_dir}/test_images'\nlevel = ['L1/L2',\n         'L1/L2', \n         'L2/L3',\n         'L2/L3',\n         'L3/L4',\n         'L3/L4',\n         'L4/L5',\n         'L4/L5',\n         'L5/S1',\n         'L5/S1']\nside = ['L',\n        'R',\n        'L',\n        'R',\n        'L',\n        'R',\n        'L',\n        'R',\n        'L',\n        'R']\n\n#df = pd.read_csv('/kaggle/input/rsna-2024-lumbar-spine-degenerative-classification/test_series_descriptions.csv')\ndf1 = test[test['series_description'] == 'Sagittal T2/STIR']\ndf1 = df1.reset_index(drop=True)\nds= RSNADatasetTest(df1, cfg) \n\nfor i, row in tqdm(df1.iterrows()):\n    try:\n        print(i)\n        img_t = torch.Tensor(ds[i]['img']).to(cfg.device).unsqueeze(0)\n\n        output = model(img_t)\n        pred = torch.sigmoid(output)\n\n        output_L = model_L(img_t)\n        pred_L = torch.sigmoid(output_L)\n\n        pred_L = pred_L.cpu().detach().numpy()[0]\n        pred_L_x = pred_L[0::2]\n        pred_L_y = pred_L[1::2]\n\n        pred_R = pred.cpu().detach().numpy()[0]\n        pred_R_x = pred_R[0::2]\n        pred_R_y = pred_R[1::2]\n\n        relative_x = [pred_L[0], pred_R[0], pred_L[2], pred_R[2], pred_L[4], pred_R[4], pred_L[6], pred_R[6], pred_L[8], pred_R[8]]\n        relative_y = [pred_L[1], pred_R[1], pred_L[3], pred_R[3], pred_L[5], pred_R[5], pred_L[7], pred_R[7], pred_L[9], pred_R[9]]\n\n        df_test = pd.DataFrame({\n            'relative_x':relative_x,\n            'relative_y':relative_y,\n            'side':side,\n            'level':level})\n\n        sag_t2 = load_dicom_stack(os.path.join(cfg.img_dir, str(row.study_id), str(row.series_id)), plane=\"sagittal\")\n\n        real_image_cropped = sag_t2[\"array\"][(len(sag_t2[\"array\"])//2)-1: (len(sag_t2[\"array\"])//2)+2]\n\n        #plot_img(real_image_cropped[1,:,:], df_test)\n        plot_5_crops_3D_and_save(real_image_cropped, df_test, row, preprocessed_path)\n        \n    except Exception as error:\n            # handle the exception\n            print(\"An exception occurred:\", type(error).__name__, \"–\", error)\n            pass\n","metadata":{"execution":{"iopub.status.busy":"2024-09-28T09:39:36.254478Z","iopub.execute_input":"2024-09-28T09:39:36.254945Z","iopub.status.idle":"2024-09-28T09:39:39.037525Z","shell.execute_reply.started":"2024-09-28T09:39:36.254901Z","shell.execute_reply":"2024-09-28T09:39:39.036429Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"f= \"/kaggle/input/resnet18_10_weights_logloss_20_epochs_sigmoid_last/pytorch/default/1/resnet18_0_by_vertebra_10_weights_logloss_20_epochs_sigmoid_last.pt\"\n# Load backbone for RSNA 2024 task\nmodel_class = timm.create_model('resnet18', pretrained=False, num_classes=3)\nmodel_class = model_class.to(cfg.device)\nload_weights_skip_mismatch(model_class, f, cfg.device)","metadata":{"execution":{"iopub.status.busy":"2024-09-28T09:39:39.038897Z","iopub.execute_input":"2024-09-28T09:39:39.039282Z","iopub.status.idle":"2024-09-28T09:39:39.778151Z","shell.execute_reply.started":"2024-09-28T09:39:39.039220Z","shell.execute_reply":"2024-09-28T09:39:39.777045Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"cfg.img_dir = '/kaggle/working/preprocessed_test_data'","metadata":{"execution":{"iopub.status.busy":"2024-09-28T09:39:39.779591Z","iopub.execute_input":"2024-09-28T09:39:39.780379Z","iopub.status.idle":"2024-09-28T09:39:39.785160Z","shell.execute_reply.started":"2024-09-28T09:39:39.780335Z","shell.execute_reply":"2024-09-28T09:39:39.784004Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"preprocessed_path","metadata":{"execution":{"iopub.status.busy":"2024-09-28T09:39:39.786533Z","iopub.execute_input":"2024-09-28T09:39:39.786929Z","iopub.status.idle":"2024-09-28T09:39:39.798390Z","shell.execute_reply.started":"2024-09-28T09:39:39.786892Z","shell.execute_reply":"2024-09-28T09:39:39.797316Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class RSNADatasetCroppedTest(torch.utils.data.Dataset):\n    def __init__(self, df, cfg, classes):\n        self.cfg= cfg\n        self.df= df\n        self.classes = classes\n    \n    def pad_image(self, img):\n        n= img.shape[0]\n        if n >= self.cfg.n_frames:\n            start_idx = (n - self.cfg.n_frames) // 2\n            return img[start_idx:start_idx + self.cfg.n_frames, :, :]\n        else:\n            pad_left = (self.cfg.n_frames - n) // 2\n            pad_right = self.cfg.n_frames - n - pad_left\n            return np.pad(img, ((pad_left, pad_right), (0,0), (0,0)), 'constant', constant_values=0)\n    \n    def load_img(self, study_id, series_id, level):\n        img = np.load(f'{self.cfg.img_dir}/{str(study_id)}_{str(series_id)}_{level.replace(\"/\",\"_\").replace(\"spinal_canal_stenosis_\",\"\")}.npy')\n        return img\n        \n        \n    def __getitem__(self, idx):\n        d= self.df\n        study_id = d[\"study_id\"][idx]\n        series_id = d[\"series_id\"][idx]\n        level = d['level'][idx]\n        \n        self.series_id = series_id\n        \n        img = self.load_img(study_id, series_id, level)\n        \n        return {\n            'img': img.astype(np.float32), \n            #'label': label\n            }\n    \n    def __len__(self,):\n        return len(self.df)","metadata":{"execution":{"iopub.status.busy":"2024-09-28T09:39:39.800134Z","iopub.execute_input":"2024-09-28T09:39:39.800550Z","iopub.status.idle":"2024-09-28T09:39:39.811677Z","shell.execute_reply.started":"2024-09-28T09:39:39.800501Z","shell.execute_reply":"2024-09-28T09:39:39.810339Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"LEVELS = ['spinal_canal_stenosis_l1_l2', 'spinal_canal_stenosis_l2_l3',\n       'spinal_canal_stenosis_l3_l4', 'spinal_canal_stenosis_l4_l5',\n       'spinal_canal_stenosis_l5_s1']","metadata":{"execution":{"iopub.status.busy":"2024-09-28T09:39:39.813157Z","iopub.execute_input":"2024-09-28T09:39:39.814102Z","iopub.status.idle":"2024-09-28T09:39:39.825622Z","shell.execute_reply.started":"2024-09-28T09:39:39.814053Z","shell.execute_reply":"2024-09-28T09:39:39.824372Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"classes = {'Normal/Mild':0,\n           'Moderate':1,\n           'Severe':2}","metadata":{"execution":{"iopub.status.busy":"2024-09-28T09:39:39.827046Z","iopub.execute_input":"2024-09-28T09:39:39.827474Z","iopub.status.idle":"2024-09-28T09:39:39.842615Z","shell.execute_reply.started":"2024-09-28T09:39:39.827434Z","shell.execute_reply":"2024-09-28T09:39:39.841537Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df1_test = df1.merge(pd.Series(LEVELS, name='value2'), how='cross')\ndf1_test = df1_test.rename(columns={\"value2\": \"level\"})\n\ndf1_test.head()","metadata":{"execution":{"iopub.status.busy":"2024-09-28T09:39:39.848897Z","iopub.execute_input":"2024-09-28T09:39:39.849357Z","iopub.status.idle":"2024-09-28T09:39:39.872714Z","shell.execute_reply.started":"2024-09-28T09:39:39.849312Z","shell.execute_reply":"2024-09-28T09:39:39.871592Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"ds= RSNADatasetCroppedTest(df1_test, cfg, classes)  ","metadata":{"execution":{"iopub.status.busy":"2024-09-28T09:39:39.874014Z","iopub.execute_input":"2024-09-28T09:39:39.874404Z","iopub.status.idle":"2024-09-28T09:39:39.884582Z","shell.execute_reply.started":"2024-09-28T09:39:39.874359Z","shell.execute_reply":"2024-09-28T09:39:39.883499Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#df1_test","metadata":{"execution":{"iopub.status.busy":"2024-09-28T09:39:39.886050Z","iopub.execute_input":"2024-09-28T09:39:39.886475Z","iopub.status.idle":"2024-09-28T09:39:39.896802Z","shell.execute_reply.started":"2024-09-28T09:39:39.886434Z","shell.execute_reply":"2024-09-28T09:39:39.895461Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from tqdm import tqdm","metadata":{"execution":{"iopub.status.busy":"2024-09-28T09:39:39.898335Z","iopub.execute_input":"2024-09-28T09:39:39.898722Z","iopub.status.idle":"2024-09-28T09:39:39.909316Z","shell.execute_reply.started":"2024-09-28T09:39:39.898679Z","shell.execute_reply":"2024-09-28T09:39:39.908220Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"with torch.no_grad():\n    model_class = model_class.eval()\n    for i, row in tqdm(df1_test.iterrows()):\n        \n        try:\n            img_t = torch.Tensor(ds[i]['img']).to(cfg.device).unsqueeze(0)\n            output = model_class(img_t)\n            pred = torch.softmax(output, dim=1)\n            epsilon = 2e-1\n            clipped_probabilities = torch.clamp(pred, epsilon, 1. - epsilon)\n            # Renormaliser pour que la somme soit toujours égale à 1\n            pred = clipped_probabilities / clipped_probabilities.sum(dim=1, keepdim=True)\n            sub.loc[sub['row_id']== f'{row.study_id}_{row.level}',['normal_mild','moderate','severe']] = pred.detach().cpu().numpy()\n        except Exception as error:\n            # handle the exception\n            print(\"An exception occurred:\", type(error).__name__, \"–\", error)\n            pass","metadata":{"execution":{"iopub.status.busy":"2024-09-28T09:39:39.910673Z","iopub.execute_input":"2024-09-28T09:39:39.911065Z","iopub.status.idle":"2024-09-28T09:39:40.254515Z","shell.execute_reply.started":"2024-09-28T09:39:39.911028Z","shell.execute_reply":"2024-09-28T09:39:40.253324Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"sub.head(50)","metadata":{"execution":{"iopub.status.busy":"2024-09-28T09:39:40.256537Z","iopub.execute_input":"2024-09-28T09:39:40.257049Z","iopub.status.idle":"2024-09-28T09:39:40.273433Z","shell.execute_reply.started":"2024-09-28T09:39:40.256996Z","shell.execute_reply":"2024-09-28T09:39:40.272320Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#sub.to_csv('submission.csv', index=False)","metadata":{"execution":{"iopub.status.busy":"2024-09-28T09:39:40.274963Z","iopub.execute_input":"2024-09-28T09:39:40.275391Z","iopub.status.idle":"2024-09-28T09:39:40.284506Z","shell.execute_reply.started":"2024-09-28T09:39:40.275348Z","shell.execute_reply":"2024-09-28T09:39:40.283275Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"cfg.img_dir","metadata":{"execution":{"iopub.status.busy":"2024-09-28T09:39:40.285843Z","iopub.execute_input":"2024-09-28T09:39:40.286307Z","iopub.status.idle":"2024-09-28T09:39:40.299661Z","shell.execute_reply.started":"2024-09-28T09:39:40.286152Z","shell.execute_reply":"2024-09-28T09:39:40.298313Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"folder_path_L = f'{cfg.img_dir}/sag1_per_vertebra_256_256_3_shift_contrast_L'\nfolder_path_R = f'{cfg.img_dir}/sag1_per_vertebra_256_256_3_shift_contrast_R'\n\n\ndef convert_to_8bit(x):\n    lower, upper = np.percentile(x, (1, 99))\n    x = np.clip(x, lower, upper)\n    x = x - np.min(x)\n    x = x / np.max(x) \n    return (x * 255).astype(\"uint8\")\n\n\ndef load_dicom_stack(dicom_folder, plane, reverse_sort=False):\n    dicom_files = glob.glob(os.path.join(dicom_folder, \"*.dcm\"))\n    dicoms = [pydicom.dcmread(f) for f in dicom_files]\n    plane = {\"sagittal\": 0, \"coronal\": 1, \"axial\": 2}[plane.lower()]\n    positions = np.asarray([float(d.ImagePositionPatient[plane]) for d in dicoms])\n    # if reverse_sort=False, then increasing array index will be from RIGHT->LEFT and CAUDAL->CRANIAL\n    # thus we do reverse_sort=True for axial so increasing array index is craniocaudal\n    idx = np.argsort(-positions if reverse_sort else positions)\n    ipp = np.asarray([d.ImagePositionPatient for d in dicoms]).astype(\"float\")[idx]\n    array = np.stack([d.pixel_array.astype(\"float32\") for d in dicoms])\n    array = array[idx]\n    return {\"array\": convert_to_8bit(array), \"positions\": ipp, \"pixel_spacing\": np.asarray(dicoms[0].PixelSpacing).astype(\"float\")}","metadata":{"execution":{"iopub.status.busy":"2024-09-28T09:39:40.301181Z","iopub.execute_input":"2024-09-28T09:39:40.301671Z","iopub.status.idle":"2024-09-28T09:39:40.317769Z","shell.execute_reply.started":"2024-09-28T09:39:40.301619Z","shell.execute_reply":"2024-09-28T09:39:40.316313Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# CONTRASTE\n\ndef plot_5_crops_3D_and_save(img, coords_temp, df_row, path):\n\n    # transpose\n\n    img = np.transpose(img, (1,2,0))\n    \n    # Create a figure and axis for the grid\n    fig = plt.figure(figsize=(10, 10))\n    gs = gridspec.GridSpec(1, 5, width_ratios=[1]*5)\n\n    \n    # Plot the crops\n    p= coords_temp.groupby(\"level\").apply(lambda g: list(zip(g['relative_x'], g['relative_y'])), include_groups=False).reset_index(drop=False, name=\"vals\")\n    for idx, (_, row) in enumerate(p.iterrows()):\n        # Copy of img\n        img_copy= img.copy()\n        h, w, d = img.shape\n        print(img.shape)\n\n        # Extract Keypoints\n        level = row['level']\n        vals = sorted(row[\"vals\"], key=lambda x: x[0])\n        a,b= vals\n        a= (a[0]*w, a[1]*h)\n        b= (b[0]*w, b[1]*h)\n        print(a)\n        print(b)\n        \n        # Rotate\n        rotate_angle= angle_of_line(a[0], a[1], b[0], b[1])\n        transform = A.Compose([\n            A.Rotate(limit=(-rotate_angle, -rotate_angle), p=1.0),\n        ], keypoint_params= A.KeypointParams(format='xy', remove_invisible=False),\n        )\n\n        t= transform(image=img_copy, keypoints=[a,b])\n        img_copy= t[\"image\"]\n        a,b= t[\"keypoints\"]\n\n        # Crop + Resize\n        img_copy= crop_between_keypoints(img_copy, a, b)\n        print(img_copy.shape)\n        img_copy= resize_transform(image=img_copy)[\"image\"]\n\n        # Transpose and save\n        img_copy = np.transpose(img_copy, (2,0,1))\n        saving_path = f'{path}/{str(df_row.study_id)}_{str(df_row.series_id)}_{level.replace(\"/\",\"_\")}'\n        \n        transform = A.CLAHE(clip_limit=(1, 4),p=1)\n        res0 = transform(image=img_copy[0, :,:])['image']\n        res1 = transform(image=img_copy[1, :,:])['image']\n        res2 = transform(image=img_copy[2, :,:])['image']\n        img_copy= np.array([res0, res1, res2])\n        \n        np.save(saving_path, img_copy)\n        print(saving_path)\n        \n        \n        # Plot\n        #ax = plt.subplot(gs[idx])\n        #ax.imshow(img_copy[1,:,:], cmap='gray')\n        #ax.set_title(level)\n        #ax.axis('on')\n    #plt.show()\n\ndef crop_between_keypoints(img, keypoint1, keypoint2):\n    h, w, d = img.shape\n    x1, y1 = int(keypoint1[0]), int(keypoint1[1])\n    x2, y2 = int(keypoint2[0]), int(keypoint2[1])\n    \n    # Calculate bounding box around the keypoints\n    left = int(min(x1, x2))# + 0.05*w)\n    right = int(max(x1, x2) + 0.15*w)\n    top = int(min(y1, y2) - (h * 0.1))\n    bottom = int(max(y1, y2) + (h * 0.1))\n\n    if left < 0: left = 0\n    if top < 0: top = 0 \n    if right > (w-1): right = (w-1) \n    if bottom > (h-1): bottom = (h-1) \n            \n    # Crop the image\n    return img[top:bottom, left:right,:]","metadata":{"execution":{"iopub.status.busy":"2024-09-28T09:39:40.319614Z","iopub.execute_input":"2024-09-28T09:39:40.320035Z","iopub.status.idle":"2024-09-28T09:39:40.352659Z","shell.execute_reply.started":"2024-09-28T09:39:40.319986Z","shell.execute_reply":"2024-09-28T09:39:40.351041Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"folder_path_L","metadata":{"execution":{"iopub.status.busy":"2024-09-28T09:39:40.354144Z","iopub.execute_input":"2024-09-28T09:39:40.354676Z","iopub.status.idle":"2024-09-28T09:39:40.372089Z","shell.execute_reply.started":"2024-09-28T09:39:40.354621Z","shell.execute_reply":"2024-09-28T09:39:40.370925Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"SEED= 10\nN= 2\n\nfrom tqdm import tqdm\n\nif not os.path.exists(folder_path_L):\n    os.makedirs(folder_path_L)\n    \nif not os.path.exists(folder_path_R):\n    os.makedirs(folder_path_R)\n\ncfg.img_dir = '/kaggle/input/rsna-2024-lumbar-spine-degenerative-classification/test_images'\nlevel = ['L1/L2',\n         'L1/L2', \n         'L2/L3',\n         'L2/L3',\n         'L3/L4',\n         'L3/L4',\n         'L4/L5',\n         'L4/L5',\n         'L5/S1',\n         'L5/S1']\nside = ['L',\n        'R',\n        'L',\n        'R',\n        'L',\n        'R',\n        'L',\n        'R',\n        'L',\n        'R']\n\n#df = pd.read_csv('/kaggle/input/rsna-2024-lumbar-spine-degenerative-classification/train_series_descriptions.csv')\n#df1 = df[df['series_description'] == 'Sagittal T2/STIR']\ndf1 = test[test['series_description'] == 'Sagittal T1']\n\ndf1 = df1.reset_index()\nds= RSNADatasetTest(df1, cfg) \n\nfor i, row in tqdm(df1.iterrows()):\n    img_t = torch.Tensor(ds[i]['img']).to(cfg.device).unsqueeze(0)\n    \n    output = model(img_t)\n    pred = torch.sigmoid(output)\n    \n    output_L = model_L(img_t)\n    pred_L = torch.sigmoid(output_L)\n\n    pred_L = pred_L.cpu().detach().numpy()[0]\n    pred_L_x = pred_L[0::2]\n    pred_L_y = pred_L[1::2]\n    \n    pred_R = pred.cpu().detach().numpy()[0]\n    pred_R_x = pred_R[0::2]\n    pred_R_y = pred_R[1::2]\n    \n    relative_x = [pred_L[0], pred_R[0], pred_L[2], pred_R[2], pred_L[4], pred_R[4], pred_L[6], pred_R[6], pred_L[8], pred_R[8]]\n    relative_y = [pred_L[1], pred_R[1], pred_L[3], pred_R[3], pred_L[5], pred_R[5], pred_L[7], pred_R[7], pred_L[9], pred_R[9]]\n    \n    df_test = pd.DataFrame({\n        'relative_x':relative_x,\n        'relative_y':relative_y,\n        'side':side,\n        'level':level})\n    \n    sag_t2 = load_dicom_stack(os.path.join(cfg.img_dir, str(row.study_id), str(row.series_id)), plane=\"sagittal\")\n\n    #real_image_cropped = sag_t2[\"array\"][(len(sag_t2[\"array\"])//2)-1: (len(sag_t2[\"array\"])//2)+2]\n    real_image_cropped_L = sag_t2[\"array\"][(len(sag_t2[\"array\"])//2)+2: (len(sag_t2[\"array\"])//2)+5] #(+2:3)\n    real_image_cropped_R = sag_t2[\"array\"][(len(sag_t2[\"array\"])//2)-5: (len(sag_t2[\"array\"])//2)-2]\n    #real_image_cropped = sag_t2[\"array\"][(len(sag_t2[\"array\"])//2)-4: (len(sag_t2[\"array\"])//2)+6]\n    \n    #plot_img(real_image_cropped_L[1,:,:], df_test)\n    plot_5_crops_3D_and_save(real_image_cropped_L, df_test, row, folder_path_L)\n    plot_5_crops_3D_and_save(real_image_cropped_R, df_test, row, folder_path_R)","metadata":{"execution":{"iopub.status.busy":"2024-09-28T09:39:40.373708Z","iopub.execute_input":"2024-09-28T09:39:40.374098Z","iopub.status.idle":"2024-09-28T09:39:42.354199Z","shell.execute_reply.started":"2024-09-28T09:39:40.374058Z","shell.execute_reply":"2024-09-28T09:39:42.352905Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"cfg.img_dir = '/kaggle/working/preprocessed_test_data'","metadata":{"execution":{"iopub.status.busy":"2024-09-28T09:39:42.355737Z","iopub.execute_input":"2024-09-28T09:39:42.356203Z","iopub.status.idle":"2024-09-28T09:39:42.363092Z","shell.execute_reply.started":"2024-09-28T09:39:42.356142Z","shell.execute_reply":"2024-09-28T09:39:42.361945Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class RSNADatasetTest(torch.utils.data.Dataset):\n    def __init__(self, df, cfg):\n        self.cfg= cfg\n        self.df= df\n    \n    def load_img(self, study_id, series_id, level, side):\n        if side == 'R':\n            side_dir = 'sag1_per_vertebra_256_256_3_shift_contrast_R'\n        elif side =='L':\n            side_dir = 'sag1_per_vertebra_256_256_3_shift_contrast_L'\n        f =f'{self.cfg.img_dir}/{side_dir}/{str(study_id)}_{str(series_id)}_{level.replace(\"/\",\"_\").replace(\"left_neural_foraminal_narrowing_\",\"\").replace(\"right_neural_foraminal_narrowing_\",\"\").upper()}.npy'\n        img = np.load(f)\n        return img\n        \n    def __getitem__(self, idx):\n        d= self.df\n        study_id = d[\"study_id\"][idx]\n        series_id = d[\"series_id\"][idx]\n        level = d['level'][idx]\n\n        side = 'R' if 'right' in d['level'].values[idx] else 'L'\n        \n        img = self.load_img(study_id, series_id, level, side)\n    \n        return {\n            'img': img.astype(np.float32),\n            }\n    \n    def __len__(self,):\n        return len(self.df)","metadata":{"execution":{"iopub.status.busy":"2024-09-28T09:39:42.364594Z","iopub.execute_input":"2024-09-28T09:39:42.364964Z","iopub.status.idle":"2024-09-28T09:39:42.375185Z","shell.execute_reply.started":"2024-09-28T09:39:42.364926Z","shell.execute_reply":"2024-09-28T09:39:42.373649Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"cols = ['left_neural_foraminal_narrowing_l1_l2',\n       'left_neural_foraminal_narrowing_l2_l3',\n       'left_neural_foraminal_narrowing_l3_l4',\n       'left_neural_foraminal_narrowing_l4_l5',\n       'left_neural_foraminal_narrowing_l5_s1',\n       'right_neural_foraminal_narrowing_l1_l2',\n       'right_neural_foraminal_narrowing_l2_l3',\n       'right_neural_foraminal_narrowing_l3_l4',\n       'right_neural_foraminal_narrowing_l4_l5',\n       'right_neural_foraminal_narrowing_l5_s1']\n\ndf_sag1 = test[test['series_description'] == 'Sagittal T1']\ndf_sag1 = df_sag1.reset_index(drop=True)\ndf_sag1_test = df_sag1.merge(pd.Series(cols, name='value2'), how='cross')\ndf_sag1_test = df_sag1_test.rename(columns={\"value2\": \"level\"})\n\ndf_sag1_test.head(20)","metadata":{"execution":{"iopub.status.busy":"2024-09-28T09:39:42.377378Z","iopub.execute_input":"2024-09-28T09:39:42.377808Z","iopub.status.idle":"2024-09-28T09:39:42.402515Z","shell.execute_reply.started":"2024-09-28T09:39:42.377767Z","shell.execute_reply":"2024-09-28T09:39:42.401045Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"ds= RSNADatasetTest(df_sag1_test, cfg) ","metadata":{"execution":{"iopub.status.busy":"2024-09-28T09:39:42.404192Z","iopub.execute_input":"2024-09-28T09:39:42.404704Z","iopub.status.idle":"2024-09-28T09:39:42.418975Z","shell.execute_reply.started":"2024-09-28T09:39:42.404649Z","shell.execute_reply":"2024-09-28T09:39:42.417552Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"f= \"/kaggle/input/res8_15_weights_logloss_sigmoid_vr_shift_contrast/pytorch/default/1/resnet18_0_by_vertebra_15_weights_logloss_sigmoid_VR_shift_contrast.pt\"\n# Load backbone for RSNA 2024 task\nmodel_class = timm.create_model('resnet18', pretrained=False, num_classes=3)\nmodel_class = model_class.to(cfg.device)\nload_weights_skip_mismatch(model_class, f, cfg.device)","metadata":{"execution":{"iopub.status.busy":"2024-09-28T09:39:42.420844Z","iopub.execute_input":"2024-09-28T09:39:42.421369Z","iopub.status.idle":"2024-09-28T09:39:43.267143Z","shell.execute_reply.started":"2024-09-28T09:39:42.421323Z","shell.execute_reply":"2024-09-28T09:39:43.266129Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"ds[0]","metadata":{"execution":{"iopub.status.busy":"2024-09-28T09:39:43.268554Z","iopub.execute_input":"2024-09-28T09:39:43.269251Z","iopub.status.idle":"2024-09-28T09:39:43.279898Z","shell.execute_reply.started":"2024-09-28T09:39:43.269186Z","shell.execute_reply":"2024-09-28T09:39:43.278570Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model = model_class\nwith torch.no_grad():\n    model = model.eval()\n    for i, row in tqdm(df_sag1_test.iterrows()):\n        try:\n            img_t = torch.Tensor(ds[i]['img']).to(cfg.device).unsqueeze(0)\n            output = model(img_t)\n            pred = torch.softmax(output, dim=1)\n            epsilon = 2e-1\n            clipped_probabilities = torch.clamp(pred, epsilon, 1. - epsilon)\n            #\n            ## Renormaliser pour que la somme soit toujours égale à 1\n            pred = clipped_probabilities / clipped_probabilities.sum(dim=1, keepdim=True)\n            sub.loc[sub['row_id']== f'{row.study_id}_{row.level}',['normal_mild','moderate','severe']] = pred.detach().cpu().numpy()\n        except Exception as error:\n            # handle the exception\n            print(\"An exception occurred:\", type(error).__name__, \"–\", error)\n            pass","metadata":{"execution":{"iopub.status.busy":"2024-09-28T09:39:43.281559Z","iopub.execute_input":"2024-09-28T09:39:43.282751Z","iopub.status.idle":"2024-09-28T09:39:44.333730Z","shell.execute_reply.started":"2024-09-28T09:39:43.282693Z","shell.execute_reply":"2024-09-28T09:39:44.332622Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import shutil\n\nshutil.rmtree('/kaggle/working/preprocessed_test_data')","metadata":{"execution":{"iopub.status.busy":"2024-09-28T09:39:44.334899Z","iopub.execute_input":"2024-09-28T09:39:44.335275Z","iopub.status.idle":"2024-09-28T09:39:44.342785Z","shell.execute_reply.started":"2024-09-28T09:39:44.335212Z","shell.execute_reply":"2024-09-28T09:39:44.341112Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"sub.to_csv('submission.csv', index=False)","metadata":{"execution":{"iopub.status.busy":"2024-09-28T09:39:44.344540Z","iopub.execute_input":"2024-09-28T09:39:44.344951Z","iopub.status.idle":"2024-09-28T09:39:44.355603Z","shell.execute_reply.started":"2024-09-28T09:39:44.344908Z","shell.execute_reply":"2024-09-28T09:39:44.354368Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"pd.read_csv('submission.csv').head(50)","metadata":{"execution":{"iopub.status.busy":"2024-09-28T09:39:44.356897Z","iopub.execute_input":"2024-09-28T09:39:44.357472Z","iopub.status.idle":"2024-09-28T09:39:44.375830Z","shell.execute_reply.started":"2024-09-28T09:39:44.357413Z","shell.execute_reply":"2024-09-28T09:39:44.374621Z"},"trusted":true},"execution_count":null,"outputs":[]}]}