{"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":"nvidiaTeslaT4","dataSources":[{"sourceId":52254,"databundleVersionId":9674523,"sourceType":"competition"},{"sourceId":6211844,"sourceType":"datasetVersion","datasetId":3567114}],"dockerImageVersionId":30554,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":true}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"markdown","source":"# <center>Multi-label classification of abdominal trauma from CT images</center>\n\n","metadata":{"papermill":{"duration":0.025483,"end_time":"2022-02-01T10:21:43.84374","exception":false,"start_time":"2022-02-01T10:21:43.818257","status":"completed"},"tags":[]}},{"cell_type":"markdown","source":"## To commence this project, the neccesary libraries need to be installed.\n## We would be using the **TensorFlow** framework and the pretrained **EfficientNetB1**\n","metadata":{}},{"cell_type":"code","source":"# Imporitng libraries\nimport pandas as pd\nimport os\nimport random\nimport numpy as np\nimport tensorflow as tf\nimport cv2\nimport matplotlib.pyplot as plt\nimport seaborn as sns\nfrom IPython.display import clear_output\nfrom sklearn.metrics import confusion_matrix\nfrom sklearn.model_selection import StratifiedKFold\n\n\nrandom.seed(42)","metadata":{"id":"fUPKjZaaJHkM","papermill":{"duration":5.021373,"end_time":"2022-02-01T10:21:48.88737","exception":false,"start_time":"2022-02-01T10:21:43.865997","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2024-11-09T11:58:01.122981Z","iopub.execute_input":"2024-11-09T11:58:01.123313Z","iopub.status.idle":"2024-11-09T11:58:12.50809Z","shell.execute_reply.started":"2024-11-09T11:58:01.123285Z","shell.execute_reply":"2024-11-09T11:58:12.50728Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"#Loading the training dataset\ntrain_img = \"/kaggle/input/rsna-atd-512x512-png-v2-dataset/train_images\"","metadata":{"execution":{"iopub.status.busy":"2024-11-09T11:58:12.50979Z","iopub.execute_input":"2024-11-09T11:58:12.510342Z","iopub.status.idle":"2024-11-09T11:58:12.514693Z","shell.execute_reply.started":"2024-11-09T11:58:12.510304Z","shell.execute_reply":"2024-11-09T11:58:12.513634Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"for i in os.listdir(train_img):\n    for j in os.listdir(os.path.join(train_img,i)):\n        print(len(os.listdir(os.path.join(train_img,i,j))))","metadata":{"_kg_hide-output":true,"execution":{"iopub.status.busy":"2024-11-09T11:58:12.51592Z","iopub.execute_input":"2024-11-09T11:58:12.516272Z","iopub.status.idle":"2024-11-09T11:58:17.091572Z","shell.execute_reply.started":"2024-11-09T11:58:12.516241Z","shell.execute_reply":"2024-11-09T11:58:17.090653Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"pip install imbalanced-learn","metadata":{"execution":{"iopub.status.busy":"2024-11-09T11:58:17.09408Z","iopub.execute_input":"2024-11-09T11:58:17.094735Z","iopub.status.idle":"2024-11-09T11:58:29.978974Z","shell.execute_reply.started":"2024-11-09T11:58:17.094701Z","shell.execute_reply":"2024-11-09T11:58:29.9779Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"# Part A\n## Import and explore the data","metadata":{"papermill":{"duration":0.02193,"end_time":"2022-02-01T10:21:48.93356","exception":false,"start_time":"2022-02-01T10:21:48.91163","status":"completed"},"tags":[]}},{"cell_type":"code","source":"# Making a list containing all unique classes in the training set\n\n# Reading the training labels\ntraining_labels = pd.read_csv(\"/kaggle/input/rsna-2023-abdominal-trauma-detection/train_2024.csv\")","metadata":{"id":"PBlH8ae3LbG0","papermill":{"duration":0.069238,"end_time":"2022-02-01T10:21:49.024476","exception":false,"start_time":"2022-02-01T10:21:48.955238","status":"completed"},"tags":[],"execution":{"iopub.status.busy":"2024-11-09T11:58:29.98037Z","iopub.execute_input":"2024-11-09T11:58:29.980694Z","iopub.status.idle":"2024-11-09T11:58:30.002688Z","shell.execute_reply.started":"2024-11-09T11:58:29.980668Z","shell.execute_reply":"2024-11-09T11:58:30.001972Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"#Viewing the dataset in a structured format\ntraining_labels","metadata":{"execution":{"iopub.status.busy":"2024-11-09T11:58:30.003816Z","iopub.execute_input":"2024-11-09T11:58:30.004165Z","iopub.status.idle":"2024-11-09T11:58:30.033969Z","shell.execute_reply.started":"2024-11-09T11:58:30.004132Z","shell.execute_reply":"2024-11-09T11:58:30.032987Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"# Part B\n## In the next few cells, we chose to explore the dataframe to check for missing values","metadata":{}},{"cell_type":"code","source":"training_labels.columns","metadata":{"execution":{"iopub.status.busy":"2024-11-09T11:58:30.035311Z","iopub.execute_input":"2024-11-09T11:58:30.036172Z","iopub.status.idle":"2024-11-09T11:58:30.042718Z","shell.execute_reply.started":"2024-11-09T11:58:30.036135Z","shell.execute_reply":"2024-11-09T11:58:30.041741Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"training_labels['patient_id'].isna().value_counts()","metadata":{"execution":{"iopub.status.busy":"2024-11-09T11:58:30.043982Z","iopub.execute_input":"2024-11-09T11:58:30.044332Z","iopub.status.idle":"2024-11-09T11:58:30.059548Z","shell.execute_reply.started":"2024-11-09T11:58:30.044298Z","shell.execute_reply":"2024-11-09T11:58:30.058736Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"training_labels['bowel_healthy'].isna().value_counts()","metadata":{"execution":{"iopub.status.busy":"2024-11-09T11:58:30.060609Z","iopub.execute_input":"2024-11-09T11:58:30.060914Z","iopub.status.idle":"2024-11-09T11:58:30.068189Z","shell.execute_reply.started":"2024-11-09T11:58:30.060884Z","shell.execute_reply":"2024-11-09T11:58:30.067413Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"training_labels['bowel_injury'].isna().value_counts()","metadata":{"execution":{"iopub.status.busy":"2024-11-09T11:58:30.073497Z","iopub.execute_input":"2024-11-09T11:58:30.073801Z","iopub.status.idle":"2024-11-09T11:58:30.081128Z","shell.execute_reply.started":"2024-11-09T11:58:30.07378Z","shell.execute_reply":"2024-11-09T11:58:30.080337Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"training_labels['extravasation_healthy'].isna().value_counts()","metadata":{"execution":{"iopub.status.busy":"2024-11-09T11:58:30.082518Z","iopub.execute_input":"2024-11-09T11:58:30.082872Z","iopub.status.idle":"2024-11-09T11:58:30.09159Z","shell.execute_reply.started":"2024-11-09T11:58:30.082842Z","shell.execute_reply":"2024-11-09T11:58:30.09079Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"training_labels['extravasation_injury'].isna().value_counts()","metadata":{"execution":{"iopub.status.busy":"2024-11-09T11:58:30.092543Z","iopub.execute_input":"2024-11-09T11:58:30.092804Z","iopub.status.idle":"2024-11-09T11:58:30.103772Z","shell.execute_reply.started":"2024-11-09T11:58:30.092782Z","shell.execute_reply":"2024-11-09T11:58:30.102976Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"training_labels['kidney_healthy'].isna().value_counts()","metadata":{"execution":{"iopub.status.busy":"2024-11-09T11:58:30.10482Z","iopub.execute_input":"2024-11-09T11:58:30.105078Z","iopub.status.idle":"2024-11-09T11:58:30.116384Z","shell.execute_reply.started":"2024-11-09T11:58:30.105057Z","shell.execute_reply":"2024-11-09T11:58:30.115554Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"training_labels['kidney_low'].isna().value_counts()","metadata":{"execution":{"iopub.status.busy":"2024-11-09T11:58:30.117347Z","iopub.execute_input":"2024-11-09T11:58:30.117609Z","iopub.status.idle":"2024-11-09T11:58:30.127205Z","shell.execute_reply.started":"2024-11-09T11:58:30.117587Z","shell.execute_reply":"2024-11-09T11:58:30.126407Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"training_labels['kidney_high'].isna().value_counts()","metadata":{"execution":{"iopub.status.busy":"2024-11-09T11:58:30.12819Z","iopub.execute_input":"2024-11-09T11:58:30.128465Z","iopub.status.idle":"2024-11-09T11:58:30.139765Z","shell.execute_reply.started":"2024-11-09T11:58:30.128437Z","shell.execute_reply":"2024-11-09T11:58:30.1388Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"training_labels['liver_healthy'].isna().value_counts()","metadata":{"execution":{"iopub.status.busy":"2024-11-09T11:58:30.140873Z","iopub.execute_input":"2024-11-09T11:58:30.141437Z","iopub.status.idle":"2024-11-09T11:58:30.151386Z","shell.execute_reply.started":"2024-11-09T11:58:30.141406Z","shell.execute_reply":"2024-11-09T11:58:30.150601Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"training_labels['liver_low'].isna().value_counts()","metadata":{"execution":{"iopub.status.busy":"2024-11-09T11:58:30.152512Z","iopub.execute_input":"2024-11-09T11:58:30.152834Z","iopub.status.idle":"2024-11-09T11:58:30.165117Z","shell.execute_reply.started":"2024-11-09T11:58:30.152805Z","shell.execute_reply":"2024-11-09T11:58:30.16427Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"training_labels['liver_high'].isna().value_counts()","metadata":{"execution":{"iopub.status.busy":"2024-11-09T11:58:30.166207Z","iopub.execute_input":"2024-11-09T11:58:30.166524Z","iopub.status.idle":"2024-11-09T11:58:30.177468Z","shell.execute_reply.started":"2024-11-09T11:58:30.166501Z","shell.execute_reply":"2024-11-09T11:58:30.176831Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"training_labels['spleen_healthy'].isna().value_counts()","metadata":{"execution":{"iopub.status.busy":"2024-11-09T11:58:30.178532Z","iopub.execute_input":"2024-11-09T11:58:30.178846Z","iopub.status.idle":"2024-11-09T11:58:30.190834Z","shell.execute_reply.started":"2024-11-09T11:58:30.178816Z","shell.execute_reply":"2024-11-09T11:58:30.190024Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"training_labels['spleen_low'].isna().value_counts()","metadata":{"execution":{"iopub.status.busy":"2024-11-09T11:58:30.191868Z","iopub.execute_input":"2024-11-09T11:58:30.192197Z","iopub.status.idle":"2024-11-09T11:58:30.201632Z","shell.execute_reply.started":"2024-11-09T11:58:30.192165Z","shell.execute_reply":"2024-11-09T11:58:30.200881Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"training_labels['spleen_high'].isna().value_counts()","metadata":{"execution":{"iopub.status.busy":"2024-11-09T11:58:30.202759Z","iopub.execute_input":"2024-11-09T11:58:30.202982Z","iopub.status.idle":"2024-11-09T11:58:30.213827Z","shell.execute_reply.started":"2024-11-09T11:58:30.202962Z","shell.execute_reply":"2024-11-09T11:58:30.213055Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"training_labels['any_injury'].isna().value_counts()","metadata":{"execution":{"iopub.status.busy":"2024-11-09T11:58:30.214786Z","iopub.execute_input":"2024-11-09T11:58:30.215228Z","iopub.status.idle":"2024-11-09T11:58:30.22496Z","shell.execute_reply.started":"2024-11-09T11:58:30.215204Z","shell.execute_reply":"2024-11-09T11:58:30.224077Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# Using the EfficientNetB1 model and tweaking the last two layers to suit our work\n#def create_model(decay_steps=10,warmup_steps=10):\n#    base_model = tf.keras.applications.EfficientNetB1(\n#    weights= \"imagenet\", include_top=False, input_shape= (512,512,3)\n#    )\n#    num_classes=61\n\n#    x = base_model.output\n#    x = tf.keras.layers.GlobalAveragePooling2D()(x)\n#    x = tf.keras.layers.Dropout(0.2)(x)\n#    x_bowel = tf.keras.layers.Dense(32, activation='silu')(x)\n#    x_extra = tf.keras.layers.Dense(32, activation='silu')(x)\n#    x_liver = tf.keras.layers.Dense(32, activation='silu')(x)\n #   x_kidney = tf.keras.layers.Dense(32, activation='silu')(x)\n#    x_spleen = tf.keras.layers.Dense(32, activation='silu')(x)\n\n    # Define heads\n#    out_bowel = tf.keras.layers.Dense(1, name='bowel', activation='sigmoid')(x_bowel) # use sigmoid to convert predictions to [0-1]\n#    out_extra = tf.keras.layers.Dense(1, name='extra', activation='sigmoid')(x_extra) # use sigmoid to convert predictions to [0-1]\n#    out_liver = tf.keras.layers.Dense(3, name='liver', activation='softmax')(x_liver) # use softmax for the liver head\n#    out_kidney = tf.keras.layers.Dense(3, name='kidney', activation='softmax')(x_kidney) # use softmax for the kidney head\n#    out_spleen = tf.keras.layers.Dense(3, name='spleen', activation='softmax')(x_spleen) # use softmax for the spleen head\n\n#    model = tf.keras.Model(inputs = base_model.input, outputs = [out_bowel,out_extra,out_liver,out_kidney,out_spleen])\n        # Cosine Decay\n#    cosine_decay = tf.keras.optimizers.schedules.CosineDecay(\n#        initial_learning_rate=1e-4,\n#        decay_steps=decay_steps,\n#        alpha=0.0,\n        #warmup_target=1e-3,\n        #warmup_steps=warmup_steps,\n #   )\n\n    # Compile the model\n #   optimizer = tf.keras.optimizers.Adam(learning_rate=cosine_decay)\n #   loss = [\n #       tf.keras.losses.BinaryCrossentropy(),\n #       tf.keras.losses.BinaryCrossentropy(),\n #       tf.keras.losses.CategoricalCrossentropy(),\n #       tf.keras.losses.CategoricalCrossentropy(),\n #       tf.keras.losses.CategoricalCrossentropy()]\n    \n #   metrics = [\n #       [tf.keras.metrics.BinaryAccuracy(name=\"bowel_binary_accuracy\")],\n #       [tf.keras.metrics.BinaryAccuracy(name=\"extra_binary_accuracy\")],\n  #      [tf.keras.metrics.CategoricalAccuracy(name=\"liver_cat_accuracy\")],\n #       [tf.keras.metrics.CategoricalAccuracy(name=\"kidney_cat_accuracy\")],\n #       [tf.keras.metrics.CategoricalAccuracy(name=\"spleen_cat_accuracy\")]]\n    #    \"bowel\":[\"accuracy\"],\n    #    \"extra\":[\"accuracy\"],\n    #    \"liver\":[\"accuracy\"],\n    #    \"kidney\":[\"accuracy\"],\n    #    \"spleen\":[\"accuracy\"],\n    #}\n  #  print(\"[INFO] Compiling the model...\")\n #   model.compile(\n #       optimizer=optimizer,\n #     loss=loss,\n #     metrics=metrics\n #   )\n #   return model","metadata":{"execution":{"iopub.status.busy":"2024-11-09T11:58:30.226136Z","iopub.execute_input":"2024-11-09T11:58:30.226415Z","iopub.status.idle":"2024-11-09T11:58:30.234536Z","shell.execute_reply.started":"2024-11-09T11:58:30.226386Z","shell.execute_reply":"2024-11-09T11:58:30.233867Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"+ Sử dụng các kỹ thuật ensemble như bagging hoặc boosting:","metadata":{}},{"cell_type":"code","source":"import tensorflow as tf\n\n\n\ndef create_model(decay_steps=900, warmup_steps=60, fine_tune_from=100):\n    # Tải EfficientNetB1 làm base model\n    base_model = tf.keras.applications.EfficientNetB1(\n        weights=\"imagenet\", include_top=False, input_shape=(512, 512, 3)\n    )\n\n    # Fine-tune một phần của base model\n    for layer in base_model.layers[:fine_tune_from]:\n        layer.trainable = False\n\n    x = base_model.output\n\n    # Lớp Convolution với kernel 3x3 và tăng số lượng filters\n    x = tf.keras.layers.Conv2D(128, (5, 5), activation='relu', padding='same')(x)\n    x = tf.keras.layers.BatchNormalization()(x)\n    x = tf.keras.layers.MaxPooling2D((2, 2), padding='same')(x)\n    \n    x = tf.keras.layers.Conv2D(256, (5, 5), activation='relu', padding='same')(x)\n    x = tf.keras.layers.BatchNormalization()(x)\n    x = tf.keras.layers.MaxPooling2D((2, 2), padding='same')(x)\n\n    x = tf.keras.layers.Conv2D(512, (5, 5), activation='relu', padding='same')(x)\n    x = tf.keras.layers.BatchNormalization()(x)\n    x = tf.keras.layers.MaxPooling2D((2, 2), padding='same')(x)\n\n    x = tf.keras.layers.Conv2D(1024, (5, 5), activation='relu', padding='same')(x)\n    x = tf.keras.layers.BatchNormalization()(x)\n    x = tf.keras.layers.MaxPooling2D((2, 2), padding='same')(x)\n\n    # Residual Block\n    residual = x\n    x = tf.keras.layers.Conv2D(1024, (2, 2), activation='relu', padding='same')(x)\n    x = tf.keras.layers.BatchNormalization()(x)\n    x = tf.keras.layers.Add()([x, residual])  # Skip connection\n\n    # Dense Block với dropout cao hơn và số lượng units lớn hơn\n    x = tf.keras.layers.GlobalAveragePooling2D()(x)\n    x = tf.keras.layers.Dropout(0.6)(x)  # Tăng dropout\n\n    # Dense layers cho các đầu ra\n    x_bowel = tf.keras.layers.Dense(512, activation='relu')(x)\n    x_extra = tf.keras.layers.Dense(512, activation='relu')(x)\n    x_liver = tf.keras.layers.Dense(512, activation='relu')(x)\n    x_kidney = tf.keras.layers.Dense(512, activation='relu')(x)\n    x_spleen = tf.keras.layers.Dense(512, activation='relu')(x)\n\n    # Output Layers\n    out_bowel = tf.keras.layers.Dense(1, name='bowel', activation='sigmoid')(x_bowel)  # Bowel (binary)\n    out_extra = tf.keras.layers.Dense(1, name='extra', activation='sigmoid')(x_extra)  # Extra (binary)\n    out_liver = tf.keras.layers.Dense(3, name='liver', activation='softmax')(x_liver)  # Liver (multiclass)\n    out_kidney = tf.keras.layers.Dense(3, name='kidney', activation='softmax')(x_kidney)  # Kidney (multiclass)\n    out_spleen = tf.keras.layers.Dense(3, name='spleen', activation='softmax')(x_spleen)  # Spleen (multiclass)\n\n    # Create model\n    model = tf.keras.Model(inputs=base_model.input, outputs=[out_bowel, out_extra, out_liver, out_kidney, out_spleen])\n    \n    # Cosine Decay with a warmup phase\n    cosine_decay = tf.keras.optimizers.schedules.CosineDecayRestarts(\n        initial_learning_rate=3e-4,  # Lower initial learning rate\n        first_decay_steps=warmup_steps,\n        t_mul=1.8,\n        m_mul=0.8,\n        alpha=0.1\n    )\n\n    # Compile the model\n    optimizer = tf.keras.optimizers.Adam(learning_rate=cosine_decay)\n    loss = [\n        tf.keras.losses.BinaryCrossentropy(),\n        tf.keras.losses.BinaryCrossentropy(),\n        tf.keras.losses.CategoricalCrossentropy(),\n        tf.keras.losses.CategoricalCrossentropy(),\n        tf.keras.losses.CategoricalCrossentropy()\n    ]\n    \n    metrics = [\n        [tf.keras.metrics.BinaryAccuracy(name=\"bowel_binary_accuracy\")],\n        [tf.keras.metrics.BinaryAccuracy(name=\"extra_binary_accuracy\")],\n        [tf.keras.metrics.CategoricalAccuracy(name=\"liver_cat_accuracy\")],\n        [tf.keras.metrics.CategoricalAccuracy(name=\"kidney_cat_accuracy\")],\n        [tf.keras.metrics.CategoricalAccuracy(name=\"spleen_cat_accuracy\")]\n    ]\n    \n    print(\"[INFO] Compiling the model...\")\n    model.compile(\n        optimizer=optimizer,\n        loss=loss,\n        metrics=metrics\n    )\n    \n    return model","metadata":{"execution":{"iopub.status.busy":"2024-11-09T11:58:30.235896Z","iopub.execute_input":"2024-11-09T11:58:30.23617Z","iopub.status.idle":"2024-11-09T11:58:30.256482Z","shell.execute_reply.started":"2024-11-09T11:58:30.236146Z","shell.execute_reply":"2024-11-09T11:58:30.255703Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"model = create_model()","metadata":{"execution":{"iopub.status.busy":"2024-11-09T11:58:30.257366Z","iopub.execute_input":"2024-11-09T11:58:30.257603Z","iopub.status.idle":"2024-11-09T11:58:35.236578Z","shell.execute_reply.started":"2024-11-09T11:58:30.257581Z","shell.execute_reply":"2024-11-09T11:58:35.235591Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# In ra tóm tắt mô hình\nmodel.summary()","metadata":{"execution":{"iopub.status.busy":"2024-11-09T11:58:35.237865Z","iopub.execute_input":"2024-11-09T11:58:35.238155Z","iopub.status.idle":"2024-11-09T11:58:36.086229Z","shell.execute_reply.started":"2024-11-09T11:58:35.238122Z","shell.execute_reply":"2024-11-09T11:58:36.085311Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"tf.keras.utils.plot_model(\n    model,  # Sử dụng đúng tên biến của mô hình\n    to_file='model.png'\n)\n","metadata":{"execution":{"iopub.status.busy":"2024-11-09T11:58:36.087436Z","iopub.execute_input":"2024-11-09T11:58:36.087716Z","iopub.status.idle":"2024-11-09T11:58:38.708136Z","shell.execute_reply.started":"2024-11-09T11:58:36.087691Z","shell.execute_reply":"2024-11-09T11:58:38.706855Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"training_labels = training_labels.set_index('patient_id')\ntraining_labels.head(5)","metadata":{"execution":{"iopub.status.busy":"2024-11-09T11:58:38.714447Z","iopub.execute_input":"2024-11-09T11:58:38.714773Z","iopub.status.idle":"2024-11-09T11:58:38.735233Z","shell.execute_reply.started":"2024-11-09T11:58:38.714744Z","shell.execute_reply":"2024-11-09T11:58:38.73421Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"# Part C\n## Balancing the imbalanced training dataset ","metadata":{}},{"cell_type":"code","source":"#Using histogram to get the distribution of the labels and to check if there are outliers and wrong labels\ntraining_labels.hist(figsize=(20,12),bins=2)\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2024-11-09T11:58:38.736479Z","iopub.execute_input":"2024-11-09T11:58:38.736792Z","iopub.status.idle":"2024-11-09T11:58:41.104242Z","shell.execute_reply.started":"2024-11-09T11:58:38.736766Z","shell.execute_reply":"2024-11-09T11:58:41.103387Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"#images ,labels","metadata":{"execution":{"iopub.status.busy":"2024-11-09T11:58:41.105432Z","iopub.execute_input":"2024-11-09T11:58:41.105723Z","iopub.status.idle":"2024-11-09T11:58:41.109897Z","shell.execute_reply.started":"2024-11-09T11:58:41.105698Z","shell.execute_reply":"2024-11-09T11:58:41.108923Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"images = []\nlabels = []\nfor i in sorted(os.listdir(train_img)):\n    folder = os.listdir(os.path.join(train_img,i))[0]\n    file = os.listdir(os.path.join(train_img,i,folder))[0]\n    images.append(cv2.imread(os.path.join(train_img,i,folder,file), cv2.IMREAD_COLOR ))\n    labels.append(np.asarray(training_labels.loc[int(i)]))\nimages = np.asarray(images)\nlabels = np.asarray(labels)","metadata":{"execution":{"iopub.status.busy":"2024-11-09T11:58:41.111009Z","iopub.execute_input":"2024-11-09T11:58:41.111324Z","iopub.status.idle":"2024-11-09T11:58:43.638205Z","shell.execute_reply.started":"2024-11-09T11:58:41.111293Z","shell.execute_reply":"2024-11-09T11:58:43.637398Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"## Examples of images","metadata":{}},{"cell_type":"code","source":"plt.figure(figsize=(30,12))\nfor i in range(10):\n    plt.subplot(2,5,i+1)\n    plt.imshow(images[i])\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2024-11-09T11:58:43.639545Z","iopub.execute_input":"2024-11-09T11:58:43.640265Z","iopub.status.idle":"2024-11-09T11:58:45.950816Z","shell.execute_reply.started":"2024-11-09T11:58:43.640228Z","shell.execute_reply":"2024-11-09T11:58:45.949934Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"from sklearn.model_selection import train_test_split","metadata":{"execution":{"iopub.status.busy":"2024-11-09T11:58:45.952048Z","iopub.execute_input":"2024-11-09T11:58:45.952386Z","iopub.status.idle":"2024-11-09T11:58:45.956761Z","shell.execute_reply.started":"2024-11-09T11:58:45.952355Z","shell.execute_reply":"2024-11-09T11:58:45.955933Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"X_train, X_val, y_train, y_val = train_test_split(images, labels, test_size=0.25)","metadata":{"execution":{"iopub.status.busy":"2024-11-09T11:58:45.957949Z","iopub.execute_input":"2024-11-09T11:58:45.95822Z","iopub.status.idle":"2024-11-09T11:58:46.024356Z","shell.execute_reply.started":"2024-11-09T11:58:45.958196Z","shell.execute_reply":"2024-11-09T11:58:46.023502Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"from imblearn.over_sampling import RandomOverSampler\n\n#oversampler = RandomOverSampler(random_state=42)\n#new_images, new_labels = oversampler.fit_resample(images, labels)","metadata":{"execution":{"iopub.status.busy":"2024-11-09T11:58:46.025616Z","iopub.execute_input":"2024-11-09T11:58:46.025906Z","iopub.status.idle":"2024-11-09T11:58:46.575612Z","shell.execute_reply.started":"2024-11-09T11:58:46.025882Z","shell.execute_reply":"2024-11-09T11:58:46.574841Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"# Part D\n## Training the model with the training dataset","metadata":{}},{"cell_type":"code","source":"bowel_labels = labels[:,2]\nextravasation_labels = labels[:,4]\nkidney_labels = labels[:,4:7]\nliver_labels = labels[:,7:10]\nspleen_labels = labels[:,10:13]\nany_labels = labels[:,-1]","metadata":{"execution":{"iopub.status.busy":"2024-11-09T11:58:46.576811Z","iopub.execute_input":"2024-11-09T11:58:46.577811Z","iopub.status.idle":"2024-11-09T11:58:46.582884Z","shell.execute_reply.started":"2024-11-09T11:58:46.57778Z","shell.execute_reply":"2024-11-09T11:58:46.581961Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"bowel_val = y_val[:,2]\nextravasation_val = y_val[:,4]\nkidney_val = y_val[:,4:7]\nliver_val = y_val[:,7:10]\nspleen_val = y_val[:,10:13]\nany_val = y_val[:,-1]","metadata":{"execution":{"iopub.status.busy":"2024-11-09T11:58:46.583973Z","iopub.execute_input":"2024-11-09T11:58:46.584279Z","iopub.status.idle":"2024-11-09T11:58:46.593818Z","shell.execute_reply.started":"2024-11-09T11:58:46.584245Z","shell.execute_reply":"2024-11-09T11:58:46.592946Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"bowel_train = y_train[:,2]\nextravasation_train = y_train[:,4]\nkidney_train = y_train[:,4:7]\nliver_train = y_train[:,7:10]\nspleen_train = y_train[:,10:13]\nany_train = y_train[:,-1]","metadata":{"execution":{"iopub.status.busy":"2024-11-09T11:58:46.595791Z","iopub.execute_input":"2024-11-09T11:58:46.596744Z","iopub.status.idle":"2024-11-09T11:58:46.601986Z","shell.execute_reply.started":"2024-11-09T11:58:46.596709Z","shell.execute_reply":"2024-11-09T11:58:46.601264Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"#batch_size = 8\n#num_epoch = 2\n#history = model.fit(x=X_train,y=[bowel_train,extravasation_train,kidney_train,liver_train,spleen_train],batch_size=batch_size, epochs=num_epoch, verbose=1, validation_data=(X_val,[bowel_val,extravasation_val,kidney_val,liver_val,spleen_val]))\n\n\n#validation_data=(X_val,[bowel_val,extravasation_val,kidney_val,liver_val,spleen_val])","metadata":{"papermill":{"duration":1176.379334,"end_time":"2022-02-01T14:07:30.902597","exception":false,"start_time":"2022-02-01T13:47:54.523263","status":"completed"},"tags":[],"_kg_hide-output":true,"execution":{"iopub.status.busy":"2024-11-09T11:58:46.603156Z","iopub.execute_input":"2024-11-09T11:58:46.603428Z","iopub.status.idle":"2024-11-09T11:58:46.612724Z","shell.execute_reply.started":"2024-11-09T11:58:46.603396Z","shell.execute_reply":"2024-11-09T11:58:46.611956Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import tensorflow as tf\nfrom tensorflow.keras.preprocessing.image import ImageDataGenerator\nfrom tensorflow.keras.callbacks import EarlyStopping, ModelCheckpoint\nimport tensorflow as tf\n\n\n\ndef create_model(decay_steps=900, warmup_steps=60, fine_tune_from=100):\n    # Tải EfficientNetB1 làm base model\n    base_model = tf.keras.applications.EfficientNetB1(\n        weights=\"imagenet\", include_top=False, input_shape=(512, 512, 3)\n    )\n\n    # Fine-tune một phần của base model\n    for layer in base_model.layers[:fine_tune_from]:\n        layer.trainable = False\n\n    x = base_model.output\n\n    # Lớp Convolution với kernel 3x3 và tăng số lượng filters\n    x = tf.keras.layers.Conv2D(128, (5, 5), activation='relu', padding='same')(x)\n    x = tf.keras.layers.BatchNormalization()(x)\n    x = tf.keras.layers.MaxPooling2D((2, 2), padding='same')(x)\n    \n    x = tf.keras.layers.Conv2D(256, (5, 5), activation='relu', padding='same')(x)\n    x = tf.keras.layers.BatchNormalization()(x)\n    x = tf.keras.layers.MaxPooling2D((2, 2), padding='same')(x)\n\n    x = tf.keras.layers.Conv2D(512, (5, 5), activation='relu', padding='same')(x)\n    x = tf.keras.layers.BatchNormalization()(x)\n    x = tf.keras.layers.MaxPooling2D((2, 2), padding='same')(x)\n\n    x = tf.keras.layers.Conv2D(1024, (5, 5), activation='relu', padding='same')(x)\n    x = tf.keras.layers.BatchNormalization()(x)\n    x = tf.keras.layers.MaxPooling2D((2, 2), padding='same')(x)\n\n    # Residual Block\n    residual = x\n    x = tf.keras.layers.Conv2D(1024, (2, 2), activation='relu', padding='same')(x)\n    x = tf.keras.layers.BatchNormalization()(x)\n    x = tf.keras.layers.Add()([x, residual])  # Skip connection\n\n    # Dense Block với dropout cao hơn và số lượng units lớn hơn\n    x = tf.keras.layers.GlobalAveragePooling2D()(x)\n    x = tf.keras.layers.Dropout(0.6)(x)  # Tăng dropout\n\n    # Dense layers cho các đầu ra\n    x_bowel = tf.keras.layers.Dense(512, activation='relu')(x)\n    x_extra = tf.keras.layers.Dense(512, activation='relu')(x)\n    x_liver = tf.keras.layers.Dense(512, activation='relu')(x)\n    x_kidney = tf.keras.layers.Dense(512, activation='relu')(x)\n    x_spleen = tf.keras.layers.Dense(512, activation='relu')(x)\n\n    # Output Layers\n    out_bowel = tf.keras.layers.Dense(1, name='bowel', activation='sigmoid')(x_bowel)  # Bowel (binary)\n    out_extra = tf.keras.layers.Dense(1, name='extra', activation='sigmoid')(x_extra)  # Extra (binary)\n    out_liver = tf.keras.layers.Dense(3, name='liver', activation='softmax')(x_liver)  # Liver (multiclass)\n    out_kidney = tf.keras.layers.Dense(3, name='kidney', activation='softmax')(x_kidney)  # Kidney (multiclass)\n    out_spleen = tf.keras.layers.Dense(3, name='spleen', activation='softmax')(x_spleen)  # Spleen (multiclass)\n\n    # Create model\n    model = tf.keras.Model(inputs=base_model.input, outputs=[out_bowel, out_extra, out_liver, out_kidney, out_spleen])\n    \n    # Cosine Decay with a warmup phase\n    cosine_decay = tf.keras.optimizers.schedules.CosineDecayRestarts(\n        initial_learning_rate=3e-4,  # Lower initial learning rate\n        first_decay_steps=warmup_steps,\n        t_mul=1.8,\n        m_mul=0.8,\n        alpha=0.1\n    )\n\n    # Compile the model\n    optimizer = tf.keras.optimizers.Adam(learning_rate=cosine_decay)\n    loss = [\n        tf.keras.losses.BinaryCrossentropy(),\n        tf.keras.losses.BinaryCrossentropy(),\n        tf.keras.losses.CategoricalCrossentropy(),\n        tf.keras.losses.CategoricalCrossentropy(),\n        tf.keras.losses.CategoricalCrossentropy()\n    ]\n    \n    metrics = [\n        [tf.keras.metrics.BinaryAccuracy(name=\"bowel_binary_accuracy\")],\n        [tf.keras.metrics.BinaryAccuracy(name=\"extra_binary_accuracy\")],\n        [tf.keras.metrics.CategoricalAccuracy(name=\"liver_cat_accuracy\")],\n        [tf.keras.metrics.CategoricalAccuracy(name=\"kidney_cat_accuracy\")],\n        [tf.keras.metrics.CategoricalAccuracy(name=\"spleen_cat_accuracy\")]\n    ]\n    \n    print(\"[INFO] Compiling the model...\")\n    model.compile(\n        optimizer=optimizer,\n        loss=loss,\n        metrics=metrics\n    )\n    \n    return model\n\n\n# Load images and labels\nimages = []\nlabels = []\nfor i in sorted(os.listdir(train_img)):\n    folder = os.listdir(os.path.join(train_img, i))[0]\n    file = os.listdir(os.path.join(train_img, i, folder))[0]\n    images.append(cv2.imread(os.path.join(train_img, i, folder, file), cv2.IMREAD_COLOR))\n    labels.append(np.asarray(training_labels.loc[int(i)]))\nimages = np.asarray(images)\nlabels = np.asarray(labels)\n\n# Split data\nX_train, X_val, y_train, y_val = train_test_split(images, labels, test_size=0.25)\n\n# Prepare labels for each class\nbowel_labels = labels[:, 2]\nextravasation_labels = labels[:, 4]\nkidney_labels = labels[:, 4:7]\nliver_labels = labels[:, 7:10]\nspleen_labels = labels[:, 10:13]\nany_labels = labels[:, -1]\n\nbowel_val = y_val[:, 2]\nextravasation_val = y_val[:, 4]\nkidney_val = y_val[:, 4:7]\nliver_val = y_val[:, 7:10]\nspleen_val = y_val[:, 10:13]\nany_val = y_val[:, -1]\n\n# KFold Cross Validation\nkf = StratifiedKFold(n_splits=5, shuffle=True, random_state=42)\n\n# Store results for each fold\nfold_results = []\n\n# Data Augmentation\ntrain_datagen = ImageDataGenerator(\n    rotation_range=40,\n    width_shift_range=0.2,\n    height_shift_range=0.2,\n    shear_range=0.2,\n    zoom_range=0.2,\n    horizontal_flip=True,\n    fill_mode='nearest'\n)\n\n# Validation data generator (no augmentation)\nval_datagen = ImageDataGenerator()\n\nfor fold, (train_index, val_index) in enumerate(kf.split(images, any_labels)):\n    print(f\"Fold {fold}\")  # Changed to print fold number from 0 to 4\n\n    # Split data into train and validation according to fold\n    X_train_fold, X_val_fold = images[train_index], images[val_index]\n    y_train_fold, y_val_fold = labels[train_index], labels[val_index]\n\n    # Prepare labels for each class for the fold\n    bowel_train = y_train_fold[:, 2]\n    extravasation_train = y_train_fold[:, 4]\n    kidney_train = y_train_fold[:, 4:7]\n    liver_train = y_train_fold[:, 7:10]\n    spleen_train = y_train_fold[:, 10:13]\n\n    bowel_val = y_val_fold[:, 2]\n    extravasation_val = y_val_fold[:, 4]\n    kidney_val = y_val_fold[:, 4:7]\n    liver_val = y_val_fold[:, 7:10]\n    spleen_val = y_val_fold[:, 10:13]\n\n    # Create a new model for each fold\n    model = create_model()\n\n    # EarlyStopping and ModelCheckpoint\n    early_stopping = EarlyStopping(monitor='val_loss', patience=10, restore_best_weights=True)\n    checkpoint = ModelCheckpoint(f'best_model_fold_{fold}.h5', save_best_only=True, monitor='val_loss')\n\n    # Train the model\n    batch_size = 16\n    num_epoch = 50  # You can modify this value based on the training time and model convergence\n    \n    history = model.fit(\n        x=X_train_fold,\n        y=[bowel_train, extravasation_train, kidney_train, liver_train, spleen_train],\n        batch_size=batch_size,\n        epochs=num_epoch,\n        verbose=1,\n         validation_data=(X_val_fold, [bowel_val, extravasation_val, kidney_val, liver_val, spleen_val])\n    )\n\n    # Store results for this fold\n    fold_results.append(history.history)\n\n# Check results\nfor fold, result in enumerate(fold_results):\n    print(f\"Fold {fold} Results:\")  # Changed to print fold number from 0 to 4\n    for key in result.keys():\n        print(f\"{key}: {result[key][-1]}\")","metadata":{"execution":{"iopub.status.busy":"2024-11-09T11:58:46.614033Z","iopub.execute_input":"2024-11-09T11:58:46.614437Z","iopub.status.idle":"2024-11-09T12:32:33.295866Z","shell.execute_reply.started":"2024-11-09T11:58:46.614413Z","shell.execute_reply":"2024-11-09T12:32:33.294811Z"},"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"history.history.keys()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-11-09T12:32:33.300802Z","iopub.execute_input":"2024-11-09T12:32:33.301112Z","iopub.status.idle":"2024-11-09T12:32:33.307006Z","shell.execute_reply.started":"2024-11-09T12:32:33.301071Z","shell.execute_reply":"2024-11-09T12:32:33.306152Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"val_acc = ['val_bowel_bowel_binary_accuracy', 'val_extra_extra_binary_accuracy', 'val_liver_liver_cat_accuracy', 'val_kidney_kidney_cat_accuracy', 'val_spleen_spleen_cat_accuracy']","metadata":{"_kg_hide-input":true,"trusted":true,"execution":{"iopub.status.busy":"2024-11-09T12:32:33.308094Z","iopub.execute_input":"2024-11-09T12:32:33.30838Z","iopub.status.idle":"2024-11-09T12:32:33.314298Z","shell.execute_reply.started":"2024-11-09T12:32:33.308356Z","shell.execute_reply":"2024-11-09T12:32:33.313412Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"#for i,j in enumerate(val_acc):\n    #print(j, np.asarray(history.history[val_acc[i]])[-1].round(2))\n#np.asarray(history.history['val_bowel_bowel_binary_accuracy'])[-1].round(2)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-11-09T12:32:33.315288Z","iopub.execute_input":"2024-11-09T12:32:33.315858Z","iopub.status.idle":"2024-11-09T12:32:33.324373Z","shell.execute_reply.started":"2024-11-09T12:32:33.315819Z","shell.execute_reply":"2024-11-09T12:32:33.323571Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"for i, j in enumerate(val_acc):\n    # Lấy danh sách các giá trị metric của từng metric (ví dụ: 'val_bowel_binary_accuracy')\n    metric_values = np.asarray(history.history[val_acc[i]])\n\n    # Tìm giá trị tốt nhất (max đối với accuracy, min đối với loss)\n    best_value = np.max(metric_values) if 'accuracy' in j else np.min(metric_values)\n    \n    # In ra tên của metric và giá trị tốt nhất\n    print(f\"{j}: {best_value.round(2)}\")\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-11-09T12:32:33.325415Z","iopub.execute_input":"2024-11-09T12:32:33.325677Z","iopub.status.idle":"2024-11-09T12:32:33.335672Z","shell.execute_reply.started":"2024-11-09T12:32:33.325654Z","shell.execute_reply":"2024-11-09T12:32:33.334834Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"for i in history.history.keys():\n    if i.endswith(\"_loss\") and not i ==\"val_loss\":\n        plt.plot(history.history[i], label=i)\nplt.xlabel(\"Epochs\")\nplt.ylabel(\"Loss\")\nplt.legend(loc=(1.05,0.0))\nplt.show()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-11-09T12:32:33.336832Z","iopub.execute_input":"2024-11-09T12:32:33.337137Z","iopub.status.idle":"2024-11-09T12:32:33.670452Z","shell.execute_reply.started":"2024-11-09T12:32:33.337087Z","shell.execute_reply":"2024-11-09T12:32:33.669559Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"for i in history.history.keys():\n    if i.endswith(\"accuracy\") and not i ==\"val_accuracy\":\n        plt.plot(history.history[i], label=i)\nplt.xlabel(\"Epochs\")\nplt.ylabel(\"Loss\")\nplt.legend(loc=(1.05,0.0))\nplt.show()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-11-09T12:32:33.671766Z","iopub.execute_input":"2024-11-09T12:32:33.672078Z","iopub.status.idle":"2024-11-09T12:32:34.026604Z","shell.execute_reply.started":"2024-11-09T12:32:33.67205Z","shell.execute_reply":"2024-11-09T12:32:34.025745Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"plt.plot(history.history[\"val_loss\"], label=\"val_loss\")\nplt.plot(history.history[\"loss\"], label=\"loss\")\nplt.legend()\nplt.show()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2024-11-09T12:32:34.027872Z","iopub.execute_input":"2024-11-09T12:32:34.028207Z","iopub.status.idle":"2024-11-09T12:32:34.202362Z","shell.execute_reply.started":"2024-11-09T12:32:34.028179Z","shell.execute_reply":"2024-11-09T12:32:34.201331Z"}},"outputs":[],"execution_count":null}]}