{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.10.12","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"none","dataSources":[{"sourceId":36363,"databundleVersionId":4050810,"sourceType":"competition"},{"sourceId":5718655,"sourceType":"datasetVersion","datasetId":2373279},{"sourceId":6587064,"sourceType":"datasetVersion","datasetId":3802375},{"sourceId":6733646,"sourceType":"datasetVersion","datasetId":3878164},{"sourceId":213440416,"sourceType":"kernelVersion"},{"sourceId":200858,"sourceType":"modelInstanceVersion","isSourceIdPinned":true,"modelInstanceId":171346,"modelId":193671}],"dockerImageVersionId":30558,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":false}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"# # This Python 3 environment comes with many helpful analytics libraries installed\n# # It is defined by the kaggle/python Docker image: https://github.com/kaggle/docker-python\n# # For example, here's several helpful packages to load\n\n# import numpy as np # linear algebra\n# import pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)\n\n# # Input data files are available in the read-only \"../input/\" directory\n# # For example, running this (by clicking run or pressing Shift+Enter) will list all files under the input directory\n\n# import os\n# for dirname, _, filenames in os.walk('/kaggle/input'):\n#     for filename in filenames:\n#         print(os.path.join(dirname, filename))\n\n# # You can write up to 20GB to the current directory (/kaggle/working/) that gets preserved as output when you create a version using \"Save & Run All\" \n# # You can also write temporary files to /kaggle/temp/, but they won't be saved outside of the current session","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"\n!pip install -qU ../input/for-pydicom/python_gdcm-3.0.22-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl ../input/for-pydicom/pylibjpeg-1.4.0-py3-none-any.whl --find-links frozen_packages --no-index","metadata":{"execution":{"iopub.status.busy":"2024-12-17T03:20:20.911543Z","iopub.execute_input":"2024-12-17T03:20:20.912208Z","iopub.status.idle":"2024-12-17T03:20:34.015313Z","shell.execute_reply.started":"2024-12-17T03:20:20.912148Z","shell.execute_reply":"2024-12-17T03:20:34.014018Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import pandas as pd\nimport numpy as np\nimport pydicom as dicom\nimport glob\nimport nibabel as nib\nimport os\nimport cv2\nfrom tqdm import tqdm\nimport tensorflow as tf\nimport tensorflow.keras.layers as tfl\nfrom tensorflow.keras import backend as K\nfrom sklearn.model_selection import StratifiedKFold\nfrom tensorflow.keras.preprocessing.image import load_img, img_to_array\nfrom tensorflow.keras.applications import EfficientNetB0\nimport keras\nfrom keras.models import Sequential\nfrom keras.layers import Dense, Dropout, Flatten\nfrom keras.layers import Conv2D, MaxPooling2D\nfrom keras.utils import to_categorical\nfrom keras.preprocessing import image\nimport matplotlib.pyplot as plt\nfrom sklearn.model_selection import train_test_split\nfrom sklearn.metrics import confusion_matrix, classification_report\nimport seaborn as sns\nfrom sklearn.metrics import roc_curve, auc\nfrom sklearn.metrics import ConfusionMatrixDisplay\nfrom shutil import copy\nfrom tensorflow.keras.models import load_model\nfrom tensorflow.image import resize\nimport pydicom","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-17T03:22:28.735184Z","iopub.execute_input":"2024-12-17T03:22:28.73564Z","iopub.status.idle":"2024-12-17T03:22:41.03196Z","shell.execute_reply.started":"2024-12-17T03:22:28.735603Z","shell.execute_reply":"2024-12-17T03:22:41.030638Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"base_dir = r'/kaggle/input/rsna-2022-cervical-spine-fracture-detection'\ntrain_images = os.path.join(base_dir,'train_images')\ntest_images = os.path.join(base_dir,'test_images')\nsegmentation_data = r'/kaggle/input/rsna-cervical-fracture-segmentations-npy/npy_segmentations'\ntrain_data = pd.read_csv(os.path.join(base_dir,'train.csv'))\nsegmentation_meta_data = pd.read_csv(r'/kaggle/input/rsna-cervical-fracture-segmentation-metadata/meta_segmentation.csv')\n","metadata":{"execution":{"iopub.status.busy":"2024-12-17T03:23:07.801532Z","iopub.execute_input":"2024-12-17T03:23:07.802395Z","iopub.status.idle":"2024-12-17T03:23:08.081143Z","shell.execute_reply.started":"2024-12-17T03:23:07.802347Z","shell.execute_reply":"2024-12-17T03:23:08.080073Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"segmentation_meta_data.shape","metadata":{"execution":{"iopub.status.busy":"2024-12-17T03:23:10.35371Z","iopub.execute_input":"2024-12-17T03:23:10.354229Z","iopub.status.idle":"2024-12-17T03:23:10.364475Z","shell.execute_reply.started":"2024-12-17T03:23:10.354187Z","shell.execute_reply":"2024-12-17T03:23:10.362865Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"segmentation_meta_data.columns","metadata":{"execution":{"iopub.status.busy":"2024-12-17T03:23:11.765958Z","iopub.execute_input":"2024-12-17T03:23:11.766377Z","iopub.status.idle":"2024-12-17T03:23:11.774803Z","shell.execute_reply.started":"2024-12-17T03:23:11.766344Z","shell.execute_reply":"2024-12-17T03:23:11.773325Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"columns = ['StudyInstanceUID','SOPInstanceUID','C1','C2','C3','C4','C5','C6','C7']","metadata":{"execution":{"iopub.status.busy":"2024-12-17T03:23:15.092195Z","iopub.execute_input":"2024-12-17T03:23:15.092577Z","iopub.status.idle":"2024-12-17T03:23:15.09867Z","shell.execute_reply.started":"2024-12-17T03:23:15.092545Z","shell.execute_reply":"2024-12-17T03:23:15.097081Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"seg_labels = segmentation_meta_data[columns]","metadata":{"execution":{"iopub.status.busy":"2024-12-17T03:23:17.504221Z","iopub.execute_input":"2024-12-17T03:23:17.504661Z","iopub.status.idle":"2024-12-17T03:23:17.530531Z","shell.execute_reply.started":"2024-12-17T03:23:17.504619Z","shell.execute_reply":"2024-12-17T03:23:17.528836Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"seg_labels.head(2)","metadata":{"execution":{"iopub.status.busy":"2024-12-17T03:23:19.948436Z","iopub.execute_input":"2024-12-17T03:23:19.948889Z","iopub.status.idle":"2024-12-17T03:23:19.967408Z","shell.execute_reply.started":"2024-12-17T03:23:19.948854Z","shell.execute_reply":"2024-12-17T03:23:19.965701Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"#Get Slice instance number\nseg_labels.loc[:,'slice'] = seg_labels['SOPInstanceUID'].apply(lambda x:x.split('.')[-1:][0])","metadata":{"execution":{"iopub.status.busy":"2024-12-17T03:23:22.978622Z","iopub.execute_input":"2024-12-17T03:23:22.979111Z","iopub.status.idle":"2024-12-17T03:23:23.007151Z","shell.execute_reply.started":"2024-12-17T03:23:22.979072Z","shell.execute_reply":"2024-12-17T03:23:23.005682Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"def load_dicom(path):\n    '''Function to load and transform DICOM images'''\n    img=dicom.dcmread(path)\n    img.PhotometricInterpretation = 'YBR_FULL'\n    data=img.pixel_array\n    data=data-np.min(data)\n    if np.max(data) != 0:\n        data=data/np.max(data)\n    data=(data*255).astype(np.uint8)        \n    return cv2.cvtColor(data.reshape(512, 512), cv2.COLOR_GRAY2RGB)","metadata":{"execution":{"iopub.status.busy":"2024-12-17T03:23:25.085454Z","iopub.execute_input":"2024-12-17T03:23:25.087067Z","iopub.status.idle":"2024-12-17T03:23:25.094332Z","shell.execute_reply.started":"2024-12-17T03:23:25.087017Z","shell.execute_reply":"2024-12-17T03:23:25.092845Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"def ImgDataGenerator(train_df,base_path):\n        '''Function to read dicom image path and store the images as numpy arrays'''\n        trainset = []\n        trainlabel = []\n        for i in tqdm(range(len(train_df))):\n            study_id = train_df.loc[i,'StudyInstanceUID']\n            slice_id = train_df.loc[i,'slice']+'.dcm'\n            study_path = study_id+'/'+slice_id\n            \n            path = os.path.join(base_path, study_path)\n      \n                #dc = dicom.read_file(os.path.join(path,im))\n            #if dc.file_meta.TransferSyntaxUID.name =='JPEG Lossless, Non-Hierarchical, First-Order Prediction (Process 14 [Selection Value 1])':\n            #    continue\n            img = load_dicom(path)\n            img = cv2.resize(img, (128 , 128))\n            image = img_to_array(img)\n            image = image / 255.0\n            trainset += [image]\n            cur_label = [train_df.loc[i,f'C{j}'] for j in range(1,8)]\n            trainlabel += [cur_label]\n\n                         \n                \n        return np.array(trainset), np.array(trainlabel)\n","metadata":{"execution":{"iopub.status.busy":"2024-12-17T03:23:26.130924Z","iopub.execute_input":"2024-12-17T03:23:26.131944Z","iopub.status.idle":"2024-12-17T03:23:26.139648Z","shell.execute_reply.started":"2024-12-17T03:23:26.131897Z","shell.execute_reply":"2024-12-17T03:23:26.138424Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# def RSNAImgArrayGenerator(ids,base_path):\n#     '''Function to generate numpy array for test dataset'''\n           \n#     testset=[]\n#     for id in tqdm(ids):        \n#         path = os.path.join(base_path, id)\n#         if os.path.exists(path):\n#             for im in (os.listdir(path)):\n#                 dc = dicom.read_file(os.path.join(path,im))\n#                 img=load_dicom(os.path.join(path,im))\n#                 img=cv2.resize(img,(128, 128))\n#                 image=img_to_array(img)\n#                 image=image/255.0\n#                 testset+=[image]\n#     return np.array(testset)\n","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"#Get list of study ids who doesn't have segmentation data\nnon_seg_train_ids = [id for id in train_data['StudyInstanceUID'].unique() if id not in seg_labels['StudyInstanceUID'].unique()]","metadata":{"execution":{"iopub.status.busy":"2024-12-17T03:23:31.345366Z","iopub.execute_input":"2024-12-17T03:23:31.345798Z","iopub.status.idle":"2024-12-17T03:23:35.399298Z","shell.execute_reply.started":"2024-12-17T03:23:31.345737Z","shell.execute_reply":"2024-12-17T03:23:35.39815Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"len(non_seg_train_ids)","metadata":{"execution":{"iopub.status.busy":"2024-12-17T03:24:05.921873Z","iopub.execute_input":"2024-12-17T03:24:05.922319Z","iopub.status.idle":"2024-12-17T03:24:05.931336Z","shell.execute_reply.started":"2024-12-17T03:24:05.922289Z","shell.execute_reply":"2024-12-17T03:24:05.929695Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"#non_seg_training_data = RSNAImgArrayGenerator(non_seg_train_ids,train_images)","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"#Fetch training data for study ids who doesn't have segmentation images\nnon_seg_train_data = train_data[train_data['StudyInstanceUID'].isin(non_seg_train_ids)]","metadata":{"execution":{"iopub.status.busy":"2024-12-17T03:24:09.930224Z","iopub.execute_input":"2024-12-17T03:24:09.930626Z","iopub.status.idle":"2024-12-17T03:24:09.940585Z","shell.execute_reply.started":"2024-12-17T03:24:09.930596Z","shell.execute_reply":"2024-12-17T03:24:09.939239Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"non_seg_train_data.head(2)","metadata":{"execution":{"iopub.status.busy":"2024-12-17T03:24:11.824985Z","iopub.execute_input":"2024-12-17T03:24:11.825394Z","iopub.status.idle":"2024-12-17T03:24:11.839343Z","shell.execute_reply.started":"2024-12-17T03:24:11.825366Z","shell.execute_reply":"2024-12-17T03:24:11.837954Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"#Convert train images of segmented studyids to array\nX_seg,y_seg = ImgDataGenerator(seg_labels,train_images)\n\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-17T03:24:16.702702Z","iopub.execute_input":"2024-12-17T03:24:16.703354Z","iopub.status.idle":"2024-12-17T03:37:04.460461Z","shell.execute_reply.started":"2024-12-17T03:24:16.703299Z","shell.execute_reply":"2024-12-17T03:37:04.458589Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"#save for future use\nnp.save('/kaggle/working/seg_train_images.npy',X_seg)\nnp.save('/kaggle/working/seg_train_images_labels.npy',y_seg)","metadata":{"execution":{"iopub.status.busy":"2024-12-17T03:39:06.773318Z","iopub.execute_input":"2024-12-17T03:39:06.774665Z","iopub.status.idle":"2024-12-17T03:39:19.122998Z","shell.execute_reply.started":"2024-12-17T03:39:06.77461Z","shell.execute_reply":"2024-12-17T03:39:19.119537Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Uncomment this if you want to use the above output in the next run\nX_seg = np.load(r'/kaggle/input/identify-vertebrae-using-cnn/seg_train_images.npy')\ny_seg = np.load(r'/kaggle/input/identify-vertebrae-using-cnn/seg_train_images_labels.npy')","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-17T02:32:32.762215Z","iopub.execute_input":"2024-12-17T02:32:32.762627Z","iopub.status.idle":"2024-12-17T02:33:00.068867Z","shell.execute_reply.started":"2024-12-17T02:32:32.762595Z","shell.execute_reply":"2024-12-17T02:33:00.067753Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"print(X_seg.shape,y_seg.shape)","metadata":{"execution":{"iopub.status.busy":"2024-12-17T03:39:32.353434Z","iopub.execute_input":"2024-12-17T03:39:32.354015Z","iopub.status.idle":"2024-12-17T03:39:32.364744Z","shell.execute_reply.started":"2024-12-17T03:39:32.353968Z","shell.execute_reply":"2024-12-17T03:39:32.362868Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"#Visualize a random CT scan image\nimport matplotlib.pyplot as plt\nplt.imshow(X_seg[500], cmap = 'bone')","metadata":{"execution":{"iopub.status.busy":"2024-12-17T03:39:34.340723Z","iopub.execute_input":"2024-12-17T03:39:34.34121Z","iopub.status.idle":"2024-12-17T03:39:34.738664Z","shell.execute_reply.started":"2024-12-17T03:39:34.341175Z","shell.execute_reply":"2024-12-17T03:39:34.737022Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"#Find its segmentation value. \ny_seg[500]\n#The above slice represents cervicals C3 and C4","metadata":{"execution":{"iopub.status.busy":"2024-12-17T03:39:38.735895Z","iopub.execute_input":"2024-12-17T03:39:38.736361Z","iopub.status.idle":"2024-12-17T03:39:38.746014Z","shell.execute_reply.started":"2024-12-17T03:39:38.73632Z","shell.execute_reply":"2024-12-17T03:39:38.744453Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"\n# Sensitivity (Recall)\ndef sensitivity(y_true, y_pred):\n    true_positives = K.sum(K.round(K.clip(y_true * y_pred, 0, 1)))\n    possible_positives = K.sum(K.round(K.clip(y_true, 0, 1)))\n    return true_positives / (possible_positives + K.epsilon())\n\n# Specificity\ndef specificity(y_true, y_pred):\n    true_negatives = K.sum(K.round(K.clip((1 - y_true) * (1 - y_pred), 0, 1)))\n    possible_negatives = K.sum(K.round(K.clip(1 - y_true, 0, 1)))\n    return true_negatives / (possible_negatives + K.epsilon())\n\n# F1 Score\ndef f1_score(y_true, y_pred):\n    precision = K.sum(K.round(K.clip(y_true * y_pred, 0, 1))) / (K.sum(K.round(K.clip(y_pred, 0, 1))) + K.epsilon())\n    recall = sensitivity(y_true, y_pred)\n    return 2 * ((precision * recall) / (precision + recall + K.epsilon()))","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-17T03:39:41.549241Z","iopub.execute_input":"2024-12-17T03:39:41.549675Z","iopub.status.idle":"2024-12-17T03:39:41.561962Z","shell.execute_reply.started":"2024-12-17T03:39:41.549636Z","shell.execute_reply":"2024-12-17T03:39:41.559725Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"def get_basic_cnn():\n    '''Basic Convolutional Neural Network to train segmentation CT scan images'''\n    inp = tfl.Input((128, 128 ,3))\n    x = tfl.Conv2D(32, (3, 3), activation='relu')(inp)\n    x = tfl.MaxPooling2D((2, 2))(x)\n    x = tfl.Conv2D(64, (3, 3), activation='relu')(x)  # Fixed issue with the second convolution layer using 'inp' instead of 'x'\n    x = tfl.MaxPooling2D((2, 2))(x)\n    x = tfl.Conv2D(128, (3, 3), activation='relu')(x)  # Fixed issue here as well\n    x = tfl.MaxPooling2D((2, 2))(x)\n    x = tfl.Flatten()(x)\n    x = tfl.Dense(128, 'relu')(x)\n    x = tfl.Dropout(0.5)(x)\n    out = tfl.Dense(7, 'sigmoid')(x)\n    \n    model = tf.keras.models.Model(inp, out)\n    \n    model.compile(loss=\"binary_crossentropy\",\n                  optimizer=tf.keras.optimizers.Adam(learning_rate=1e-4),\n                  metrics=[tf.keras.metrics.BinaryAccuracy(), sensitivity, specificity, f1_score])  # Added custom metrics\n    \n    model.summary()\n    \n    return model","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-17T03:39:43.078599Z","iopub.execute_input":"2024-12-17T03:39:43.079509Z","iopub.status.idle":"2024-12-17T03:39:43.088526Z","shell.execute_reply.started":"2024-12-17T03:39:43.079464Z","shell.execute_reply":"2024-12-17T03:39:43.087127Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"X_train, X_test, y_train, y_test = train_test_split(X_seg, y_seg, random_state=42, test_size=0.1)","metadata":{"execution":{"iopub.status.busy":"2024-12-17T03:39:44.922321Z","iopub.execute_input":"2024-12-17T03:39:44.922809Z","iopub.status.idle":"2024-12-17T03:39:52.568196Z","shell.execute_reply.started":"2024-12-17T03:39:44.922746Z","shell.execute_reply":"2024-12-17T03:39:52.566834Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"print(X_train.shape,y_train.shape)\nprint(X_test.shape,y_test.shape)","metadata":{"execution":{"iopub.status.busy":"2024-12-17T03:39:53.967861Z","iopub.execute_input":"2024-12-17T03:39:53.969036Z","iopub.status.idle":"2024-12-17T03:39:53.975397Z","shell.execute_reply.started":"2024-12-17T03:39:53.968991Z","shell.execute_reply":"2024-12-17T03:39:53.973873Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"model = get_basic_cnn()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-17T03:39:59.343578Z","iopub.execute_input":"2024-12-17T03:39:59.344092Z","iopub.status.idle":"2024-12-17T03:39:59.886072Z","shell.execute_reply.started":"2024-12-17T03:39:59.344042Z","shell.execute_reply":"2024-12-17T03:39:59.884471Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"history = model.fit(X_train, y_train, epochs=10, validation_data=(X_test, y_test), batch_size=64)","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"model.save('/kaggle/working/cnn_model.h5')","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-17T03:42:16.30493Z","iopub.execute_input":"2024-12-17T03:42:16.305444Z","iopub.status.idle":"2024-12-17T03:42:16.421239Z","shell.execute_reply.started":"2024-12-17T03:42:16.305406Z","shell.execute_reply":"2024-12-17T03:42:16.419874Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"model.save('/kaggle/working/saved_model')\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-17T03:42:20.931779Z","iopub.execute_input":"2024-12-17T03:42:20.932178Z","iopub.status.idle":"2024-12-17T03:42:23.137388Z","shell.execute_reply.started":"2024-12-17T03:42:20.932148Z","shell.execute_reply":"2024-12-17T03:42:23.135827Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"os.listdir('/kaggle/working')","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-17T03:42:25.705731Z","iopub.execute_input":"2024-12-17T03:42:25.706343Z","iopub.status.idle":"2024-12-17T03:42:25.716976Z","shell.execute_reply.started":"2024-12-17T03:42:25.706294Z","shell.execute_reply":"2024-12-17T03:42:25.715564Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"copy('/kaggle/working/cnn_model.h5', '/kaggle/working/cnn_model_download.h5')","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-17T03:42:37.7869Z","iopub.execute_input":"2024-12-17T03:42:37.788194Z","iopub.status.idle":"2024-12-17T03:42:37.90932Z","shell.execute_reply.started":"2024-12-17T03:42:37.788146Z","shell.execute_reply":"2024-12-17T03:42:37.907708Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"y_pred = model.predict(X_test)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-17T03:42:39.854667Z","iopub.execute_input":"2024-12-17T03:42:39.856112Z","iopub.status.idle":"2024-12-17T03:42:53.855423Z","shell.execute_reply.started":"2024-12-17T03:42:39.856059Z","shell.execute_reply":"2024-12-17T03:42:53.854355Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"y_pred_bin = (y_pred > 0.5).astype(int)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-17T03:43:09.319495Z","iopub.execute_input":"2024-12-17T03:43:09.319938Z","iopub.status.idle":"2024-12-17T03:43:09.32724Z","shell.execute_reply.started":"2024-12-17T03:43:09.319896Z","shell.execute_reply":"2024-12-17T03:43:09.325328Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"conf_matrix = confusion_matrix(np.argmax(y_test, axis=1), np.argmax(y_pred_bin, axis=1))\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-17T03:43:10.575894Z","iopub.execute_input":"2024-12-17T03:43:10.577119Z","iopub.status.idle":"2024-12-17T03:43:10.587959Z","shell.execute_reply.started":"2024-12-17T03:43:10.577067Z","shell.execute_reply":"2024-12-17T03:43:10.58654Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Plot confusion matrix\nplt.figure(figsize=(8, 6))\nsns.heatmap(conf_matrix, annot=True, fmt='d', cmap='Blues', xticklabels=['C1', 'C2', 'C3', 'C4', 'C5', 'C6', 'C7'], yticklabels=['C1', 'C2', 'C3', 'C4', 'C5', 'C6', 'C7'])\nplt.xlabel('Predicted')\nplt.ylabel('True')\nplt.title('Confusion Matrix')\nplt.show()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-17T03:43:11.688812Z","iopub.execute_input":"2024-12-17T03:43:11.689302Z","iopub.status.idle":"2024-12-17T03:43:12.129017Z","shell.execute_reply.started":"2024-12-17T03:43:11.689264Z","shell.execute_reply":"2024-12-17T03:43:12.127679Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Classification report (Precision, Recall, F1-Score for each class)\nprint(classification_report(np.argmax(y_test, axis=1), np.argmax(y_pred_bin, axis=1), target_names=['C1', 'C2', 'C3', 'C4', 'C5', 'C6', 'C7']))","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-17T03:43:15.549409Z","iopub.execute_input":"2024-12-17T03:43:15.550226Z","iopub.status.idle":"2024-12-17T03:43:15.57356Z","shell.execute_reply.started":"2024-12-17T03:43:15.550167Z","shell.execute_reply":"2024-12-17T03:43:15.57217Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"score = model.evaluate(X_test, y_test, verbose = 1)","metadata":{"execution":{"iopub.status.busy":"2024-12-17T03:43:17.762937Z","iopub.execute_input":"2024-12-17T03:43:17.763682Z","iopub.status.idle":"2024-12-17T03:43:39.517833Z","shell.execute_reply.started":"2024-12-17T03:43:17.76363Z","shell.execute_reply":"2024-12-17T03:43:39.516346Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"print('Test loss:', score[0]) \nprint('Test accuracy:', score[1])","metadata":{"execution":{"iopub.status.busy":"2024-12-17T03:43:58.032499Z","iopub.execute_input":"2024-12-17T03:43:58.032967Z","iopub.status.idle":"2024-12-17T03:43:58.040505Z","shell.execute_reply.started":"2024-12-17T03:43:58.032932Z","shell.execute_reply":"2024-12-17T03:43:58.038853Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"classes = np.array(seg_labels.columns[2:-1])\nimg = X_test[17]\n\nproba = model.predict(img.reshape(1,128,128,3))","metadata":{"execution":{"iopub.status.busy":"2024-12-17T03:44:00.563901Z","iopub.execute_input":"2024-12-17T03:44:00.564345Z","iopub.status.idle":"2024-12-17T03:44:00.657393Z","shell.execute_reply.started":"2024-12-17T03:44:00.564311Z","shell.execute_reply":"2024-12-17T03:44:00.655518Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"#Fetches the probability value for each class in a sorted order\nnp.argsort(proba[0]) ","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-17T03:44:05.935141Z","iopub.execute_input":"2024-12-17T03:44:05.93605Z","iopub.status.idle":"2024-12-17T03:44:05.945216Z","shell.execute_reply.started":"2024-12-17T03:44:05.93601Z","shell.execute_reply":"2024-12-17T03:44:05.943551Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"def plot_accuracy_curve(history):\n    \"\"\"\n    Plot the training vs validation accuracy curve.\n    \"\"\"\n    # Extract accuracy values from training history\n    train_acc = history.history['binary_accuracy']\n    val_acc = history.history['val_binary_accuracy']\n    epochs = range(1, len(train_acc) + 1)\n\n    # Plot the accuracy curves\n    plt.figure(figsize=(8, 6))\n    plt.plot(epochs, train_acc, 'b-', label='Training Accuracy')\n    plt.plot(epochs, val_acc, 'r-', label='Validation Accuracy')\n    plt.title('Training vs Validation Accuracy')\n    plt.xlabel('Epochs')\n    plt.ylabel('Accuracy')\n    plt.legend()\n    plt.grid(True)\n    plt.show()\n\n# Example Usage\nplot_accuracy_curve(history)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-17T03:44:09.366064Z","iopub.execute_input":"2024-12-17T03:44:09.366529Z","iopub.status.idle":"2024-12-17T03:44:09.426341Z","shell.execute_reply.started":"2024-12-17T03:44:09.366492Z","shell.execute_reply":"2024-12-17T03:44:09.424288Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"def plot_loss_curve(history):\n    \"\"\"\n    Plots the training vs validation loss curve from the model's history.\n    \n    Parameters:\n        history: The history object returned by the `model.fit()` function.\n    \"\"\"\n    # Extract loss values\n    train_loss = history.history['loss']\n    val_loss = history.history['val_loss']\n\n    # Plot the loss curve\n    plt.figure(figsize=(8, 6))\n    plt.plot(train_loss, label='Training Loss', color='blue', marker='o')\n    plt.plot(val_loss, label='Validation Loss', color='orange', marker='o')\n    plt.title('Training vs Validation Loss Curve', fontsize=16)\n    plt.xlabel('Epochs', fontsize=12)\n    plt.ylabel('Loss', fontsize=12)\n    plt.legend(fontsize=10)\n    plt.grid(True)\n    plt.show()\n\n# Example usage:\nplot_loss_curve(history)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-17T02:40:59.324559Z","iopub.execute_input":"2024-12-17T02:40:59.324957Z","iopub.status.idle":"2024-12-17T02:40:59.366131Z","shell.execute_reply.started":"2024-12-17T02:40:59.324923Z","shell.execute_reply":"2024-12-17T02:40:59.364524Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"def plot_confusion_matrix_per_class(y_test, y_pred_bin, class_names):\n    \"\"\"\n    Plots a confusion matrix for each vertebra class separately.\n    \"\"\"\n    num_classes = len(class_names)\n    \n    for i, class_name in enumerate(class_names):\n        # Get the true and predicted values for the specific class\n        true_class = y_test[:, i]\n        pred_class = y_pred_bin[:, i]\n\n        # Compute the confusion matrix\n        cm = confusion_matrix(true_class, pred_class)\n\n        # Plot confusion matrix for this class\n        disp = ConfusionMatrixDisplay(confusion_matrix=cm, display_labels=[\"Non-Fracture\", \"Fracture\"])\n        disp.plot(cmap='Blues', values_format='d')\n\n        plt.title(f'Confusion Matrix for Class: {class_name}')\n        plt.xlabel('Predicted Label')\n        plt.ylabel('True Label')\n        plt.grid(False)\n        plt.show()\n\n# Example usage:\nclass_names = ['C1', 'C2', 'C3', 'C4', 'C5', 'C6', 'C7']  # Vertebrae classes\nplot_confusion_matrix_per_class(y_test, y_pred_bin, class_names)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-17T03:44:14.504187Z","iopub.execute_input":"2024-12-17T03:44:14.504579Z","iopub.status.idle":"2024-12-17T03:44:16.258632Z","shell.execute_reply.started":"2024-12-17T03:44:14.504546Z","shell.execute_reply":"2024-12-17T03:44:16.257333Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Step 1: Load the DICOM file\ndef load_dicom_image(dicom_path):\n    \"\"\"\n    Loads a DICOM file and extracts the pixel array.\n    \"\"\"\n    dicom_data = pydicom.dcmread(dicom_path)\n    img = dicom_data.pixel_array  # Extract pixel data\n    return img\n\n# Step 2: Preprocess the Image\ndef preprocess_image(dicom_image):\n    \"\"\"\n    Preprocesses the input DICOM image to resize and normalize it.\n    \"\"\"\n    # Resize the image to (128, 128, 3)\n    image_resized = cv2.resize(dicom_image, (128, 128))  # Resize to 128x128 (grayscale)\n    \n    # Convert grayscale image to RGB by repeating the single channel (optional for color input models)\n    image_rgb = np.stack([image_resized] * 3, axis=-1)  # Create 3 channels by stacking\n    \n    # Normalize the image\n    image_normalized = image_rgb / 255.0  # Normalize to [0, 1] range\n    \n    # Add batch dimension (1 image in the batch)\n    image_batch = np.expand_dims(image_normalized, axis=0)\n    \n    return image_batch\n\n# Step 3: Load the Pretrained Model\ndef load_trained_model(model_path):\n    \"\"\"\n    Loads the pre-trained model from the given path.\n    \"\"\"\n    return load_model(model_path, custom_objects={\n        'sensitivity': sensitivity, \n        'specificity': specificity, \n        'f1_score': f1_score\n    })\n\n# Step 4: Make Predictions\ndef predict_fracture(model, preprocessed_img, threshold=0.5):\n    \"\"\"\n    Predicts the probabilities of fractures and determines fracture presence based on the threshold.\n    \"\"\"\n    proba = model.predict(preprocessed_img)[0]  # Get probabilities for each class\n    classes = ['C1', 'C2', 'C3', 'C4', 'C5', 'C6', 'C7']  # Define class labels\n    results = {cls: (prob, prob >= threshold) for cls, prob in zip(classes, proba)}\n    return results\n\n# Step 5: Visualize the Results\ndef visualize_results(img, predictions):\n    \"\"\"\n    Displays the input image and prints the fracture predictions.\n    \"\"\"\n    # Display the image\n    plt.figure(figsize=(8, 8))\n    plt.imshow(img, cmap='bone')\n    plt.axis('off')\n    plt.title(\"Input CT Image\")\n    plt.show()\n\n    # Print predictions\n    print(\"Fracture Predictions:\")\n    for cls, (prob, is_fractured) in predictions.items():\n        status = \"Fractured\" if is_fractured else \"No Fracture\"\n        print(f\"{cls}: Probability={prob:.2f}, Status={status}\")\n\n\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-17T03:40:30.81813Z","iopub.execute_input":"2024-12-17T03:40:30.818768Z","iopub.status.idle":"2024-12-17T03:40:30.835902Z","shell.execute_reply.started":"2024-12-17T03:40:30.818699Z","shell.execute_reply":"2024-12-17T03:40:30.83371Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Step 6: Execute the Pipeline\nif __name__ == \"__main__\":\n    # Define paths\n    dicom_path = '/kaggle/input/rsna-2022-cervical-spine-fracture-detection/test_images/1.2.826.0.1.3680043.5876/17.dcm'\n    model_path = '/kaggle/input/cervical_customcnn_model/tensorflow2/default/1/cnn_model.h5'\n\n    # Load and preprocess the image\n    dicom_image = load_dicom_image(dicom_path)\n    preprocessed_image = preprocess_image(dicom_image)\n\n    # Load the model\n    model = load_trained_model(model_path)\n\n    # Make predictions\n    predictions = predict_fracture(model, preprocessed_image)\n\n    # Visualize results\n    visualize_results(dicom_image, predictions)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-12-17T03:47:14.238984Z","iopub.execute_input":"2024-12-17T03:47:14.239445Z","iopub.status.idle":"2024-12-17T03:47:15.048129Z","shell.execute_reply.started":"2024-12-17T03:47:14.239409Z","shell.execute_reply":"2024-12-17T03:47:15.046956Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"\n#When I try to generate non_seg_image array for predictions, the notebook ran out of memory. Will be\n#fixed in future iteration\n\n# non_seg_data = train_data[~train_data['StudyInstanceUID'].isin(seg_labels['StudyInstanceUID'])]\n\n# X_non_seg = RSNADFGenerator(non_seg_data,train_images)","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"#Code for future purpose \n# accuracies=[]\n# for train_idx, val_idx in StratifiedKFold(5).split(df_train, df_train['patient_overall']):    \n#     K.clear_session()\n#     x_train = df_train.iloc[train_idx].reset_index()\n#     x_val = df_train.iloc[val_idx].reset_index()\n\n#     train_gen = RSNATrainGenerator(x_train, min(len(x_train), 64), infinite = False, base_path = train_images_dir)\n#     val_gen = RSNATrainGenerator(x_val, min(len(x_val), 64), infinite = False, base_path = train_images_dir)\n\n#     model = get_basic_cnn()\n#     print(\"validation steps: \",(len(x_val) // 64), \"steps_per_epoch: \",(len(x_train) // 64))\n\n#     hist = model.fit(                            \n#         train_gen,\n#         epochs = 5,\n#         callbacks = [tf.keras.callbacks.EarlyStopping(monitor = 'val_loss', patience = 2, restore_best_weights = True)],\n#         validation_steps = max((len(x_val) // 64), 1),\n#         steps_per_epoch = max((len(x_train) // 64), 1),\n#         validation_data = val_gen\n#       )\n\n#     #hist2 = model2.fit_generator(                            \n#     #    train_gen,\n#     #    epochs = 5,\n#     #    callbacks = [tf.keras.callbacks.EarlyStopping(monitor = 'val_loss', patience = 2, restore_best_weights = True)],\n#     #    validation_steps = max((len(x_val) // 64), 1),\n#     #    steps_per_epoch = max((len(x_train) // 64), 1),\n#     #    validation_data = val_gen,\n#     #  )\n#     accuracies.append(model.evaluate(val_gen, steps = max((len(x_val) // 64), 1))[1])","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# model.fit(X_train, y_train, epochs=10, validation_data=(X_test, y_test), batch_size=64)","metadata":{"trusted":true},"outputs":[],"execution_count":null}]}