{"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":"gpu","dataSources":[{"sourceId":71549,"databundleVersionId":8561470,"sourceType":"competition"},{"sourceId":9195731,"sourceType":"datasetVersion","datasetId":5559249},{"sourceId":9494264,"sourceType":"datasetVersion","datasetId":5777086},{"sourceId":9769250,"sourceType":"datasetVersion","datasetId":5983464},{"sourceId":9828781,"sourceType":"datasetVersion","datasetId":5930251},{"sourceId":193161758,"sourceType":"kernelVersion"},{"sourceId":194526416,"sourceType":"kernelVersion"},{"sourceId":204240454,"sourceType":"kernelVersion"}],"dockerImageVersionId":30747,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":true}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"import os\nimport pandas as pd\nimport numpy as np\nimport pydicom\nfrom tqdm.auto import tqdm\nimport matplotlib.pyplot as plt\nimport cv2\nimport glob","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"!wandb off","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Install the ultralytics package from GitHub\n!pip install git+https://github.com/lll8866/ultralytics_RSNA-2024.git@main","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-11-08T04:58:47.063447Z","iopub.execute_input":"2024-11-08T04:58:47.064111Z","iopub.status.idle":"2024-11-08T04:59:16.578354Z","shell.execute_reply.started":"2024-11-08T04:58:47.064074Z","shell.execute_reply":"2024-11-08T04:59:16.577436Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"查看'Normal/Mild', 'Moderate', 'Severe' 标签分布情况","metadata":{}},{"cell_type":"code","source":"# flag = 0\n# re = []\n# j = 0\n\n# for i in glob.glob('/kaggle/working/data_fold0/labels/train/*.txt'):\n#     data = np.loadtxt(i)\n#     if len(data.shape)>1:\n#         r = data[:,0].astype(int)\n#         r2 = set([item%3 for item in r])\n            \n#         if len(r2)>1 and 2 in r2:\n#             flag+=1\n#             re.append([r,r2])\n    \n#     j+=1\n# #     if j==10:break\n\n# # print(re)\n# print(flag)\n# print(j)\n    ","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"IMG_DIR = \"/kaggle/input/rsna-2024-lumbar-spine-degenerative-classification/train_images\"","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"FOLD = 0\nOD_INPUT_SIZE = 384\nSTD_BOX_SIZE = 20\nBATCH_SIZE = 64\nEPOCHS = 80\n\nSAMPLE = None\nCONDITIONS = ['Left Subarticular Stenosis', 'Right Subarticular Stenosis']\nSEVERITIES = ['Normal/Mild', 'Moderate', 'Severe']\nLEVELS = ['l1_l2', 'l2_l3', 'l3_l4', 'l4_l5', 'l5_s1']\n\nDATA_DIR = f'data_fold{FOLD}'\n\n","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# rm -rf val_fold0","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"train_val_df = pd.read_csv('/kaggle/input/rsna-2024-lumbar-spine-degenerative-classification/train.csv')\ntrain_xy = pd.read_csv('/kaggle/input/rsna-2024-lumbar-spine-degenerative-classification/train_label_coordinates.csv')\ntrain_des = pd.read_csv('/kaggle/input/rsna-2024-lumbar-spine-degenerative-classification/train_series_descriptions.csv')","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"if SAMPLE:\n    train_val_df = train_val_df.sample(SAMPLE, random_state=2698)","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"fold_df = pd.read_csv('/kaggle/input/lsdc-fold-split/5folds.csv')","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"train_xy.head(3)","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"def get_level(text):\n    for lev in ['l1_l2', 'l2_l3', 'l3_l4', 'l4_l5', 'l5_s1']:\n        if lev in text:\n            split = lev.split('_')\n            split[0] = split[0].capitalize()\n            split[1] = split[1].capitalize()\n            return '/'.join(split)\n    raise ValueError('Level not found '+ lev)\n    \ndef get_condition(text):\n    split = text.split('_')\n    for i in range(len(split)):\n        split[i] = split[i].capitalize()\n    split = split[:-2]\n    return ' '.join(split)\n#     raise ValueError('Condition not found '+ lev)","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"train_xy['condition'].unique()","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# train_df = train_df.dropna()","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"label_df = {'study_id':[], 'condition': [], 'level':[], 'label':[]}\n\nfor i, row in train_val_df.iterrows():\n    study_id = row['study_id']\n    for k, label in row.iloc[1:].to_dict().items():\n        level = get_level(k)\n        condition = get_condition(k)\n        label_df['study_id'].append(study_id)\n        label_df['condition'].append(condition)\n        label_df['level'].append(level)\n        label_df['label'].append(label)\n#         break\n#     break\n\nlabel_df = pd.DataFrame(label_df)\nlabel_df = label_df.merge(fold_df, on='study_id')","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"train_xy = train_xy.merge(train_des, how='inner', on=['study_id', 'series_id'])\nlabel_df = label_df.merge(train_xy, how='inner', on=['study_id', 'condition', 'level'])","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"def query_train_xy_row(study_id, series_id=None, instance_num=None):\n    if series_id is not None and instance_num is not None:\n        return label_df[(label_df.study_id==study_id) & (label_df.series_id==series_id) &\n            (label_df.instance_number==instance_num)]\n    elif series_id is None and instance_num is None:\n        return label_df[(label_df.study_id==study_id)]\n    else:\n        return label_df[(train_xy.study_id==study_id) & (label_df.series_id==series_id)]","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"def read_dcm(src_path):\n    dicom_data = pydicom.dcmread(src_path)\n    image = dicom_data.pixel_array\n    image = (image - image.min()) / (image.max() - image.min() +1e-6) * 255\n    image = np.stack([image]*3, axis=-1).astype('uint8')\n    return image\n\ndef get_accronym(text):\n    split = text.split(' ')\n    return ''.join([x[0] for x in split])","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# study_id = 4003253 \n# series_id = 2448190387\n# instance_num = 28\n\nex = label_df.sample(1).iloc[0]\nstudy_id = ex.study_id\nseries_id = ex.series_id\ninstance_num = ex.instance_number\n\nWIDTH = 15\n\npath = os.path.join(IMG_DIR, str(study_id), str(series_id), f'{instance_num}.dcm')","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"\nWIDTH = 15\nimg = read_dcm(path)\n\ntmp_df = query_train_xy_row(study_id, series_id, instance_num)\nfor i, row in tmp_df.iterrows():\n    lbl = f\"{get_accronym(row['condition'])}_{row['level']}\"\n    x, y = row['x'], row['y']\n    x1 = int(x - WIDTH)\n    x2 = int(x + WIDTH)\n    y1 = int(y - WIDTH)\n    y2 = int(y + WIDTH)\n    color = None\n    if row['label'] == 'Normal/Mild':\n        color =  (0, 255, 0)\n    elif row['label'] == 'Moderate':\n        color = (255,255,0) \n    elif row['label'] == 'Severe':\n        color = (255,0,0)\n        \n    fontFace = cv2.FONT_HERSHEY_SIMPLEX\n    fontScale = 0.5\n    thickness = 1\n    cv2.rectangle(img, (x1,y1), (x2,y2), color, 2)\n    cv2.putText(img, lbl, (x1,y1), fontFace, fontScale, color, thickness, cv2.LINE_AA)\nplt.imshow(img)\nplt.show()\ntmp_df","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# label_df[['study_id', 'series_id']].drop_duplicates()","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"def read_dcm(src_path):\n    dicom_data = pydicom.dcmread(src_path)\n    image = dicom_data.pixel_array\n    image = (image - image.min()) / (image.max() - image.min() +1e-6) * 255\n    image = np.stack([image]*3, axis=-1).astype('uint8')\n    return image","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"filtered_df = label_df[label_df.condition.map(lambda x: x in CONDITIONS)]","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"label2id = {}\nid2label = {}\ni = 0\nfor cond in CONDITIONS:\n    for level in LEVELS:\n        for severity in SEVERITIES:\n            cls_ = f\"{cond.lower().replace(' ', '_')}_{level}_{severity.lower()}\"\n            label2id[cls_] = i\n            id2label[i] = cls_\n            i+=1","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"id2label","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"train_df = filtered_df[filtered_df.fold != FOLD]\nval_df = filtered_df[filtered_df.fold == FOLD]","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# # # test generated annotations\n\n# _IM_DIR = f'{DATA_DIR}/images/train'\n# _ANN_DIR = f'{DATA_DIR}/labels/train'\n# name = np.random.choice(os.listdir(_IM_DIR))[:-4]\n\n# im = plt.imread(os.path.join(_IM_DIR, name+'.jpg')).copy()\n# H,W = im.shape[:2]\n# anns = np.loadtxt(os.path.join(_ANN_DIR, name+'.txt')).reshape(-1, 5)\n# for _cls, x,y,w,h in anns.tolist():\n#     x *= W\n#     y *= H\n#     w *= W\n#     h *= H\n#     x1 = int(x-w/2)\n#     x2 = int(x+w/2)\n#     y1 = int(y-h/2)\n#     y2 = int(y+h/2)\n#     label = id2label[_cls]\n    \n# #     if _cls == 0:\n# #         c = (255,0,0)\n# #     elif _cls == 1:\n# #         c = (0,255,0)\n# #     else:\n# #         c = (255,255,0)\n#     c = (0,255,255)\n\n#     im = cv2.rectangle(im, (x1,y1), (x2,y2), c, 2)\n#     cv2.putText(im, label, (x1,y1), fontFace, 0.3, c, 1, cv2.LINE_AA)\n\n\n# plt.imshow(im)","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"for k, v in id2label.items():\n    print(f'{k}: {v}')","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"ls","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"%%writefile yolov8_p2BiFPN.yaml\n# Ultralytics YOLO 🚀, AGPL-3.0 license\n# YOLOv8 object detection model with P3-P5 outputs. For Usage examples see https://docs.ultralytics.com/tasks/detect\n \n# Parameters\nnc: 80  # number of classes\nscales: # model compound scaling constants, i.e. 'model=yolov8n.yaml' will call yolov8.yaml with scale 'n'\n  # [depth, width, max_channels]\n#   n: [0.33, 0.25, 1024]  # YOLOv8n summary: 225 layers,  3157200 parameters,  3157184 gradients,   8.9 GFLOPs\n  s: [0.33, 0.50, 1024]  # YOLOv8s summary: 225 layers, 11166560 parameters, 11166544 gradients,  28.8 GFLOPs\n#   m: [0.67, 0.75, 768]   # YOLOv8m summary: 295 layers, 25902640 parameters, 25902624 gradients,  79.3 GFLOPs\n#   l: [1.00, 1.00, 512]   # YOLOv8l summary: 365 layers, 43691520 parameters, 43691504 gradients, 165.7 GFLOPs\n#   x: [1.00, 1.25, 512]   # YOLOv8x summary: 365 layers, 68229648 parameters, 68229632 gradients, 258.5 GFLOPs\n \n# YOLOv8.0n backbone\nbackbone:\n  # [from, repeats, module, args]\n  - [-1, 1, Conv, [64, 3, 2]]  # 0-P1/2\n  - [-1, 1, Conv, [128, 3, 2]]  # 1-P2/4\n  - [-1, 3, C2f, [128, True]]\n  - [-1, 1, Conv, [256, 3, 2]]  # 3-P3/8\n  - [-1, 6, C2f, [256, True]]\n  - [-1, 1, Conv, [512, 3, 2]]  # 5-P4/16\n  - [-1, 6, C2f, [512, True]]\n  - [-1, 1, Conv, [1024, 3, 2]]  # 7-P5/32\n  - [-1, 3, C2f, [1024, True]]\n  - [-1, 1, SPPF, [1024, 5]]  # 9\n \n# YOLOv8.0n head\nhead:\n  - [4, 1, Conv, [256]]  # 10\n  - [6, 1, Conv, [256]]  # 11\n  - [9, 1, Conv, [256]]  # 12\n \n  - [-1, 1,  nn.Upsample, [None, 2, 'nearest']] \n  - [[-1, 11], 1, Concat, [1]] \n  - [-1, 3, C2f, [256]] # 15\n \n  - [-1, 1,  nn.Upsample, [None, 2, 'nearest']] \n  - [[-1, 10], 1, Concat, [1]] \n  - [-1, 3, C2f, [256]] \n  - [-1, 1,  nn.Upsample, [None, 2, 'nearest']] #19\n\n  - [2, 1,  Conv, [256]] \n  - [[-1, 19], 1, Concat, [1]]\n  - [-1, 3, C2f, [256]] #22\n \n  - [-1, 1, Conv, [256, 3, 2]]\n  - [[-1, 10, 18], 1, Concat, [1]] \n  - [-1, 3, C2f, [256]] # 25\n \n  - [-1, 1, Conv, [256, 3, 2]] \n  - [[-1, 11, 15], 1, Concat, [1]] \n  - [-1, 3, C2f, [256]] # 28\n \n  - [-1, 1, Conv, [256, 3, 2]] \n  - [[-1, 12], 1, Concat, [1]] \n  - [-1, 3, C2f, [256]] # 31\n \n  - [[22, 25, 28, 31], 1, Detect, [nc]]  # Detect(P2, P3, P4, P5)","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"%%writefile yolo_scs.yaml\npath: /kaggle/input/ss-data21/data_fold0 # dataset root dir\ntrain: images/train  \nval: images/val \ntest: images/val \n\n# Classes\nnames:\n    0: left_subarticular_stenosis_l1_l2_normal/mild\n    1: left_subarticular_stenosis_l1_l2_moderate\n    2: left_subarticular_stenosis_l1_l2_severe\n    3: left_subarticular_stenosis_l2_l3_normal/mild\n    4: left_subarticular_stenosis_l2_l3_moderate\n    5: left_subarticular_stenosis_l2_l3_severe\n    6: left_subarticular_stenosis_l3_l4_normal/mild\n    7: left_subarticular_stenosis_l3_l4_moderate\n    8: left_subarticular_stenosis_l3_l4_severe\n    9: left_subarticular_stenosis_l4_l5_normal/mild\n    10: left_subarticular_stenosis_l4_l5_moderate\n    11: left_subarticular_stenosis_l4_l5_severe\n    12: left_subarticular_stenosis_l5_s1_normal/mild\n    13: left_subarticular_stenosis_l5_s1_moderate\n    14: left_subarticular_stenosis_l5_s1_severe\n    15: right_subarticular_stenosis_l1_l2_normal/mild\n    16: right_subarticular_stenosis_l1_l2_moderate\n    17: right_subarticular_stenosis_l1_l2_severe\n    18: right_subarticular_stenosis_l2_l3_normal/mild\n    19: right_subarticular_stenosis_l2_l3_moderate\n    20: right_subarticular_stenosis_l2_l3_severe\n    21: right_subarticular_stenosis_l3_l4_normal/mild\n    22: right_subarticular_stenosis_l3_l4_moderate\n    23: right_subarticular_stenosis_l3_l4_severe\n    24: right_subarticular_stenosis_l4_l5_normal/mild\n    25: right_subarticular_stenosis_l4_l5_moderate\n    26: right_subarticular_stenosis_l4_l5_severe\n    27: right_subarticular_stenosis_l5_s1_normal/mild\n    28: right_subarticular_stenosis_l5_s1_moderate\n    29: right_subarticular_stenosis_l5_s1_severe\n  ","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# import wandb\n# from wandb.integration.ultralytics import add_wandb_callback\n\n# from kaggle_secrets import UserSecretsClient\n# user_secrets = UserSecretsClient()\n# secret_value_0 = user_secrets.get_secret(\"wandbkey\")\n# wandb.login(key=secret_value_0)","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# # Initialize W&B run\n# wandb.init(\n#     project=\"lsdc_yolov8\",\n# #     name=f\"Demo_fold0\",\n# #     tags=[\"baseline\", \"search-lr\", ],\n#     group=\";\".join(CONDITIONS),\n# #     config={\n# #         \"lr\": LR,\n# #         \"model-name\":\"xtremedistill-trim\",\n# #         \"dataset\": [\n# #             \"raw_compettion\",\n# #             \"MPWare\",\n# #             \"Nicholas\"\n# #         ]\n# #     }\n# )","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"from ultralytics import YOLO\nimport ultralytics\nimport torch\nimport warnings\nimport torch.nn.init as init\n\nwith warnings.catch_warnings():\n    warnings.simplefilter(\"ignore\")\n    # Initialize YOLO Model\n#     model = YOLO(\"yolov8_p2BiFPN.yaml\")\n    model = YOLO(\"yolov8s.pt\")\n\n#     新加入模块的参数初始化 xavier_normal_\n#     init.xavier_normal_(model.model.model[9].conv_h.weight)  #CA\n#     init.xavier_normal_(model.model.model[9].conv_w.weight)  #CA\n#     init.xavier_normal_(model.model.model[9].conv2.conv.weight)  #CAA\n\n#     xavier_uniform_\n#     init.xavier_uniform_(model.model.model[9].conv_h.weight)  #CA\n#     init.xavier_uniform_(model.model.model[9].conv_w.weight)  #CA\n#     init.xavier_uniform_(model.model.model[9].conv2.conv.weight)  #CAA \n\n# 加载模型预训练参数\n#     model.load('/kaggle/input/yolo-base-weights/yolov8s.pt')\n#     model.load('/kaggle/working/lsdc_yolov8/train29/weights/best.pt')\n\n# 模型训练\n    model.train(project=\"lsdc_yolov8\", data=\"yolo_scs.yaml\", \n                epochs=EPOCHS, imgsz=OD_INPUT_SIZE, batch=BATCH_SIZE, optimizer='AdamW', lr0=5e-5)","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-11-08T04:59:37.072876Z","iopub.execute_input":"2024-11-08T04:59:37.073818Z","iopub.status.idle":"2024-11-08T04:59:37.081587Z","shell.execute_reply.started":"2024-11-08T04:59:37.073783Z","shell.execute_reply":"2024-11-08T04:59:37.080007Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"","metadata":{"trusted":true},"outputs":[],"execution_count":null}]}