{"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":"gpu","dataSources":[{"sourceType":"competition","sourceId":13451,"datasetId":654585,"databundleVersionId":1188070}],"dockerImageVersionId":30559,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":true}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"import numpy as np\nimport pandas as pd \nimport os\nimport math\nimport random\nimport pydicom\nimport matplotlib.pyplot as plt\nimport cv2 as cv\nimport tensorflow as tf\nfrom PIL import Image\nimport pickle\nfrom sklearn.metrics import classification_report, confusion_matrix \nfrom concurrent.futures import ProcessPoolExecutor\n#from tensorflow.keras.metrics import F1Score\n","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","execution":{"iopub.status.busy":"2023-12-04T16:59:47.829056Z","iopub.execute_input":"2023-12-04T16:59:47.829823Z","iopub.status.idle":"2023-12-04T16:59:57.078055Z","shell.execute_reply.started":"2023-12-04T16:59:47.829791Z","shell.execute_reply":"2023-12-04T16:59:57.07719Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print(\"/kaggle/input/rsna-intracranial-hemorrhage-detection/rsna-intracranial-hemorrhage-detection/stage_2_train/ID_000012eaf.dcm\")","metadata":{"execution":{"iopub.status.busy":"2023-12-04T17:00:17.132744Z","iopub.execute_input":"2023-12-04T17:00:17.13311Z","iopub.status.idle":"2023-12-04T17:00:17.138396Z","shell.execute_reply.started":"2023-12-04T17:00:17.133083Z","shell.execute_reply":"2023-12-04T17:00:17.137441Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"input_path = \"/kaggle/input/rsna-intracranial-hemorrhage-detection/rsna-intracranial-hemorrhage-detection/\"\ndata = os.listdir(input_path + \"stage_2_train\")\nprint(len(data))\nprint(data[:10])","metadata":{"execution":{"iopub.status.busy":"2023-11-05T07:05:46.843296Z","iopub.execute_input":"2023-11-05T07:05:46.844016Z","iopub.status.idle":"2023-11-05T07:06:21.975833Z","shell.execute_reply.started":"2023-11-05T07:05:46.843978Z","shell.execute_reply":"2023-11-05T07:06:21.974833Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df = pd.read_csv(input_path+\"stage_2_train.csv\") # read csv file with labels\ndf = df.drop_duplicates() # remove duplicated data\nlabels =  df.Label.values # get labels column\n\ndf = df.ID.str.rsplit(\"_\",n=1,expand=True) # separate image ID and subtype into 2 columns \ndf.loc[:, \"label\"] = labels \ndf.head()\n\ndf = df.rename({0 : \"Image\",1 : \"Subtype\"}, axis=1) # define colum headings\n\nprint(\"Dataframe shape : \",df.shape)\nprint(\"\\nDataframe :\\n\")\nprint(df[:10])","metadata":{"execution":{"iopub.status.busy":"2023-11-05T07:06:21.976957Z","iopub.execute_input":"2023-11-05T07:06:21.977213Z","iopub.status.idle":"2023-11-05T07:06:41.543817Z","shell.execute_reply.started":"2023-11-05T07:06:21.977191Z","shell.execute_reply":"2023-11-05T07:06:41.542878Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def dafa_frame2dic (dataframe):\n    # Create a pivot table with image IDs as rows and subtypes as columns\n    pivot_table = dataframe.pivot(index='Image', columns='Subtype', values='label')\n    \n    # Fill missing values with 0 (for subtypes that are not present for a specific image)\n    pivot_table = pivot_table.fillna(0)\n    \n    pivot_table = pivot_table.drop(columns=\"any\") # drop the column named \"any\"\n    \n    print (pivot_table)\n    \n    # Convert the pivot table to a dictionary with image IDs as keys and row vectors of labels as values\n    label_dict = pivot_table.apply(lambda row: row.values.tolist(), axis=1).to_dict()\n\n    return label_dict\n\noriginal_dict = dafa_frame2dic (df)","metadata":{"execution":{"iopub.status.busy":"2023-11-05T07:06:41.546832Z","iopub.execute_input":"2023-11-05T07:06:41.54713Z","iopub.status.idle":"2023-11-05T07:06:54.165965Z","shell.execute_reply.started":"2023-11-05T07:06:41.547104Z","shell.execute_reply":"2023-11-05T07:06:54.164988Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Plot data distribution\n\ndata_df = pd.DataFrame(original_dict).T  # Convert the dictionary into a DataFrame & transpose to have the correct orientation\n\n# Rename the columns to represent the subtypes\ndata_df.columns = ['epidural', 'intraparenchymal', 'intraventricular', 'subarachnoid', 'subdural']\n\n# Calculate the sum of each subtype column\nsubtype_sum = data_df.sum()\n\n# Plot the results in a bar graph\nplt.figure(figsize=(10, 6))\nsubtype_sum.plot(kind='bar')\nplt.xlabel('Subtype')\nplt.ylabel('Count')\nplt.title('Sum of Subtype Availabilities')\nplt.show()\n","metadata":{"execution":{"iopub.status.busy":"2023-11-05T07:06:54.167205Z","iopub.execute_input":"2023-11-05T07:06:54.167492Z","iopub.status.idle":"2023-11-05T07:07:16.954221Z","shell.execute_reply.started":"2023-11-05T07:06:54.167466Z","shell.execute_reply":"2023-11-05T07:07:16.953326Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Separating dataset into hemorrhage and non hemmrrhage\n\nhemorrhage_dict = {}\nnon_hemorrhage_dict = {}\n\nfor image_id, label in original_dict.items():\n    if any(label):\n        hemorrhage_dict[image_id] = label\n    else:\n        non_hemorrhage_dict[image_id] = label\n        ","metadata":{"execution":{"iopub.status.busy":"2023-11-05T07:07:16.955244Z","iopub.execute_input":"2023-11-05T07:07:16.955503Z","iopub.status.idle":"2023-11-05T07:07:17.445959Z","shell.execute_reply.started":"2023-11-05T07:07:16.955481Z","shell.execute_reply":"2023-11-05T07:07:17.444973Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print(\"Hemorrhage positive data: \",len(hemorrhage_dict))\nprint(\"Hemorrhage negative data: \",len(non_hemorrhage_dict))","metadata":{"execution":{"iopub.status.busy":"2023-11-05T07:07:17.44712Z","iopub.execute_input":"2023-11-05T07:07:17.44738Z","iopub.status.idle":"2023-11-05T07:07:17.4527Z","shell.execute_reply.started":"2023-11-05T07:07:17.447358Z","shell.execute_reply":"2023-11-05T07:07:17.451752Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"non_hemorrhage_keys = list(non_hemorrhage_dict.keys())\nselected_non_hemorrhage_keys = random.sample(non_hemorrhage_keys, 150000) # Randomly select 150,000 non_hemorrhage data\n\nnew_non_hemorrhage_dict = {k: non_hemorrhage_dict[k] for k in selected_non_hemorrhage_keys} # Create a new dictionary with the selected non-hemorrhage entities\ncombined_dict = {**hemorrhage_dict, **new_non_hemorrhage_dict} # Merge the new non-hemorrhage dictionary with the hemorrhage dictionary\n\n\nshuffled_dict = dict(random.sample(combined_dict.items(), len(combined_dict))) # Shuffle the combined dictionary\nprint(\"Shuffled dictionary size: \",len(shuffled_dict))","metadata":{"execution":{"iopub.status.busy":"2023-11-05T07:07:17.453953Z","iopub.execute_input":"2023-11-05T07:07:17.454215Z","iopub.status.idle":"2023-11-05T07:07:18.481376Z","shell.execute_reply.started":"2023-11-05T07:07:17.454192Z","shell.execute_reply":"2023-11-05T07:07:18.480471Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Randomply split data into train set, test set and validation set\n\nfrom sklearn.model_selection import train_test_split\n\nkey_list = list(shuffled_dict.keys())\n\ntrain_keys, test_keys = train_test_split(key_list, test_size = 0.2, random_state = 42)\ntest_keys, val_keys = train_test_split(test_keys, test_size = 0.5, random_state = 42)\n\ntrain_dict = {key: shuffled_dict[key] for key in train_keys}\ntest_dict = {key: shuffled_dict[key] for key in test_keys}\nval_dict = {key: shuffled_dict[key] for key in val_keys}","metadata":{"execution":{"iopub.status.busy":"2023-11-05T07:07:18.482519Z","iopub.execute_input":"2023-11-05T07:07:18.482808Z","iopub.status.idle":"2023-11-05T07:07:18.787411Z","shell.execute_reply.started":"2023-11-05T07:07:18.482784Z","shell.execute_reply":"2023-11-05T07:07:18.786631Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print(\"train set size: \",len(train_dict))\nprint(\"test set size: \",len(test_dict))\nprint(\"validation set size: \",len(val_dict))","metadata":{"execution":{"iopub.status.busy":"2023-11-05T07:07:18.791731Z","iopub.execute_input":"2023-11-05T07:07:18.792121Z","iopub.status.idle":"2023-11-05T07:07:18.797589Z","shell.execute_reply.started":"2023-11-05T07:07:18.792081Z","shell.execute_reply":"2023-11-05T07:07:18.796642Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# get image data correspond to train, test and validation sets\n\nfrom pathos.multiprocessing import ProcessingPool as Pool\n\ndef map_images_to_labels(label_dict, image_dir, num_processes=4):\n    id_array = list(label_dict.keys())\n    labels = np.array(list(label_dict.values()))\n    \n    # Define a function for parallel processing\n    def process_image_path(ID):\n        return os.path.join(image_dir, f'{ID}.dcm')\n    \n    # Use pathos multiprocessing to construct image paths in parallel\n    with Pool(num_processes) as pool:\n        image_paths = pool.map(process_image_path, id_array)\n    \n    return image_paths, labels\n\nimage_dir = '/kaggle/input/rsna-intracranial-hemorrhage-detection/rsna-intracranial-hemorrhage-detection/stage_2_train/'\n\ntrain_image_paths, _ = map_images_to_labels(train_dict, image_dir)\nval_image_paths, _ = map_images_to_labels(val_dict, image_dir)\ntest_image_paths, _ = map_images_to_labels(test_dict, image_dir)","metadata":{"execution":{"iopub.status.busy":"2023-11-05T07:07:18.798784Z","iopub.execute_input":"2023-11-05T07:07:18.799138Z","iopub.status.idle":"2023-11-05T07:07:23.914504Z","shell.execute_reply.started":"2023-11-05T07:07:18.799113Z","shell.execute_reply":"2023-11-05T07:07:23.912852Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Preprocessing images\n\n# Windowing\ndef apply_window(dcm_image,window):\n    \n    #define center and width for each type of window\n    if window == \"brain\":\n        w_center = 40\n        w_width = 80\n    elif window == \"subdural\":\n        w_center = 80\n        w_width = 200\n    elif window == \"soft_tissue\":\n        w_center = 40\n        w_width = 380\n        \n    windowed_img = dcm_image.pixel_array * dcm_image.RescaleSlope + dcm_image.RescaleIntercept #image reconstruction\n    \n    minimum = w_center - w_width//2 #window lower limit\n    maximum = w_center + w_width//2 #window upper limit\n    windowed_img = np.clip(windowed_img, minimum, maximum) #replace values <minimum with minimum and values > maximum with maximum\n    \n    normalized_Image = (windowed_img - minimum) / (w_width)\n    #print(normalized_Image.shape)\n    return normalized_Image\n\n\n# Form color images\ndef build_colorImage(dcm_image ,image_size):\n    \n    brain = apply_window(dcm_image,\"brain\")\n    subdural = apply_window(dcm_image,\"subdural\")\n    soft_tissue = apply_window(dcm_image,\"soft_tissue\")\n    \n    resized_brain = cv.resize(brain, image_size, interpolation = cv.INTER_LINEAR)\n    resized_subdural = cv.resize(subdural, image_size, interpolation = cv.INTER_LINEAR)\n    resized_soft_tissue = cv.resize(soft_tissue, image_size, interpolation = cv.INTER_LINEAR)\n\n    win_combinedImage = cv.merge((resized_brain, resized_subdural, resized_soft_tissue))\n    \n    return win_combinedImage","metadata":{"execution":{"iopub.status.busy":"2023-11-05T07:07:23.918168Z","iopub.execute_input":"2023-11-05T07:07:23.918575Z","iopub.status.idle":"2023-11-05T07:07:23.931925Z","shell.execute_reply.started":"2023-11-05T07:07:23.91852Z","shell.execute_reply":"2023-11-05T07:07:23.931074Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"test_image_path = \"/kaggle/input/rsna-intracranial-hemorrhage-detection/rsna-intracranial-hemorrhage-detection/stage_2_train/ID_000012eaf.dcm\"\ntest_image = pydicom.dcmread(test_image_path)\ntest_image_colored = build_colorImage(test_image ,(256,256))\n\nplt.imshow(test_image_colored)","metadata":{"execution":{"iopub.status.busy":"2023-11-05T07:07:23.933003Z","iopub.execute_input":"2023-11-05T07:07:23.933607Z","iopub.status.idle":"2023-11-05T07:07:24.388559Z","shell.execute_reply.started":"2023-11-05T07:07:23.933581Z","shell.execute_reply":"2023-11-05T07:07:24.387674Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Build the model\n\n\nfrom tensorflow import keras\nfrom tensorflow.keras import layers\nfrom tensorflow.keras.applications import ResNet50\nfrom tensorflow.keras.layers import Conv2D, MaxPooling2D, Flatten, Dense, Input, Attention, GlobalAveragePooling2D\n#from retnet import ReXNetV1\n#from efficientnet.tfkeras import EfficientNetB0  # You may choose a different variant (e.g., B1, B2, etc.)\n\ndef set_model (model_type):\n    \n    if model_type == \"CNN\":\n        \n        # Define the CNN model\n        model = keras.Sequential([\n            Conv2D(64, (3, 3), activation='relu', input_shape=(256, 256, 3)),\n            MaxPooling2D((2, 2)),\n            Conv2D(128, (3, 3), activation='relu'),\n            MaxPooling2D((2, 2)),\n            Conv2D(256, (3, 3), activation='relu'),\n            MaxPooling2D((2, 2)),\n            Flatten(),\n            Dense(256, activation='relu'),\n            Dense(5, activation = \"sigmoid\")  # 5 output neurons with sigmoid activation\n        ])\n\n        \n        model.compile(optimizer='adam', loss='binary_crossentropy', metrics=['binary_accuracy']) # Compile the model\n        \n        return model\n        \n    \n    elif model_type == \"ResNet50\":\n        input_tensor = Input(shape=(256, 256, 3))\n\n        base_model = ResNet50(include_top=False, weights='imagenet', input_tensor=input_tensor)\n\n        x = base_model.output\n        x = Flatten()(x)\n        x = Dense(256, activation='relu')(x)\n        x = Attention()([x, x])\n        predictions = Dense(5, activation='sigmoid')(x)  # 5 output neurons with sigmoid activation\n        \n        model = keras.Model(inputs=input_tensor, outputs=predictions) \n        model.compile(optimizer='adam', loss='binary_crossentropy', metrics=['binary_accuracy'])# Compile the model\n \n        return model \n\n   \n    elif model_type == \"Custom\":\n\n        # Define a custom model with attention mechanism\n        input_tensor = Input(shape=(256, 256, 3))\n\n        x = Conv2D(64, (3, 3), activation='relu')(input_tensor)\n        x = MaxPooling2D((2, 2))(x)\n        x = Conv2D(128, (3, 3), activation='relu')(x)\n        x = MaxPooling2D((2, 2))(x)\n        x = Flatten()(x)\n        x = Dense(256, activation='relu')(x)\n        x = Attention()([x, x])  # Adding attention mechanism\n        predictions = Dense(5, activation='sigmoid')(x)  # 5 output neurons with sigmoid activation\n\n        model = keras.Model(inputs = input_tensor, outputs = predictions)\n       \n        model.compile(optimizer='adam', loss='binary_crossentropy', metrics=['binary_accuracy'])  # Compile the model\n        return model","metadata":{"execution":{"iopub.status.busy":"2023-11-05T07:07:24.389941Z","iopub.execute_input":"2023-11-05T07:07:24.390298Z","iopub.status.idle":"2023-11-05T07:07:24.409378Z","shell.execute_reply.started":"2023-11-05T07:07:24.390266Z","shell.execute_reply":"2023-11-05T07:07:24.408626Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Train and validation data generator\n\nclass train_val_DataGenerator(tf.keras.utils.Sequence):\n    def __init__(self, image_paths, label_dict, batch_size, image_size, shuffle=True):\n        self.image_paths = image_paths\n        self.label_dict = label_dict\n        self.batch_size = batch_size\n        self.image_size = image_size\n        self.shuffle = shuffle\n        self.on_epoch_end()\n    \n    def __len__(self):\n        return int(np.ceil(len(self.image_paths) / self.batch_size))\n\n    def __getitem__(self, index):\n        batch_indices = self.indices[index * self.batch_size:(index + 1) * self.batch_size]\n        batch_image_paths = [self.image_paths[i] for i in batch_indices]\n        X, labels = self.__data_generation(batch_image_paths)\n        \n        return X,labels \n    \n    def on_epoch_end(self):\n        self.indices = np.arange(len(self.image_paths))\n        if self.shuffle:\n            np.random.shuffle(self.indices)\n\n    def __data_generation(self, batch_image_paths):\n        X = []\n        labels = []\n        global Type\n        for image_path in batch_image_paths:\n            try:\n                dcm_image = pydicom.dcmread(image_path)       \n                color_image = build_colorImage(dcm_image ,self.image_size)\n\n                X.append(color_image) #new\n                labels.append(self.label_dict[image_path[-16:-4]])\n            \n            except Exception as e:\n                print(\"Error file found: \",image_path)\n                continue\n\n        X = np.array(X)\n        labels=np.array(labels)\n        \n        \n        return X, labels","metadata":{"execution":{"iopub.status.busy":"2023-11-05T07:07:24.410564Z","iopub.execute_input":"2023-11-05T07:07:24.410899Z","iopub.status.idle":"2023-11-05T07:07:24.422524Z","shell.execute_reply.started":"2023-11-05T07:07:24.410874Z","shell.execute_reply":"2023-11-05T07:07:24.421535Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Test data genertion\nclass test_DataGenerator(tf.keras.utils.Sequence):\n    def __init__(self, image_paths, labels=None, batch_size=128, image_size=(256, 256), shuffle=True):\n        self.image_paths = image_paths\n        self.labels = labels\n        self.batch_size = batch_size\n        self.image_size = image_size\n        self.shuffle = shuffle\n        self.on_epoch_end()\n\n    \n    def __len__(self):\n        return int(np.ceil(len(self.image_paths) / self.batch_size))\n\n    \n    def __getitem__(self, index):\n        batch_indices = self.indices[index * self.batch_size:(index + 1) * self.batch_size]\n        batch_image_paths = [self.image_paths[i] for i in batch_indices]\n        \n        X_test, y_test = self.__data_generation(batch_image_paths)\n\n        return X_test, y_test    \n\n    \n    def on_epoch_end(self):\n        self.indices = np.arange(len(self.image_paths))\n        if self.shuffle:\n            np.random.shuffle(self.indices)      \n    \n    \n    def __data_generation(self, batch_image_paths):\n        X_test = [] # store images\n        y_test = [] # store labels\n        image_ids = []  # store image IDs\n\n        for image_path in batch_image_paths:\n            try:\n                dcm_image = pydicom.dcmread(image_path)\n                color_image = build_colorImage(dcm_image, self.image_size)\n\n                X_test.append(color_image)\n                # Get the corresponding labels\n                y_test.append(self.labels[image_path[-16:-4]])\n                # Store the image ID\n                image_ids.append(os.path.basename(image_path).split('.')[0])\n\n            except Exception as e:\n                print(\"Error file found: \", e)\n                continue\n\n        X_test = np.array(X_test)\n        y_test = np.array(y_test)\n\n        return X_test, y_test, image_ids\n    \n    \n    def predict_data(self, model):\n       \n        predictions = model.predict(self)  # Generate predictions for the data\n        predictions = (predictions >= 0.5).astype(int) # get predictions in binary format\n        \n        return predictions","metadata":{"execution":{"iopub.status.busy":"2023-11-05T07:07:24.423744Z","iopub.execute_input":"2023-11-05T07:07:24.424257Z","iopub.status.idle":"2023-11-05T07:07:24.43835Z","shell.execute_reply.started":"2023-11-05T07:07:24.424224Z","shell.execute_reply":"2023-11-05T07:07:24.437406Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"epochs = 5\nbatch_size = 128\nimage_size = (256, 256)\n     \n# Create the data generator\ntrain_generator = train_val_DataGenerator (train_image_paths, label_dict = train_dict, batch_size = batch_size, image_size = image_size, shuffle = True)\nval_generator = train_val_DataGenerator (val_image_paths, label_dict = val_dict, batch_size = batch_size, image_size = image_size, shuffle = True)\n\nfirst_train_batch = train_generator[0]\nimages_batch , label_batch = first_train_batch\n\nfirst_five_images = images_batch[:5]\n\nfig, axes = plt.subplots(1,5, figsize =(10,10))\n\nfor index, ax in enumerate(axes):\n    ax.imshow(first_five_images[index])\n    ax.set_title(\"Input image \" + str(index+1))\n    #ax.axis(\"off\")\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2023-11-05T07:07:24.439691Z","iopub.execute_input":"2023-11-05T07:07:24.440018Z","iopub.status.idle":"2023-11-05T07:07:28.13106Z","shell.execute_reply.started":"2023-11-05T07:07:24.439994Z","shell.execute_reply":"2023-11-05T07:07:28.130173Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model = set_model(\"CNN\")\nmodel.fit(train_generator, epochs=epochs, verbose=1, validation_data = val_generator)","metadata":{"execution":{"iopub.status.busy":"2023-11-05T07:07:28.13231Z","iopub.execute_input":"2023-11-05T07:07:28.132667Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"test_generator = test_DataGenerator (test_image_paths, labels = test_dict, batch_size = 64, image_size = (256,256), shuffle = True)\n\n\ntest_batch = test_generator[0]  # Fetch the first batch of data from the generator\nX_test_batch, y_test_batch = test_batch  # Unpack the data batch\nprint(\"Shape of X_test in the first batch:\", X_test_batch.shape)\nprint(\"Shape of y_test in the first batch:\", y_test_batch.shape)\n\n\nloss, accuracy = model.evaluate(test_generator)\n\nprint('Test accuracy:', accuracy)\n","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"predictions = test_generator.predict_data(model)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"true_labels = []\n\nfor index in range(len(test_generator)):\n    _, y_test = test_generator.__getitem__(index)\n    true_labels.extend(y_test)\n\ntrue_labels = np.array(true_labels, dtype=\"int32\")","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#print(\"\\nClassification Report:\")\n#print(classification_report(true_labels, predictions)) ","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# save to a csv file\npredictions_df = pd.DataFrame(data=predictions, columns=[\"epidural\", \"intraparenchymal\", \"intraventricular\", \"subarachnoid\", \"subdural\"]) # Create a DataFrame for predictions\n\npredictions_df[\"any\"] = predictions_df[[\"epidural\", \"intraparenchymal\", \"intraventricular\", \"subarachnoid\", \"subdural\"]].apply(lambda row: row.any(), axis=1)\npredictions_df.insert(0, \"any\", predictions_df[\"any\"])\npredictions_df.insert(0, \"Image_ID\", test_generator.image_ids) # Add the image IDs as the first column\n\n# Specify the path where you want to save the CSV file\ncsv_file_path = \"/kaggle/working/predictions.csv\"\n\n# Save the DataFrame to a CSV file\npredictions_df.to_csv(csv_file_path, index=False) ","metadata":{"trusted":true},"execution_count":null,"outputs":[]}]}