{"metadata":{"kaggle":{"accelerator":"gpu","dataSources":[{"sourceId":45867,"databundleVersionId":6924515,"sourceType":"competition"}],"dockerImageVersionId":30683,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":true},"kernelspec":{"display_name":"Python 3","language":"python","name":"python3"},"language_info":{"codemirror_mode":{"name":"ipython","version":3},"file_extension":".py","mimetype":"text/x-python","name":"python","nbconvert_exporter":"python","pygments_lexer":"ipython3","version":"3.10.13"}},"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\nimport warnings\nwarnings.filterwarnings('ignore')\n\nimport numpy as np # linear algebra\nimport 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\nimport os\nfor 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":{"_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","execution":{"iopub.status.busy":"2024-04-12T10:46:04.681057Z","iopub.execute_input":"2024-04-12T10:46:04.68146Z","iopub.status.idle":"2024-04-12T10:46:04.709627Z","shell.execute_reply.started":"2024-04-12T10:46:04.681431Z","shell.execute_reply":"2024-04-12T10:46:04.708707Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import pandas as pd\nimport os\nimport cv2\nimport random\nimport tensorflow as tf\nimport matplotlib.pyplot as plt\nimport numpy as np\n\ndef list_folders_in_folder(folder_path):\n    files = os.listdir(folder_path)\n    return files\n\ndef list_files_in_folders(folder_path, train_df):\n    files = []\n    labels = []\n    for root, _, filenames in os.walk(folder_path):\n        for filename in filenames:\n            image_id = train_df[train_df['image_id'] == int(filename.split('_')[0])]['label'].iloc[0]\n            labels.append(image_id)\n            files.append(os.path.join(root, filename))\n    return files, labels\n\ndef save_to_excel(files, labels, output_path='UBC.xlsx'):\n    df = pd.DataFrame({'path': files, 'category': labels})\n    df.to_excel(output_path, index=False)\n    return df\n\ndef read_image(df):\n    images = []\n    labels = []\n    for _, row in df.iterrows():\n       image = cv2.imread(row['path'])\n       image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)\n       images.append(image)\n       labels.append(row['category'])\n    return images, labels\n\ndef resize_normalize_batch(images, image_size):\n    resized_images = []\n    for image in images:\n        resized_image = cv2.resize(image, (224, 224))\n        resized_image = resized_image / 255.\n        resized_images.append(resized_image)\n    return np.array(resized_images)\n\nCONFIG = {\n    'TRAIN_DF': \"/kaggle/input/UBC-OCEAN/train.csv\",\n    'TRAIN_PATH': \"/kaggle/input/UBC-OCEAN/train_thumbnails\",\n    'BATCH_SIZE':32,\n}\n\ntrain_df = pd.read_csv(CONFIG['TRAIN_DF'])\nfolders = list_folders_in_folder(CONFIG['TRAIN_PATH'])\nprint(folders[0].split('_')[0])\n\nfiles, labels = list_files_in_folders(CONFIG['TRAIN_PATH'], train_df)\nprint(files[:5])  # Print first 5 file paths\nprint(labels[:5])  # Print first 5 labels\n\ndf = save_to_excel(files, labels)\nprint(df.head())\n\nimages, labels = read_image(df)\nrandom_numbers = [random.randint(0, len(images)) for _ in range(16)]\n\ndef visualize_images(images, labels, random_numbers):\n    fig, axes = plt.subplots(4, 4, figsize=(8, 8))\n    axes = axes.flatten()\n\n    for i, ax in enumerate(axes):\n        rand = random_numbers[i]\n        if rand < len(images):\n            ax.imshow(images[rand])\n            ax.set_title(labels[rand])\n            ax.axis('off')\n        else:\n            ax.axis('off')\n\n    plt.tight_layout()\n    plt.show()\n\n# Resize and normalize the images\nimages_resized = resize_normalize_batch(images,224)\n\n# Visualize a subset of the images\nvisualize_images(images_resized, labels, random_numbers)\n\n# Further processing, model training, etc., can be added here\n","metadata":{"execution":{"iopub.status.busy":"2024-04-12T10:46:05.161179Z","iopub.execute_input":"2024-04-12T10:46:05.161529Z","iopub.status.idle":"2024-04-12T10:47:35.165753Z","shell.execute_reply.started":"2024-04-12T10:46:05.161503Z","shell.execute_reply":"2024-04-12T10:47:35.16482Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import tensorflow as tf\nimport numpy as np\n\n# Assuming `images` is a list of images in RGB format\n\n# Resize all images to a fixed size\nimage_size = (224, 224)  # Define the desired image size\nimages_resized = [tf.image.resize(image, image_size) for image in images]\nlabel_to_index = {label: i for i, label in enumerate(set(labels))}\nprint(label_to_index)  # Check the mapping of labels to indices\n\n# Convert labels to indices using the label_to_index mapping\nlabels_numpy = [label_to_index[label] for label in labels]\n\n# Convert labels to NumPy array\nlabels_numpy = np.array(labels_numpy)\n\n# Convert images to NumPy array\nimages_numpy = np.array([image.numpy() for image in images_resized])\n\n# Create a TensorFlow dataset from the NumPy arrays\ndataset = tf.data.Dataset.from_tensor_slices((images_numpy, labels_numpy))\n\n# Shuffle the dataset with buffer size equal to the number of images\nshuffle_buffer_size = len(images_numpy)\ndataset = dataset.shuffle(shuffle_buffer_size)\n\n# Define the train size based on a specified ratio (e.g., 0.8 for 80% train, 20% test)\ntrain_size = int(len(images_numpy) * 0.9)\n\n# Split the dataset into training and testing datasets\ntrain_dataset = dataset.take(train_size)\ntest_dataset = dataset.skip(train_size)\n\n# Batch the datasets\ntrain_dataset = train_dataset.batch(CONFIG['BATCH_SIZE'])\ntest_dataset = test_dataset.batch(CONFIG['BATCH_SIZE'])\n\n# Prefetch the datasets for better performance\ntrain_dataset = train_dataset.prefetch(buffer_size=tf.data.experimental.AUTOTUNE)\ntest_dataset = test_dataset.prefetch(buffer_size=tf.data.experimental.AUTOTUNE)\n\n# Now you have `train_dataset` and `test_dataset` ready for model training\n# You can iterate over these datasets in a loop for training your model\n","metadata":{"execution":{"iopub.status.busy":"2024-04-12T10:47:35.167322Z","iopub.execute_input":"2024-04-12T10:47:35.167641Z","iopub.status.idle":"2024-04-12T10:47:42.482265Z","shell.execute_reply.started":"2024-04-12T10:47:35.167614Z","shell.execute_reply":"2024-04-12T10:47:42.481395Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import tensorflow as tf\nfrom tensorflow import keras\nfrom tensorflow.keras.callbacks import TensorBoard\ntensorboard_callback = TensorBoard(log_dir='./logs', histogram_freq=1)","metadata":{"execution":{"iopub.status.busy":"2024-04-12T10:47:42.483532Z","iopub.execute_input":"2024-04-12T10:47:42.483874Z","iopub.status.idle":"2024-04-12T10:47:42.491691Z","shell.execute_reply.started":"2024-04-12T10:47:42.483835Z","shell.execute_reply":"2024-04-12T10:47:42.490671Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import tensorflow as tf\nimport numpy as np\nimport random\n\n# Set random seed for TensorFlow\ntf.random.set_seed(42)\n\n# Set random seed for Python's built-in random number generator\nnp.random.seed(42)\n\n# Set random seed for Python's random module\nrandom.seed(42)","metadata":{"execution":{"iopub.status.busy":"2024-04-12T10:47:42.494668Z","iopub.execute_input":"2024-04-12T10:47:42.495435Z","iopub.status.idle":"2024-04-12T10:47:42.512084Z","shell.execute_reply.started":"2024-04-12T10:47:42.495406Z","shell.execute_reply":"2024-04-12T10:47:42.51125Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"!wget https://bin.equinox.io/c/4VmDzA7iaHb/ngrok-stable-linux-amd64.zip\n!unzip -o ngrok-stable-linux-amd64.zip","metadata":{"execution":{"iopub.status.busy":"2024-04-12T10:47:42.514742Z","iopub.execute_input":"2024-04-12T10:47:42.515038Z","iopub.status.idle":"2024-04-12T10:47:45.832609Z","shell.execute_reply.started":"2024-04-12T10:47:42.515008Z","shell.execute_reply":"2024-04-12T10:47:45.831391Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"LOG_DIR = 'tb_folder/log/' \nNGROK_AUTH_TOKEN = '2cveAcYz7C9XenNn8EJTaeLTFMQ_23XHanSd85DAb7in3sxqC'\n\n# Authenticate ngrok using your authentication token\n!./ngrok authtoken $NGROK_AUTH_TOKEN","metadata":{"execution":{"iopub.status.busy":"2024-04-12T10:47:45.83435Z","iopub.execute_input":"2024-04-12T10:47:45.834729Z","iopub.status.idle":"2024-04-12T10:47:47.113097Z","shell.execute_reply.started":"2024-04-12T10:47:45.834687Z","shell.execute_reply":"2024-04-12T10:47:47.111785Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"!./ngrok update\n","metadata":{"execution":{"iopub.status.busy":"2024-04-12T10:47:47.114859Z","iopub.execute_input":"2024-04-12T10:47:47.115191Z","iopub.status.idle":"2024-04-12T10:47:48.665359Z","shell.execute_reply.started":"2024-04-12T10:47:47.115161Z","shell.execute_reply":"2024-04-12T10:47:48.664055Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"!killall tensorboard\n","metadata":{"execution":{"iopub.status.busy":"2024-04-12T10:47:48.667094Z","iopub.execute_input":"2024-04-12T10:47:48.667449Z","iopub.status.idle":"2024-04-12T10:47:49.872717Z","shell.execute_reply.started":"2024-04-12T10:47:48.667418Z","shell.execute_reply":"2024-04-12T10:47:49.871599Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"!kill -9 PID\n","metadata":{"execution":{"iopub.status.busy":"2024-04-12T10:47:49.876856Z","iopub.execute_input":"2024-04-12T10:47:49.877242Z","iopub.status.idle":"2024-04-12T10:47:51.1236Z","shell.execute_reply.started":"2024-04-12T10:47:49.87721Z","shell.execute_reply":"2024-04-12T10:47:51.122284Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"!ps -aux | grep tensorboard\n","metadata":{"execution":{"iopub.status.busy":"2024-04-12T10:47:51.128044Z","iopub.execute_input":"2024-04-12T10:47:51.128378Z","iopub.status.idle":"2024-04-12T10:47:52.418959Z","shell.execute_reply.started":"2024-04-12T10:47:51.12835Z","shell.execute_reply":"2024-04-12T10:47:52.417565Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"get_ipython().system_raw(\n    'tensorboard --logdir {} --host 0.0.0.0 --port 6006 &'\n    .format(LOG_DIR)\n)\nget_ipython().system_raw('./ngrok http 6006 &')\n! curl -s http://localhost:4040/api/tunnels | python3 -c \\\n    \"import sys, json; print(json.load(sys.stdin)['tunnels'][0]['public_url'])\"","metadata":{"execution":{"iopub.status.busy":"2024-04-12T10:47:52.420796Z","iopub.execute_input":"2024-04-12T10:47:52.421193Z","iopub.status.idle":"2024-04-12T10:47:54.060402Z","shell.execute_reply.started":"2024-04-12T10:47:52.421156Z","shell.execute_reply":"2024-04-12T10:47:54.058994Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"!pkill -f \"tensorboard\"","metadata":{"execution":{"iopub.status.busy":"2024-04-12T10:47:54.062571Z","iopub.execute_input":"2024-04-12T10:47:54.063041Z","iopub.status.idle":"2024-04-12T10:47:55.329548Z","shell.execute_reply.started":"2024-04-12T10:47:54.062997Z","shell.execute_reply":"2024-04-12T10:47:55.328198Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"\nfrom tensorflow.keras.models import Sequential\nfrom tensorflow.keras.layers import Dense , Conv2D , MaxPooling2D ,BatchNormalization ,InputLayer ,Flatten, Dropout\nfrom tensorflow.keras.optimizers import Adam\nfrom tensorflow.keras.losses import CategoricalCrossentropy\nfrom tensorflow.keras.metrics import MeanIoU\nmodel = Sequential([\n    InputLayer(input_shape=(224, 224, 3)),\n    Conv2D(filters=32, kernel_size=3, padding='same', activation='relu'),\n    BatchNormalization(),\n    MaxPooling2D(pool_size=(2, 2), strides=2),\n\n    Conv2D(filters=64, kernel_size=3, padding='same', activation='relu'),\n    BatchNormalization(),\n    MaxPooling2D(pool_size=(2, 2), strides=2),\n\n    Conv2D(filters=128, kernel_size=3, padding='same', activation='relu'),\n    BatchNormalization(),\n    MaxPooling2D(pool_size=(2, 2), strides=2),\n\n    Flatten(),\n    Dense(256, activation='relu'),\n    BatchNormalization(),\n    Dropout(0.5),\n\n    Dense(128, activation='relu'),\n    BatchNormalization(),\n    Dropout(0.5),\n\n    Dense(5, activation='softmax')\n])\n","metadata":{"execution":{"iopub.status.busy":"2024-04-12T11:25:06.56479Z","iopub.execute_input":"2024-04-12T11:25:06.565179Z","iopub.status.idle":"2024-04-12T11:25:06.677345Z","shell.execute_reply.started":"2024-04-12T11:25:06.565149Z","shell.execute_reply":"2024-04-12T11:25:06.676446Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model.summary()","metadata":{"execution":{"iopub.status.busy":"2024-04-12T11:25:10.050309Z","iopub.execute_input":"2024-04-12T11:25:10.051498Z","iopub.status.idle":"2024-04-12T11:25:10.087102Z","shell.execute_reply.started":"2024-04-12T11:25:10.051447Z","shell.execute_reply":"2024-04-12T11:25:10.086033Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"for images, labels in train_dataset.take(1):\n    print(images.shape)","metadata":{"execution":{"iopub.status.busy":"2024-04-12T11:25:18.831163Z","iopub.execute_input":"2024-04-12T11:25:18.8322Z","iopub.status.idle":"2024-04-12T11:25:18.92959Z","shell.execute_reply.started":"2024-04-12T11:25:18.832162Z","shell.execute_reply":"2024-04-12T11:25:18.928498Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import tensorflow as tf\nfrom tensorflow.keras import backend as K\n\n# Define a custom F1 Score metric\nclass F1Score(tf.keras.metrics.Metric):\n    def __init__(self, name='f1_score', **kwargs):\n        super(F1Score, self).__init__(name=name, **kwargs)\n        self.precision = tf.keras.metrics.Precision()\n        self.recall = tf.keras.metrics.Recall()\n\n    def update_state(self, y_true, y_pred, sample_weight=None):\n        if y_pred.shape[-1] > 1:  # Check if predictions are one-hot encoded\n            y_pred = tf.argmax(y_pred, axis=-1)\n        else:\n            y_pred = tf.cast(y_pred, tf.int64)\n\n        self.precision.update_state(y_true, y_pred, sample_weight)\n        self.recall.update_state(y_true, y_pred, sample_weight)\n\n    def result(self):\n        precision = self.precision.result()\n        recall = self.recall.result()\n\n        # Calculate F1 Score\n        f1_score = 2 * ((precision * recall) / (precision + recall + K.epsilon()))\n\n        return f1_score\n\n    def reset_states(self):\n        self.precision.reset_states()\n        self.recall.reset_states()\n","metadata":{"execution":{"iopub.status.busy":"2024-04-12T11:25:21.754803Z","iopub.execute_input":"2024-04-12T11:25:21.755485Z","iopub.status.idle":"2024-04-12T11:25:21.766403Z","shell.execute_reply.started":"2024-04-12T11:25:21.755451Z","shell.execute_reply":"2024-04-12T11:25:21.765174Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model.compile(\n    optimizer='adam',\n    loss='sparse_categorical_crossentropy',\n    metrics=['accuracy', F1Score()]\n)","metadata":{"execution":{"iopub.status.busy":"2024-04-12T11:45:54.241005Z","iopub.execute_input":"2024-04-12T11:45:54.241507Z","iopub.status.idle":"2024-04-12T11:45:54.259596Z","shell.execute_reply.started":"2024-04-12T11:45:54.241473Z","shell.execute_reply":"2024-04-12T11:45:54.258376Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"history = model.fit(train_dataset, validation_data=test_dataset , epochs=30,callbacks=[tensorboard_callback])\n","metadata":{"execution":{"iopub.status.busy":"2024-04-12T11:45:57.054952Z","iopub.execute_input":"2024-04-12T11:45:57.055446Z","iopub.status.idle":"2024-04-12T11:47:34.161854Z","shell.execute_reply.started":"2024-04-12T11:45:57.055412Z","shell.execute_reply":"2024-04-12T11:47:34.16077Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"test_metrics = model.evaluate(test_dataset)\n\n# Unpack and print the test metrics\ntest_accuracy = test_metrics[1]\ntest_f1_score = test_metrics[2]\ntest_loss = test_metrics[0]\n\nprint(f\"Test Accuracy: {test_accuracy:.4f}\")\nprint(f\"Test F1 Score: {test_f1_score:.4f}\")\nprint(f\"Test Loss: {test_loss:.4f}\")","metadata":{"execution":{"iopub.status.busy":"2024-04-12T11:48:12.855818Z","iopub.execute_input":"2024-04-12T11:48:12.856275Z","iopub.status.idle":"2024-04-12T11:48:12.905285Z","shell.execute_reply.started":"2024-04-12T11:48:12.85624Z","shell.execute_reply":"2024-04-12T11:48:12.904235Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def get_class_name(index):\n    return list(label_to_index.keys())[index]","metadata":{"execution":{"iopub.status.busy":"2024-04-12T11:48:17.674766Z","iopub.execute_input":"2024-04-12T11:48:17.675468Z","iopub.status.idle":"2024-04-12T11:48:17.680254Z","shell.execute_reply.started":"2024-04-12T11:48:17.675432Z","shell.execute_reply":"2024-04-12T11:48:17.679219Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"plt.figure(figsize=(15, 15))\nfor i, (image, label) in enumerate(test_dataset.take(9)):\n  ax = plt.subplot(3, 3, i + 1)\n  ax.imshow(image[0])\n  plt.title(f\"True: {get_class_name(label.numpy()[0])}\\nPredicted: {get_class_name(np.argmax(model.predict(image), axis=1)[0])}\")\n  plt.axis('off')","metadata":{"execution":{"iopub.status.busy":"2024-04-12T11:48:20.405051Z","iopub.execute_input":"2024-04-12T11:48:20.406054Z","iopub.status.idle":"2024-04-12T11:48:21.910418Z","shell.execute_reply.started":"2024-04-12T11:48:20.406008Z","shell.execute_reply":"2024-04-12T11:48:21.909167Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import matplotlib.pyplot as plt\n\n# Plot training and validation accuracy\nplt.plot(history.history['accuracy'], label='Training Accuracy')\nplt.plot(history.history['val_accuracy'], label='Validation Accuracy')\nplt.title('Training and Validation Accuracy')\nplt.xlabel('Epoch')\nplt.ylabel('Accuracy')\nplt.legend()\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2024-04-12T11:48:34.015236Z","iopub.execute_input":"2024-04-12T11:48:34.016302Z","iopub.status.idle":"2024-04-12T11:48:35.014698Z","shell.execute_reply.started":"2024-04-12T11:48:34.016266Z","shell.execute_reply":"2024-04-12T11:48:35.013706Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Plot training and validation loss\nplt.plot(history.history['loss'], label='Training Loss')\nplt.plot(history.history['val_loss'], label='Validation Loss')\nplt.title('Training and Validation Loss')\nplt.xlabel('Epoch')\nplt.ylabel('Loss')\nplt.legend()\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2024-04-12T11:48:39.040377Z","iopub.execute_input":"2024-04-12T11:48:39.041339Z","iopub.status.idle":"2024-04-12T11:48:39.38616Z","shell.execute_reply.started":"2024-04-12T11:48:39.041303Z","shell.execute_reply":"2024-04-12T11:48:39.385138Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"true_labels = []\npredicted_labels = []\nim = []\nfor images, labels in test_dataset:\n    for image, label in zip(images, labels):\n        true_labels.append(label.numpy())\n        im.append(image.numpy())\n        plt.show()\n        predicted_label = np.argmax(model.predict(np.expand_dims(image, axis=0)), axis=1)[0]\n        predicted_labels.append(predicted_label)","metadata":{"execution":{"iopub.status.busy":"2024-04-12T11:56:08.386184Z","iopub.execute_input":"2024-04-12T11:56:08.387089Z","iopub.status.idle":"2024-04-12T11:56:12.829093Z","shell.execute_reply.started":"2024-04-12T11:56:08.387046Z","shell.execute_reply":"2024-04-12T11:56:12.828216Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"plt.figure(figsize=(10, 10))\nfor i in range(16):\n    ax = plt.subplot(4, 4, i + 1)\n    ax.imshow(im[i])\n    ax.set_title(f\"True: {get_class_name(true_labels[i])}\\nPredicted: {get_class_name(predicted_labels[i])}\")\n    ax.axis('off')\n\nplt.tight_layout()\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2024-04-12T11:57:03.35494Z","iopub.execute_input":"2024-04-12T11:57:03.355758Z","iopub.status.idle":"2024-04-12T11:57:04.877617Z","shell.execute_reply.started":"2024-04-12T11:57:03.355722Z","shell.execute_reply":"2024-04-12T11:57:04.876498Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"cm = confusion_matrix(true_labels, predicted_labels)\nplt.figure(figsize=(8, 6))\nsns.heatmap(cm, annot=True, cmap='Blues', fmt='g')\nplt.xlabel('Predicted Label')\nplt.ylabel('True Label')\nplt.title('Confusion Matrix')\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2024-04-12T11:57:48.546028Z","iopub.execute_input":"2024-04-12T11:57:48.546457Z","iopub.status.idle":"2024-04-12T11:57:48.962098Z","shell.execute_reply.started":"2024-04-12T11:57:48.546428Z","shell.execute_reply":"2024-04-12T11:57:48.961051Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"keras.utils.plot_model(\n    model,\n    to_file=\"model.png\",\n    show_shapes=False,\n    show_dtype=False,\n    show_layer_names=False,\n    rankdir=\"TB\",\n    expand_nested=False,\n    dpi=200,\n    show_layer_activations=False,\n    show_trainable=False,\n    **kwargs\n)","metadata":{},"execution_count":null,"outputs":[]}]}