{"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"}],"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":"2025-01-22T01:43:43.991512Z","iopub.execute_input":"2025-01-22T01:43:43.991928Z","iopub.status.idle":"2025-01-22T01:43:55.963217Z","shell.execute_reply.started":"2025-01-22T01:43:43.991881Z","shell.execute_reply":"2025-01-22T01:43:55.961608Z"},"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 re\nimport cv2\nimport random\nfrom tqdm import tqdm\nimport matplotlib.pyplot as plt\n\nimport tensorflow as tf\nfrom tensorflow.keras import layers, callbacks\nfrom tensorflow.keras import backend as K\nfrom tensorflow.keras.models import Model\nfrom sklearn.model_selection import StratifiedKFold\nfrom tensorflow.keras.preprocessing.image import load_img, img_to_array\nfrom tensorflow.keras.applications import InceptionV3, DenseNet121, InceptionResNetV2\n\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, plot_model\nfrom keras.preprocessing import image\n\nfrom sklearn.model_selection import train_test_split\nfrom sklearn.metrics import precision_score, recall_score, f1_score, multilabel_confusion_matrix\nfrom sklearn.metrics import roc_auc_score, roc_curve\npd.set_option('display.max_columns', None)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-01-22T01:44:05.672866Z","iopub.execute_input":"2025-01-22T01:44:05.673291Z","iopub.status.idle":"2025-01-22T01:44:17.19784Z","shell.execute_reply.started":"2025-01-22T01:44:05.673254Z","shell.execute_reply":"2025-01-22T01:44:17.19681Z"}},"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":"2025-01-22T01:44:53.817781Z","iopub.execute_input":"2025-01-22T01:44:53.818552Z","iopub.status.idle":"2025-01-22T01:44:54.042566Z","shell.execute_reply.started":"2025-01-22T01:44:53.818511Z","shell.execute_reply":"2025-01-22T01:44:54.041372Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"segmentation_meta_data.shape","metadata":{"execution":{"iopub.status.busy":"2025-01-22T01:44:56.521821Z","iopub.execute_input":"2025-01-22T01:44:56.522178Z","iopub.status.idle":"2025-01-22T01:44:56.530782Z","shell.execute_reply.started":"2025-01-22T01:44:56.522152Z","shell.execute_reply":"2025-01-22T01:44:56.529347Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"segmentation_meta_data.columns","metadata":{"execution":{"iopub.status.busy":"2025-01-22T01:44:57.526055Z","iopub.execute_input":"2025-01-22T01:44:57.52644Z","iopub.status.idle":"2025-01-22T01:44:57.533376Z","shell.execute_reply.started":"2025-01-22T01:44:57.526409Z","shell.execute_reply":"2025-01-22T01:44:57.53223Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"segmentation_meta_data['PhotometricInterpretation'].value_counts()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-01-22T01:45:17.612104Z","iopub.execute_input":"2025-01-22T01:45:17.612586Z","iopub.status.idle":"2025-01-22T01:45:17.637123Z","shell.execute_reply.started":"2025-01-22T01:45:17.612547Z","shell.execute_reply":"2025-01-22T01:45:17.6356Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"columns = ['StudyInstanceUID','SOPInstanceUID','C1','C2','C3','C4','C5','C6','C7']","metadata":{"execution":{"iopub.status.busy":"2025-01-22T01:45:32.188552Z","iopub.execute_input":"2025-01-22T01:45:32.188951Z","iopub.status.idle":"2025-01-22T01:45:32.193768Z","shell.execute_reply.started":"2025-01-22T01:45:32.188918Z","shell.execute_reply":"2025-01-22T01:45:32.192699Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"seg_labels = segmentation_meta_data[columns]","metadata":{"execution":{"iopub.status.busy":"2025-01-22T01:45:33.412036Z","iopub.execute_input":"2025-01-22T01:45:33.412438Z","iopub.status.idle":"2025-01-22T01:45:33.427686Z","shell.execute_reply.started":"2025-01-22T01:45:33.412405Z","shell.execute_reply":"2025-01-22T01:45:33.42659Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"seg_labels.head(2)","metadata":{"execution":{"iopub.status.busy":"2025-01-22T01:45:35.575315Z","iopub.execute_input":"2025-01-22T01:45:35.575722Z","iopub.status.idle":"2025-01-22T01:45:35.592203Z","shell.execute_reply.started":"2025-01-22T01:45:35.575689Z","shell.execute_reply":"2025-01-22T01:45:35.59105Z"},"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":"2025-01-22T01:45:44.160903Z","iopub.execute_input":"2025-01-22T01:45:44.16127Z","iopub.status.idle":"2025-01-22T01:45:44.186474Z","shell.execute_reply.started":"2025-01-22T01:45:44.161226Z","shell.execute_reply":"2025-01-22T01:45:44.185355Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"seg_labels","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-01-22T01:46:05.761723Z","iopub.execute_input":"2025-01-22T01:46:05.76289Z","iopub.status.idle":"2025-01-22T01:46:05.785952Z","shell.execute_reply.started":"2025-01-22T01:46:05.76284Z","shell.execute_reply":"2025-01-22T01:46:05.784442Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Function to load DICOM images\ndef load_scan(dcm_paths):  \n    patient_scan = [dicom.dcmread(paths) for paths in dcm_paths]\n    return patient_scan\n\ndef get_pixels_hu(img):\n    image = cv2.resize(img.pixel_array,(128, 128),interpolation = cv2.INTER_NEAREST)\n    image = image.astype(np.int16)\n    # Set outside-of-scan pixels to 0, the intercept is usually -1024, so air is approximately 0\n    image[image <= -1000] = 0\n    # Convert to Hounsfield units (HU)    \n    intercept = np.array(img.RescaleIntercept)\n    slope = np.array(img.RescaleSlope)\n    image= (slope * image.astype(\"float64\")) + intercept\n#     plt.imshow(image.astype(\"int16\"), cmap='bone') \n    return image.astype(\"int16\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-01-22T01:46:22.192502Z","iopub.execute_input":"2025-01-22T01:46:22.193257Z","iopub.status.idle":"2025-01-22T01:46:22.199934Z","shell.execute_reply.started":"2025-01-22T01:46:22.193212Z","shell.execute_reply":"2025-01-22T01:46:22.198844Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"list(seg_labels['StudyInstanceUID'].unique())","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-01-22T01:46:29.526815Z","iopub.execute_input":"2025-01-22T01:46:29.527187Z","iopub.status.idle":"2025-01-22T01:46:29.540356Z","shell.execute_reply.started":"2025-01-22T01:46:29.527157Z","shell.execute_reply":"2025-01-22T01:46:29.539325Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"def get_image(study_instance):\n    path = '/kaggle/input/rsna-2022-cervical-spine-fracture-detection/train_images'\n    # study_instances = list(seg_labels['StudyInstanceUID'].unique())\n    patient_slices = []\n    org_images = []\n#     study_instance = '1.2.826.0.1.3680043.1868'\n    # for study_instance in study_instances:\n    slices = list(seg_labels[seg_labels['StudyInstanceUID']==study_instance]['slice'])\n    dcm_paths = [path+'/'+study_instance+'/'+ slic + '.dcm' for slic in slices]\n    image = load_scan(dcm_paths)\n    org_images.append(image)\n    slices_p = [dicom.read_file(dcm_path) for dcm_path in dcm_paths]\n    patient_slice = [get_pixels_hu(slic) for slic in slices_p]\n    patient_slices.append(patient_slice)\n    \n    return org_images, patient_slices, slices","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-01-22T01:46:39.581275Z","iopub.execute_input":"2025-01-22T01:46:39.581798Z","iopub.status.idle":"2025-01-22T01:46:39.588681Z","shell.execute_reply.started":"2025-01-22T01:46:39.581765Z","shell.execute_reply":"2025-01-22T01:46:39.587426Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"study_instance = '1.2.826.0.1.3680043.1868'\norg_images, patient_slices, slices = get_image(study_instance = study_instance)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-01-22T01:46:49.711045Z","iopub.execute_input":"2025-01-22T01:46:49.712071Z","iopub.status.idle":"2025-01-22T01:47:02.30186Z","shell.execute_reply.started":"2025-01-22T01:46:49.712029Z","shell.execute_reply":"2025-01-22T01:47:02.300708Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"dat  = seg_labels[seg_labels['StudyInstanceUID']==study_instance][['SOPInstanceUID', 'C1', 'C2', 'C3', 'C4', 'C5', 'C6', 'C7']]\ndat","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-01-22T01:47:08.002772Z","iopub.execute_input":"2025-01-22T01:47:08.003162Z","iopub.status.idle":"2025-01-22T01:47:08.022226Z","shell.execute_reply.started":"2025-01-22T01:47:08.00313Z","shell.execute_reply":"2025-01-22T01:47:08.021129Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"plt.rc('xtick',labelsize=8)\nplt.rc('ytick',labelsize=8)\n\nstart = 0\nimg = 67\nlabel = dat[dat['SOPInstanceUID']==study_instance+'.1.'+slices[start]][['C1', 'C2', 'C3', 'C4', 'C5', 'C6', 'C7']].to_string(index=False).split('\\n')\nplt.figure(figsize=(11, 8))\n# Ploting pixel array\nplt.subplot(2, 2, 1)\nplt.imshow(org_images[start][img].pixel_array,cmap='bone', aspect='auto')\nplt.title('Original image')\nplt.axis(\"off\")\n\n# Ploting pixel array distribution\nplt.subplot(2, 2, 2)\nplt.hist(org_images[start][img].pixel_array.flatten(),color=\"b\",bins=50)\n# plt.title('Pixel array distribution')\nplt.xlabel(\"Pixel Values\")\nplt.ylabel(\"Fequency\")\n\n#Ploting HU array\nplt.subplot(2, 2, 3)\nplt.imshow(get_pixels_hu(org_images[start][img]),cmap='bone', aspect='auto')\nplt.title('Processed image')\nplt.axis(\"off\")\n\n# Ploting HU distribution\nplt.subplot(2, 2, 4)\nplt.hist(patient_slices[start][img].flatten(),color=\"b\",bins=50)\n# plt.title('HU distribution')\nplt.xlabel(\"HU Values\")\nplt.ylabel(\"Fequency\")\nplt.suptitle(f\"{label[0]} \\n {label[1].strip()}\", y=0.98, fontsize=12)\nplt.show()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-01-22T01:47:19.099943Z","iopub.execute_input":"2025-01-22T01:47:19.100371Z","iopub.status.idle":"2025-01-22T01:47:19.89807Z","shell.execute_reply.started":"2025-01-22T01:47:19.100338Z","shell.execute_reply":"2025-01-22T01:47:19.896964Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"label, label[1].split()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-01-22T01:47:48.970522Z","iopub.execute_input":"2025-01-22T01:47:48.970949Z","iopub.status.idle":"2025-01-22T01:47:48.978212Z","shell.execute_reply.started":"2025-01-22T01:47:48.970915Z","shell.execute_reply":"2025-01-22T01:47:48.976817Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"def load_dicom(path):\n    '''\n    Function to load and transform DICOM images.\n    \n    Parameters:\n    path(string): Path to the DICOM images\n\n    Returns:\n    Transformed and resized image.\n    \n    '''\n    img=dicom.dcmread(path)\n    img.PhotometricInterpretation = 'YBR_FULL'\n#     data=img.pixel_array\n    data=get_pixels_hu(img)\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(128, 128), cv2.COLOR_GRAY2RGB)\n\ndef ImgDataGenerator(train_df,base_path):\n    '''\n    Function to read dicom image path and store the images as numpy arrays.\n\n    Parameters:\n    train_df: Pandas dataframe.\n    base_path: Python list containing image filepaths.\n\n    Returns:\n    [Train image dataset, Train image labels]\n\n    '''\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        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    return np.array(trainset), np.array(trainlabel)\n    \ndef metrics(y_test, y_pred_binary):\n    '''\n    Function to display accuracy, precision, recall and f1-score for the classification task.\n    \n    Parameters:\n    y_test: True labels.\n    y_pred_binary: Predicted binary labels.\n\n    Returns:\n    Pandas dataframe containing class-wise Sensitivity, Specificity, and F1-score.\n    \n    '''\n    classes = np.array(seg_labels.columns[2:-1])\n    df_res = []\n    precision_per_class = precision_score(y_test, y_pred_binary, average=None)\n    recall_per_class = recall_score(y_test, y_pred_binary, average=None)\n    f1_per_class = f1_score(y_test, y_pred_binary, average=None)\n\n    for i in range(len(classes)):\n        df_res.append([classes[i], recall_per_class[i], precision_per_class[i], f1_per_class[i]])\n    df_res = pd.DataFrame(df_res, columns = ['Class','Sensitivity','Specificity', 'F1-score'])\n    return df_res\n\ndef plot_history(history):\n    '''\n    Function to plot the train and validation accuracy and loss.\n    \n    Parameters:\n    history: model train history\n\n    Returns:\n    None.\n    \n    '''\n    hist = history.history\n    plt.figure(figsize=(8, 4));\n    plt.suptitle(f\"Performance Metrics\", fontsize=12)\n\n    # Actual and validation losses\n    plt.subplot(1, 2, 1);\n    plt.plot(hist['loss'], label='train')\n    plt.plot(hist['val_loss'], label='validation')\n    plt.title('Train and val loss curve', fontsize=8)\n    plt.legend()\n\n    # Actual and validation accuracy\n    plt.subplot(1, 2, 2);\n    plt.plot(hist['binary_accuracy'], label='train')\n    plt.plot(hist['val_binary_accuracy'], label='validation')\n    plt.title('Train and val accuracy curve', fontsize=8)\n    plt.legend();\n    \ndef callback(model_name, patience=5): \n    '''\n    Function to define callback for model training.\n    \n    Parameters:\n    model_name(string): Name for the saved model with `.h5` extension.\n    patience: Patience for early stopping. Usually, the value lies between 5-11.\n\n    Returns:\n    [Early Stopping Callback, Model Checkpoint Callback]\n    \n    '''\n    early_stopping = callbacks.EarlyStopping(patience=patience, restore_best_weights=True)\n    model_checkpoint = callbacks.ModelCheckpoint(model_name, save_best_only=True)\n    learning_rate_reduction = callbacks.ReduceLROnPlateau(monitor='val_acc', \n                                                        patience=2, \n                                                        verbose=1, \n                                                        factor=0.5, \n                                                        min_lr=0.00001)\n    return [early_stopping, model_checkpoint, learning_rate_reduction]","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-01-22T01:47:56.633819Z","iopub.execute_input":"2025-01-22T01:47:56.634288Z","iopub.status.idle":"2025-01-22T01:47:56.655222Z","shell.execute_reply.started":"2025-01-22T01:47:56.634249Z","shell.execute_reply":"2025-01-22T01:47:56.654094Z"}},"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)\nX_seg.shape,y_seg.shape","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-01-22T01:48:13.759823Z","iopub.execute_input":"2025-01-22T01:48:13.760242Z","iopub.status.idle":"2025-01-22T01:58:19.32527Z","shell.execute_reply.started":"2025-01-22T01:48:13.760203Z","shell.execute_reply":"2025-01-22T01:58:19.323524Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Divide train and test data\nX_train, X_test, y_train, y_test = train_test_split(X_seg, y_seg, random_state=42, test_size=0.1)\ny_train, y_test = y_train.astype('float32'), y_test.astype('float32')\nX_train.shape, y_train.shape, X_test.shape, y_test.shape","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-01-22T01:59:06.332341Z","iopub.execute_input":"2025-01-22T01:59:06.33283Z","iopub.status.idle":"2025-01-22T01:59:08.604607Z","shell.execute_reply.started":"2025-01-22T01:59:06.332796Z","shell.execute_reply":"2025-01-22T01:59:08.60347Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"labels = ['C1', 'C2', 'C3', 'C4', 'C5', 'C6', 'C7']","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-01-22T01:59:19.385144Z","iopub.execute_input":"2025-01-22T01:59:19.386103Z","iopub.status.idle":"2025-01-22T01:59:19.39108Z","shell.execute_reply.started":"2025-01-22T01:59:19.386065Z","shell.execute_reply":"2025-01-22T01:59:19.39Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"plt.figure(figsize=(7, 5))\nplt.bar(x=labels, height=np.mean(y_train, axis=0))\nplt.title(\"Frequency of Each Class\")\nplt.show()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-01-22T01:59:27.55876Z","iopub.execute_input":"2025-01-22T01:59:27.559139Z","iopub.status.idle":"2025-01-22T01:59:27.782002Z","shell.execute_reply.started":"2025-01-22T01:59:27.559109Z","shell.execute_reply":"2025-01-22T01:59:27.780809Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Prepare data batches for training images\nX_train_tensor = tf.data.Dataset.from_tensor_slices(X_train)\ny_train_tensor = tf.data.Dataset.from_tensor_slices(y_train)\ntrain_dataset = tf.data.Dataset.zip((X_train_tensor, y_train_tensor)).batch(16).prefetch(tf.data.AUTOTUNE)\n# Prepare data batches for validation images\nX_test_tensor = tf.data.Dataset.from_tensor_slices(X_test)\ny_test_tensor = tf.data.Dataset.from_tensor_slices(y_test)\nval_dataset = tf.data.Dataset.zip((X_test_tensor, y_test_tensor)).batch(16).prefetch(tf.data.AUTOTUNE)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-01-22T01:59:37.648623Z","iopub.execute_input":"2025-01-22T01:59:37.649041Z","iopub.status.idle":"2025-01-22T01:59:44.121879Z","shell.execute_reply.started":"2025-01-22T01:59:37.649009Z","shell.execute_reply":"2025-01-22T01:59:44.12059Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"## 3. Modelling\nWe'll opt for three different modelling approaches:\n1. **Custom CNN** - Here we will implement our own custom CNN model from scratch involving blocks of Convolution, Pooling and DropOut layers.\n2. **Transfer Learning models** - In this section, we will employ various pre-trained deep learning models to further improve on the results of the Custom CNN model.\n3. **Encoder decoder Architecture** - Finally, we will implement an encoder-decoder model where we will use the U-Net model for encoder and the best performing transfer learning model as a decoder. ","metadata":{}},{"cell_type":"code","source":"def conv_block(input, num_filters):\n    '''\n    Function for convolution block unit.\n    \n    Parameters:\n    input(keras layer): Input layer.\n    num_filters(int): Number of filters in the Conv2D layer. \n\n    Returns:\n    Final convoluted and activated output layer.\n    \n    '''\n    x = layers.Conv2D(num_filters, 3, padding=\"same\")(input)\n    x = layers.BatchNormalization()(x)\n    x = layers.Activation(\"relu\")(x)\n\n    x = layers.Conv2D(num_filters, 3, padding=\"same\")(x)\n    x = layers.BatchNormalization()(x)\n    x = layers.Activation(\"relu\")(x)\n\n    return x\n\ndef decoder_block(input, skip_features, num_filters):\n    '''\n    Function for convolution block unit.\n    \n    Parameters:\n    input(keras layer): Input layer.\n    num_filters(int): Number of filters in the Conv2D layer. \n\n    Returns:\n    Final convoluted and activated output layer.\n    \n    '''\n    x = layers.Conv2DTranspose(num_filters, (2, 2), strides=2, padding=\"same\")(input)\n    x = layers.Concatenate()([x, skip_features])\n    x = conv_block(x, num_filters)\n    return x\n\ndef build_inception_resnetv2_unet(input_shape):\n    # Input layer\n    inputs = layers.Input(input_shape)\n    \n    # Pre-trained transfer learning model\n    encoder = InceptionResNetV2(include_top=False, weights=\"imagenet\", input_tensor=inputs)\n#     encoder.trainable = False\n    # Encoder\n    s1 = encoder.get_layer(\"input_1\").output           ## (512 x 512)\n    s2 = encoder.get_layer(\"activation\").output        ## (255 x 255)\n    s2 = layers.ZeroPadding2D(((1, 0), (1, 0)))(s2)         ## (256 x 256)\n    s3 = encoder.get_layer(\"activation_3\").output      ## (126 x 126)\n    s3 = layers.ZeroPadding2D((1, 1))(s3)                     ## (128 x 128)\n    s4 = encoder.get_layer(\"activation_74\").output      ## (61 x 61)\n    s4 = layers.ZeroPadding2D(((2, 1), (2, 1)))(s4)           ## (64 x 64)\n\n    # Bridge\n    b1 = encoder.get_layer(\"activation_161\").output     ## (30 x 30)\n    b1 = layers.ZeroPadding2D((1, 1))(b1)                      ## (32 x 32)\n\n    # Decoder layer\n    d1 = decoder_block(b1, s4, 512)                     ## (64 x 64)\n    d2 = decoder_block(d1, s3, 256)                     ## (128 x 128)\n    d3 = decoder_block(d2, s2, 128)                     ## (256 x 256)\n    d4 = decoder_block(d3, s1, 64)                      ## (512 x 512)\n    \n    # Output layer\n    gap = layers.GlobalAveragePooling2D()(d4)\n    dropout = layers.Dropout(0.2)(gap)\n    outputs = layers.Dense(7, activation=\"sigmoid\")(dropout)\n    # Build the model\n    model = Model(inputs, outputs, name=\"InceptionResNetV2-UNet\")\n    \n    return encoder, model\n\ninception_resnet, model = build_inception_resnetv2_unet(input_shape = (128, 128, 3))","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-01-22T02:01:08.026439Z","iopub.execute_input":"2025-01-22T02:01:08.026867Z","iopub.status.idle":"2025-01-22T02:01:22.413134Z","shell.execute_reply.started":"2025-01-22T02:01:08.026832Z","shell.execute_reply":"2025-01-22T02:01:22.411828Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# inception_resnet.summary() #none:3, 3:13, 74:266, 161:606\nfor i in range(len(inception_resnet.layers)):\n    print (i, inception_resnet.layers[i].name)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-01-22T02:01:50.825962Z","iopub.execute_input":"2025-01-22T02:01:50.826378Z","iopub.status.idle":"2025-01-22T02:01:51.360482Z","shell.execute_reply.started":"2025-01-22T02:01:50.826345Z","shell.execute_reply":"2025-01-22T02:01:51.359215Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"plot_model(inception_resnet, to_file='model_plot_inception_resnet.png', show_shapes=True, show_layer_names=True)","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"model_0 = model","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-01-22T02:03:07.098525Z","iopub.execute_input":"2025-01-22T02:03:07.099052Z","iopub.status.idle":"2025-01-22T02:03:07.104974Z","shell.execute_reply.started":"2025-01-22T02:03:07.099015Z","shell.execute_reply":"2025-01-22T02:03:07.103623Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"plot_model(model_0, to_file='model_plot_inception_resnet_unet.png', show_shapes=True, show_layer_names=True)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-01-22T02:03:23.53035Z","iopub.execute_input":"2025-01-22T02:03:23.530872Z","iopub.status.idle":"2025-01-22T02:03:28.294433Z","shell.execute_reply.started":"2025-01-22T02:03:23.530838Z","shell.execute_reply":"2025-01-22T02:03:28.292679Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"for i in range(len(model_0.layers)):\n    print (i, model_0.layers[i].name)\n    \nfor layer in model_0.layers[274:]:\n    layer.trainable=True\nfor layer in model_0.layers[0:274]:\n    layer.trainable=False","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-01-22T02:06:03.402179Z","iopub.execute_input":"2025-01-22T02:06:03.404337Z","iopub.status.idle":"2025-01-22T02:06:03.848955Z","shell.execute_reply.started":"2025-01-22T02:06:03.404266Z","shell.execute_reply":"2025-01-22T02:06:03.847664Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"model_0.summary()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-01-22T02:06:18.261836Z","iopub.execute_input":"2025-01-22T02:06:18.262276Z","iopub.status.idle":"2025-01-22T02:06:19.902014Z","shell.execute_reply.started":"2025-01-22T02:06:18.262238Z","shell.execute_reply":"2025-01-22T02:06:19.900733Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Compile the model\nmodel_0.compile(loss=\"binary_crossentropy\",\n              optimizer = keras.optimizers.SGD(lr=0.01, decay=1e-6, momentum=0.9, nesterov=True),\n              metrics=[tf.keras.metrics.BinaryAccuracy()])\n\n# Train the model\nhistory_model_0 = model_0.fit(train_dataset, \n                              epochs=100, \n                              validation_data=val_dataset,\n                              steps_per_epoch=int(len(train_dataset)/32),\n                              validation_steps=int(len(val_dataset)),\n                              callbacks=[callback(patience=15, model_name=\"model_0_InceptionResNetV2.h5\")])","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-01-22T02:07:54.675717Z","iopub.execute_input":"2025-01-22T02:07:54.676686Z","iopub.status.idle":"2025-01-22T02:08:29.00722Z","shell.execute_reply.started":"2025-01-22T02:07:54.676613Z","shell.execute_reply":"2025-01-22T02:08:29.005408Z"}},"outputs":[],"execution_count":null}]}