{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.10.13","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"none","dataSources":[{"sourceId":71549,"databundleVersionId":8561470,"sourceType":"competition"}],"dockerImageVersionId":30746,"isInternetEnabled":false,"language":"python","sourceType":"notebook","isGpuEnabled":false}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"import os\nimport time\nimport wandb\nimport torch\nimport random\nimport torchvision\n\nimport numpy as np\nimport pandas as pd\nimport torchmetrics as tm \n# import plotly.express as px\nimport pytorch_lightning as pl\nimport matplotlib.pyplot as plt\n\nfrom torch import nn\nfrom pathlib import Path, PurePath\nfrom torch.utils.data import Dataset, DataLoader\nfrom torch.optim import Adam, AdamW, RMSprop # optmizers\n# from warmup_scheduler import GradualWarmupScheduler\nfrom sklearn.model_selection import train_test_split\nfrom torch.optim.lr_scheduler import CosineAnnealingLR, ReduceLROnPlateau # Learning rate schedulers\n\nimport albumentations as A\n# from albumentations.pytorch import ToTensorV2\n\nimport timm","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","execution":{"iopub.status.busy":"2024-08-14T10:21:17.420096Z","iopub.execute_input":"2024-08-14T10:21:17.420501Z","iopub.status.idle":"2024-08-14T10:21:27.169802Z","shell.execute_reply.started":"2024-08-14T10:21:17.420461Z","shell.execute_reply":"2024-08-14T10:21:27.168762Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print('timm version', timm.__version__)\nprint('torch version', torch.__version__)","metadata":{"execution":{"iopub.status.busy":"2024-08-14T10:21:27.171870Z","iopub.execute_input":"2024-08-14T10:21:27.172458Z","iopub.status.idle":"2024-08-14T10:21:27.177621Z","shell.execute_reply.started":"2024-08-14T10:21:27.172423Z","shell.execute_reply":"2024-08-14T10:21:27.176640Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# detect and define device \ndevice = torch.device('cuda' if torch.cuda.is_available() else 'cpu')\n\nprint(device)","metadata":{"execution":{"iopub.status.busy":"2024-08-14T10:21:27.178729Z","iopub.execute_input":"2024-08-14T10:21:27.179026Z","iopub.status.idle":"2024-08-14T10:21:27.190886Z","shell.execute_reply.started":"2024-08-14T10:21:27.179000Z","shell.execute_reply":"2024-08-14T10:21:27.189633Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# for reproducibility\ndef seed_torch(seed):\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 = True","metadata":{"execution":{"iopub.status.busy":"2024-08-14T10:21:27.192181Z","iopub.execute_input":"2024-08-14T10:21:27.192932Z","iopub.status.idle":"2024-08-14T10:21:27.201209Z","shell.execute_reply.started":"2024-08-14T10:21:27.192899Z","shell.execute_reply":"2024-08-14T10:21:27.200223Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Config","metadata":{}},{"cell_type":"code","source":"# TODO: maybe use condition and level for classes\nclasses = ['SCS', 'RNFN', 'LNFN', 'LSS', 'RSS'] + ['H'] # add healthy class\n\nclasses = ['SCSL1L2', 'SCSL2L3', 'SCSL3L4', 'SCSL4L5', 'SCSL5S1', 'RNFNL4L5',\n       'RNFNL5S1', 'RNFNL3L4', 'RNFNL1L2', 'RNFNL2L3', 'LNFNL1L2',\n       'LNFNL4L5', 'LNFNL5S1', 'LNFNL2L3', 'LNFNL3L4', 'LSSL1L2',\n       'RSSL1L2', 'LSSL2L3', 'RSSL2L3', 'LSSL3L4', 'RSSL3L4', 'LSSL4L5',\n       'RSSL4L5', 'LSSL5S1', 'RSSL5S1'] + ['H']\n\nnum_classes = len(classes)\nclass2id = {b: i for i, b in enumerate(classes)}","metadata":{"execution":{"iopub.status.busy":"2024-08-14T10:21:27.204038Z","iopub.execute_input":"2024-08-14T10:21:27.204412Z","iopub.status.idle":"2024-08-14T10:21:27.212031Z","shell.execute_reply.started":"2024-08-14T10:21:27.204378Z","shell.execute_reply":"2024-08-14T10:21:27.211019Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_dir = Path('/kaggle/input/rsna-2024-lumbar-spine-degenerative-classification')\n\nclass CFG:\n\n    project = 'rsna-local'\n    comment = 'first'\n\n    ### model\n    model_name = 'eca_nfnet_l0' # 'resnet34', 'resnet200d', 'efficientnet_b1_pruned', 'efficientnetv2_m', efficientnet_b7 \n\n    image_size = 256\n    \n    ROOT_FOLDER = train_dir\n    IMAGES_DIR = ROOT_FOLDER / 'train_images'\n    TEST_IMAGES_DIR = ROOT_FOLDER / 'test_images'\n    PNG_DIR = ROOT_FOLDER / f'pngs_{image_size}'\n    FILES_CSV = ROOT_FOLDER / 'train_files.csv'\n    TRAIN_CSV = ROOT_FOLDER / 'train.csv'\n    TRAIN_DESC_CSV = ROOT_FOLDER / 'train_series_descriptions.csv'\n    TEST_DESC_CSV = ROOT_FOLDER / 'test_series_descriptions.csv'\n    COORDS_CSV = ROOT_FOLDER / 'train_label_coordinates.csv'\n    SAMPLE_CSV = ROOT_FOLDER / 'sample_submission.csv'\n\n    RESULTS_DIR = train_dir / 'results'\n    CKPT_DIR = RESULTS_DIR / 'ckpt'\n\n    classes = classes\n\n    split_fraction = 0.95\n\n    MIXUP = False\n\n    ### training\n    BATCH_SIZE = 128\n    \n    ### Optimizer\n    N_EPOCHS = 10\n    USE_SCHD = False\n    WARM_EPOCHS = 3\n    COS_EPOCHS = N_EPOCHS - WARM_EPOCHS\n\n    # LEARNING_RATE = 5*1e-5 # best\n    LEARNING_RATE = 5e-5\n    \n    weight_decay = 1e-6 # for adamw\n\n    device = 'cuda' if torch.cuda.is_available() else 'cpu'\n\n    ### split train and validation sets\n    num_workers = 16\n\n    random_seed = 42\n\nCFG.N_LABELS = len(CFG.classes)\n\nseed_torch(seed = CFG.random_seed)","metadata":{"execution":{"iopub.status.busy":"2024-08-14T10:21:27.213319Z","iopub.execute_input":"2024-08-14T10:21:27.213720Z","iopub.status.idle":"2024-08-14T10:21:27.226343Z","shell.execute_reply.started":"2024-08-14T10:21:27.213685Z","shell.execute_reply":"2024-08-14T10:21:27.225363Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"CFG.N_LABELS ","metadata":{"execution":{"iopub.status.busy":"2024-08-14T10:21:27.227804Z","iopub.execute_input":"2024-08-14T10:21:27.228244Z","iopub.status.idle":"2024-08-14T10:21:27.238654Z","shell.execute_reply.started":"2024-08-14T10:21:27.228208Z","shell.execute_reply":"2024-08-14T10:21:27.237532Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Load data","metadata":{}},{"cell_type":"code","source":"test_desc_df = pd.read_csv(CFG.TEST_DESC_CSV)\n# test_desc_df = pd.read_csv(CFG.TRAIN_DESC_CSV)\nsample_df = pd.read_csv(CFG.SAMPLE_CSV)\n\ntest_desc_df.shape, sample_df.shape","metadata":{"execution":{"iopub.status.busy":"2024-08-14T10:21:27.240037Z","iopub.execute_input":"2024-08-14T10:21:27.240462Z","iopub.status.idle":"2024-08-14T10:21:27.261906Z","shell.execute_reply.started":"2024-08-14T10:21:27.240427Z","shell.execute_reply":"2024-08-14T10:21:27.260956Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"test_desc_df.head()","metadata":{"execution":{"iopub.status.busy":"2024-08-14T10:21:27.263041Z","iopub.execute_input":"2024-08-14T10:21:27.263356Z","iopub.status.idle":"2024-08-14T10:21:27.280380Z","shell.execute_reply.started":"2024-08-14T10:21:27.263330Z","shell.execute_reply":"2024-08-14T10:21:27.279259Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# list files\nfiles = [str(item) for item in CFG.TEST_IMAGES_DIR.rglob('*.dcm') ]\nlen(files)","metadata":{"execution":{"iopub.status.busy":"2024-08-14T10:21:27.281646Z","iopub.execute_input":"2024-08-14T10:21:27.282901Z","iopub.status.idle":"2024-08-14T10:21:27.308479Z","shell.execute_reply.started":"2024-08-14T10:21:27.282863Z","shell.execute_reply":"2024-08-14T10:21:27.307261Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"os.listdir(CFG.TEST_IMAGES_DIR)","metadata":{"execution":{"iopub.status.busy":"2024-08-14T10:21:27.309584Z","iopub.execute_input":"2024-08-14T10:21:27.309888Z","iopub.status.idle":"2024-08-14T10:21:27.316891Z","shell.execute_reply.started":"2024-08-14T10:21:27.309864Z","shell.execute_reply":"2024-08-14T10:21:27.315963Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"sample_df.head(3)","metadata":{"execution":{"iopub.status.busy":"2024-08-14T10:21:27.318205Z","iopub.execute_input":"2024-08-14T10:21:27.319049Z","iopub.status.idle":"2024-08-14T10:21:27.335666Z","shell.execute_reply.started":"2024-08-14T10:21:27.319010Z","shell.execute_reply":"2024-08-14T10:21:27.334586Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"sample_df.dtypes","metadata":{"execution":{"iopub.status.busy":"2024-08-14T10:21:27.337118Z","iopub.execute_input":"2024-08-14T10:21:27.337465Z","iopub.status.idle":"2024-08-14T10:21:27.349225Z","shell.execute_reply.started":"2024-08-14T10:21:27.337431Z","shell.execute_reply":"2024-08-14T10:21:27.348224Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"columns = sample_df.columns.to_list()\n\ncolumns","metadata":{"execution":{"iopub.status.busy":"2024-08-14T10:21:27.354876Z","iopub.execute_input":"2024-08-14T10:21:27.355205Z","iopub.status.idle":"2024-08-14T10:21:27.361760Z","shell.execute_reply.started":"2024-08-14T10:21:27.355180Z","shell.execute_reply":"2024-08-14T10:21:27.360710Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"labels = sample_df.row_id.to_list()\nlabels = ['_'.join(l.split('_')[1:]) for l in labels]\n\nlen(labels), labels[:3]","metadata":{"execution":{"iopub.status.busy":"2024-08-14T10:21:27.363152Z","iopub.execute_input":"2024-08-14T10:21:27.363632Z","iopub.status.idle":"2024-08-14T10:21:27.373282Z","shell.execute_reply.started":"2024-08-14T10:21:27.363596Z","shell.execute_reply":"2024-08-14T10:21:27.372338Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"CONDITIONS = [\n    'spinal_canal_stenosis', \n    'left_neural_foraminal_narrowing', \n    'right_neural_foraminal_narrowing',\n    'left_subarticular_stenosis',\n    'right_subarticular_stenosis'\n]\n\nLEVELS = [\n    'l1_l2',\n    'l2_l3',\n    'l3_l4',\n    'l4_l5',\n    'l5_s1',\n]\n\nlabels = ['_'.join([c,l]) for l in LEVELS for c in CONDITIONS]\n\nlen(labels), labels[:3]","metadata":{"execution":{"iopub.status.busy":"2024-08-14T10:22:21.622619Z","iopub.execute_input":"2024-08-14T10:22:21.622978Z","iopub.status.idle":"2024-08-14T10:22:21.631449Z","shell.execute_reply.started":"2024-08-14T10:22:21.622951Z","shell.execute_reply":"2024-08-14T10:22:21.630367Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Dataloader","metadata":{}},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Model","metadata":{}},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Inference","metadata":{}},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Create dataframe","metadata":{}},{"cell_type":"code","source":"ids = test_desc_df.study_id.unique().tolist()\n\n# ids += ids\n\nlen(ids)","metadata":{"execution":{"iopub.status.busy":"2024-08-14T10:22:25.994268Z","iopub.execute_input":"2024-08-14T10:22:25.995025Z","iopub.status.idle":"2024-08-14T10:22:26.001911Z","shell.execute_reply.started":"2024-08-14T10:22:25.994992Z","shell.execute_reply":"2024-08-14T10:22:26.000750Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"ids","metadata":{"execution":{"iopub.status.busy":"2024-08-14T10:22:26.325741Z","iopub.execute_input":"2024-08-14T10:22:26.326504Z","iopub.status.idle":"2024-08-14T10:22:26.332812Z","shell.execute_reply.started":"2024-08-14T10:22:26.326466Z","shell.execute_reply":"2024-08-14T10:22:26.331712Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# ids = os.listdir(CFG.TEST_IMAGES_DIR)\n\n# len(ids)","metadata":{"execution":{"iopub.status.busy":"2024-08-14T10:22:26.940044Z","iopub.execute_input":"2024-08-14T10:22:26.940455Z","iopub.status.idle":"2024-08-14T10:22:26.944769Z","shell.execute_reply.started":"2024-08-14T10:22:26.940424Z","shell.execute_reply":"2024-08-14T10:22:26.943688Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# ids += [1234]","metadata":{"execution":{"iopub.status.busy":"2024-08-14T10:22:27.167306Z","iopub.execute_input":"2024-08-14T10:22:27.167714Z","iopub.status.idle":"2024-08-14T10:22:27.172203Z","shell.execute_reply.started":"2024-08-14T10:22:27.167686Z","shell.execute_reply":"2024-08-14T10:22:27.170855Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"rows = []\n\nvals = [0.1, 0.1, 0.799]\n\nvals = sample_df.iloc[0].values[1:]\n\nfor i in ids:\n    for l in labels:\n        random.shuffle(vals)\n        v = tuple(vals)\n#         rows.append((i, f'{i}_{l}') + v)\n        rows.append((f'{i}_{l}',) + v)\n        \nlen(rows)","metadata":{"execution":{"iopub.status.busy":"2024-08-14T10:22:27.551867Z","iopub.execute_input":"2024-08-14T10:22:27.552219Z","iopub.status.idle":"2024-08-14T10:22:27.560852Z","shell.execute_reply.started":"2024-08-14T10:22:27.552192Z","shell.execute_reply":"2024-08-14T10:22:27.559828Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"vals","metadata":{"execution":{"iopub.status.busy":"2024-08-14T10:22:27.721656Z","iopub.execute_input":"2024-08-14T10:22:27.722056Z","iopub.status.idle":"2024-08-14T10:22:27.728774Z","shell.execute_reply.started":"2024-08-14T10:22:27.722020Z","shell.execute_reply":"2024-08-14T10:22:27.727627Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"rows[0]","metadata":{"execution":{"iopub.status.busy":"2024-08-14T10:22:29.058855Z","iopub.execute_input":"2024-08-14T10:22:29.059232Z","iopub.status.idle":"2024-08-14T10:22:29.065594Z","shell.execute_reply.started":"2024-08-14T10:22:29.059203Z","shell.execute_reply":"2024-08-14T10:22:29.064501Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# submission_df = pd.DataFrame(rows, columns=['study_id'] + columns)\n\nsubmission_df = pd.DataFrame(rows, columns = columns)\n\nsubmission_df.shape","metadata":{"execution":{"iopub.status.busy":"2024-08-14T10:22:33.287454Z","iopub.execute_input":"2024-08-14T10:22:33.288098Z","iopub.status.idle":"2024-08-14T10:22:33.295221Z","shell.execute_reply.started":"2024-08-14T10:22:33.288069Z","shell.execute_reply":"2024-08-14T10:22:33.294098Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"submission_df.head()","metadata":{"execution":{"iopub.status.busy":"2024-08-14T10:22:33.492188Z","iopub.execute_input":"2024-08-14T10:22:33.492592Z","iopub.status.idle":"2024-08-14T10:22:33.504103Z","shell.execute_reply.started":"2024-08-14T10:22:33.492563Z","shell.execute_reply":"2024-08-14T10:22:33.503040Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Submit","metadata":{}},{"cell_type":"code","source":"submission_df.columns.to_list()","metadata":{"execution":{"iopub.status.busy":"2024-08-14T10:22:34.312229Z","iopub.execute_input":"2024-08-14T10:22:34.312624Z","iopub.status.idle":"2024-08-14T10:22:34.319391Z","shell.execute_reply.started":"2024-08-14T10:22:34.312594Z","shell.execute_reply":"2024-08-14T10:22:34.318345Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"columns","metadata":{"execution":{"iopub.status.busy":"2024-08-14T10:22:34.847435Z","iopub.execute_input":"2024-08-14T10:22:34.847793Z","iopub.status.idle":"2024-08-14T10:22:34.854882Z","shell.execute_reply.started":"2024-08-14T10:22:34.847767Z","shell.execute_reply":"2024-08-14T10:22:34.853505Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# submission_df = submission_df.loc[:, columns]\n\n# submission_df.shape","metadata":{"execution":{"iopub.status.busy":"2024-08-14T10:22:35.251319Z","iopub.execute_input":"2024-08-14T10:22:35.251696Z","iopub.status.idle":"2024-08-14T10:22:35.255793Z","shell.execute_reply.started":"2024-08-14T10:22:35.251669Z","shell.execute_reply":"2024-08-14T10:22:35.254764Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"submission_df.dtypes","metadata":{"execution":{"iopub.status.busy":"2024-08-14T10:22:35.737900Z","iopub.execute_input":"2024-08-14T10:22:35.738309Z","iopub.status.idle":"2024-08-14T10:22:35.746080Z","shell.execute_reply.started":"2024-08-14T10:22:35.738262Z","shell.execute_reply":"2024-08-14T10:22:35.745022Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"submission_df.to_csv(\"/kaggle/working/submission.csv\", index=False)","metadata":{"execution":{"iopub.status.busy":"2024-08-14T10:22:36.256819Z","iopub.execute_input":"2024-08-14T10:22:36.257666Z","iopub.status.idle":"2024-08-14T10:22:36.264536Z","shell.execute_reply.started":"2024-08-14T10:22:36.257630Z","shell.execute_reply":"2024-08-14T10:22:36.263196Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"submission_df.head()","metadata":{"execution":{"iopub.status.busy":"2024-08-14T10:22:36.615971Z","iopub.execute_input":"2024-08-14T10:22:36.616355Z","iopub.status.idle":"2024-08-14T10:22:36.627874Z","shell.execute_reply.started":"2024-08-14T10:22:36.616326Z","shell.execute_reply":"2024-08-14T10:22:36.626716Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"submission_df.dtypes, sample_df.dtypes","metadata":{"execution":{"iopub.status.busy":"2024-08-14T10:22:36.975331Z","iopub.execute_input":"2024-08-14T10:22:36.976279Z","iopub.status.idle":"2024-08-14T10:22:36.983807Z","shell.execute_reply.started":"2024-08-14T10:22:36.976241Z","shell.execute_reply":"2024-08-14T10:22:36.982736Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# set(sample_df.row_id.to_list())==set(submission_df.row_id.to_list())","metadata":{"execution":{"iopub.status.busy":"2024-08-14T10:22:39.614129Z","iopub.execute_input":"2024-08-14T10:22:39.614497Z","iopub.status.idle":"2024-08-14T10:22:39.618577Z","shell.execute_reply.started":"2024-08-14T10:22:39.614470Z","shell.execute_reply":"2024-08-14T10:22:39.617629Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"assert len(submission_df) == 25 * len(ids)","metadata":{"execution":{"iopub.status.busy":"2024-08-14T10:22:40.152213Z","iopub.execute_input":"2024-08-14T10:22:40.152607Z","iopub.status.idle":"2024-08-14T10:22:40.157259Z","shell.execute_reply.started":"2024-08-14T10:22:40.152577Z","shell.execute_reply":"2024-08-14T10:22:40.156362Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"len(submission_df)","metadata":{"execution":{"iopub.status.busy":"2024-08-14T10:22:40.925972Z","iopub.execute_input":"2024-08-14T10:22:40.926689Z","iopub.status.idle":"2024-08-14T10:22:40.932934Z","shell.execute_reply.started":"2024-08-14T10:22:40.926653Z","shell.execute_reply":"2024-08-14T10:22:40.931861Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]}]}