{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"pygments_lexer":"ipython3","nbconvert_exporter":"python","version":"3.6.4","file_extension":".py","codemirror_mode":{"name":"ipython","version":3},"name":"python","mimetype":"text/x-python"}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"markdown","source":"# RSNA - Keras Baseline","metadata":{"execution":{"iopub.status.busy":"2022-07-29T07:11:03.457277Z"},"papermill":{"duration":0.007802,"end_time":"2022-08-01T20:06:05.86552","exception":false,"start_time":"2022-08-01T20:06:05.857718","status":"completed"},"pycharm":{"name":"#%% md\n"},"tags":[]}},{"cell_type":"code","source":"import os\nimport cv2\nimport glob\nimport traceback\nimport cv2 as cv\nimport numpy as np\nimport pandas as pd\nfrom path import Path\nfrom tqdm import tqdm\nimport nibabel as nib\nimport pydicom as dicom\nimport tensorflow as tf\nfrom keras import layers\nfrom pydicom import dcmread\nfrom tensorflow import keras\nimport tensorflow_hub as hub\nimport matplotlib.pyplot as plt\nfrom tensorflow.keras import backend as K\nfrom pydicom.data import get_testdata_files\nfrom tensorflow.keras.utils import to_categorical\nfrom sklearn.model_selection import StratifiedKFold\nfrom pydicom.pixel_data_handlers.util import apply_voi_lut\nfrom tensorflow.keras.layers import Input, Dense, Flatten, Conv2D\nfrom tensorflow.keras.preprocessing.image import load_img, img_to_array\nfrom tensorflow.keras.applications.efficientnet import EfficientNetB4","metadata":{"papermill":{"duration":0.841816,"end_time":"2022-08-01T20:06:13.216484","exception":false,"start_time":"2022-08-01T20:06:12.374668","status":"completed"},"pycharm":{"name":"#%%\n"},"tags":[],"execution":{"iopub.status.busy":"2022-10-02T05:45:53.485525Z","iopub.execute_input":"2022-10-02T05:45:53.486231Z","iopub.status.idle":"2022-10-02T05:46:00.705357Z","shell.execute_reply.started":"2022-10-02T05:45:53.486109Z","shell.execute_reply":"2022-10-02T05:46:00.704392Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"bad = np.array([['1.2.826.0.1.3680043.10197_C1', '1.2.826.0.1.3680043.10197','C1'],['1.2.826.0.1.3680043.10454_C1', '1.2.826.0.1.3680043.10454','C1'],['1.2.826.0.1.3680043.10690_C1', '1.2.826.0.1.3680043.10690','C1']], dtype=np.object)\n\ntrain_df = pd.read_csv(\"../input/rsna-2022-cervical-spine-fracture-detection/train.csv\")\ntest_df = pd.read_csv(\"../input/rsna-2022-cervical-spine-fracture-detection/test.csv\")\n\ntrain_dir = '../input/rsna-2022-cervical-spine-fracture-detection/train_images'\ntest_dir = '../input/rsna-2022-cervical-spine-fracture-detection/test_images'\nfirst_image = os.path.join(test_dir, test_df['StudyInstanceUID'].iloc[0])\n\nif(test_df.values[0][0] == bad[0][0]): test_df = pd.DataFrame({\"row_id\": ['1.2.826.0.1.3680043.22327_C1', '1.2.826.0.1.3680043.25399_C1', '1.2.826.0.1.3680043.5876_C1'], \"StudyInstanceUID\": ['1.2.826.0.1.3680043.22327', '1.2.826.0.1.3680043.25399', '1.2.826.0.1.3680043.5876'], \"prediction_type\": [\"C1\", \"C1\", \"C1\"]})\nmeans = list(train_df.mean(numeric_only=True).to_dict().values())","metadata":{"papermill":{"duration":0.042004,"end_time":"2022-08-01T20:06:13.265124","exception":false,"start_time":"2022-08-01T20:06:13.22312","status":"completed"},"pycharm":{"name":"#%%\n"},"tags":[],"execution":{"iopub.status.busy":"2022-10-02T05:46:00.707355Z","iopub.execute_input":"2022-10-02T05:46:00.708152Z","iopub.status.idle":"2022-10-02T05:46:00.746706Z","shell.execute_reply.started":"2022-10-02T05:46:00.708111Z","shell.execute_reply":"2022-10-02T05:46:00.745096Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_df","metadata":{"papermill":{"duration":0.029604,"end_time":"2022-08-01T20:06:13.301885","exception":false,"start_time":"2022-08-01T20:06:13.272281","status":"completed"},"pycharm":{"name":"#%%\n"},"tags":[],"execution":{"iopub.status.busy":"2022-10-02T05:46:00.747963Z","iopub.execute_input":"2022-10-02T05:46:00.748331Z","iopub.status.idle":"2022-10-02T05:46:00.770849Z","shell.execute_reply.started":"2022-10-02T05:46:00.748296Z","shell.execute_reply":"2022-10-02T05:46:00.769873Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def load_dicom(path, size = 64):\n    try:\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)\n    except:        \n        return np.zeros((512, 512, 3))","metadata":{"papermill":{"duration":0.017119,"end_time":"2022-08-01T20:06:13.325881","exception":false,"start_time":"2022-08-01T20:06:13.308762","status":"completed"},"pycharm":{"name":"#%%\n"},"tags":[],"execution":{"iopub.status.busy":"2022-10-02T05:46:00.773407Z","iopub.execute_input":"2022-10-02T05:46:00.773754Z","iopub.status.idle":"2022-10-02T05:46:00.780246Z","shell.execute_reply.started":"2022-10-02T05:46:00.77372Z","shell.execute_reply":"2022-10-02T05:46:00.779264Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def listdirs(folder):\n    return [d for d in os.listdir(folder) if os.path.isdir(os.path.join(folder, d))]","metadata":{"papermill":{"duration":0.015007,"end_time":"2022-08-01T20:06:13.34859","exception":false,"start_time":"2022-08-01T20:06:13.333583","status":"completed"},"pycharm":{"name":"#%%\n"},"tags":[],"execution":{"iopub.status.busy":"2022-10-02T05:46:00.78155Z","iopub.execute_input":"2022-10-02T05:46:00.782639Z","iopub.status.idle":"2022-10-02T05:46:00.792182Z","shell.execute_reply.started":"2022-10-02T05:46:00.782603Z","shell.execute_reply":"2022-10-02T05:46:00.791242Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_dir = '../input/rsna-2022-cervical-spine-fracture-detection/train_images'\ntest_dir = '../input/rsna-2022-cervical-spine-fracture-detection/test_images'\npatients = sorted(os.listdir(train_dir))\npatients[:5]","metadata":{"papermill":{"duration":0.13231,"end_time":"2022-08-01T20:06:13.48762","exception":false,"start_time":"2022-08-01T20:06:13.35531","status":"completed"},"pycharm":{"name":"#%%\n"},"tags":[],"execution":{"iopub.status.busy":"2022-10-02T05:46:00.794015Z","iopub.execute_input":"2022-10-02T05:46:00.794432Z","iopub.status.idle":"2022-10-02T05:46:00.864122Z","shell.execute_reply.started":"2022-10-02T05:46:00.794331Z","shell.execute_reply":"2022-10-02T05:46:00.863306Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"image_file = glob.glob(\"../input/rsna-2022-cervical-spine-fracture-detection/train_images/1.2.826.0.1.3680043.10001/*.dcm\")\nplt.figure(figsize=(20, 20))\n\nfor i in range(28):\n    ax = plt.subplot(7, 7, i + 1)\n    image_path = image_file[i]\n    image = load_dicom(image_path)\n    plt.axis('off')   \n    plt.imshow(image)","metadata":{"papermill":{"duration":2.485904,"end_time":"2022-08-01T20:06:15.980511","exception":false,"start_time":"2022-08-01T20:06:13.494607","status":"completed"},"pycharm":{"name":"#%%\n"},"tags":[],"execution":{"iopub.status.busy":"2022-10-02T05:46:00.866119Z","iopub.execute_input":"2022-10-02T05:46:00.866757Z","iopub.status.idle":"2022-10-02T05:46:03.664775Z","shell.execute_reply.started":"2022-10-02T05:46:00.866721Z","shell.execute_reply":"2022-10-02T05:46:03.663907Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"image_file = glob.glob(\"../input/rsna-2022-cervical-spine-fracture-detection/segmentations/*.nii\")\nplt.figure(figsize=(20, 20))\n\nfor i in range(28):\n    ax = plt.subplot(7, 7, i + 1)\n    image_path = image_file[i]\n    nii_img = nib.load(image_path).get_fdata()\n    nib_image = nii_img[:,:,59]\n    plt.axis('off')\n    plt.imshow(nib_image)","metadata":{"papermill":{"duration":33.495765,"end_time":"2022-08-01T20:06:49.489929","exception":false,"start_time":"2022-08-01T20:06:15.994164","status":"completed"},"pycharm":{"name":"#%%\n"},"tags":[],"execution":{"iopub.status.busy":"2022-10-02T05:46:03.665842Z","iopub.execute_input":"2022-10-02T05:46:03.666299Z","iopub.status.idle":"2022-10-02T05:46:37.832127Z","shell.execute_reply.started":"2022-10-02T05:46:03.66625Z","shell.execute_reply":"2022-10-02T05:46:37.831193Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Data Generators","metadata":{"papermill":{"duration":0.014768,"end_time":"2022-08-01T20:06:49.52077","exception":false,"start_time":"2022-08-01T20:06:49.506002","status":"completed"},"pycharm":{"name":"#%% md\n"},"tags":[]}},{"cell_type":"markdown","source":"#### Train Generator \n\n- Also yields labels","metadata":{"papermill":{"duration":0.014372,"end_time":"2022-08-01T20:06:49.549828","exception":false,"start_time":"2022-08-01T20:06:49.535456","status":"completed"},"pycharm":{"name":"#%% md\n"},"tags":[]}},{"cell_type":"code","source":"def RSNATrainGenerator(train_df, batch_size, infinite = True, base_path = train_dir):\n    while True:\n        trainset = []\n        trainidt = []\n        trainlabel = []\n        for i in (range(len(train_df))):\n            idt = train_df.loc[i, 'StudyInstanceUID']\n            path = os.path.join(train_dir, idt)\n            for im in os.listdir(path):\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(os.path.join(path , im))\n                img = cv.resize(img, (64 , 64))\n                image = img_to_array(img)\n                image = image / 255.0\n                trainset += [image]\n                cur_label = []\n                cur_label.append(train_df.loc[i,'C1'])\n                cur_label.append(train_df.loc[i,'C2'])\n                cur_label.append(train_df.loc[i,'C3'])\n                cur_label.append(train_df.loc[i,'C4'])\n                cur_label.append(train_df.loc[i,'C5'])\n                cur_label.append(train_df.loc[i,'C6'])\n                cur_label.append(train_df.loc[i,'C7'])\n                trainlabel += [cur_label]\n                trainidt += [idt]\n                if len(trainidt) == batch_size:                    \n                    yield np.array(trainset), np.array(trainlabel)\n                    trainset, trainlabel, trainidt = [], [], []\n            i+=1","metadata":{"papermill":{"duration":0.031629,"end_time":"2022-08-01T20:06:49.596032","exception":false,"start_time":"2022-08-01T20:06:49.564403","status":"completed"},"pycharm":{"name":"#%%\n"},"tags":[],"execution":{"iopub.status.busy":"2022-10-02T05:46:37.833522Z","iopub.execute_input":"2022-10-02T05:46:37.833986Z","iopub.status.idle":"2022-10-02T05:46:37.847048Z","shell.execute_reply.started":"2022-10-02T05:46:37.833948Z","shell.execute_reply":"2022-10-02T05:46:37.846162Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"#### Test Generator\n\n- Yields only image samples","metadata":{"papermill":{"duration":0.014784,"end_time":"2022-08-01T20:06:49.625207","exception":false,"start_time":"2022-08-01T20:06:49.610423","status":"completed"},"tags":[]}},{"cell_type":"code","source":"def RSNATestGenerator(test_df, batch_size, infinite = True, base_path = test_dir):\n    while 1:        \n        testset=[]\n        testidt=[]\n        for i in (range(len(test_df))):        \n            if type(test_df) is list: idt = test_df[i]\n            else: idt = test_df['StudyInstanceUID'].iloc[i]\n            path = os.path.join(base_path, idt)\n            if os.path.exists(path):\n                for im in os.listdir(path):\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(os.path.join(path,im))\n                    img=cv.resize(img,(64,64))\n                    image=img_to_array(img)\n                    image=image/255.0\n                    testset+=[image]\n                    testidt+=[idt]\n                    if len(testset) == batch_size:                        \n                        yield np.array(testset)\n                        testset = []\n        if len(testset) > 0: yield np.array(testset)\n        if not infinite: break","metadata":{"papermill":{"duration":0.028724,"end_time":"2022-08-01T20:06:49.668792","exception":false,"start_time":"2022-08-01T20:06:49.640068","status":"completed"},"pycharm":{"name":"#%%\n"},"tags":[],"execution":{"iopub.status.busy":"2022-10-02T05:46:37.85387Z","iopub.execute_input":"2022-10-02T05:46:37.854198Z","iopub.status.idle":"2022-10-02T05:46:37.889015Z","shell.execute_reply.started":"2022-10-02T05:46:37.854172Z","shell.execute_reply":"2022-10-02T05:46:37.888017Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"#### The Model","metadata":{"papermill":{"duration":0.014295,"end_time":"2022-08-01T20:06:49.697763","exception":false,"start_time":"2022-08-01T20:06:49.683468","status":"completed"},"tags":[]}},{"cell_type":"code","source":"def get_model():\n    inp = keras.layers.Input((None, None ,1))\n    x = Conv2D(3, 3, padding = 'SAME')(inp)\n    x = EfficientNetB4(include_top=False, weights='imagenet',)(x)\n    x = keras.layers.GlobalAveragePooling2D()(x)\n    x = keras.layers.Dense(512,activation='relu')(x)\n    x = keras.layers.Dropout(0.5)(x)\n    x = Dense(256,activation='relu')(x)\n    out = keras.layers.Dense(7, 'sigmoid')(x)\n    model = keras.models.Model(inp, out)\n    model.summary()\n    model.compile(loss=\"binary_crossentropy\", optimizer = tf.keras.optimizers.Adam(learning_rate = 0.001), metrics=['accuracy'])\n    return model","metadata":{"papermill":{"duration":0.024772,"end_time":"2022-08-01T20:06:49.737013","exception":false,"start_time":"2022-08-01T20:06:49.712241","status":"completed"},"pycharm":{"name":"#%%\n"},"tags":[],"execution":{"iopub.status.busy":"2022-10-02T05:46:37.890474Z","iopub.execute_input":"2022-10-02T05:46:37.891074Z","iopub.status.idle":"2022-10-02T05:46:37.903107Z","shell.execute_reply.started":"2022-10-02T05:46:37.891037Z","shell.execute_reply":"2022-10-02T05:46:37.902146Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"submission = pd.read_csv('../input/rsna-2022-cervical-spine-fracture-detection/sample_submission.csv')\nfor train_idx, val_idx in StratifiedKFold(5).split(train_df, train_df['patient_overall']):    \n    K.clear_session()\n    x_train = train_df.iloc[train_idx].reset_index()\n    x_val = train_df.iloc[val_idx].reset_index()\n    model = get_model()\n    hist = model.fit(                            \n                                    RSNATrainGenerator(x_train, min(len(x_train), 64), infinite = False, base_path = train_dir),\n                                    epochs = 50,\n                                    verbose = 1,\n                                    callbacks = [keras.callbacks.EarlyStopping(monitor = '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 = RSNATrainGenerator(x_val, min(len(x_val), 64), infinite = False, base_path = train_dir),\n                              )\n    val_pred = model.predict(RSNATestGenerator(x_val, min(len(test_df), 64), infinite = False, base_path = train_dir), steps = max((len(test_df) // 64), 1))    \n    try: # the best we can do at the moment..\n        preds = model.predict(RSNATestGenerator(test_df, min(len(test_df), 64), infinite = False, base_path = test_dir), steps = max((len(test_df) // 64), 1))\n        submission['fractured'] = np.median(preds, axis = 1)\n    except: traceback.print_exc()    ","metadata":{"papermill":{"duration":519.126101,"end_time":"2022-08-01T20:15:28.877545","exception":false,"start_time":"2022-08-01T20:06:49.751444","status":"completed"},"pycharm":{"name":"#%%\n"},"tags":[],"execution":{"iopub.status.busy":"2022-10-02T05:46:37.904557Z","iopub.execute_input":"2022-10-02T05:46:37.905042Z","iopub.status.idle":"2022-10-02T05:56:11.434473Z","shell.execute_reply.started":"2022-10-02T05:46:37.905007Z","shell.execute_reply":"2022-10-02T05:56:11.432735Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# outputs.append(means[item[3]])    ","metadata":{"papermill":{"duration":0.066175,"end_time":"2022-08-01T20:15:29.002552","exception":false,"start_time":"2022-08-01T20:15:28.936377","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2022-10-02T05:56:11.435935Z","iopub.execute_input":"2022-10-02T05:56:11.436333Z","iopub.status.idle":"2022-10-02T05:56:11.443687Z","shell.execute_reply.started":"2022-10-02T05:56:11.436294Z","shell.execute_reply":"2022-10-02T05:56:11.442093Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"submission.head()","metadata":{"papermill":{"duration":0.072923,"end_time":"2022-08-01T20:15:29.13171","exception":false,"start_time":"2022-08-01T20:15:29.058787","status":"completed"},"pycharm":{"name":"#%%\n"},"tags":[],"execution":{"iopub.status.busy":"2022-10-02T05:56:11.445182Z","iopub.execute_input":"2022-10-02T05:56:11.44559Z","iopub.status.idle":"2022-10-02T05:56:11.464017Z","shell.execute_reply.started":"2022-10-02T05:56:11.445554Z","shell.execute_reply":"2022-10-02T05:56:11.463082Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"submission.to_csv('./submission.csv', index=False, float_format='%.1g')","metadata":{"papermill":{"duration":0.064357,"end_time":"2022-08-01T20:15:29.250365","exception":false,"start_time":"2022-08-01T20:15:29.186008","status":"completed"},"pycharm":{"name":"#%%\n"},"tags":[],"execution":{"iopub.status.busy":"2022-10-02T05:56:11.466283Z","iopub.execute_input":"2022-10-02T05:56:11.46755Z","iopub.status.idle":"2022-10-02T05:56:11.47878Z","shell.execute_reply.started":"2022-10-02T05:56:11.467514Z","shell.execute_reply":"2022-10-02T05:56:11.477268Z"},"trusted":true},"execution_count":null,"outputs":[]}]}