{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.11.13","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"nvidiaTeslaT4","dataSources":[{"sourceId":59093,"databundleVersionId":7469972,"sourceType":"competition"}],"dockerImageVersionId":31090,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":true}},"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\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        (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,"execution":{"iopub.status.busy":"2025-07-12T21:54:58.409569Z","iopub.execute_input":"2025-07-12T21:54:58.410133Z","iopub.status.idle":"2025-07-12T21:55:44.948425Z","shell.execute_reply.started":"2025-07-12T21:54:58.410105Z","shell.execute_reply":"2025-07-12T21:55:44.947774Z"}},"outputs":[],"execution_count":1},{"cell_type":"code","source":"import warnings\nwarnings.filterwarnings(\"ignore\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-07-12T20:31:41.973968Z","iopub.execute_input":"2025-07-12T20:31:41.974421Z","iopub.status.idle":"2025-07-12T20:31:41.978355Z","shell.execute_reply.started":"2025-07-12T20:31:41.974401Z","shell.execute_reply":"2025-07-12T20:31:41.977493Z"}},"outputs":[],"execution_count":2},{"cell_type":"code","source":"!pip install pyspark","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-07-12T20:31:41.979181Z","iopub.execute_input":"2025-07-12T20:31:41.979541Z","iopub.status.idle":"2025-07-12T20:31:47.491495Z","shell.execute_reply.started":"2025-07-12T20:31:41.979516Z","shell.execute_reply":"2025-07-12T20:31:47.490696Z"}},"outputs":[{"name":"stdout","text":"Requirement already satisfied: pyspark in /usr/local/lib/python3.11/dist-packages (3.5.1)\nRequirement already satisfied: py4j==0.10.9.7 in /usr/local/lib/python3.11/dist-packages (from pyspark) (0.10.9.7)\n","output_type":"stream"}],"execution_count":3},{"cell_type":"code","source":"from pyspark.sql import SparkSession\n\nspark = SparkSession.builder.appName(\"CNN_Model\").getOrCreate()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-07-12T20:32:34.261586Z","iopub.execute_input":"2025-07-12T20:32:34.261906Z","iopub.status.idle":"2025-07-12T20:32:43.05117Z","shell.execute_reply.started":"2025-07-12T20:32:34.261865Z","shell.execute_reply":"2025-07-12T20:32:43.050118Z"}},"outputs":[{"name":"stderr","text":"Setting default log level to \"WARN\".\nTo adjust logging level use sc.setLogLevel(newLevel). For SparkR, use setLogLevel(newLevel).\n25/07/12 20:32:40 WARN NativeCodeLoader: Unable to load native-hadoop library for your platform... using builtin-java classes where applicable\n","output_type":"stream"}],"execution_count":4},{"cell_type":"code","source":"spark","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-07-12T20:32:49.752556Z","iopub.execute_input":"2025-07-12T20:32:49.753112Z","iopub.status.idle":"2025-07-12T20:32:51.536572Z","shell.execute_reply.started":"2025-07-12T20:32:49.753085Z","shell.execute_reply":"2025-07-12T20:32:51.535816Z"}},"outputs":[{"execution_count":5,"output_type":"execute_result","data":{"text/plain":"<pyspark.sql.session.SparkSession at 0x7e3396bcf5d0>","text/html":"\n            <div>\n                <p><b>SparkSession - in-memory</b></p>\n                \n        <div>\n            <p><b>SparkContext</b></p>\n\n            <p><a href=\"http://6f34e3bed6f4:4040\">Spark UI</a></p>\n\n            <dl>\n              <dt>Version</dt>\n                <dd><code>v3.5.1</code></dd>\n              <dt>Master</dt>\n                <dd><code>local[*]</code></dd>\n              <dt>AppName</dt>\n                <dd><code>CNN_Model</code></dd>\n            </dl>\n        </div>\n        \n            </div>\n        "},"metadata":{}}],"execution_count":5},{"cell_type":"code","source":"import os\n\nbase_dir = \"/kaggle/input/hms-harmful-brain-activity-classification\"\ntrain_eeg_dir = os.path.join(base_dir, \"train_eegs\")\ntrain_spec_dir = os.path.join(base_dir, \"train_spectrograms\")\n\neeg_parquet_files = sorted([f for f in os.listdir(train_eeg_dir) if f.endswith(\".parquet\")])\nspec_parquet_files = sorted([f for f in os.listdir(train_spec_dir) if f.endswith(\".parquet\")])\n\nprint(\"Total EEG files:\", len(eeg_parquet_files))\nprint(\"Total Spectrogram files:\", len(spec_parquet_files))","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-07-12T20:33:22.121611Z","iopub.execute_input":"2025-07-12T20:33:22.121886Z","iopub.status.idle":"2025-07-12T20:33:22.558392Z","shell.execute_reply.started":"2025-07-12T20:33:22.121868Z","shell.execute_reply":"2025-07-12T20:33:22.557762Z"}},"outputs":[{"name":"stdout","text":"Total EEG files: 17300\nTotal Spectrogram files: 11138\n","output_type":"stream"}],"execution_count":7},{"cell_type":"code","source":"# Assuming expert_consensus is the target\nfractions = {\n    \"Seizure\": 0.001,\n    \"LPD\": 0.001,\n    \"GPD\": 0.001,\n    \"LRDA\": 0.001,\n    \"GRDA\": 0.001,\n    \"Other\": 0.001\n}\n\ndf_labels = (\n    spark.read.option(\"header\", True).csv(\"/kaggle/input/hms-harmful-brain-activity-classification/train.csv\")\n    .sampleBy(\"expert_consensus\", fractions=fractions, seed=42)\n)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-07-12T20:33:38.262883Z","iopub.execute_input":"2025-07-12T20:33:38.263653Z","iopub.status.idle":"2025-07-12T20:33:43.840033Z","shell.execute_reply.started":"2025-07-12T20:33:38.263626Z","shell.execute_reply":"2025-07-12T20:33:43.839169Z"}},"outputs":[],"execution_count":8},{"cell_type":"code","source":"df_labels.printSchema()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-07-12T20:33:59.554924Z","iopub.execute_input":"2025-07-12T20:33:59.555231Z","iopub.status.idle":"2025-07-12T20:33:59.561827Z","shell.execute_reply.started":"2025-07-12T20:33:59.555207Z","shell.execute_reply":"2025-07-12T20:33:59.561174Z"}},"outputs":[{"name":"stdout","text":"root\n |-- eeg_id: string (nullable = true)\n |-- eeg_sub_id: string (nullable = true)\n |-- eeg_label_offset_seconds: string (nullable = true)\n |-- spectrogram_id: string (nullable = true)\n |-- spectrogram_sub_id: string (nullable = true)\n |-- spectrogram_label_offset_seconds: string (nullable = true)\n |-- label_id: string (nullable = true)\n |-- patient_id: string (nullable = true)\n |-- expert_consensus: string (nullable = true)\n |-- seizure_vote: string (nullable = true)\n |-- lpd_vote: string (nullable = true)\n |-- gpd_vote: string (nullable = true)\n |-- lrda_vote: string (nullable = true)\n |-- grda_vote: string (nullable = true)\n |-- other_vote: string (nullable = true)\n\n","output_type":"stream"}],"execution_count":9},{"cell_type":"code","source":"from pyspark.sql.functions import input_file_name, regexp_extract\n\n# Load EEG data and extract eeg_id\ndf_eeg = (\n    spark.read.parquet(\"/kaggle/input/hms-harmful-brain-activity-classification/train_eegs/*.parquet\")\n    .withColumn(\"file_path\", input_file_name())\n    .withColumn(\"eeg_id\", regexp_extract(\"file_path\", r\"(\\d+)\\.parquet\", 1).cast(\"long\"))\n)\n\n# Load spectrogram data and extract spectrogram_id\ndf_spec = (\n    spark.read.parquet(\"/kaggle/input/hms-harmful-brain-activity-classification/train_spectrograms/*.parquet\")\n    .withColumn(\"file_path\", input_file_name())\n    .withColumn(\"spectrogram_id\", regexp_extract(\"file_path\", r\"(\\d+)\\.parquet\", 1).cast(\"long\"))\n)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-07-12T20:34:09.182309Z","iopub.execute_input":"2025-07-12T20:34:09.182569Z","iopub.status.idle":"2025-07-12T20:37:10.24774Z","shell.execute_reply.started":"2025-07-12T20:34:09.18255Z","shell.execute_reply":"2025-07-12T20:37:10.247208Z"}},"outputs":[{"name":"stderr","text":"                                                                                \r","output_type":"stream"}],"execution_count":10},{"cell_type":"code","source":"# df_eeg.show()\n\nfrom pyspark.sql.window import Window\nfrom pyspark.sql.functions import row_number\n\n# Window to partition by eeg_id and assign row numbers\neeg_window = Window.partitionBy(\"eeg_id\").orderBy(\"file_path\")  # You can replace 'file_path' with timestamp/chunk\ndf_eeg_limited = df_eeg.withColumn(\"row_num\", row_number().over(eeg_window)).filter(\"row_num <= 2\").drop(\"row_num\")\n\n# Window to partition by spectrogram_id and assign row numbers\nspec_window = Window.partitionBy(\"spectrogram_id\").orderBy(\"file_path\")  # Adjust if needed\ndf_spec_limited = df_spec.withColumn(\"row_num\", row_number().over(spec_window)).filter(\"row_num <= 2\").drop(\"row_num\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-07-12T20:37:10.248653Z","iopub.execute_input":"2025-07-12T20:37:10.248881Z","iopub.status.idle":"2025-07-12T20:37:10.561203Z","shell.execute_reply.started":"2025-07-12T20:37:10.248864Z","shell.execute_reply":"2025-07-12T20:37:10.560316Z"}},"outputs":[],"execution_count":11},{"cell_type":"code","source":"from pyspark.sql.functions import col\n\n# Cast IDs\ndf_labels_casted = (\n    df_labels\n    .withColumn(\"eeg_id\", col(\"eeg_id\").cast(\"long\"))\n    .withColumn(\"spectrogram_id\", col(\"spectrogram_id\").cast(\"long\"))\n)\n\n# Join only on limited EEG and Spec data\ndf_joined = (\n    df_labels_casted\n    .join(df_eeg_limited, on=\"eeg_id\", how=\"inner\")\n    .join(df_spec_limited, on=\"spectrogram_id\", how=\"inner\")\n)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-07-12T20:40:05.421228Z","iopub.execute_input":"2025-07-12T20:40:05.421778Z","iopub.status.idle":"2025-07-12T20:40:05.645078Z","shell.execute_reply.started":"2025-07-12T20:40:05.421753Z","shell.execute_reply":"2025-07-12T20:40:05.644327Z"}},"outputs":[],"execution_count":12},{"cell_type":"code","source":"# Step 1: Identify frequency columns (with possible '.' in time values)\nfreq_cols = [col for col in df_joined.columns if col.startswith(('LL_', 'RL_', 'LP_', 'RP_'))]\n\n# Step 2: Rename columns to replace '.' with '_' (in Pandas)\ndef sanitize_column_names(df_spark):\n    for col_name in df_spark.columns:\n        if any(prefix in col_name for prefix in ['LL_', 'RL_', 'LP_', 'RP_']):\n            new_col = col_name.replace('.', '_')\n            if new_col != col_name:\n                df_spark = df_spark.withColumnRenamed(col_name, new_col)\n    return df_spark\n\ndf_joined = sanitize_column_names(df_joined)\n\n# Step 3: Recompute frequency columns after renaming\nfreq_cols = [col for col in df_joined.columns if col.startswith(('LL_', 'RL_', 'LP_', 'RP_'))]\ntarget = \"expert_consensus\"","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-07-12T20:40:38.037497Z","iopub.execute_input":"2025-07-12T20:40:38.037818Z","iopub.status.idle":"2025-07-12T20:43:17.038776Z","shell.execute_reply.started":"2025-07-12T20:40:38.037796Z","shell.execute_reply":"2025-07-12T20:43:17.038143Z"}},"outputs":[],"execution_count":13},{"cell_type":"code","source":"df_joined.printSchema()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-07-12T20:47:36.188979Z","iopub.execute_input":"2025-07-12T20:47:36.189595Z","iopub.status.idle":"2025-07-12T20:47:36.239395Z","shell.execute_reply.started":"2025-07-12T20:47:36.189573Z","shell.execute_reply":"2025-07-12T20:47:36.23854Z"}},"outputs":[{"name":"stdout","text":"root\n |-- spectrogram_id: long (nullable = true)\n |-- eeg_id: long (nullable = true)\n |-- eeg_sub_id: string (nullable = true)\n |-- eeg_label_offset_seconds: string (nullable = true)\n |-- spectrogram_sub_id: string (nullable = true)\n |-- spectrogram_label_offset_seconds: string (nullable = true)\n |-- label_id: string (nullable = true)\n |-- patient_id: string (nullable = true)\n |-- expert_consensus: string (nullable = true)\n |-- seizure_vote: string (nullable = true)\n |-- lpd_vote: string (nullable = true)\n |-- gpd_vote: string (nullable = true)\n |-- lrda_vote: string (nullable = true)\n |-- grda_vote: string (nullable = true)\n |-- other_vote: string (nullable = true)\n |-- Fp1: float (nullable = true)\n |-- F3: float (nullable = true)\n |-- C3: float (nullable = true)\n |-- P3: float (nullable = true)\n |-- F7: float (nullable = true)\n |-- T3: float (nullable = true)\n |-- T5: float (nullable = true)\n |-- O1: float (nullable = true)\n |-- Fz: float (nullable = true)\n |-- Cz: float (nullable = true)\n |-- Pz: float (nullable = true)\n |-- Fp2: float (nullable = true)\n |-- F4: float (nullable = true)\n |-- C4: float (nullable = true)\n |-- P4: float (nullable = true)\n |-- F8: float (nullable = true)\n |-- T4: float (nullable = true)\n |-- T6: float (nullable = true)\n |-- O2: float (nullable = true)\n |-- EKG: float (nullable = true)\n |-- file_path: string (nullable = false)\n |-- time: long (nullable = true)\n |-- LL_0_59: float (nullable = true)\n |-- LL_0_78: float (nullable = true)\n |-- LL_0_98: float (nullable = true)\n |-- LL_1_17: float (nullable = true)\n |-- LL_1_37: float (nullable = true)\n |-- LL_1_56: float (nullable = true)\n |-- LL_1_76: float (nullable = true)\n |-- LL_1_95: float (nullable = true)\n |-- LL_2_15: float (nullable = true)\n |-- LL_2_34: float (nullable = true)\n |-- LL_2_54: float (nullable = true)\n |-- LL_2_73: float (nullable = true)\n |-- LL_2_93: float (nullable = true)\n |-- LL_3_13: float (nullable = true)\n |-- LL_3_32: float (nullable = true)\n |-- LL_3_52: float (nullable = true)\n |-- LL_3_71: float (nullable = true)\n |-- LL_3_91: float (nullable = true)\n |-- LL_4_1: float (nullable = true)\n |-- LL_4_3: float (nullable = true)\n |-- LL_4_49: float (nullable = true)\n |-- LL_4_69: float (nullable = true)\n |-- LL_4_88: float (nullable = true)\n |-- LL_5_08: float (nullable = true)\n |-- LL_5_27: float (nullable = true)\n |-- LL_5_47: float (nullable = true)\n |-- LL_5_66: float (nullable = true)\n |-- LL_5_86: float (nullable = true)\n |-- LL_6_05: float (nullable = true)\n |-- LL_6_25: float (nullable = true)\n |-- LL_6_45: float (nullable = true)\n |-- LL_6_64: float (nullable = true)\n |-- LL_6_84: float (nullable = true)\n |-- LL_7_03: float (nullable = true)\n |-- LL_7_23: float (nullable = true)\n |-- LL_7_42: float (nullable = true)\n |-- LL_7_62: float (nullable = true)\n |-- LL_7_81: float (nullable = true)\n |-- LL_8_01: float (nullable = true)\n |-- LL_8_2: float (nullable = true)\n |-- LL_8_4: float (nullable = true)\n |-- LL_8_59: float (nullable = true)\n |-- LL_8_79: float (nullable = true)\n |-- LL_8_98: float (nullable = true)\n |-- LL_9_18: float (nullable = true)\n |-- LL_9_38: float (nullable = true)\n |-- LL_9_57: float (nullable = true)\n |-- LL_9_77: float (nullable = true)\n |-- LL_9_96: float (nullable = true)\n |-- LL_10_16: float (nullable = true)\n |-- LL_10_35: float (nullable = true)\n |-- LL_10_55: float (nullable = true)\n |-- LL_10_74: float (nullable = true)\n |-- LL_10_94: float (nullable = true)\n |-- LL_11_13: float (nullable = true)\n |-- LL_11_33: float (nullable = true)\n |-- LL_11_52: float (nullable = true)\n |-- LL_11_72: float (nullable = true)\n |-- LL_11_91: float (nullable = true)\n |-- LL_12_11: float (nullable = true)\n |-- LL_12_3: float (nullable = true)\n |-- LL_12_5: float (nullable = true)\n |-- LL_12_7: float (nullable = true)\n |-- LL_12_89: float (nullable = true)\n |-- LL_13_09: float (nullable = true)\n |-- LL_13_28: float (nullable = true)\n |-- LL_13_48: float (nullable = true)\n |-- LL_13_67: float (nullable = true)\n |-- LL_13_87: float (nullable = true)\n |-- LL_14_06: float (nullable = true)\n |-- LL_14_26: float (nullable = true)\n |-- LL_14_45: float (nullable = true)\n |-- LL_14_65: float (nullable = true)\n |-- LL_14_84: float (nullable = true)\n |-- LL_15_04: float (nullable = true)\n |-- LL_15_23: float (nullable = true)\n |-- LL_15_43: float (nullable = true)\n |-- LL_15_63: float (nullable = true)\n |-- LL_15_82: float (nullable = true)\n |-- LL_16_02: float (nullable = true)\n |-- LL_16_21: float (nullable = true)\n |-- LL_16_41: float (nullable = true)\n |-- LL_16_6: float (nullable = true)\n |-- LL_16_8: float (nullable = true)\n |-- LL_16_99: float (nullable = true)\n |-- LL_17_19: float (nullable = true)\n |-- LL_17_38: float (nullable = true)\n |-- LL_17_58: float (nullable = true)\n |-- LL_17_77: float (nullable = true)\n |-- LL_17_97: float (nullable = true)\n |-- LL_18_16: float (nullable = true)\n |-- LL_18_36: float (nullable = true)\n |-- LL_18_55: float (nullable = true)\n |-- LL_18_75: float (nullable = true)\n |-- LL_18_95: float (nullable = true)\n |-- LL_19_14: float (nullable = true)\n |-- LL_19_34: float (nullable = true)\n |-- LL_19_53: float (nullable = true)\n |-- LL_19_73: float (nullable = true)\n |-- LL_19_92: float (nullable = true)\n |-- RL_0_59: float (nullable = true)\n |-- RL_0_78: float (nullable = true)\n |-- RL_0_98: float (nullable = true)\n |-- RL_1_17: float (nullable = true)\n |-- RL_1_37: float (nullable = true)\n |-- RL_1_56: float (nullable = true)\n |-- RL_1_76: float (nullable = true)\n |-- RL_1_95: float (nullable = true)\n |-- RL_2_15: float (nullable = true)\n |-- RL_2_34: float (nullable = true)\n |-- RL_2_54: float (nullable = true)\n |-- RL_2_73: float (nullable = true)\n |-- RL_2_93: float (nullable = true)\n |-- RL_3_13: float (nullable = true)\n |-- RL_3_32: float (nullable = true)\n |-- RL_3_52: float (nullable = true)\n |-- RL_3_71: float (nullable = true)\n |-- RL_3_91: float (nullable = true)\n |-- RL_4_1: float (nullable = true)\n |-- RL_4_3: float (nullable = true)\n |-- RL_4_49: float (nullable = true)\n |-- RL_4_69: float (nullable = true)\n |-- RL_4_88: float (nullable = true)\n |-- RL_5_08: float (nullable = true)\n |-- RL_5_27: float (nullable = true)\n |-- RL_5_47: float (nullable = true)\n |-- RL_5_66: float (nullable = true)\n |-- RL_5_86: float (nullable = true)\n |-- RL_6_05: float (nullable = true)\n |-- RL_6_25: float (nullable = true)\n |-- RL_6_45: float (nullable = true)\n |-- RL_6_64: float (nullable = true)\n |-- RL_6_84: float (nullable = true)\n |-- RL_7_03: float (nullable = true)\n |-- RL_7_23: float (nullable = true)\n |-- RL_7_42: float (nullable = true)\n |-- RL_7_62: float (nullable = true)\n |-- RL_7_81: float (nullable = true)\n |-- RL_8_01: float (nullable = true)\n |-- RL_8_2: float (nullable = true)\n |-- RL_8_4: float (nullable = true)\n |-- RL_8_59: float (nullable = true)\n |-- RL_8_79: float (nullable = true)\n |-- RL_8_98: float (nullable = true)\n |-- RL_9_18: float (nullable = true)\n |-- RL_9_38: float (nullable = true)\n |-- RL_9_57: float (nullable = true)\n |-- RL_9_77: float (nullable = true)\n |-- RL_9_96: float (nullable = true)\n |-- RL_10_16: float (nullable = true)\n |-- RL_10_35: float (nullable = true)\n |-- RL_10_55: float (nullable = true)\n |-- RL_10_74: float (nullable = true)\n |-- RL_10_94: float (nullable = true)\n |-- RL_11_13: float (nullable = true)\n |-- RL_11_33: float (nullable = true)\n |-- RL_11_52: float (nullable = true)\n |-- RL_11_72: float (nullable = true)\n |-- RL_11_91: float (nullable = true)\n |-- RL_12_11: float (nullable = true)\n |-- RL_12_3: float (nullable = true)\n |-- RL_12_5: float (nullable = true)\n |-- RL_12_7: float (nullable = true)\n |-- RL_12_89: float (nullable = true)\n |-- RL_13_09: float (nullable = true)\n |-- RL_13_28: float (nullable = true)\n |-- RL_13_48: float (nullable = true)\n |-- RL_13_67: float (nullable = true)\n |-- RL_13_87: float (nullable = true)\n |-- RL_14_06: float (nullable = true)\n |-- RL_14_26: float (nullable = true)\n |-- RL_14_45: float (nullable = true)\n |-- RL_14_65: float (nullable = true)\n |-- RL_14_84: float (nullable = true)\n |-- RL_15_04: float (nullable = true)\n |-- RL_15_23: float (nullable = true)\n |-- RL_15_43: float (nullable = true)\n |-- RL_15_63: float (nullable = true)\n |-- RL_15_82: float (nullable = true)\n |-- RL_16_02: float (nullable = true)\n |-- RL_16_21: float (nullable = true)\n |-- RL_16_41: float (nullable = true)\n |-- RL_16_6: float (nullable = true)\n |-- RL_16_8: float (nullable = true)\n |-- RL_16_99: float (nullable = true)\n |-- RL_17_19: float (nullable = true)\n |-- RL_17_38: float (nullable = true)\n |-- RL_17_58: float (nullable = true)\n |-- RL_17_77: float (nullable = true)\n |-- RL_17_97: float (nullable = true)\n |-- RL_18_16: float (nullable = true)\n |-- RL_18_36: float (nullable = true)\n |-- RL_18_55: float (nullable = true)\n |-- RL_18_75: float (nullable = true)\n |-- RL_18_95: float (nullable = true)\n |-- RL_19_14: float (nullable = true)\n |-- RL_19_34: float (nullable = true)\n |-- RL_19_53: float (nullable = true)\n |-- RL_19_73: float (nullable = true)\n |-- RL_19_92: float (nullable = true)\n |-- LP_0_59: float (nullable = true)\n |-- LP_0_78: float (nullable = true)\n |-- LP_0_98: float (nullable = true)\n |-- LP_1_17: float (nullable = true)\n |-- LP_1_37: float (nullable = true)\n |-- LP_1_56: float (nullable = true)\n |-- LP_1_76: float (nullable = true)\n |-- LP_1_95: float (nullable = true)\n |-- LP_2_15: float (nullable = true)\n |-- LP_2_34: float (nullable = true)\n |-- LP_2_54: float (nullable = true)\n |-- LP_2_73: float (nullable = true)\n |-- LP_2_93: float (nullable = true)\n |-- LP_3_13: float (nullable = true)\n |-- LP_3_32: float (nullable = true)\n |-- LP_3_52: float (nullable = true)\n |-- LP_3_71: float (nullable = true)\n |-- LP_3_91: float (nullable = true)\n |-- LP_4_1: float (nullable = true)\n |-- LP_4_3: float (nullable = true)\n |-- LP_4_49: float (nullable = true)\n |-- LP_4_69: float (nullable = true)\n |-- LP_4_88: float (nullable = true)\n |-- LP_5_08: float (nullable = true)\n |-- LP_5_27: float (nullable = true)\n |-- LP_5_47: float (nullable = true)\n |-- LP_5_66: float (nullable = true)\n |-- LP_5_86: float (nullable = true)\n |-- LP_6_05: float (nullable = true)\n |-- LP_6_25: float (nullable = true)\n |-- LP_6_45: float (nullable = true)\n |-- LP_6_64: float (nullable = true)\n |-- LP_6_84: float (nullable = true)\n |-- LP_7_03: float (nullable = true)\n |-- LP_7_23: float (nullable = true)\n |-- LP_7_42: float (nullable = true)\n |-- LP_7_62: float (nullable = true)\n |-- LP_7_81: float (nullable = true)\n |-- LP_8_01: float (nullable = true)\n |-- LP_8_2: float (nullable = true)\n |-- LP_8_4: float (nullable = true)\n |-- LP_8_59: float (nullable = true)\n |-- LP_8_79: float (nullable = true)\n |-- LP_8_98: float (nullable = true)\n |-- LP_9_18: float (nullable = true)\n |-- LP_9_38: float (nullable = true)\n |-- LP_9_57: float (nullable = true)\n |-- LP_9_77: float (nullable = true)\n |-- LP_9_96: float (nullable = true)\n |-- LP_10_16: float (nullable = true)\n |-- LP_10_35: float (nullable = true)\n |-- LP_10_55: float (nullable = true)\n |-- LP_10_74: float (nullable = true)\n |-- LP_10_94: float (nullable = true)\n |-- LP_11_13: float (nullable = true)\n |-- LP_11_33: float (nullable = true)\n |-- LP_11_52: float (nullable = true)\n |-- LP_11_72: float (nullable = true)\n |-- LP_11_91: float (nullable = true)\n |-- LP_12_11: float (nullable = true)\n |-- LP_12_3: float (nullable = true)\n |-- LP_12_5: float (nullable = true)\n |-- LP_12_7: float (nullable = true)\n |-- LP_12_89: float (nullable = true)\n |-- LP_13_09: float (nullable = true)\n |-- LP_13_28: float (nullable = true)\n |-- LP_13_48: float (nullable = true)\n |-- LP_13_67: float (nullable = true)\n |-- LP_13_87: float (nullable = true)\n |-- LP_14_06: float (nullable = true)\n |-- LP_14_26: float (nullable = true)\n |-- LP_14_45: float (nullable = true)\n |-- LP_14_65: float (nullable = true)\n |-- LP_14_84: float (nullable = true)\n |-- LP_15_04: float (nullable = true)\n |-- LP_15_23: float (nullable = true)\n |-- LP_15_43: float (nullable = true)\n |-- LP_15_63: float (nullable = true)\n |-- LP_15_82: float (nullable = true)\n |-- LP_16_02: float (nullable = true)\n |-- LP_16_21: float (nullable = true)\n |-- LP_16_41: float (nullable = true)\n |-- LP_16_6: float (nullable = true)\n |-- LP_16_8: float (nullable = true)\n |-- LP_16_99: float (nullable = true)\n |-- LP_17_19: float (nullable = true)\n |-- LP_17_38: float (nullable = true)\n |-- LP_17_58: float (nullable = true)\n |-- LP_17_77: float (nullable = true)\n |-- LP_17_97: float (nullable = true)\n |-- LP_18_16: float (nullable = true)\n |-- LP_18_36: float (nullable = true)\n |-- LP_18_55: float (nullable = true)\n |-- LP_18_75: float (nullable = true)\n |-- LP_18_95: float (nullable = true)\n |-- LP_19_14: float (nullable = true)\n |-- LP_19_34: float (nullable = true)\n |-- LP_19_53: float (nullable = true)\n |-- LP_19_73: float (nullable = true)\n |-- LP_19_92: float (nullable = true)\n |-- RP_0_59: float (nullable = true)\n |-- RP_0_78: float (nullable = true)\n |-- RP_0_98: float (nullable = true)\n |-- RP_1_17: float (nullable = true)\n |-- RP_1_37: float (nullable = true)\n |-- RP_1_56: float (nullable = true)\n |-- RP_1_76: float (nullable = true)\n |-- RP_1_95: float (nullable = true)\n |-- RP_2_15: float (nullable = true)\n |-- RP_2_34: float (nullable = true)\n |-- RP_2_54: float (nullable = true)\n |-- RP_2_73: float (nullable = true)\n |-- RP_2_93: float (nullable = true)\n |-- RP_3_13: float (nullable = true)\n |-- RP_3_32: float (nullable = true)\n |-- RP_3_52: float (nullable = true)\n |-- RP_3_71: float (nullable = true)\n |-- RP_3_91: float (nullable = true)\n |-- RP_4_1: float (nullable = true)\n |-- RP_4_3: float (nullable = true)\n |-- RP_4_49: float (nullable = true)\n |-- RP_4_69: float (nullable = true)\n |-- RP_4_88: float (nullable = true)\n |-- RP_5_08: float (nullable = true)\n |-- RP_5_27: float (nullable = true)\n |-- RP_5_47: float (nullable = true)\n |-- RP_5_66: float (nullable = true)\n |-- RP_5_86: float (nullable = true)\n |-- RP_6_05: float (nullable = true)\n |-- RP_6_25: float (nullable = true)\n |-- RP_6_45: float (nullable = true)\n |-- RP_6_64: float (nullable = true)\n |-- RP_6_84: float (nullable = true)\n |-- RP_7_03: float (nullable = true)\n |-- RP_7_23: float (nullable = true)\n |-- RP_7_42: float (nullable = true)\n |-- RP_7_62: float (nullable = true)\n |-- RP_7_81: float (nullable = true)\n |-- RP_8_01: float (nullable = true)\n |-- RP_8_2: float (nullable = true)\n |-- RP_8_4: float (nullable = true)\n |-- RP_8_59: float (nullable = true)\n |-- RP_8_79: float (nullable = true)\n |-- RP_8_98: float (nullable = true)\n |-- RP_9_18: float (nullable = true)\n |-- RP_9_38: float (nullable = true)\n |-- RP_9_57: float (nullable = true)\n |-- RP_9_77: float (nullable = true)\n |-- RP_9_96: float (nullable = true)\n |-- RP_10_16: float (nullable = true)\n |-- RP_10_35: float (nullable = true)\n |-- RP_10_55: float (nullable = true)\n |-- RP_10_74: float (nullable = true)\n |-- RP_10_94: float (nullable = true)\n |-- RP_11_13: float (nullable = true)\n |-- RP_11_33: float (nullable = true)\n |-- RP_11_52: float (nullable = true)\n |-- RP_11_72: float (nullable = true)\n |-- RP_11_91: float (nullable = true)\n |-- RP_12_11: float (nullable = true)\n |-- RP_12_3: float (nullable = true)\n |-- RP_12_5: float (nullable = true)\n |-- RP_12_7: float (nullable = true)\n |-- RP_12_89: float (nullable = true)\n |-- RP_13_09: float (nullable = true)\n |-- RP_13_28: float (nullable = true)\n |-- RP_13_48: float (nullable = true)\n |-- RP_13_67: float (nullable = true)\n |-- RP_13_87: float (nullable = true)\n |-- RP_14_06: float (nullable = true)\n |-- RP_14_26: float (nullable = true)\n |-- RP_14_45: float (nullable = true)\n |-- RP_14_65: float (nullable = true)\n |-- RP_14_84: float (nullable = true)\n |-- RP_15_04: float (nullable = true)\n |-- RP_15_23: float (nullable = true)\n |-- RP_15_43: float (nullable = true)\n |-- RP_15_63: float (nullable = true)\n |-- RP_15_82: float (nullable = true)\n |-- RP_16_02: float (nullable = true)\n |-- RP_16_21: float (nullable = true)\n |-- RP_16_41: float (nullable = true)\n |-- RP_16_6: float (nullable = true)\n |-- RP_16_8: float (nullable = true)\n |-- RP_16_99: float (nullable = true)\n |-- RP_17_19: float (nullable = true)\n |-- RP_17_38: float (nullable = true)\n |-- RP_17_58: float (nullable = true)\n |-- RP_17_77: float (nullable = true)\n |-- RP_17_97: float (nullable = true)\n |-- RP_18_16: float (nullable = true)\n |-- RP_18_36: float (nullable = true)\n |-- RP_18_55: float (nullable = true)\n |-- RP_18_75: float (nullable = true)\n |-- RP_18_95: float (nullable = true)\n |-- RP_19_14: float (nullable = true)\n |-- RP_19_34: float (nullable = true)\n |-- RP_19_53: float (nullable = true)\n |-- RP_19_73: float (nullable = true)\n |-- RP_19_92: float (nullable = true)\n |-- file_path: string (nullable = false)\n\n","output_type":"stream"}],"execution_count":14},{"cell_type":"code","source":"# Step 3: Convert to Pandas (no limit)\ndf_pandas = df_joined.select(freq_cols + [target]).toPandas()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-07-12T20:52:19.912058Z","iopub.execute_input":"2025-07-12T20:52:19.912401Z","iopub.status.idle":"2025-07-12T21:07:32.140658Z","shell.execute_reply.started":"2025-07-12T20:52:19.912381Z","shell.execute_reply":"2025-07-12T21:07:32.139839Z"}},"outputs":[{"name":"stderr","text":"25/07/12 20:52:28 WARN SparkStringUtils: Truncated the string representation of a plan since it was too large. This behavior can be adjusted by setting 'spark.sql.debug.maxToStringFields'.\n                                                                                \r","output_type":"stream"}],"execution_count":15},{"cell_type":"code","source":"# Step 3: Encode label\nfrom sklearn.preprocessing import LabelEncoder\nfrom tensorflow.keras.utils import to_categorical\n\nle = LabelEncoder()\ny = le.fit_transform(df_pandas[target])\ny_cat = to_categorical(y)\n\n# Step 4: Prepare CNN input shape\nimport numpy as np\n\n# Spectrogram data is 4 regions (LL, LR, LP, RP), each with N frequency bands\nn_regions = 4\nfreq_cols_sorted = sorted(freq_cols, key=lambda x: (x.split('_')[0], float(x.split('_')[1] + '.' + x.split('_')[2])))\nn_freq_bins = len(freq_cols_sorted) // n_regions\n\nX = df_pandas[freq_cols_sorted].values\nX = X.reshape(-1, n_regions, n_freq_bins, 1)  # Shape: (samples, 4, N_freq_bins, 1)\n\n# Step 5: Train/test split\nfrom sklearn.model_selection import train_test_split\nX_train, X_test, y_train, y_test = train_test_split(X, y_cat, test_size=0.2, stratify=y, random_state=42)\n\nprint(\"X_train shape:\", X_train.shape)\nprint(\"y_train shape:\", y_train.shape)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-07-12T21:16:56.906931Z","iopub.execute_input":"2025-07-12T21:16:56.90728Z","iopub.status.idle":"2025-07-12T21:17:20.049342Z","shell.execute_reply.started":"2025-07-12T21:16:56.907257Z","shell.execute_reply":"2025-07-12T21:17:20.048473Z"}},"outputs":[{"name":"stderr","text":"2025-07-12 21:17:01.071946: E external/local_xla/xla/stream_executor/cuda/cuda_fft.cc:477] Unable to register cuFFT factory: Attempting to register factory for plugin cuFFT when one has already been registered\nWARNING: All log messages before absl::InitializeLog() is called are written to STDERR\nE0000 00:00:1752355021.449460      36 cuda_dnn.cc:8310] Unable to register cuDNN factory: Attempting to register factory for plugin cuDNN when one has already been registered\nE0000 00:00:1752355021.550538      36 cuda_blas.cc:1418] Unable to register cuBLAS factory: Attempting to register factory for plugin cuBLAS when one has already been registered\n","output_type":"stream"},{"name":"stdout","text":"X_train shape: (342, 4, 100, 1)\ny_train shape: (342, 6)\n","output_type":"stream"}],"execution_count":16},{"cell_type":"code","source":"import tensorflow as tf\nfrom tensorflow.keras.models import Sequential\nfrom tensorflow.keras.layers import (\n    Conv2D, MaxPooling2D, Flatten, Dense, Dropout, BatchNormalization\n)\n\n# Define input shape\ninput_shape = X_train.shape[1:]  # (4, time_bins_per_location, 1)\nnum_classes = y_cat.shape[1]\n\n# Build the model\nmodel = Sequential()\n\n# Convolutional block 1\nmodel.add(Conv2D(32, (2, 3), activation='relu', padding='same', input_shape=input_shape))\nmodel.add(BatchNormalization())\nmodel.add(MaxPooling2D(pool_size=(1, 2)))\n\n# Convolutional block 2\nmodel.add(Conv2D(64, (2, 3), activation='relu', padding='same'))\nmodel.add(BatchNormalization())\nmodel.add(MaxPooling2D(pool_size=(1, 2)))\n\n# Optional: third block\nmodel.add(Conv2D(128, (2, 3), activation='relu', padding='same'))\nmodel.add(BatchNormalization())\nmodel.add(MaxPooling2D(pool_size=(1, 2)))\n\n# Flatten and fully connected layers\nmodel.add(Flatten())\nmodel.add(Dense(128, activation='relu'))\nmodel.add(Dropout(0.5))  # Prevent overfitting\n\n# Output layer\nmodel.add(Dense(num_classes, activation='softmax'))\n\n# Compile model\nmodel.compile(optimizer='adam',\n              loss='categorical_crossentropy',\n              metrics=['accuracy'])\n\n# Summary\nmodel.summary()","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import tensorflow as tf\nfrom tensorflow.keras.models import Sequential\nfrom tensorflow.keras.layers import Conv2D, MaxPooling2D, Flatten, Dense, Dropout, BatchNormalization\n\n# Ensure TensorFlow sees both GPUs\ngpus = tf.config.list_physical_devices('GPU')\nif gpus:\n    print(\"GPUs detected:\", gpus)\n    try:\n        for gpu in gpus:\n            tf.config.experimental.set_memory_growth(gpu, True)\n    except RuntimeError as e:\n        print(e)\n\n# Create a strategy for multiple GPUs\nstrategy = tf.distribute.MirroredStrategy()\n\n# Print number of GPUs being used\nprint(\"Number of GPUs available:\", strategy.num_replicas_in_sync)\n\n# Build model inside the strategy scope\nwith strategy.scope():\n    input_shape = X_train.shape[1:]  # (4, time_bins, 1)\n    num_classes = y_cat.shape[1]\n\n    model = Sequential()\n    model.add(Conv2D(32, (2, 3), activation='relu', padding='same', input_shape=input_shape))\n    model.add(BatchNormalization())\n    model.add(MaxPooling2D(pool_size=(1, 2)))\n\n    model.add(Conv2D(64, (2, 3), activation='relu', padding='same'))\n    model.add(BatchNormalization())\n    model.add(MaxPooling2D(pool_size=(1, 2)))\n\n    model.add(Conv2D(128, (2, 3), activation='relu', padding='same'))\n    model.add(BatchNormalization())\n    model.add(MaxPooling2D(pool_size=(1, 2)))\n\n    model.add(Flatten())\n    model.add(Dense(128, activation='relu'))\n    model.add(Dropout(0.5))\n    model.add(Dense(num_classes, activation='softmax'))\n\n    model.compile(\n        optimizer='adam',\n        loss='categorical_crossentropy',\n        metrics=['accuracy']\n    )\n\n# Optional: print model summary\nmodel.summary()\n\n# Train the model\nhistory = model.fit(\n    X_train, y_train,\n    validation_data=(X_test, y_test),\n    epochs=30,\n    batch_size=64,  # Larger batch size to utilize both GPUs\n    verbose=1\n)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-07-12T21:24:11.467763Z","iopub.execute_input":"2025-07-12T21:24:11.46868Z","iopub.status.idle":"2025-07-12T21:24:52.238545Z","shell.execute_reply.started":"2025-07-12T21:24:11.468655Z","shell.execute_reply":"2025-07-12T21:24:52.237954Z"}},"outputs":[{"name":"stdout","text":"GPUs detected: [PhysicalDevice(name='/physical_device:GPU:0', device_type='GPU'), PhysicalDevice(name='/physical_device:GPU:1', device_type='GPU')]\nNumber of GPUs available: 2\n","output_type":"stream"},{"name":"stderr","text":"I0000 00:00:1752355453.682802      36 gpu_device.cc:2022] Created device /job:localhost/replica:0/task:0/device:GPU:0 with 13942 MB memory:  -> device: 0, name: Tesla T4, pci bus id: 0000:00:04.0, compute capability: 7.5\nI0000 00:00:1752355453.683700      36 gpu_device.cc:2022] Created device /job:localhost/replica:0/task:0/device:GPU:1 with 13942 MB memory:  -> device: 1, name: Tesla T4, pci bus id: 0000:00:05.0, compute capability: 7.5\n","output_type":"stream"},{"output_type":"display_data","data":{"text/plain":"\u001b[1mModel: \"sequential\"\u001b[0m\n","text/html":"<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\"><span style=\"font-weight: bold\">Model: \"sequential\"</span>\n</pre>\n"},"metadata":{}},{"output_type":"display_data","data":{"text/plain":"┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┓\n┃\u001b[1m \u001b[0m\u001b[1mLayer (type)                   \u001b[0m\u001b[1m \u001b[0m┃\u001b[1m \u001b[0m\u001b[1mOutput Shape          \u001b[0m\u001b[1m \u001b[0m┃\u001b[1m \u001b[0m\u001b[1m      Param #\u001b[0m\u001b[1m \u001b[0m┃\n┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━┩\n│ conv2d (\u001b[38;5;33mConv2D\u001b[0m)                 │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m4\u001b[0m, \u001b[38;5;34m100\u001b[0m, \u001b[38;5;34m32\u001b[0m)     │           \u001b[38;5;34m224\u001b[0m │\n├─────────────────────────────────┼────────────────────────┼───────────────┤\n│ batch_normalization             │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m4\u001b[0m, \u001b[38;5;34m100\u001b[0m, \u001b[38;5;34m32\u001b[0m)     │           \u001b[38;5;34m128\u001b[0m │\n│ (\u001b[38;5;33mBatchNormalization\u001b[0m)            │                        │               │\n├─────────────────────────────────┼────────────────────────┼───────────────┤\n│ max_pooling2d (\u001b[38;5;33mMaxPooling2D\u001b[0m)    │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m4\u001b[0m, \u001b[38;5;34m50\u001b[0m, \u001b[38;5;34m32\u001b[0m)      │             \u001b[38;5;34m0\u001b[0m │\n├─────────────────────────────────┼────────────────────────┼───────────────┤\n│ conv2d_1 (\u001b[38;5;33mConv2D\u001b[0m)               │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m4\u001b[0m, \u001b[38;5;34m50\u001b[0m, \u001b[38;5;34m64\u001b[0m)      │        \u001b[38;5;34m12,352\u001b[0m │\n├─────────────────────────────────┼────────────────────────┼───────────────┤\n│ batch_normalization_1           │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m4\u001b[0m, \u001b[38;5;34m50\u001b[0m, \u001b[38;5;34m64\u001b[0m)      │           \u001b[38;5;34m256\u001b[0m │\n│ (\u001b[38;5;33mBatchNormalization\u001b[0m)            │                        │               │\n├─────────────────────────────────┼────────────────────────┼───────────────┤\n│ max_pooling2d_1 (\u001b[38;5;33mMaxPooling2D\u001b[0m)  │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m4\u001b[0m, \u001b[38;5;34m25\u001b[0m, \u001b[38;5;34m64\u001b[0m)      │             \u001b[38;5;34m0\u001b[0m │\n├─────────────────────────────────┼────────────────────────┼───────────────┤\n│ conv2d_2 (\u001b[38;5;33mConv2D\u001b[0m)               │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m4\u001b[0m, \u001b[38;5;34m25\u001b[0m, \u001b[38;5;34m128\u001b[0m)     │        \u001b[38;5;34m49,280\u001b[0m │\n├─────────────────────────────────┼────────────────────────┼───────────────┤\n│ batch_normalization_2           │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m4\u001b[0m, \u001b[38;5;34m25\u001b[0m, \u001b[38;5;34m128\u001b[0m)     │           \u001b[38;5;34m512\u001b[0m │\n│ (\u001b[38;5;33mBatchNormalization\u001b[0m)            │                        │               │\n├─────────────────────────────────┼────────────────────────┼───────────────┤\n│ max_pooling2d_2 (\u001b[38;5;33mMaxPooling2D\u001b[0m)  │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m4\u001b[0m, \u001b[38;5;34m12\u001b[0m, \u001b[38;5;34m128\u001b[0m)     │             \u001b[38;5;34m0\u001b[0m │\n├─────────────────────────────────┼────────────────────────┼───────────────┤\n│ flatten (\u001b[38;5;33mFlatten\u001b[0m)               │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m6144\u001b[0m)           │             \u001b[38;5;34m0\u001b[0m │\n├─────────────────────────────────┼────────────────────────┼───────────────┤\n│ dense (\u001b[38;5;33mDense\u001b[0m)                   │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m128\u001b[0m)            │       \u001b[38;5;34m786,560\u001b[0m │\n├─────────────────────────────────┼────────────────────────┼───────────────┤\n│ dropout (\u001b[38;5;33mDropout\u001b[0m)               │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m128\u001b[0m)            │             \u001b[38;5;34m0\u001b[0m │\n├─────────────────────────────────┼────────────────────────┼───────────────┤\n│ dense_1 (\u001b[38;5;33mDense\u001b[0m)                 │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m6\u001b[0m)              │           \u001b[38;5;34m774\u001b[0m │\n└─────────────────────────────────┴────────────────────────┴───────────────┘\n","text/html":"<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\">┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┓\n┃<span style=\"font-weight: bold\"> Layer (type)                    </span>┃<span style=\"font-weight: bold\"> Output Shape           </span>┃<span style=\"font-weight: bold\">       Param # </span>┃\n┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━┩\n│ conv2d (<span style=\"color: #0087ff; text-decoration-color: #0087ff\">Conv2D</span>)                 │ (<span style=\"color: #00d7ff; text-decoration-color: #00d7ff\">None</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">4</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">100</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">32</span>)     │           <span style=\"color: #00af00; text-decoration-color: #00af00\">224</span> │\n├─────────────────────────────────┼────────────────────────┼───────────────┤\n│ batch_normalization             │ (<span style=\"color: #00d7ff; text-decoration-color: #00d7ff\">None</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">4</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">100</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">32</span>)     │           <span style=\"color: #00af00; text-decoration-color: #00af00\">128</span> │\n│ (<span style=\"color: #0087ff; text-decoration-color: #0087ff\">BatchNormalization</span>)            │                        │               │\n├─────────────────────────────────┼────────────────────────┼───────────────┤\n│ max_pooling2d (<span style=\"color: #0087ff; text-decoration-color: #0087ff\">MaxPooling2D</span>)    │ (<span style=\"color: #00d7ff; text-decoration-color: #00d7ff\">None</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">4</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">50</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">32</span>)      │             <span style=\"color: #00af00; text-decoration-color: #00af00\">0</span> │\n├─────────────────────────────────┼────────────────────────┼───────────────┤\n│ conv2d_1 (<span style=\"color: #0087ff; text-decoration-color: #0087ff\">Conv2D</span>)               │ (<span style=\"color: #00d7ff; text-decoration-color: #00d7ff\">None</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">4</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">50</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">64</span>)      │        <span style=\"color: #00af00; text-decoration-color: #00af00\">12,352</span> │\n├─────────────────────────────────┼────────────────────────┼───────────────┤\n│ batch_normalization_1           │ (<span style=\"color: #00d7ff; text-decoration-color: #00d7ff\">None</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">4</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">50</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">64</span>)      │           <span style=\"color: #00af00; text-decoration-color: #00af00\">256</span> │\n│ (<span style=\"color: #0087ff; text-decoration-color: #0087ff\">BatchNormalization</span>)            │                        │               │\n├─────────────────────────────────┼────────────────────────┼───────────────┤\n│ max_pooling2d_1 (<span style=\"color: #0087ff; text-decoration-color: #0087ff\">MaxPooling2D</span>)  │ (<span style=\"color: #00d7ff; text-decoration-color: #00d7ff\">None</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">4</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">25</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">64</span>)      │             <span style=\"color: #00af00; text-decoration-color: #00af00\">0</span> │\n├─────────────────────────────────┼────────────────────────┼───────────────┤\n│ conv2d_2 (<span style=\"color: #0087ff; text-decoration-color: #0087ff\">Conv2D</span>)               │ (<span style=\"color: #00d7ff; text-decoration-color: #00d7ff\">None</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">4</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">25</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">128</span>)     │        <span style=\"color: #00af00; text-decoration-color: #00af00\">49,280</span> │\n├─────────────────────────────────┼────────────────────────┼───────────────┤\n│ batch_normalization_2           │ (<span style=\"color: #00d7ff; text-decoration-color: #00d7ff\">None</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">4</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">25</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">128</span>)     │           <span style=\"color: #00af00; text-decoration-color: #00af00\">512</span> │\n│ (<span style=\"color: #0087ff; text-decoration-color: #0087ff\">BatchNormalization</span>)            │                        │               │\n├─────────────────────────────────┼────────────────────────┼───────────────┤\n│ max_pooling2d_2 (<span style=\"color: #0087ff; text-decoration-color: #0087ff\">MaxPooling2D</span>)  │ (<span style=\"color: #00d7ff; text-decoration-color: #00d7ff\">None</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">4</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">12</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">128</span>)     │             <span style=\"color: #00af00; text-decoration-color: #00af00\">0</span> │\n├─────────────────────────────────┼────────────────────────┼───────────────┤\n│ flatten (<span style=\"color: #0087ff; text-decoration-color: #0087ff\">Flatten</span>)               │ (<span style=\"color: #00d7ff; text-decoration-color: #00d7ff\">None</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">6144</span>)           │             <span style=\"color: #00af00; text-decoration-color: #00af00\">0</span> │\n├─────────────────────────────────┼────────────────────────┼───────────────┤\n│ dense (<span style=\"color: #0087ff; text-decoration-color: #0087ff\">Dense</span>)                   │ (<span style=\"color: #00d7ff; text-decoration-color: #00d7ff\">None</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">128</span>)            │       <span style=\"color: #00af00; text-decoration-color: #00af00\">786,560</span> │\n├─────────────────────────────────┼────────────────────────┼───────────────┤\n│ dropout (<span style=\"color: #0087ff; text-decoration-color: #0087ff\">Dropout</span>)               │ (<span style=\"color: #00d7ff; text-decoration-color: #00d7ff\">None</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">128</span>)            │             <span style=\"color: #00af00; text-decoration-color: #00af00\">0</span> │\n├─────────────────────────────────┼────────────────────────┼───────────────┤\n│ dense_1 (<span style=\"color: #0087ff; text-decoration-color: #0087ff\">Dense</span>)                 │ (<span style=\"color: #00d7ff; text-decoration-color: #00d7ff\">None</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">6</span>)              │           <span style=\"color: #00af00; text-decoration-color: #00af00\">774</span> │\n└─────────────────────────────────┴────────────────────────┴───────────────┘\n</pre>\n"},"metadata":{}},{"output_type":"display_data","data":{"text/plain":"\u001b[1m Total params: \u001b[0m\u001b[38;5;34m850,086\u001b[0m (3.24 MB)\n","text/html":"<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\"><span style=\"font-weight: bold\"> Total params: </span><span style=\"color: #00af00; text-decoration-color: #00af00\">850,086</span> (3.24 MB)\n</pre>\n"},"metadata":{}},{"output_type":"display_data","data":{"text/plain":"\u001b[1m Trainable params: \u001b[0m\u001b[38;5;34m849,638\u001b[0m (3.24 MB)\n","text/html":"<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\"><span style=\"font-weight: bold\"> Trainable params: </span><span style=\"color: #00af00; text-decoration-color: #00af00\">849,638</span> (3.24 MB)\n</pre>\n"},"metadata":{}},{"output_type":"display_data","data":{"text/plain":"\u001b[1m Non-trainable params: \u001b[0m\u001b[38;5;34m448\u001b[0m (1.75 KB)\n","text/html":"<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\"><span style=\"font-weight: bold\"> Non-trainable params: </span><span style=\"color: #00af00; text-decoration-color: #00af00\">448</span> (1.75 KB)\n</pre>\n"},"metadata":{}},{"name":"stdout","text":"Epoch 1/30\n","output_type":"stream"},{"name":"stderr","text":"I0000 00:00:1752355461.122546     427 cuda_dnn.cc:529] Loaded cuDNN version 90300\nI0000 00:00:1752355461.553348     428 cuda_dnn.cc:529] Loaded cuDNN version 90300\n","output_type":"stream"},{"name":"stdout","text":"\u001b[1m6/6\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m11s\u001b[0m 361ms/step - accuracy: 0.0930 - loss: nan - val_accuracy: 0.1200 - val_loss: nan\nEpoch 2/30\n\u001b[1m6/6\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m1s\u001b[0m 131ms/step - accuracy: 0.1201 - loss: nan - val_accuracy: 0.1200 - val_loss: nan\nEpoch 3/30\n\u001b[1m6/6\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m1s\u001b[0m 132ms/step - accuracy: 0.1409 - loss: nan - val_accuracy: 0.1200 - val_loss: nan\nEpoch 4/30\n\u001b[1m6/6\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m1s\u001b[0m 132ms/step - accuracy: 0.1480 - loss: nan - val_accuracy: 0.1200 - val_loss: nan\nEpoch 5/30\n\u001b[1m6/6\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m1s\u001b[0m 134ms/step - accuracy: 0.1207 - loss: nan - val_accuracy: 0.1200 - val_loss: nan\nEpoch 6/30\n\u001b[1m6/6\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m1s\u001b[0m 132ms/step - accuracy: 0.0761 - loss: nan - val_accuracy: 0.1200 - val_loss: nan\nEpoch 7/30\n\u001b[1m6/6\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m1s\u001b[0m 129ms/step - accuracy: 0.0873 - loss: nan - val_accuracy: 0.1200 - val_loss: nan\nEpoch 8/30\n\u001b[1m6/6\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m1s\u001b[0m 128ms/step - accuracy: 0.1076 - loss: nan - val_accuracy: 0.1200 - val_loss: nan\nEpoch 9/30\n\u001b[1m6/6\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m1s\u001b[0m 130ms/step - accuracy: 0.0987 - loss: nan - val_accuracy: 0.1200 - val_loss: nan\nEpoch 10/30\n\u001b[1m6/6\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m1s\u001b[0m 132ms/step - accuracy: 0.0748 - loss: nan - val_accuracy: 0.1200 - val_loss: nan\nEpoch 11/30\n\u001b[1m6/6\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m1s\u001b[0m 132ms/step - accuracy: 0.1196 - loss: nan - val_accuracy: 0.1200 - val_loss: nan\nEpoch 12/30\n\u001b[1m6/6\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m1s\u001b[0m 127ms/step - accuracy: 0.0950 - loss: nan - val_accuracy: 0.1200 - val_loss: nan\nEpoch 13/30\n\u001b[1m6/6\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m1s\u001b[0m 128ms/step - accuracy: 0.1379 - loss: nan - val_accuracy: 0.1200 - val_loss: nan\nEpoch 14/30\n\u001b[1m6/6\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m1s\u001b[0m 130ms/step - accuracy: 0.1629 - loss: nan - val_accuracy: 0.1200 - val_loss: nan\nEpoch 15/30\n\u001b[1m6/6\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m1s\u001b[0m 130ms/step - accuracy: 0.1212 - loss: nan - val_accuracy: 0.1200 - val_loss: nan\nEpoch 16/30\n\u001b[1m6/6\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m1s\u001b[0m 134ms/step - accuracy: 0.0819 - loss: nan - val_accuracy: 0.1200 - val_loss: nan\nEpoch 17/30\n\u001b[1m6/6\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m1s\u001b[0m 130ms/step - accuracy: 0.1145 - loss: nan - val_accuracy: 0.1200 - val_loss: nan\nEpoch 18/30\n\u001b[1m6/6\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m1s\u001b[0m 130ms/step - accuracy: 0.1001 - loss: nan - val_accuracy: 0.1200 - val_loss: nan\nEpoch 19/30\n\u001b[1m6/6\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m1s\u001b[0m 130ms/step - accuracy: 0.1137 - loss: nan - val_accuracy: 0.1200 - val_loss: nan\nEpoch 20/30\n\u001b[1m6/6\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m1s\u001b[0m 130ms/step - accuracy: 0.1095 - loss: nan - val_accuracy: 0.1200 - val_loss: nan\nEpoch 21/30\n\u001b[1m6/6\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m1s\u001b[0m 130ms/step - accuracy: 0.1033 - loss: nan - val_accuracy: 0.1200 - val_loss: nan\nEpoch 22/30\n\u001b[1m6/6\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m1s\u001b[0m 233ms/step - accuracy: 0.0903 - loss: nan - val_accuracy: 0.1200 - val_loss: nan\nEpoch 23/30\n\u001b[1m6/6\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m1s\u001b[0m 136ms/step - accuracy: 0.0967 - loss: nan - val_accuracy: 0.1200 - val_loss: nan\nEpoch 24/30\n\u001b[1m6/6\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m1s\u001b[0m 134ms/step - accuracy: 0.1282 - loss: nan - val_accuracy: 0.1200 - val_loss: nan\nEpoch 25/30\n\u001b[1m6/6\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m1s\u001b[0m 134ms/step - accuracy: 0.1128 - loss: nan - val_accuracy: 0.1200 - val_loss: nan\nEpoch 26/30\n\u001b[1m6/6\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m1s\u001b[0m 129ms/step - accuracy: 0.1193 - loss: nan - val_accuracy: 0.1200 - val_loss: nan\nEpoch 27/30\n\u001b[1m6/6\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m1s\u001b[0m 136ms/step - accuracy: 0.1040 - loss: nan - val_accuracy: 0.1200 - val_loss: nan\nEpoch 28/30\n\u001b[1m6/6\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m1s\u001b[0m 131ms/step - accuracy: 0.1325 - loss: nan - val_accuracy: 0.1200 - val_loss: nan\nEpoch 29/30\n\u001b[1m6/6\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m1s\u001b[0m 130ms/step - accuracy: 0.1047 - loss: nan - val_accuracy: 0.1200 - val_loss: nan\nEpoch 30/30\n\u001b[1m6/6\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m1s\u001b[0m 130ms/step - accuracy: 0.1302 - loss: nan - val_accuracy: 0.1200 - val_loss: nan\n","output_type":"stream"}],"execution_count":17},{"cell_type":"code","source":"import numpy as np\n\nprint(\"Any NaNs in X_train?\", np.isnan(X_train).any())\nprint(\"Any Infs in X_train?\", np.isinf(X_train).any())\n\n# Optionally, replace them\nX_train = np.nan_to_num(X_train, nan=0.0, posinf=0.0, neginf=0.0)\nX_test = np.nan_to_num(X_test, nan=0.0, posinf=0.0, neginf=0.0)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-07-12T21:27:10.197533Z","iopub.execute_input":"2025-07-12T21:27:10.198072Z","iopub.status.idle":"2025-07-12T21:27:10.206398Z","shell.execute_reply.started":"2025-07-12T21:27:10.198048Z","shell.execute_reply":"2025-07-12T21:27:10.205772Z"}},"outputs":[{"name":"stdout","text":"Any NaNs in X_train? True\nAny Infs in X_train? False\n","output_type":"stream"}],"execution_count":18},{"cell_type":"code","source":"# Optionally, replace them\nX_train = np.nan_to_num(X_train, nan=0.0, posinf=0.0, neginf=0.0)\nX_test = np.nan_to_num(X_test, nan=0.0, posinf=0.0, neginf=0.0)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-07-12T21:27:30.358232Z","iopub.execute_input":"2025-07-12T21:27:30.358955Z","iopub.status.idle":"2025-07-12T21:27:30.364861Z","shell.execute_reply.started":"2025-07-12T21:27:30.358928Z","shell.execute_reply":"2025-07-12T21:27:30.364087Z"}},"outputs":[],"execution_count":19},{"cell_type":"code","source":"print(\"Any NaNs in y_train?\", np.isnan(y_train).any())\nprint(\"Any Infs in y_train?\", np.isinf(y_train).any())\nprint(\"y_train sample:\\n\", y_train[:5])","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-07-12T21:27:37.787712Z","iopub.execute_input":"2025-07-12T21:27:37.788021Z","iopub.status.idle":"2025-07-12T21:27:37.793818Z","shell.execute_reply.started":"2025-07-12T21:27:37.787998Z","shell.execute_reply":"2025-07-12T21:27:37.793276Z"}},"outputs":[{"name":"stdout","text":"Any NaNs in y_train? False\nAny Infs in y_train? False\ny_train sample:\n [[0. 1. 0. 0. 0. 0.]\n [0. 0. 0. 0. 0. 1.]\n [0. 0. 0. 0. 1. 0.]\n [0. 0. 0. 0. 1. 0.]\n [0. 0. 0. 0. 0. 1.]]\n","output_type":"stream"}],"execution_count":20},{"cell_type":"code","source":"import tensorflow as tf\nfrom tensorflow.keras.models import Sequential\nfrom tensorflow.keras.layers import Conv2D, MaxPooling2D, Flatten, Dense, Dropout, BatchNormalization\n\n# Ensure TensorFlow sees both GPUs\ngpus = tf.config.list_physical_devices('GPU')\nif gpus:\n    print(\"GPUs detected:\", gpus)\n    try:\n        for gpu in gpus:\n            tf.config.experimental.set_memory_growth(gpu, True)\n    except RuntimeError as e:\n        print(e)\n\n# Create a strategy for multiple GPUs\nstrategy = tf.distribute.MirroredStrategy()\n\n# Print number of GPUs being used\nprint(\"Number of GPUs available:\", strategy.num_replicas_in_sync)\n\n# Build model inside the strategy scope\nwith strategy.scope():\n    input_shape = X_train.shape[1:]  # (4, time_bins, 1)\n    num_classes = y_cat.shape[1]\n\n    model = Sequential()\n    model.add(Conv2D(32, (2, 3), activation='relu', padding='same', input_shape=input_shape))\n    model.add(BatchNormalization())\n    model.add(MaxPooling2D(pool_size=(1, 2)))\n\n    model.add(Conv2D(64, (2, 3), activation='relu', padding='same'))\n    model.add(BatchNormalization())\n    model.add(MaxPooling2D(pool_size=(1, 2)))\n\n    model.add(Conv2D(128, (2, 3), activation='relu', padding='same'))\n    model.add(BatchNormalization())\n    model.add(MaxPooling2D(pool_size=(1, 2)))\n\n    model.add(Flatten())\n    model.add(Dense(128, activation='relu'))\n    model.add(Dropout(0.5))\n    model.add(Dense(num_classes, activation='softmax'))\n\n    model.compile(\n        optimizer='adam',\n        loss='categorical_crossentropy',\n        metrics=['accuracy']\n    )\n\n# Optional: print model summary\nmodel.summary()\n\n# Train the model\nhistory = model.fit(\n    X_train, y_train,\n    validation_data=(X_test, y_test),\n    epochs=30,\n    batch_size=64,  # Larger batch size to utilize both GPUs\n    verbose=1\n)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-07-12T21:27:59.212005Z","iopub.execute_input":"2025-07-12T21:27:59.212282Z","iopub.status.idle":"2025-07-12T21:28:29.107479Z","shell.execute_reply.started":"2025-07-12T21:27:59.212262Z","shell.execute_reply":"2025-07-12T21:28:29.106707Z"}},"outputs":[{"name":"stdout","text":"GPUs detected: [PhysicalDevice(name='/physical_device:GPU:0', device_type='GPU'), PhysicalDevice(name='/physical_device:GPU:1', device_type='GPU')]\nNumber of GPUs available: 2\n","output_type":"stream"},{"output_type":"display_data","data":{"text/plain":"\u001b[1mModel: \"sequential_1\"\u001b[0m\n","text/html":"<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\"><span style=\"font-weight: bold\">Model: \"sequential_1\"</span>\n</pre>\n"},"metadata":{}},{"output_type":"display_data","data":{"text/plain":"┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┓\n┃\u001b[1m \u001b[0m\u001b[1mLayer (type)                   \u001b[0m\u001b[1m \u001b[0m┃\u001b[1m \u001b[0m\u001b[1mOutput Shape          \u001b[0m\u001b[1m \u001b[0m┃\u001b[1m \u001b[0m\u001b[1m      Param #\u001b[0m\u001b[1m \u001b[0m┃\n┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━┩\n│ conv2d_3 (\u001b[38;5;33mConv2D\u001b[0m)               │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m4\u001b[0m, \u001b[38;5;34m100\u001b[0m, \u001b[38;5;34m32\u001b[0m)     │           \u001b[38;5;34m224\u001b[0m │\n├─────────────────────────────────┼────────────────────────┼───────────────┤\n│ batch_normalization_3           │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m4\u001b[0m, \u001b[38;5;34m100\u001b[0m, \u001b[38;5;34m32\u001b[0m)     │           \u001b[38;5;34m128\u001b[0m │\n│ (\u001b[38;5;33mBatchNormalization\u001b[0m)            │                        │               │\n├─────────────────────────────────┼────────────────────────┼───────────────┤\n│ max_pooling2d_3 (\u001b[38;5;33mMaxPooling2D\u001b[0m)  │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m4\u001b[0m, \u001b[38;5;34m50\u001b[0m, \u001b[38;5;34m32\u001b[0m)      │             \u001b[38;5;34m0\u001b[0m │\n├─────────────────────────────────┼────────────────────────┼───────────────┤\n│ conv2d_4 (\u001b[38;5;33mConv2D\u001b[0m)               │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m4\u001b[0m, \u001b[38;5;34m50\u001b[0m, \u001b[38;5;34m64\u001b[0m)      │        \u001b[38;5;34m12,352\u001b[0m │\n├─────────────────────────────────┼────────────────────────┼───────────────┤\n│ batch_normalization_4           │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m4\u001b[0m, \u001b[38;5;34m50\u001b[0m, \u001b[38;5;34m64\u001b[0m)      │           \u001b[38;5;34m256\u001b[0m │\n│ (\u001b[38;5;33mBatchNormalization\u001b[0m)            │                        │               │\n├─────────────────────────────────┼────────────────────────┼───────────────┤\n│ max_pooling2d_4 (\u001b[38;5;33mMaxPooling2D\u001b[0m)  │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m4\u001b[0m, \u001b[38;5;34m25\u001b[0m, \u001b[38;5;34m64\u001b[0m)      │             \u001b[38;5;34m0\u001b[0m │\n├─────────────────────────────────┼────────────────────────┼───────────────┤\n│ conv2d_5 (\u001b[38;5;33mConv2D\u001b[0m)               │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m4\u001b[0m, \u001b[38;5;34m25\u001b[0m, \u001b[38;5;34m128\u001b[0m)     │        \u001b[38;5;34m49,280\u001b[0m │\n├─────────────────────────────────┼────────────────────────┼───────────────┤\n│ batch_normalization_5           │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m4\u001b[0m, \u001b[38;5;34m25\u001b[0m, \u001b[38;5;34m128\u001b[0m)     │           \u001b[38;5;34m512\u001b[0m │\n│ (\u001b[38;5;33mBatchNormalization\u001b[0m)            │                        │               │\n├─────────────────────────────────┼────────────────────────┼───────────────┤\n│ max_pooling2d_5 (\u001b[38;5;33mMaxPooling2D\u001b[0m)  │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m4\u001b[0m, \u001b[38;5;34m12\u001b[0m, \u001b[38;5;34m128\u001b[0m)     │             \u001b[38;5;34m0\u001b[0m │\n├─────────────────────────────────┼────────────────────────┼───────────────┤\n│ flatten_1 (\u001b[38;5;33mFlatten\u001b[0m)             │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m6144\u001b[0m)           │             \u001b[38;5;34m0\u001b[0m │\n├─────────────────────────────────┼────────────────────────┼───────────────┤\n│ dense_2 (\u001b[38;5;33mDense\u001b[0m)                 │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m128\u001b[0m)            │       \u001b[38;5;34m786,560\u001b[0m │\n├─────────────────────────────────┼────────────────────────┼───────────────┤\n│ dropout_1 (\u001b[38;5;33mDropout\u001b[0m)             │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m128\u001b[0m)            │             \u001b[38;5;34m0\u001b[0m │\n├─────────────────────────────────┼────────────────────────┼───────────────┤\n│ dense_3 (\u001b[38;5;33mDense\u001b[0m)                 │ (\u001b[38;5;45mNone\u001b[0m, \u001b[38;5;34m6\u001b[0m)              │           \u001b[38;5;34m774\u001b[0m │\n└─────────────────────────────────┴────────────────────────┴───────────────┘\n","text/html":"<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\">┏━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━━━━━━━━━━┳━━━━━━━━━━━━━━━┓\n┃<span style=\"font-weight: bold\"> Layer (type)                    </span>┃<span style=\"font-weight: bold\"> Output Shape           </span>┃<span style=\"font-weight: bold\">       Param # </span>┃\n┡━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━━━━━━━━━━╇━━━━━━━━━━━━━━━┩\n│ conv2d_3 (<span style=\"color: #0087ff; text-decoration-color: #0087ff\">Conv2D</span>)               │ (<span style=\"color: #00d7ff; text-decoration-color: #00d7ff\">None</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">4</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">100</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">32</span>)     │           <span style=\"color: #00af00; text-decoration-color: #00af00\">224</span> │\n├─────────────────────────────────┼────────────────────────┼───────────────┤\n│ batch_normalization_3           │ (<span style=\"color: #00d7ff; text-decoration-color: #00d7ff\">None</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">4</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">100</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">32</span>)     │           <span style=\"color: #00af00; text-decoration-color: #00af00\">128</span> │\n│ (<span style=\"color: #0087ff; text-decoration-color: #0087ff\">BatchNormalization</span>)            │                        │               │\n├─────────────────────────────────┼────────────────────────┼───────────────┤\n│ max_pooling2d_3 (<span style=\"color: #0087ff; text-decoration-color: #0087ff\">MaxPooling2D</span>)  │ (<span style=\"color: #00d7ff; text-decoration-color: #00d7ff\">None</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">4</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">50</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">32</span>)      │             <span style=\"color: #00af00; text-decoration-color: #00af00\">0</span> │\n├─────────────────────────────────┼────────────────────────┼───────────────┤\n│ conv2d_4 (<span style=\"color: #0087ff; text-decoration-color: #0087ff\">Conv2D</span>)               │ (<span style=\"color: #00d7ff; text-decoration-color: #00d7ff\">None</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">4</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">50</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">64</span>)      │        <span style=\"color: #00af00; text-decoration-color: #00af00\">12,352</span> │\n├─────────────────────────────────┼────────────────────────┼───────────────┤\n│ batch_normalization_4           │ (<span style=\"color: #00d7ff; text-decoration-color: #00d7ff\">None</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">4</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">50</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">64</span>)      │           <span style=\"color: #00af00; text-decoration-color: #00af00\">256</span> │\n│ (<span style=\"color: #0087ff; text-decoration-color: #0087ff\">BatchNormalization</span>)            │                        │               │\n├─────────────────────────────────┼────────────────────────┼───────────────┤\n│ max_pooling2d_4 (<span style=\"color: #0087ff; text-decoration-color: #0087ff\">MaxPooling2D</span>)  │ (<span style=\"color: #00d7ff; text-decoration-color: #00d7ff\">None</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">4</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">25</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">64</span>)      │             <span style=\"color: #00af00; text-decoration-color: #00af00\">0</span> │\n├─────────────────────────────────┼────────────────────────┼───────────────┤\n│ conv2d_5 (<span style=\"color: #0087ff; text-decoration-color: #0087ff\">Conv2D</span>)               │ (<span style=\"color: #00d7ff; text-decoration-color: #00d7ff\">None</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">4</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">25</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">128</span>)     │        <span style=\"color: #00af00; text-decoration-color: #00af00\">49,280</span> │\n├─────────────────────────────────┼────────────────────────┼───────────────┤\n│ batch_normalization_5           │ (<span style=\"color: #00d7ff; text-decoration-color: #00d7ff\">None</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">4</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">25</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">128</span>)     │           <span style=\"color: #00af00; text-decoration-color: #00af00\">512</span> │\n│ (<span style=\"color: #0087ff; text-decoration-color: #0087ff\">BatchNormalization</span>)            │                        │               │\n├─────────────────────────────────┼────────────────────────┼───────────────┤\n│ max_pooling2d_5 (<span style=\"color: #0087ff; text-decoration-color: #0087ff\">MaxPooling2D</span>)  │ (<span style=\"color: #00d7ff; text-decoration-color: #00d7ff\">None</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">4</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">12</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">128</span>)     │             <span style=\"color: #00af00; text-decoration-color: #00af00\">0</span> │\n├─────────────────────────────────┼────────────────────────┼───────────────┤\n│ flatten_1 (<span style=\"color: #0087ff; text-decoration-color: #0087ff\">Flatten</span>)             │ (<span style=\"color: #00d7ff; text-decoration-color: #00d7ff\">None</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">6144</span>)           │             <span style=\"color: #00af00; text-decoration-color: #00af00\">0</span> │\n├─────────────────────────────────┼────────────────────────┼───────────────┤\n│ dense_2 (<span style=\"color: #0087ff; text-decoration-color: #0087ff\">Dense</span>)                 │ (<span style=\"color: #00d7ff; text-decoration-color: #00d7ff\">None</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">128</span>)            │       <span style=\"color: #00af00; text-decoration-color: #00af00\">786,560</span> │\n├─────────────────────────────────┼────────────────────────┼───────────────┤\n│ dropout_1 (<span style=\"color: #0087ff; text-decoration-color: #0087ff\">Dropout</span>)             │ (<span style=\"color: #00d7ff; text-decoration-color: #00d7ff\">None</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">128</span>)            │             <span style=\"color: #00af00; text-decoration-color: #00af00\">0</span> │\n├─────────────────────────────────┼────────────────────────┼───────────────┤\n│ dense_3 (<span style=\"color: #0087ff; text-decoration-color: #0087ff\">Dense</span>)                 │ (<span style=\"color: #00d7ff; text-decoration-color: #00d7ff\">None</span>, <span style=\"color: #00af00; text-decoration-color: #00af00\">6</span>)              │           <span style=\"color: #00af00; text-decoration-color: #00af00\">774</span> │\n└─────────────────────────────────┴────────────────────────┴───────────────┘\n</pre>\n"},"metadata":{}},{"output_type":"display_data","data":{"text/plain":"\u001b[1m Total params: \u001b[0m\u001b[38;5;34m850,086\u001b[0m (3.24 MB)\n","text/html":"<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\"><span style=\"font-weight: bold\"> Total params: </span><span style=\"color: #00af00; text-decoration-color: #00af00\">850,086</span> (3.24 MB)\n</pre>\n"},"metadata":{}},{"output_type":"display_data","data":{"text/plain":"\u001b[1m Trainable params: \u001b[0m\u001b[38;5;34m849,638\u001b[0m (3.24 MB)\n","text/html":"<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\"><span style=\"font-weight: bold\"> Trainable params: </span><span style=\"color: #00af00; text-decoration-color: #00af00\">849,638</span> (3.24 MB)\n</pre>\n"},"metadata":{}},{"output_type":"display_data","data":{"text/plain":"\u001b[1m Non-trainable params: \u001b[0m\u001b[38;5;34m448\u001b[0m (1.75 KB)\n","text/html":"<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\"><span style=\"font-weight: bold\"> Non-trainable params: </span><span style=\"color: #00af00; text-decoration-color: #00af00\">448</span> (1.75 KB)\n</pre>\n"},"metadata":{}},{"name":"stdout","text":"Epoch 1/30\n\u001b[1m6/6\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m5s\u001b[0m 303ms/step - accuracy: 0.1592 - loss: 2.6504 - val_accuracy: 0.2467 - val_loss: 3654.8308\nEpoch 2/30\n\u001b[1m6/6\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m1s\u001b[0m 122ms/step - accuracy: 0.2920 - loss: 2.7310 - val_accuracy: 0.2733 - val_loss: 4.0555\nEpoch 3/30\n\u001b[1m6/6\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m1s\u001b[0m 127ms/step - accuracy: 0.3615 - loss: 1.6000 - val_accuracy: 0.3000 - val_loss: 3.5739\nEpoch 4/30\n\u001b[1m6/6\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m1s\u001b[0m 122ms/step - accuracy: 0.3816 - loss: 1.7513 - val_accuracy: 0.3000 - val_loss: 5.0027\nEpoch 5/30\n\u001b[1m6/6\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m1s\u001b[0m 129ms/step - accuracy: 0.3776 - loss: 1.4969 - val_accuracy: 0.3000 - val_loss: 6.2611\nEpoch 6/30\n\u001b[1m6/6\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m1s\u001b[0m 125ms/step - accuracy: 0.3712 - loss: 1.6715 - val_accuracy: 0.3000 - val_loss: 8.1133\nEpoch 7/30\n\u001b[1m6/6\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m1s\u001b[0m 123ms/step - accuracy: 0.4288 - loss: 1.4113 - val_accuracy: 0.2933 - val_loss: 7.7365\nEpoch 8/30\n\u001b[1m6/6\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m1s\u001b[0m 201ms/step - accuracy: 0.4476 - loss: 1.3529 - val_accuracy: 0.3067 - val_loss: 1.7176\nEpoch 9/30\n\u001b[1m6/6\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m1s\u001b[0m 123ms/step - accuracy: 0.4705 - loss: 1.4503 - val_accuracy: 0.3067 - val_loss: 1.7027\nEpoch 10/30\n\u001b[1m6/6\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m1s\u001b[0m 123ms/step - accuracy: 0.4247 - loss: 1.3580 - val_accuracy: 0.3067 - val_loss: 1.7095\nEpoch 11/30\n\u001b[1m6/6\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m1s\u001b[0m 125ms/step - accuracy: 0.4812 - loss: 1.2613 - val_accuracy: 0.3067 - val_loss: 1.7068\nEpoch 12/30\n\u001b[1m6/6\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m1s\u001b[0m 127ms/step - accuracy: 0.4935 - loss: 1.1867 - val_accuracy: 0.2533 - val_loss: 1.8186\nEpoch 13/30\n\u001b[1m6/6\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m1s\u001b[0m 125ms/step - accuracy: 0.5493 - loss: 1.1733 - val_accuracy: 0.1533 - val_loss: 1.9378\nEpoch 14/30\n\u001b[1m6/6\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m1s\u001b[0m 135ms/step - accuracy: 0.5618 - loss: 1.1602 - val_accuracy: 0.1667 - val_loss: 1.7382\nEpoch 15/30\n\u001b[1m6/6\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m1s\u001b[0m 125ms/step - accuracy: 0.4234 - loss: 1.3860 - val_accuracy: 0.1733 - val_loss: 1.7707\nEpoch 16/30\n\u001b[1m6/6\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m1s\u001b[0m 128ms/step - accuracy: 0.4464 - loss: 1.4809 - val_accuracy: 0.3133 - val_loss: 1.6903\nEpoch 17/30\n\u001b[1m6/6\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m1s\u001b[0m 123ms/step - accuracy: 0.5644 - loss: 1.1245 - val_accuracy: 0.3133 - val_loss: 1.6902\nEpoch 18/30\n\u001b[1m6/6\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m1s\u001b[0m 124ms/step - accuracy: 0.4367 - loss: 1.3497 - val_accuracy: 0.3133 - val_loss: 1.6888\nEpoch 19/30\n\u001b[1m6/6\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m1s\u001b[0m 124ms/step - accuracy: 0.3962 - loss: 1.4695 - val_accuracy: 0.3133 - val_loss: 1.6971\nEpoch 20/30\n\u001b[1m6/6\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m1s\u001b[0m 124ms/step - accuracy: 0.6114 - loss: 0.9973 - val_accuracy: 0.3133 - val_loss: 1.6968\nEpoch 21/30\n\u001b[1m6/6\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m1s\u001b[0m 122ms/step - accuracy: 0.5850 - loss: 1.1456 - val_accuracy: 0.3133 - val_loss: 1.6978\nEpoch 22/30\n\u001b[1m6/6\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m1s\u001b[0m 122ms/step - accuracy: 0.6517 - loss: 0.9122 - val_accuracy: 0.3133 - val_loss: 1.7101\nEpoch 23/30\n\u001b[1m6/6\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m1s\u001b[0m 123ms/step - accuracy: 0.6363 - loss: 0.8970 - val_accuracy: 0.3133 - val_loss: 1.7083\nEpoch 24/30\n\u001b[1m6/6\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m1s\u001b[0m 122ms/step - accuracy: 0.6745 - loss: 0.8549 - val_accuracy: 0.3133 - val_loss: 1.7055\nEpoch 25/30\n\u001b[1m6/6\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m1s\u001b[0m 128ms/step - accuracy: 0.6466 - loss: 1.0571 - val_accuracy: 0.2800 - val_loss: 1.7062\nEpoch 26/30\n\u001b[1m6/6\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m1s\u001b[0m 141ms/step - accuracy: 0.6793 - loss: 0.8777 - val_accuracy: 0.2800 - val_loss: 1.7133\nEpoch 27/30\n\u001b[1m6/6\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m1s\u001b[0m 129ms/step - accuracy: 0.4940 - loss: 1.2448 - val_accuracy: 0.2267 - val_loss: 1.7251\nEpoch 28/30\n\u001b[1m6/6\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m1s\u001b[0m 123ms/step - accuracy: 0.5089 - loss: 1.2318 - val_accuracy: 0.1733 - val_loss: 1.7767\nEpoch 29/30\n\u001b[1m6/6\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m1s\u001b[0m 121ms/step - accuracy: 0.7243 - loss: 0.8114 - val_accuracy: 0.1733 - val_loss: 1.8658\nEpoch 30/30\n\u001b[1m6/6\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m1s\u001b[0m 227ms/step - accuracy: 0.6301 - loss: 0.8849 - val_accuracy: 0.1733 - val_loss: 1.8191\n","output_type":"stream"}],"execution_count":21},{"cell_type":"code","source":"from sklearn.metrics import classification_report, confusion_matrix\nimport numpy as np\n\n# Step 1: Predict on the test set\ny_pred_probs = model.predict(X_test)\ny_pred = np.argmax(y_pred_probs, axis=1)\ny_true = np.argmax(y_test, axis=1)\n\n# Step 2: Decode the label indices back to original class names\nclass_names = le.classes_\n\n# Step 3: Print classification report\nprint(classification_report(y_true, y_pred, target_names=class_names))\n\n# Optional: Confusion matrix\nimport seaborn as sns\nimport matplotlib.pyplot as plt\n\ncm = confusion_matrix(y_true, y_pred)\nplt.figure(figsize=(8, 6))\nsns.heatmap(cm, annot=True, fmt='d', xticklabels=class_names, yticklabels=class_names, cmap='Blues')\nplt.xlabel('Predicted')\nplt.ylabel('True')\nplt.title('Confusion Matrix')\nplt.show()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-07-12T21:29:57.011587Z","iopub.execute_input":"2025-07-12T21:29:57.012217Z","iopub.status.idle":"2025-07-12T21:29:58.934247Z","shell.execute_reply.started":"2025-07-12T21:29:57.012192Z","shell.execute_reply":"2025-07-12T21:29:58.933442Z"}},"outputs":[{"name":"stdout","text":"\u001b[1m3/3\u001b[0m \u001b[32m━━━━━━━━━━━━━━━━━━━━\u001b[0m\u001b[37m\u001b[0m \u001b[1m1s\u001b[0m 192ms/step\n              precision    recall  f1-score   support\n\n         GPD       0.12      1.00      0.22        10\n        GRDA       0.00      0.00      0.00         9\n         LPD       1.00      0.33      0.50         9\n        LRDA       0.00      0.00      0.00        14\n       Other       1.00      0.10      0.17        21\n     Seizure       0.00      0.00      0.00        23\n\n    accuracy                           0.17        86\n   macro avg       0.35      0.24      0.15        86\nweighted avg       0.36      0.17      0.12        86\n\n","output_type":"stream"},{"output_type":"display_data","data":{"text/plain":"<Figure size 800x600 with 2 Axes>","image/png":"iVBORw0KGgoAAAANSUhEUgAAAoAAAAIjCAYAAACTRapjAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjcuMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8pXeV/AAAACXBIWXMAAA9hAAAPYQGoP6dpAABeMUlEQVR4nO3dd3gU5ff38c8mJJuEhBACJBRNgGjoTaSIUqSEYqGIgA0QsdE0ghSlRTE/ESmKgAoCIjYUsYOIIqKIhV6ligihhAQIpEAyzx887Nc1ARLYzexm3i+vuS53ZnbmzLkWPZy55x6bYRiGAAAAYBk+ZgcAAACAwkUBCAAAYDEUgAAAABZDAQgAAGAxFIAAAAAWQwEIAABgMRSAAAAAFkMBCAAAYDEUgAAAABZDAQjgknbu3Km2bdsqNDRUNptNixcvdunx9+3bJ5vNprlz57r0uN6sRYsWatGihdlhACjCKAABL7B792498sgjqly5sgICAlSiRAk1bdpUU6dOVXp6ulvP3atXL23atEnjx4/X/Pnz1aBBA7eerzD17t1bNptNJUqUyDOPO3fulM1mk81m08SJEwt8/IMHD2rs2LFav369C6IFANcpZnYAAC7tyy+/VLdu3WS32/XAAw+oZs2aysrK0qpVqzR06FBt2bJFb7zxhlvOnZ6ertWrV+uZZ57RgAED3HKOqKgopaeny8/Pzy3Hv5xixYrpzJkz+vzzz3X33Xc7bVuwYIECAgKUkZFxRcc+ePCgxo0bp+joaNWtWzff3/vmm2+u6HwAkF8UgIAH27t3r3r06KGoqCh99913KleunGNb//79tWvXLn355ZduO//Ro0clSSVLlnTbOWw2mwICAtx2/Mux2+1q2rSp3nvvvVwF4LvvvquOHTvq448/LpRYzpw5o6CgIPn7+xfK+QBYF7eAAQ82YcIEpaWlafbs2U7F3wUxMTEaPHiw4/O5c+f03HPPqUqVKrLb7YqOjtbIkSOVmZnp9L3o6GjddtttWrVqlRo2bKiAgABVrlxZb7/9tmOfsWPHKioqSpI0dOhQ2Ww2RUdHSzp/6/TCv//b2LFjZbPZnNYtW7ZMN998s0qWLKng4GDFxsZq5MiRju0XGwP43Xff6ZZbblHx4sVVsmRJ3Xnnndq2bVue59u1a5d69+6tkiVLKjQ0VH369NGZM2cuntj/uOeee/T1118rNTXVse63337Tzp07dc899+Ta//jx4xoyZIhq1aql4OBglShRQu3bt9eGDRsc+6xYsUI33nijJKlPnz6OW8kXrrNFixaqWbOm/vjjDzVr1kxBQUGOvPx3DGCvXr0UEBCQ6/rj4uIUFhamgwcP5vtaAUCiAAQ82ueff67KlSvrpptuytf+Dz30kEaPHq369etr8uTJat68uRITE9WjR49c++7atUt33XWX2rRpo5dffllhYWHq3bu3tmzZIknq0qWLJk+eLEnq2bOn5s+frylTphQo/i1btui2225TZmamEhIS9PLLL+uOO+7QTz/9dMnvffvtt4qLi9ORI0c0duxYxcfH6+eff1bTpk21b9++XPvffffdOnXqlBITE3X33Xdr7ty5GjduXL7j7NKli2w2mxYtWuRY9+6776pq1aqqX79+rv337NmjxYsX67bbbtOkSZM0dOhQbdq0Sc2bN3cUY9WqVVNCQoIk6eGHH9b8+fM1f/58NWvWzHGc5ORktW/fXnXr1tWUKVPUsmXLPOObOnWqypQpo169eik7O1uS9Prrr+ubb77Rq6++qvLly+f7WgFAkmQA8EgnTpwwJBl33nlnvvZfv369Icl46KGHnNYPGTLEkGR89913jnVRUVGGJGPlypWOdUeOHDHsdrvx1FNPOdbt3bvXkGS89NJLTsfs1auXERUVlSuGMWPGGP/+z8rkyZMNScbRo0cvGveFc8yZM8exrm7dukbZsmWN5ORkx7oNGzYYPj4+xgMPPJDrfA8++KDTMTt37myEh4df9Jz/vo7ixYsbhmEYd911l9GqVSvDMAwjOzvbiIyMNMaNG5dnDjIyMozs7Oxc12G3242EhATHut9++y3XtV3QvHlzQ5Ixc+bMPLc1b97cad3SpUsNScbzzz9v7NmzxwgODjY6dep02WsEgLzQAQQ81MmTJyVJISEh+dr/q6++kiTFx8c7rX/qqackKddYwerVq+uWW25xfC5TpoxiY2O1Z8+eK475vy6MHfz000+Vk5OTr+8cOnRI69evV+/evVWqVCnH+tq1a6tNmzaO6/y3Rx991OnzLbfcouTkZEcO8+Oee+7RihUrlJSUpO+++05JSUl53v6Vzo8b9PE5/5/P7OxsJScnO25vr127Nt/ntNvt6tOnT772bdu2rR555BElJCSoS5cuCggI0Ouvv57vcwHAv1EAAh6qRIkSkqRTp07la/+//vpLPj4+iomJcVofGRmpkiVL6q+//nJaf+211+Y6RlhYmFJSUq4w4ty6d++upk2b6qGHHlJERIR69OihDz/88JLF4IU4Y2Njc22rVq2ajh07ptOnTzut/++1hIWFSVKBrqVDhw4KCQnRBx98oAULFujGG2/MlcsLcnJyNHnyZF133XWy2+0qXbq0ypQpo40bN+rEiRP5PmeFChUK9MDHxIkTVapUKa1fv16vvPKKypYtm+/vAsC/UQACHqpEiRIqX768Nm/eXKDv/fchjIvx9fXNc71hGFd8jgvj0y4IDAzUypUr9e233+r+++/Xxo0b1b17d7Vp0ybXvlfjaq7lArvdri5dumjevHn65JNPLtr9k6QXXnhB8fHxatasmd555x0tXbpUy5YtU40aNfLd6ZTO56cg1q1bpyNHjkiSNm3aVKDvAsC/UQACHuy2227T7t27tXr16svuGxUVpZycHO3cudNp/eHDh5Wamup4otcVwsLCnJ6YveC/XUZJ8vHxUatWrTRp0iRt3bpV48eP13fffafvv/8+z2NfiHPHjh25tm3fvl2lS5dW8eLFr+4CLuKee+7RunXrdOrUqTwfnLngo48+UsuWLTV79mz16NFDbdu2VevWrXPlJL/FeH6cPn1affr0UfXq1fXwww9rwoQJ+u2331x2fADWQgEIeLCnn35axYsX10MPPaTDhw/n2r57925NnTpV0vlbmJJyPak7adIkSVLHjh1dFleVKlV04sQJbdy40bHu0KFD+uSTT5z2O378eK7vXpgQ+b9T01xQrlw51a1bV/PmzXMqqDZv3qxvvvnGcZ3u0LJlSz333HOaNm2aIiMjL7qfr69vru7iwoUL9c8//zitu1Co5lUsF9SwYcO0f/9+zZs3T5MmTVJ0dLR69ep10TwCwKUwETTgwapUqaJ3331X3bt3V7Vq1ZzeBPLzzz9r4cKF6t27tySpTp066tWrl9544w2lpqaqefPm+vXXXzVv3jx16tTpolOMXIkePXpo2LBh6ty5swYNGqQzZ85oxowZuv76650egkhISNDKlSvVsWNHRUVF6ciRI5o+fboqVqyom2+++aLHf+mll9S+fXs1adJEffv2VXp6ul599VWFhoZq7NixLruO//Lx8dGzzz572f1uu+02JSQkqE+fPrrpppu0adMm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AAEAgOUxBhAAAABFGh1AAABgeRZrAFIAAgAAcAsYAAAARRodQAAAYHkWawAWzQKwZulQs0MAcjmYkmF2CEVC+bAAs0MAAK9XJAtAAACAgmAMIAAAAIo0CkAAAGB5Npv7loJauXKlbr/9dpUvX142m02LFy922t67d2/ZbDanpV27dgU6BwUgAACABzl9+rTq1Kmj11577aL7tGvXTocOHXIs7733XoHOwRhAAABgee4cA5iZmanMzEyndXa7XXa7Pc/927dvr/bt21/ymHa7XZGRkVccEx1AAABgee68BZyYmKjQ0FCnJTEx8ariXbFihcqWLavY2Fg99thjSk5OLtD36QACAAC40YgRIxQfH++07mLdv/xo166dunTpokqVKmn37t0aOXKk2rdvr9WrV8vX1zdfx6AABAAAlufOW8CXut17JXr06OH491q1aql27dqqUqWKVqxYoVatWuXrGNwCBgAA8GKVK1dW6dKltWvXrnx/hw4gAACwPG+eCPrAgQNKTk5WuXLl8v0dCkAAAAAPkpaW5tTN27t3r9avX69SpUqpVKlSGjdunLp27arIyEjt3r1bTz/9tGJiYhQXF5fvc1AAAgAAy/OkBuDvv/+uli1bOj5feICkV69emjFjhjZu3Kh58+YpNTVV5cuXV9u2bfXcc88VaJwhBSAAAIAHadGihQzDuOj2pUuXXvU5KAABAIDlefMYwCtBAQgAACzPYvUf08AAAABYDR1AAABgeVa7BUwHEAAAwGLoAAIAAMuzWAOQDiAAAIDV0AEEAACW52OxFiAdQAAAAIuhAwgAACzPYg1ACkAAAACmgQEAAECRRgcQAABYno+1GoB0AAEAAKyGDiAAALA8xgAWstOnT2v06NGqWbOmgoODFRISotq1ayshIUFnzpwxOzwAAIAix9QOYFZWlpo3b67Nmzerffv2uv3222UYhrZt26bx48fr66+/1sqVK+Xn52dmmAAAoIizWAPQ3AJwxowZOnDggDZs2KDY2Finbdu3b1eLFi00c+ZMDRw40KQIAQAAih5TbwEvWrRIo0aNylX8SVLVqlX1zDPP6KOPPjIhMgAAYCU2N/7jiUwtALdu3aoWLVpcdHvLli21devWwguoEKQcO6I3J47RoJ5t9WiX5hrd/17t27nN7LC81vvvLlD7Nrfqxnq1dG+Pbtq0caPZIXmdLz75UI/1uktd2t6kLm1v0pOP3K/fVq8yOyyvxW/Sdcila5DH/PGxuW/xRKYWgKmpqQoPD7/o9vDwcJ04caIQI3Kv02knlfj0w/ItVkxPjJ2s56a/p7v7DlJQcIjZoXmlJV9/pYkTEvXI4/31/sJPFBtbVY890lfJyclmh+ZVSpcpqz6PDtars9/TK7PeVZ36DZUwYrD+2rPL7NC8Dr9J1yGXrkEecTGmFoA5OTny9fW96HYfHx9lZ2cXYkTu9fVH81WqdIQefGKUKsfWUJnI8qpZv5HKlqtodmheaf68Oepy193q1LmrqsTE6Nkx4xQQEKDFiz42OzSv0vjmFmrY5BZVuCZKFa+NVu9HBiogMEjbt9IlKCh+k65DLl2DPOafzWZz2+KJTH0IxDAMtWrVSsWK5R3GuXPnCjki91q/5kfVrN9Y0xNH6s/N61QyvIxaduii5u06mR2a1zmblaVtW7eob79HHOt8fHzUuPFN2rhhnYmRebfs7Gz9+P03yshIV9UadcwOx6vwm3Qdcuka5BGXYmoBOGbMmMvu07Vr10tuz8zMVGZmptO6rKxM+fvbryo2dziadFDff7VIbTv1VMe7e2nfzm16743JKubnp6atOpodnldJSU1RdnZ2riEE4eHh2rt3j0lRea+9u3cq/tH7lZWVpcDAII16YbKiKlUxOyyvwm/Sdcila5DHgvHQRp3beHwBeDmJiYkaN26c07o+A57Wg4OGX/WxXc0wchQdU01dez0mSYqqEqt//tqtFV99QgEIU1W8NlqvzflQp9PStGrFMr08fpQmvDqbIhAAiijTXwX3yy+/6PPPP1dWVpZatWqldu3aFej7I0aMUHx8vNO63//2zDeIhIaVVvlro53WlbsmWn/8tMKUeLxZWMkw+fr65hrInJycrNKlS5sUlffy8/NT+YrXSpKuq1pdf27bok8XLtCgp0ebHJn34DfpOuTSNchjwfhYrAVo6kMgH330kZo2baqpU6dq1qxZ6tixoyZOnFigY9jtdpUoUcJp8cTbv5J0XfXaSjqw32nd4X/+VnjZSJMi8l5+/v6qVr2G1vyy2rEuJydHa9asVu069UyMrGgwjBydPXvW7DC8Cr9J1yGXrkEecSmmFoCJiYnq16+fTpw4oZSUFD3//PN64YUXzAzJrdrc2UN7dmzWlx/O1eGDf+uXFUv1w5LFurXjpcc5Im/39+qjRR99qM8Wf6I9u3fr+YSxSk9PV6fOXcwOzavMmTlVm9b/ocOH/tHe3Ts1Z+ZUbVz3u1q27WB2aF6H36TrkEvXII/5Z7O5b/FENsMwDLNOHhwcrPXr1ysmJkbS+XcDFy9eXP/884/Kli17xcddtTPFVSG63IZfV+njeTN0+ODfKhNRTm069fTop4AbVAozO4RLem/BO5o3Z7aOHTuq2KrVNGzks6pd2zOfXj2YkmF2CHmanDhG6//4VceTj6p48WBVqnK9ut3XR/VvbGJ2aHkqHxZgdgiX5E2/SU9HLl3Dm/IYYOLAtLvmrHXbsT/qU99tx75SphaAPj4+SkpKcir2QkJCtGHDBlWuXPmKj+vJBaC38fQC0Jt4agHobTy9AARw5SgAC4/pD4HMmjVLwcHBjs/nzp3T3LlznQaoDho0yIzQAACARXjqrVp3MbUDGB0dfdkZsm02m/bsKdh8RXQAXYcOoOvQAXQNOoBA0WVmB7DbXPd1ABf2pgPoZN++fZfcfuDAASUkJBROMAAAwLKYBsaDJCcna/bs2WaHAQAAUKSYPgYQAADAbNbq/3l4BxAAAACuRwcQAABY3uUeSi1qTC0Au3S59EzkqamphRMIAACwNB9r1X/mFoChoaGX3f7AAw8UUjQAAADWYGoBOGfOHDNPDwAAIMl6t4B5CAQAAMBieAgEAABYnsUagHQAAQAArIYOIAAAsDzGAAIAAKBIowMIAAAsj3kAAQAALIZbwAAAACjS6AACAADLs1b/jw4gAACA5VxRAfjjjz/qvvvuU5MmTfTPP/9IkubPn69Vq1a5NDgAAIDC4GOzuW3xRAUuAD/++GPFxcUpMDBQ69atU2ZmpiTpxIkTeuGFF1weIAAAAFyrwAXg888/r5kzZ+rNN9+Un5+fY33Tpk21du1alwYHAABQGGw29y2eqMAF4I4dO9SsWbNc60NDQ5WamuqKmAAAAOBGBS4AIyMjtWvXrlzrV61apcqVK7skKAAAgMJks9nctniiAheA/fr10+DBg7VmzRrZbDYdPHhQCxYs0JAhQ/TYY4+5I0YAAAC4UIHnARw+fLhycnLUqlUrnTlzRs2aNZPdbteQIUM0cOBAd8QIAADgVh7aqHObAheANptNzzzzjIYOHapdu3YpLS1N1atXV3BwsDviAwAAcDtPna7FXa74TSD+/v6qXr26K2MBAABAIShwAdiyZctLDmj87rvvriogAACAwmaxBmDBC8C6des6fT579qzWr1+vzZs3q1evXq6KCwAAAG5S4AJw8uTJea4fO3as0tLSrjogAACAwuap07W4yxW9Czgv9913n9566y1XHQ4AAABucsUPgfzX6tWrFRAQ4KrDXZXx3/5pdghFxif9GpkdQpFRPswz/nwAAHJzWUfMSxS4AOzSpYvTZ8MwdOjQIf3+++8aNWqUywIDAACAexS4AAwNDXX67OPjo9jYWCUkJKht27YuCwwAAKCwWG0MYIEKwOzsbPXp00e1atVSWFiYu2ICAAAoVD7Wqv8Kdsvb19dXbdu2VWpqqpvCAQAAgLsVeMxjzZo1tWfPHnfEAgAAYAofm/sWT1TgAvD555/XkCFD9MUXX+jQoUM6efKk0wIAAADPlu8xgAkJCXrqqafUoUMHSdIdd9zhNGDSMAzZbDZlZ2e7PkoAAAA34iGQixg3bpweffRRff/99+6MBwAAAG6W7wLQMAxJUvPmzd0WDAAAgBk8dayeuxRoDKDV2qMAAABFUYHmAbz++usvWwQeP378qgICAAAobFbrcRWoABw3blyuN4EAAAB4Ox+LVYAFKgB79OihsmXLuisWAAAAFIJ8F4CM/wMAAEVVgSdG9nL5vt4LTwEDAADAu+W7A5iTk+POOAAAAExjtRudVut4AgAAWF6BHgIBAAAoiqz2FDAdQAAAAIuhAwgAACzPYg1ACkAAAADeBQwAAIAizeM7gMePH1epUqXMDgMAABRhPATiIb755hvdfffdqlChgtmhAAAAFCkeVQD+9ddfGjNmjKKjo9WtWzf5+Pjo7bffNjssAABQxNls7ls8kekFYFZWlt5//321bt1aVatW1dq1a3XgwAGtWrVK77//vrp162Z2iAAAAIVm5cqVuv3221W+fHnZbDYtXrzYabthGBo9erTKlSunwMBAtW7dWjt37izQOUwtAAcOHKjy5ctr6tSp6ty5sw4cOKDPP/9cNptNvr6+ZoYGAAAsxMfmvqWgTp8+rTp16ui1117Lc/uECRP0yiuvaObMmVqzZo2KFy+uuLg4ZWRk5Pscpj4EMmPGDA0bNkzDhw9XSEiImaEAAAB4hPbt26t9+/Z5bjMMQ1OmTNGzzz6rO++8U5L09ttvKyIiQosXL1aPHj3ydQ5TO4Dz58/Xr7/+qnLlyql79+764osvlJ2dbWZIAADAgmxu/CczM1MnT550WjIzM68ozr179yopKUmtW7d2rAsNDVWjRo20evXqfB/H1AKwZ8+eWrZsmTZt2qSqVauqf//+ioyMVE5OjrZu3WpmaAAAwELceQs4MTFRoaGhTktiYuIVxZmUlCRJioiIcFofERHh2Jav672is7tYpUqVNG7cOO3bt0/vvPOOunbtqvvuu08VK1bUoEGDzA4PAADgio0YMUInTpxwWkaMGGFqTB41EbTNZlNcXJzi4uKUnJys+fPna86cOWaHBQAAijh3vgrObrfLbre75FiRkZGSpMOHD6tcuXKO9YcPH1bdunXzfRyP6ABK0rFjx/T777/rjz/+UHJyssLDw/XEE09ow4YNZod2xWqWC9HY9tfrnQfq6evHGqlJdNhF9x3QLFpfP9ZInWpHFmKE3u/9dxeofZtbdWO9Wrq3Rzdt2rjR7JC8Enl0HXLpOuTSNchj0VKpUiVFRkZq+fLljnUnT57UmjVr1KRJk3wfx/QCcMuWLWrWrJkiIiLUqFEjNWzYUGXLltWtt96qHTt2mB3eVQnw89Ge5DOa/uO+S+53U6UwVY0I1rG0rMIJrIhY8vVXmjghUY883l/vL/xEsbFV9dgjfZWcnGx2aF6FPLoOuXQdcuka5DH/bDab25aCSktL0/r167V+/XpJ5x/8WL9+vfbv3y+bzaYnnnhCzz//vD777DNt2rRJDzzwgMqXL69OnTrl+xymFoBJSUlq3ry5jh49qkmTJumrr77Sl19+qZdeekmHDh3SLbfcoiNHjpgZ4lX5ff8Jvf3rAf28N+Wi+4QX99NjN0drwre7lZ1jFGJ03m/+vDnqctfd6tS5q6rExOjZMeMUEBCgxYs+Njs0r0IeXYdcug65dA3y6J1+//131atXT/Xq1ZMkxcfHq169eho9erQk6emnn9bAgQP18MMP68Ybb1RaWpqWLFmigICAfJ/D1AJw8uTJioqK0rp16zR48GDFxcWpXbt2io+P19q1a3XNNddo8uTJZoboVjZJQ1pV0UfrD2p/SrrZ4XiVs1lZ2rZ1ixo3ucmxzsfHR40b36SNG9aZGJl3IY+uQy5dh1y6BnksGE+aCLpFixYyDCPXMnfuXEnnu5UJCQlKSkpSRkaGvv32W11//fUFu96Ch+U6y5Yt07Bhw/KsWAMDAzV06FAtXbr0ksfIa26dnLPecSu1W73yysmRPt102OxQvE5Kaoqys7MVHh7utD48PFzHjh0zKSrvQx5dh1y6Drl0DfKISzG1ANyzZ4/q169/0e0NGjTQnj17LnmMvObW2b10nqtDdbmY0kG6s3aEXv5ut9mhAABgeTab+xZPZOo0MKdOnVKJEiUuuj0kJERpaWmXPMaIESMUHx/vtK7bXM9/crhm+RIqGeint++v51jn62PTQ02uVadakeq9YL15wXmBsJJh8vX1zTWQOTk5WaVLlzYpKu9DHl2HXLoOuXQN8lgwPp5aqbmJ6U8Bnzp1Ktct3H8vhnHpByPsdrtKlCjhtPj4+RdS9Fdu+Y5jevzDTeq/8H/LsbQsfbz+kJ75crvZ4Xk8P39/VateQ2t++d9rb3JycrRmzWrVrlPvEt/Ev5FH1yGXrkMuXYM84lJM7QAahnHJQYuGYVzR49OeIqCYj8qH/m98Y0QJuyqHB+lU5jkdTcvSqcxzTvtn5xhKST+rf1IzCjtUr3R/rz4aNXKYatSoqZq1auud+fOUnp6uTp27mB2aVyGPrkMuXYdcugZ5zD93TgTtiUwtAL///nszT+9215Utrgl3Vnd8fqRplCRp2fajmvT9pcc24vLate+glOPHNX3aKzp27Khiq1bT9NdnKZxbGwVCHl2HXLoOuXQN8oiLsRmXu8fqhdrPWGN2CEXGJ/0amR0CAMAiAkxsS7360163HXtg00puO/aVMn0M4KWsXbtWt912m9lhAAAAFCmmF4BLly7VkCFDNHLkSMeUL9u3b1enTp104403Kicnx+QIAQBAUecjm9sWT2TqGMDZs2erX79+KlWqlFJSUjRr1ixNmjRJAwcOVPfu3bV582ZVq1bNzBABAACKHFM7gFOnTtWLL76oY8eO6cMPP9SxY8c0ffp0bdq0STNnzqT4AwAAhYKJoAvR7t271a1bN0lSly5dVKxYMb300kuqWLGimWEBAACLsdo0MKZ2ANPT0xUUFCTp/IuN7Xa7ypUrZ2ZIAAAARZ6pHUBJmjVrloKDgyVJ586d09y5c3O9ombQoEFmhAYAACzCaq+CM3UewOjo6Mu+6cNmszmeDs4v5gF0HeYBBAAUFjPnAXzjl7/cduyHG0e57dhXytQO4L59+y65/cCBA0pISCicYAAAgGVZrAFo/jyAl5KcnKzZs2ebHQYAAECRYvoYQAAAALNZbQygR3cAAQAA4Hp0AAEAgOVZrAFobgHYpUuXS25PTU0tnEAAAIClWe2WqKkFYGho6GW3P/DAA4UUDQAAgDWYWgDOmTPHzNMDAABI0mXnJS5qrNbxBAAAsDweAgEAAJZnrf4fHUAAAADLoQMIAAAsj4mgAQAAUKTRAQQAAJZnrf4fBSAAAIDl3gTCLWAAAACLoQMIAAAsj4mgAQAAUKTRAQQAAJZntY6Y1a4XAADA8ugAAgAAy2MMIAAAAIo0OoAAAMDyrNX/owMIAABgOXQAAQCA5VltDGCRLAB/Xb3H7BCKjn6NzI4AgJuknM4yO4QiI6y4v9kh4CpZ7Zao1a4XAADA8opkBxAAAKAgrHYLmA4gAACAxdABBAAAlmet/h8dQAAAAMuhAwgAACzPYkMA6QACAABYDR1AAABgeT4WGwVIAQgAACyPW8AAAAAo0ugAAgAAy7NZ7BYwHUAAAACLoQMIAAAsjzGAAAAAKNLoAAIAAMuz2jQwdAABAAAshg4gAACwPKuNAaQABAAAlme1ApBbwAAAABZDBxAAAFgeE0EXonPnzuntt9/W4cOHzQwDAADAUkwtAIsVK6ZHH31UGRkZZoYBAAAszsfmvsUTmT4GsGHDhlq/fr3ZYQAAAFiG6WMAH3/8ccXHx+vvv//WDTfcoOLFizttr127tkmRAQAAq7DaGEDTC8AePXpIkgYNGuRYZ7PZZBiGbDabsrOzzQoNAACgSDK9ANy7d6/ZIQAAAIuz2jyApheAUVFRZocAAAAszmq3gE1/CESS5s+fr6ZNm6p8+fL666+/JElTpkzRp59+anJkAAAARY/pBeCMGTMUHx+vDh06KDU11THmr2TJkpoyZYq5wQEAAEtgGphC9uqrr+rNN9/UM888I19fX8f6Bg0aaNOmTSZGBgAAUDSZPgZw7969qlevXq71drtdp0+fNiEiAABgNYwBLGSVKlXKcyLoJUuWqFq1aoUfEAAAQBFnegcwPj5e/fv3V0ZGhgzD0K+//qr33ntPiYmJmjVrltnhXZUmsWU0oEM11Y0OU2RYkO6fslJfrf3Hsb1MiQCN6V5HLWtGqkSQv1bvOKrh83/XnsNpJkbtXd5/d4HmzZmtY8eO6vrYqho+cpRqMXl4gZFH1yGXV2/B3Fla+f232v/XXtntAapRq44eGfikro2qZHZoXonfZP5YbRoY0zuADz30kF588UU9++yzOnPmjO655x7NmDFDU6dOdUwS7a2C7MW0ZX+Knn77jzy3z3/iFkWVCdZ9U35Uy1FL9Pex01o07FYF+fvmuT+cLfn6K02ckKhHHu+v9xd+otjYqnrskb5KTk42OzSvQh5dh1y6xvq1v6tTtx6aPnuBJr76hrKzz2nowEeUnn7G7NC8Dr9JXIzNMAzD7CAuOHPmjNLS0lS2bNmrOk74A++5KCLXSX67p1MHsEpkiH6dcJtuGvGldvxzUtL5v31se7Wznl+4Qe/8sMfMcB3+eaun2SFc1L09uqlGzVoa+exoSVJOTo7atmqunvfcr779HjY5Ou9BHl3H23KZcjrL7BDyJTXluDrFNdfUmXNUp34Ds8PJU1hxf7NDyJO3/SYDTLwv+dPOFLcdu+l1YW479pUyvQP4b0FBQVdd/HkL/2LnU595NsexzjCkrLPZanx9GbPC8hpns7K0besWNW5yk2Odj4+PGje+SRs3rDMxMu9CHl2HXLpPWtr5YTEhoaEmR+Jd+E0WjI/N5rbFE5leAB4+fFj333+/ypcvr2LFisnX19dpuZzMzEydPHnSaTGyzxZC5Fdn56GT+vvYaY3qVkehQX7y8/XRoI7VVCG8uCJKBpodnsdLSU1Rdna2wsPDndaHh4fr2LFjJkXlfcij65BL98jJydG0SS+qZp16qlzlOrPD8Sr8JnEppj8E0rt3b+3fv1+jRo1SuXLlZCtgpZyYmKhx48Y5rQuo3UVBde5yZZgudy7bUK9XftTUvo20Z+ZdOpedox+2HNayDQct9iA6AFzclAnjtXfPLr36xjyzQ0ERZ7X/95peAK5atUo//vij6tate0XfHzFihOLj453WRT+2+OoDKwQb9qWoxaglCgn0k38xHyWfytQ3Y9po/d7jZofm8cJKhsnX1zfXQObk5GSVLl3apKi8D3l0HXLpelNeGq/Vq37QK6/PVdmISLPD8Tr8JnEppt8Cvuaaa3Q1z6HY7XaVKFHCabH5+rkwQvc7lX5WyacyVTkiWHUrlXKaKgZ58/P3V7XqNbTml9WOdTk5OVqzZrVq18k9sTjyRh5dh1y6jmEYmvLSeK1a8Z0mT5+tchUqmh2SV+I3WUA2Ny4eyPQO4JQpUzR8+HC9/vrrio6ONjsclypuL6ZKEcGOz9eWCVbNa0sq5XSW/kk+oztuvEbJpzJ1IPm0ql9TUi/cW19f/fGPVmxOMjFq73F/rz4aNXKYatSoqZq1auud+fOUnp6uTp27mB2aVyGPrkMuXWPKhPH6dulXGj9xqgKDiiv5/49XCw4Olj0gwOTovAu/SVyMKQVgWFiY01i/06dPq0qVKgoKCpKfn3P37vhx770dWrdSKX02spXj8/h760uS3vtxjwa8uUaRJQP1/D31VCY0QIdTM/TBT3s1cfEWs8L1Ou3ad1DK8eOaPu0VHTt2VLFVq2n667MUzq2NAiGPrkMuXePTjz+QJD3x6INO64eNfk7tb+tkQkTei99k/lntVXCmzAM4b17+B/P26tWrwMf3xHkAvZUnzwMI4Op4yzyA3sBT5wH0NmbOA7hm9wm3HbtRFc+bwsiUVF9JUQcAAOAuHjpdn9uY/hCIr6+vjhw5kmt9cnJyvuYBBAAAuFoWewbE/ALwYnegMzMz5e9PSx0AAMDVTLvb/sorr0iSbDabZs2apeDg/z0tm52drZUrV6pq1apmhQcAAKzEU1t1bmJaATh58mRJ5zuAM2fOdLrd6+/vr+joaM2cOdOs8AAAAIos0wrAvXv3SpJatmypRYsW6dy5c7LZbMxODgAACp2nTAMzduzYXK+4jY2N1fbt2116HlPHAKampqpatWq67rrrFBkZqYiICJUuXVoDBgxQamqqmaEBAACYokaNGjp06JBjWbVqlcvPYVoH8Pjx42rSpIn++ecf3XvvvapWrZokaevWrZo7d66WL1+un3/+WWFhYWaFCAAALMKTpoEpVqyYIiPd+/5r0wrAhIQE+fv7a/fu3YqIiMi1rW3btkpISHCMFQQAAPBGmZmZyszMdFpnt9tlt9vz3H/nzp0qX768AgIC1KRJEyUmJuraa691aUym3QJevHixJk6cmKv4k6TIyEhNmDBBn3zyiQmRAQAAq3HnPICJiYkKDQ11WhITE/OMo1GjRpo7d66WLFmiGTNmaO/evbrlllt06tQp116vGa+Ck85Xvrt371bFihXz3H7gwAHFxMQoIyOjwMfmVXCuw6vggKKLV8G5Dq+Ccw0zXwW39q+Tbjt2jUh7gTqA/5aamqqoqChNmjRJffv2dVlMpqW6dOnS2rdv30ULwL1796pUqVKFHBUAAIBr5bfYy0vJkiV1/fXXa9euXS6NybRbwHFxcXrmmWeUlZX7b6CZmZkaNWqU2rVrZ0JkAADAamxu/OdqpKWlaffu3SpXrpyLrvQ8Ux8CadCgga677jr1799fVatWlWEY2rZtm6ZPn67MzEzNnz/frPAAAAAK3ZAhQ3T77bcrKipKBw8e1JgxY+Tr66uePV07JMu0ArBixYpavXq1Hn/8cY0YMcLxTmCbzaY2bdpo2rRpuuaaa8wKDwAAWIinTANz4MAB9ezZU8nJySpTpoxuvvlm/fLLLypTpoxLz2PicEupUqVK+vrrr5WSkqKdO3dKkmJiYhj7BwAALOn9998vlPOYWgBeEBYWpoYNG5odBgAAsCgPaQAWGlNfBQcAAIDC5xEdQAAAAFNZrAVIAQgAACzvaqdr8TbcAgYAALAYOoAAAMDyPGUamMJCBxAAAMBi6AACAADLs1gDkA4gAACA1dABBAAAsFgLkA4gAACAxdABBAAAlsc8gAAAACjS6AACAADLs9o8gBSAAADA8ixW/3ELGAAAwGroAAIAAFisBVgkC8Azm34yO4QipKfZAQBwk7Di/maHAMAkRbIABAAAKAimgQEAAECRRgcQAABYntWmgaEDCAAAYDF0AAEAgOVZrAFIAQgAAGC1CpBbwAAAABZDBxAAAFge08AAAACgSKMDCAAALI9pYAAAAFCk0QEEAACWZ7EGIB1AAAAAq6EDCAAAYLEWoEd0AFNTUzVr1iyNGDFCx48flyStXbtW//zzj8mRAQAAK7C58R9PZHoHcOPGjWrdurVCQ0O1b98+9evXT6VKldKiRYu0f/9+vf3222aHCAAAUKSY3gGMj49X7969tXPnTgUEBDjWd+jQQStXrjQxMgAAYBU2m/sWT2R6Afjbb7/pkUceybW+QoUKSkpKMiEiAACAos30W8B2u10nT57Mtf7PP/9UmTJlTIgIAABYjYc26tzG9A7gHXfcoYSEBJ09e1aSZLPZtH//fg0bNkxdu3Y1OToAAICix/QC8OWXX1ZaWprKli2r9PR0NW/eXDExMQoJCdH48ePNDg8AAFiBzY2LBzL9FnBoaKiWLVumn376SRs2bFBaWprq16+v1q1bmx0aAABAkWRqAXj27FkFBgZq/fr1atq0qZo2bWpmOAAAwKI8db4+dzG1APTz89O1116r7OxsM8MAAAAW56nTtbiL6WMAn3nmGY0cOdLxBhAAAAC4l+ljAKdNm6Zdu3apfPnyioqKUvHixZ22r1271qTIAACAVVisAWh+AdipUyezQwAAALAU0wvAMWPGmB0CAACwOMYAAgAAoEgzvQPo4+Mj2yXKbp4QBgAA7metFqDpBeAnn3zi9Pns2bNat26d5s2bp3HjxpkUFQAAQNFlegF455135lp31113qUaNGvrggw/Ut29fE6ICAABWwhhAD9G4cWMtX77c7DCuypAH22rVO0N1ZNVE/bU8UR9O6qfroso67fPqMz205bMxOr56kvZ/l6gPJz+s66MjTIrY+7z/7gK1b3OrbqxXS/f26KZNGzeaHZJXIo+uQy5dh1y6BnnMH4u9CtgzC8D09HS98sorqlChgtmhXJVb6sdo5gcr1fyBibrtsWkqVsxXX8wYoKAAf8c+67b9rYfHvqO6XZ7XHY+/JpvNpi+m95ePj6f+ZDzHkq+/0sQJiXrk8f56f+Enio2tqsce6avk5GSzQ/Mq5NF1yKXrkEvXII+4GJthGIaZAYSFhTk9BGIYhk6dOqWgoCC98847uuOOOwp8zMB6A1wZosuUDgvW39/9n1r3nayf1u7Oc5+a15XXbx+OVPXbx2rvgWOFHGFuKb9NMzuEi7q3RzfVqFlLI58dLUnKyclR21bN1fOe+9W338MmR+c9yKPrkEvXIZeu4W15DDBxYNqhE1luO3a5UP/L71TITB8DOHnyZKcC0MfHR2XKlFGjRo0UFhZmYmSuVyI4QJKUcuJMntuDAvz1wB2NtffAMR1ISinM0LzO2awsbdu6RX37PeJY5+Pjo8aNb9LGDetMjMy7kEfXIZeuQy5dgzziUkwvAHv37n1V38/MzFRmZqbTOiMnWzYf36s6rqvZbDa9NOQu/bxut7buPuS07eFut2j8E50UHGTXjr1J6vjYNJ09x/Q3l5KSmqLs7GyFh4c7rQ8PD9fevXtMisr7kEfXIZeuQy5dgzwWjM1jR+u5h+ljACtXrqw+ffrkKuKOHTumypUrX/b7iYmJCg0NdVrOHf7DXeFesSkj7laNmHJ6YPicXNve//o3Ne55/tbwzv1H9c6LD8rub3ptDgAAiijTC8B9+/bpp59+0i233KKkpCTH+uzsbP3111+X/f6IESN04sQJp6VYxA3uDLnAJg/rpg631FRcv1f0z5HUXNtPpmVo9/6j+mntbt0zZJZiK0XozlvrFH6gXiSsZJh8fX1zDWROTk5W6dKlTYrK+5BH1yGXrkMuXYM8FpDFHgM2vQC02WxasmSJKlasqBtuuEG//fZbgb5vt9tVokQJp8WTbv9OHtZNd9xaR+0eeUV/Hbz8U1c2m0022eTvRwfwUvz8/VWteg2t+WW1Y11OTo7WrFmt2nXqmRiZdyGPrkMuXYdcugZ5xKWYXmUYhqHg4GAtWrRII0aMUPPmzfXGG2+oTZs2Zod21aaMuFvd2zdQtyffUNrpDEWEh0iSTqRlKCPzrKIrhOuuuBu0fPU2HUtJU4WIknqqT1ulZ57V0lVbTI7e893fq49GjRymGjVqqmat2npn/jylp6erU+cuZofmVcij65BL1yGXrkEe889DG3VuY3oB+O8ngBMTE1WjRg3169dPPXv2NDEq13jk7maSpGWznnBa32/0fL3z+RplZp1T03pVNOCeFgorEaQjyae0au0utez9so6mpJkQsXdp176DUo4f1/Rpr+jYsaOKrVpN01+fpXBubRQIeXQdcuk65NI1yGP+We1NIKbPA+jj46OkpCSVLfu/N2SsXr1anTt31tGjR5WdXfCnYT11HkBv5MnzAAIAihYz5wE8cuqs245dNsTPbce+UqZ3AHNycnKta9KkiTZs2KDt27ebEBEAALAaq00DY3oBeDERERGKiOCduAAAAK5mSgFYv359LV++XGFhYapXr57TOMD/Wrt2bSFGBgAALMlaDUBzCsA777xTdrtdktSpUyczQgAAALAs0x8CcQceAnEdHgIBABQWMx8COZZ2zm3HLh3seSPuTJ8IWpJSU1M1a9YsjRgxQsePH5d0/tbvP//8Y3JkAAAARY/pJenGjRvVunVrhYaGat++ferXr59KlSqlRYsWaf/+/Xr77bfNDhEAABRxVpsH0PQOYHx8vHr37q2dO3cqICDAsb5Dhw5auXKliZEBAACrsLnxH09kegH422+/6ZFHHsm1vkKFCkpKSjIhIgAAgKLN9FvAdrtdJ0+ezLX+zz//VJkyZUyICAAAWA23gAvZHXfcoYSEBJ09e/4VLDabTfv379ewYcPUtWtXk6MDAAAoekwvAF9++WWlpaWpbNmySk9PV/PmzVWlShUFBwdr/PjxZocHAABQ5Jh+Czg0NFTLli3TqlWrtHHjRqWlpemGG25Qq1atzA4NAACgSDKtA7h69Wp98cUXjs8333yzihcvrunTp6tnz556+OGHlZmZaVZ4AADAQmw29y2eyLQCMCEhQVu2bHF83rRpk/r166c2bdpo+PDh+vzzz5WYmGhWeAAAAEWWaQXg+vXrnW7zvv/++2rYsKHefPNNxcfH65VXXtGHH35oVngAAMBCrDYPoGljAFNSUhQREeH4/MMPP6h9+/aOzzfeeKP+/vtvM0IDAAAW46m3at3FtA5gRESE9u7dK0nKysrS2rVr1bhxY8f2U6dOyc/Pz6zwAAAAiizTCsAOHTpo+PDh+vHHHzVixAgFBQXplltucWzfuHGjqlSpYlZ4AADAQmxuXDyRabeAn3vuOXXp0kXNmzdXcHCw5s2bJ39/f8f2t956S23btjUrPAAAgCLLZhiGYWYAJ06cUHBwsHx9fZ3WHz9+XMHBwU5FYX4F1hvgqvAsL+W3aWaHAACwiAATZyc+lZnjtmOH2E1/70YuHjERdF5KlSpVyJEAAABYg+kFIAAAgNk8dboWd/G8niQAAADcig4gAACwPOYBBAAAQJFGBxAAAFiexRqAFIAAAABWqwC5BQwAAGAxFIAAAMDybG7850q89tprio6OVkBAgBo1aqRff/3VpddLAQgAAOBBPvjgA8XHx2vMmDFau3at6tSpo7i4OB05csRl56AABAAAlmezuW8pqEmTJqlfv37q06ePqlevrpkzZyooKEhvvfWWy66XAhAAAMCNMjMzdfLkSaclMzMzz32zsrL0xx9/qHXr1o51Pj4+at26tVavXu26oAyYIiMjwxgzZoyRkZFhdihejTy6Drl0HXLpGuTRdcilucaMGWNIclrGjBmT577//POPIcn4+eefndYPHTrUaNiwoctishmGYbiunER+nTx5UqGhoTpx4oRKlChhdjheizy6Drl0HXLpGuTRdciluTIzM3N1/Ox2u+x2e659Dx48qAoVKujnn39WkyZNHOuffvpp/fDDD1qzZo1LYmIeQAAAADe6WLGXl9KlS8vX11eHDx92Wn/48GFFRka6LCbGAAIAAHgIf39/3XDDDVq+fLljXU5OjpYvX+7UEbxadAABAAA8SHx8vHr16qUGDRqoYcOGmjJlik6fPq0+ffq47BwUgCax2+0aM2ZMvlvCyBt5dB1y6Trk0jXIo+uQS+/SvXt3HT16VKNHj1ZSUpLq1q2rJUuWKCIiwmXn4CEQAAAAi2EMIAAAgMVQAAIAAFgMBSAAAIDFUAACADzK3LlzVbJkSbPD8Dpjx45V3bp1zQ4DXoIC0EWSkpI0ePBgxcTEKCAgQBEREWratKlmzJihM2fOSJKio6Nls9lks9lUvHhx1a9fXwsXLnQcY+zYsY7txYoVU+nSpdWsWTNNmTLlou8M9HYFzVtQUJBq1aqlWbNmOR1nxYoVjn18fHwUGhqqevXq6emnn9ahQ4fyPPd7770nX19f9e/f3+3XaZbevXurU6dOeW7j95i3/OaM3+Ll/f3333rwwQdVvnx5+fv7KyoqSoMHD1ZycrJjn+joaE2ZMsW8ID3I0aNH9dhjj+naa6+V3W5XZGSk4uLi9NNPP+Xr+0OGDHGaOw64FApAF9izZ4/q1aunb775Ri+88ILWrVun1atX6+mnn9YXX3yhb7/91rFvQkKCDh06pHXr1unGG29U9+7d9fPPPzu216hRQ4cOHdL+/fv1/fffq1u3bkpMTNRNN92kU6dOmXF5bnMledu8ebPuu+8+9evXT19//XWuY+7YsUMHDx7Ub7/9pmHDhunbb79VzZo1tWnTplz7zp49W08//bTee+89ZWRkuPVaPRW/x4Ljt5g/e/bsUYMGDbRz506999572rVrl2bOnOmYzPb48eOFHtPZs2cL/ZwF0bVrV61bt07z5s3Tn3/+qc8++0wtWrRwKpgvJTg4WOHh4W6LLysry23Hhglc9lZhC4uLizMqVqxopKWl5bk9JyfHMAzDiIqKMiZPnuxYf/bsWSMoKMgYPny4YRjnXxZdp06dXN/ftm2b4e/vbzzzzDMuj91MV5o3wzCMUqVKGU8++aTj8/fff29IMlJSUpz2O3PmjBEbG2s0bdrUaf2ePXuMwMBAIzU11WjUqJGxYMGCq78gD9SrVy/jzjvvzHMbv8e8FSRnhsFv8WLatWtnVKxY0Thz5ozT+kOHDhlBQUHGo48+ajRv3tyQ5LQYhmHMmTPHCA0NNZYsWWJUrVrVKF68uBEXF2ccPHjQ6VhvvvmmUbVqVcNutxuxsbHGa6+95ti2d+9eQ5Lx/vvvG82aNTPsdrsxZ84ct1/3lUpJSTEkGStWrLjkPn379jVKly5thISEGC1btjTWr1/v2P7fP7P/za0kIyoqyjCM/+X43z755BPj32XBheO9+eabRnR0tGGz2fIVB7wDHcCrlJycrG+++Ub9+/dX8eLF89zHZrPlub5YsWLy8/O77N+qqlatqvbt22vRokVXHa+nuNK85eTk6OOPP1ZKSor8/f0ve57AwEA9+uij+umnn3TkyBHH+jlz5qhjx44KDQ3Vfffdp9mzZ1/5xRQRVv49Xgl+ixd3/PhxLV26VI8//rgCAwOdtkVGRuree+/VBx98oI8//lgVK1Z0dFX/fYv8zJkzmjhxoubPn6+VK1dq//79GjJkiGP7ggULNHr0aI0fP17btm3TCy+8oFGjRmnevHlO5xs+fLgGDx6sbdu2KS4uzr0XfhWCg4MVHBysxYsXX3SIRbdu3XTkyBF9/fXX+uOPP1S/fn21atXqot3UCzk9dOiQdu3apZiYGDVr1qxAce3atUsff/yxFi1apPXr119RHPBMFIBXadeuXTIMQ7GxsU7rS5cu7fgDPWzYsFzfy8rKUmJiok6cOKFbb731suepWrWq9u3b56qwTVfQvA0bNkzBwcGy2+266667FBYWpoceeihf56pataokOfKXk5OjuXPn6r777pMk9ejRQ6tWrdLevXtdcGXeyeq/x4Lgt3h5O3fulGEYqlatWp7bq1WrppSUFGVnZ8vX11chISGKjIx0etH92bNnNXPmTDVo0ED169fXgAEDnMa3jRkzRi+//LK6dOmiSpUqqUuXLnryySf1+uuvO53riSeecOxTrlw591ywCxQrVkxz587VvHnzVLJkSTVt2lQjR47Uxo0bJUmrVq3Sr7/+qoULF6pBgwa67rrrNHHiRJUsWVIfffRRnse8kNOIiAgNHTpUoaGhufJzOVlZWXr77bdVr1491a5d+4rigGeiAHSTX3/9VevXr1eNGjWc/jZ34X8eQUFBevHFF/V///d/6tix42WPZxjGRTuJRcnF8jZ06FCtX79e3333nRo1aqTJkycrJiYmX8c0/v/Lbi7kb9myZTp9+rQ6dOgg6XzR2aZNG7311lsuvhrPx++x4Pgt5p9xFS+aCgoKUpUqVRyfy5Ur5+icnj59Wrt371bfvn0df2EMDg7W888/r927dzsdp0GDBlccQ2Hr2rWrDh48qM8++0zt2rXTihUrVL9+fc2dO1cbNmxQWlqawsPDna557969ua75v0aOHKnVq1fr008/zdWRvZyoqCiVKVPG8flq4oBn4V3AVykmJkY2m007duxwWl+5cmVJyvWHbejQoerdu7eCg4MVERGR7/+Jbtu2TZUqVXJN0B6goHkrXbq0YmJiFBMTo4ULF6pWrVpq0KCBqlevftlzbdu2TdL5pw2l8wPujx8/7nSOnJwcbdy4UePGjZOPj3X+XsTvseD4LV7ehT/f27ZtU+fOnXNt37Ztm8LCwpwKi//y8/Nz+myz2RwFZVpamiTpzTffVKNGjZz28/X1dfp8sSEmniogIEBt2rRRmzZtNGrUKD300EMaM2aMHn/8cZUrV04rVqzI9Z1LTZnzzjvvaPLkyVqxYoUqVKjgWO/j45OrQM/rIZn/5i8tLe2K4oDn8c7/uniQ8PBwtWnTRtOmTdPp06cvu/+F/3lERkbm+3+227dv15IlS9S1a9erDddjFDRv/3bNNdeoe/fuGjFixGX3TU9P1xtvvKFmzZqpTJkySk5O1qeffqr3339f69evdyzr1q1TSkqKvvnmmyu9JK/E7/Hq8FvM24U/39OnT1d6errTtqSkJC1YsEDdu3eXzWaTv7+/srOzC3T8iIgIlS9fXnv27HEU4xeWovYXk+rVq+v06dOqX7++kpKSVKxYsVzXXLp06Ty/u3r1aj300EN6/fXX1bhxY6dtZcqU0alTp5z++3thjN+lXEkc8Ex0AF1g+vTpatq0qRo0aKCxY8eqdu3a8vHx0W+//abt27frhhtuyPexzp07p6SkJOXk5Cg5OVkrVqzQ888/r7p162ro0KFuvIrCdzV5Gzx4sGrWrKnff//d6RbPkSNHlJGRoVOnTumPP/7QhAkTdOzYMccDC/Pnz1d4eLjuvvvuXAVPhw4dNHv2bLVr1849F2ySEydO5PoPe36nirDS7/HfCpIzfot5mzZtmm666SbFxcXp+eefV6VKlbRlyxYNHTpUFSpU0Pjx4yWd74auXLlSPXr0kN1uz3cRMW7cOA0aNEihoaFq166dMjMz9fvvvyslJUXx8fHuvDS3SE5OVrdu3fTggw+qdu3aCgkJ0e+//64JEybozjvvVOvWrdWkSRN16tRJEyZM0PXXX6+DBw/qyy+/VOfOnXPd6k5KSlLnzp3Vo0cPxcXFKSkpSdL5DmmZMmXUqFEjBQUFaeTIkRo0aJDWrFmjuXPnXjbOgsYBD2bW48dFzcGDB40BAwYYlSpVMvz8/Izg4GCjYcOGxksvvWScPn3aMIy8p5D4tzFjxjge1ff19TVKlSpl3HzzzcbkyZONjIyMQrqSwnU1eYuLizPat29vGMb/pt6QZNhsNiMkJMSoU6eOMXToUOPQoUOO79SqVct4/PHH84zlgw8+MPz9/Y2jR4+6/kJN0qtXrzyngujbty+/x4u4kpzxW8zbvn37jF69ehkRERGGn5+fcc011xgDBw40jh075thn9erVRu3atQ273Z5rGph/++8UJYZhGAsWLDDq1q1r+Pv7G2FhYUazZs2MRYsWGYbxv2lg1q1b59ZrdJWMjAxj+PDhRv369Y3Q0FAjKCjIiI2NNZ599lnHVDonT540Bg4caJQvX96Rz3vvvdfYv3+/YRjO08D8+3f47+XCNDCGcT6nMTExRmBgoHHbbbcZb7zxRp7TwPzX5eKAd7AZxlWM0gUAAIDXYQwgAACAxVAAAgAAWAwFIAAAgMVQAAIAAFgMBSAAAIDFUAACAABYDAUgAACAxVAAAgAAWAwFIACP1bt3b3Xq1MnxuUWLFnriiScKPY4VK1bIZrMpNTW10M8NAO5AAQigwHr37i2bzSabzSZ/f3/FxMQoISFB586dc+t5Fy1apOeeey5f+1K0AcDFFTM7AADeqV27dpozZ44yMzP11VdfqX///vLz89OIESOc9svKypK/v79LzlmqVCmXHAcArI4OIIArYrfbFRkZqaioKD322GNq3bq1PvvsM8dt2/Hjx6t8+fKKjY2VJP3999+6++67VbJkSZUqVUp33nmn9u3b5zhedna24uPjVbJkSYWHh+vpp5/Wf19V/t9bwJmZmRo2bJiuueYa2e12xcTEaPbs2dq3b59atmwpSQoLC5PNZlPv3r0lSTk5OUpMTFSlSpUUGBioOnXq6KOPPnI6z1dffaXrr79egYGBatmypVOcAFAUUAACcInAwEBlZWVJkpYvX64dO3Zo2bJl+uKLL3T27FnFxcUpJCREP/74o3766ScFBwerXbt2ju+8/PLLmjt3rt566y2tWrVKx48f1yeffHLJcz7wwAN677339Morr2jbtm16/fXXFRwcrGuuuUYff/yxJGnHjh06dOiQpk6dKklKTEzU22+/rZkzZ2rLli168skndd999+mHH36QdL5Q7dKli26//XatX79eDz30kIYPH+6utAGAKbgFDOCqGIah5cuXa+nSpRo4cKCOHj2q4sWLa9asWY5bv++8845ycnI0a9Ys2Ww2SdKcOXNUsmRJrVixQm3bttWUKVM0YsQIdenSRZI0c+ZMLV269KLn/fPPP/Xhhx9q2bJlat26tSSpcuXKju0XbheXLVtWJUuWlHS+Y/jCCy/o22+/VZMmTRzfWbVqlV5//XU1b95cM2bMUJUqVfTyyy9LkmJjY7Vp0ya9+OKLLswaAJiLAhDAFfniiy8UHByss2fPKicnR/fcc4/Gjh2r/v37q1atWk7j/jZs2KBdu3YpJCTE6RgZGRnavXu3Tpw4oUOHDqlRo0aObcWKFVODBg1y3Qa+YP369fL19VXz5s3zHfOuXbt05swZtWnTxml9VlaW6tWrJ0natm2bUxySHMUiABQVFIAArkjLli01Y8YM+fv7q3z58ipW7H//OSlevLjTvmlpabrhhhu0YMGCXMcpU6bMFZ0/MDCwwN9JS0uTJH355ZeqUKGC0za73X5FcQCAN6IABHBFihcvrpiYmHztW79+fX3wwQcqW7asSpQokec+5cqV05o1a9SsWTNJ0rlz5/THH3+ofv36ee5fq1Yt5eTk6IcffnDcAv63Cx3I7Oxsx7rq1avLbrdr//79F+0cVqtWTZ999pnTul9++eXyFwkAXoSHQAC43b333qvSpUvrzjvv1I8//qi9e/dqxYoVGjRokA4cOCBJGjx4sP7v//5Pixcv1vbt2/X4449fcg6/6Oho9erVSw8++KAWL17sOOaHH34oSYqKipLNZtMXX3yho0ePKi0tTSEhIRoyZIiefPJJzZs3T7t379batWv16quvat68eZKkRx99VDt37tTQoUO1Y8cOvfvuu5o7d667UwQAhYoCEIDbBQUFaeXKlbr22mvVpUsXVatWTX379lVGRoajI/jUU0/p/vvvV69evdSkSROFhISoc+fOlzzujBkzdNddd+nxxx9X1apV1a9fP50+fVqSVKFCBY0bN07Dhw9XRESEBgwYIEl67rnnNGrUKCUmJqpatWpq166dvvzyS1WqVEmSdO211+rjjz/W4sWLVadOHc2cOVMvvPCCG7MDAIXPZlxshDUAAACKJDqAAAAAFkMBCAAAYDEUgAAAABZDAQgAAGAxFIAAAAAWQwEIAABgMRSAAAAAFkMBCAAAYDEUgAAAABZDAQgAAGAxFIAAAAAW8/8A+Rl81hBD3sEAAAAASUVORK5CYII=\n"},"metadata":{}}],"execution_count":22},{"cell_type":"code","source":"#fvimport seaborn as sns\nimport matplotlib.pyplot as plt\nimport pandas as pd\n\n# Assuming `y_true` is a numpy array of encoded class labels (integers)\n# and `class_names` is a list mapping class index to name\n\n# Step 1: Convert y_true into a DataFrame with class labels\ndf_dist = pd.DataFrame({\n    \"Class\": [class_names[label] for label in y_true]\n})\n\n# Step 2: Plot using seaborn\nplt.figure(figsize=(8, 6))\nsns.countplot(data=df_dist, x=\"Class\", order=class_names, palette=\"pastel\")\nplt.title(\"Class Distribution in Test Set\")\nplt.ylabel(\"Count\")\nplt.xlabel(\"Class\")\nplt.xticks(rotation=45)\nplt.tight_layout()\nplt.show()","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-07-12T21:52:55.403315Z","iopub.execute_input":"2025-07-12T21:52:55.403683Z","iopub.status.idle":"2025-07-12T21:52:55.826948Z","shell.execute_reply.started":"2025-07-12T21:52:55.403657Z","shell.execute_reply":"2025-07-12T21:52:55.826065Z"}},"outputs":[{"name":"stderr","text":"[Stage 16:>              (38 + 4) / 676][Stage 17:>               (0 + 0) / 398]\r","output_type":"stream"},{"output_type":"display_data","data":{"text/plain":"<Figure size 800x600 with 1 Axes>","image/png":"iVBORw0KGgoAAAANSUhEUgAAAxYAAAJOCAYAAAAqFJGJAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjcuMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8pXeV/AAAACXBIWXMAAA9hAAAPYQGoP6dpAABLY0lEQVR4nO3dd3gUZfv28XMhIbQkgNQAAqF3AUUhVOkqiqDSVFQQlYDyIEUERECwoKBSxN59LChWmjRB2kMRKQLSqxCKJNQQNtf7h7/sy0rPHdhs+H6OYw/YmXtmr81sO2fmvsdjZiYAAAAAcJAp0AUAAAAACH4ECwAAAADOCBYAAAAAnBEsAAAAADgjWAAAAABwRrAAAAAA4IxgAQAAAMAZwQIAAACAM4IFAAAAAGcECwAZWvHixfXAAw8Eugxnzz77rDwezxV5rAYNGqhBgwa++3PmzJHH49HEiROvyOM/8MADKl68+BV5rNNt3bpVHo9HH3zwwRV/bADICAgWAILSpk2b9Mgjjyg6OlpZs2ZVRESEYmJi9Nprr+n48eOBLu+8PvjgA3k8Ht8ta9asioqKUrNmzfT666/r8OHDafI4u3fv1rPPPqsVK1akyfrSUnquLS38exuf65ZWAWrBggV69tlndejQoYte5ocfflD9+vWVP39+Zc+eXdHR0brnnns0derUVNUwYsQIffvtt6laFkDGEBLoAgDgUv3000+6++67FRYWpvvvv1+VKlXSyZMn9euvv6pPnz5as2aN3nrrrUCXeUFDhw5ViRIllJSUpD179mjOnDnq2bOnRo0ape+//15VqlTxtR04cKCeeuqpS1r/7t27NWTIEBUvXlzXXXfdRS83ffr0S3qc1DhfbW+//baSk5Mvew3/VqxYMR0/flyhoaHO66pXr54+/vhjv2ldunRRzZo11bVrV9+0nDlzOj+W9E+wGDJkiB544AHlypXrgu1ffvll9enTR/Xr11f//v2VPXt2bdy4UTNmzNDnn3+u5s2bX3INI0aM0F133aVWrVpd+hMAkCEQLAAElS1btqhdu3YqVqyYZs2apUKFCvnmxcbGauPGjfrpp58CWOHFa9Giha6//nrf/f79+2vWrFm67bbbdPvtt2vt2rXKli2bJCkkJEQhIZf3I/vYsWPKnj27smTJclkf50LS4od9aqQcPUoL0dHRio6O9pv26KOPKjo6Wvfee2+aPEZqnTp1SsOGDVOTJk3OGiLj4uICUBWAjIBToQAElZdeeklHjhzRu+++6xcqUpQqVUpPPPHEOZc/ePCgevfurcqVKytnzpyKiIhQixYt9Pvvv5/RdsyYMapYsaKyZ8+u3Llz6/rrr9dnn33mm3/48GH17NlTxYsXV1hYmPLnz68mTZpo+fLlqX5+N998swYNGqRt27bpk08+8U0/Wx+Ln3/+WXXq1FGuXLmUM2dOlS1bVk8//bSkf/pF3HDDDZKkBx980HfqTUr/gQYNGqhSpUpatmyZ6tWrp+zZs/uW/XcfixRer1dPP/20ChYsqBw5cuj222/Xjh07/Nqcq0/L6eu8UG1n62Nx9OhRPfnkkypatKjCwsJUtmxZvfzyyzIzv3Yej0fdu3fXt99+q0qVKiksLEwVK1a8qNN7ztbH4oEHHlDOnDm1a9cutWrVSjlz5lS+fPnUu3dveb3eC67zQnbt2qWHHnpIBQoU8NX63nvvndHufK/FZ599Vn369JEklShRwvf33Lp161kfc//+/UpISFBMTMxZ5+fPn9/vfmJiogYPHqxSpUopLCxMRYsWVd++fZWYmOhr4/F4dPToUX344Ye+x88IfZsAXBqOWAAIKj/88IOio6NVu3btVC2/efNmffvtt7r77rtVokQJ7d27V2+++abq16+vP/74Q1FRUZL+OR3n8ccf11133aUnnnhCJ06c0MqVK7V48WJ16NBB0j97oCdOnKju3burQoUKOnDggH799VetXbtW1atXT/VzvO+++/T0009r+vTpevjhh8/aZs2aNbrttttUpUoVDR06VGFhYdq4caPmz58vSSpfvryGDh2qZ555Rl27dlXdunUlye/vduDAAbVo0ULt2rXTvffeqwIFCpy3ruHDh8vj8ahfv36Ki4vTq6++qsaNG2vFihW+IysX42JqO52Z6fbbb9fs2bPVuXNnXXfddZo2bZr69OmjXbt2afTo0X7tf/31V33zzTfq1q2bwsPD9frrr6tNmzbavn27rrnmmouuM4XX61WzZs1044036uWXX9aMGTP0yiuvqGTJknrssccueX0p9u7dq5tuuskXhvLly6cpU6aoc+fOSkhIUM+ePSVd+LXYunVr/fnnn/rvf/+r0aNHK2/evJKkfPnynfVx8+fPr2zZsumHH35Qjx49lCdPnnPWmJyc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3bpZRESEffnllwGsEq5SjlTs27fPGjRoYC+88IKZmS1atMgqVqxopUuX9mv/9NNPW4kSJWzjxo1XvNbLiWAR5NasWWNNmza1MmXKWLVq1ezdd981r9drCxcutDvuuMOqVatmixYtMrP//+Oke/fu1r59ezt8+HCAq0dq7Nmzx3788Ufr3r27DR482D766CO/+QMGDDCPx2OFCxe23377LTBF4qIdPHjQVq5caRs2bDAzs/3791vfvn3PCBcpp0XNmTPHKlasaL///ntA6sXlk5iYaNWrV7dBgwb5dgyk7BwyM1u3bh2nsAaZjRs3WnR0tG9HwLp16yx37tzWvXt3v3YdO3a0qKgovpeD3IIFC6xDhw7Wpk0bO3jwoJmZHT161MaMGWPFixe3WrVqWdeuXe2uu+6yPHny2PLlywNccdojWASxFStWWEREhHXq1MlGjRplN9xwg+XNm9e+/vprM/vnnN0777zTL1wMHDjQ8ufPb3/88UcgS0cqrVmzxmrXrm033XSTVahQwYoVK2Yej8fat29vO3fuNDOzX375xYoXL25ffPGFmf3/H6RIf1atWmXVq1e34sWLW5YsWSw2NtZ27dple/futb59+1rZsmX9woWZWa9evax58+Z24MCBAFUNFzt27LDx48fb7bffbrfeeqvFxsba/v37ffMnT55sISEhdu211/p2DJzrHH2kf/PmzbPKlSubmdnWrVutaNGi9sgjj/jm//rrr77///XXX1e8PqQNr9drJ06csKFDh1qRIkWsZMmSfvMPHz5s8+fPt44dO9o999xjffv2tXXr1gWo2suLYBGk1qxZY+Hh4fbUU0/5Tb/22mvtzjvv9N2fM2eO3XnnnXbTTTdZx44dLXv27Bmuo9DVYsWKFRYZGWm9e/e2NWvWmJnZzp077a233rJcuXJZy5YtfSGiefPmVq9evUCWiwv4/fffLUeOHPbEE0/Y1KlTrW/fvhYWFmYDBw40M7PNmzdbv379/MLFkCFDLE+ePLZq1apAlo5UWrVqlVWpUsWaNWtmd955pzVt2tSuueYau/baa23OnDlm9s+Pz+rVq9uAAQPMjI7awW7ZsmXWpEkTW7x4sRUtWtS6du3q+5z+7bffLDY21tauXRvgKuEq5fTE7du324gRIyx79uz2xBNPBLaoACFYBKHk5GRr06aNhYWF2ezZs83r9frO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/DwAAO4IFgCAVCtdurQ8Hs8lddBeuHChOnbsqFtuuUU//vijfvvtNw0YMEAnT570tXn22We1Zs0a3XrrrZo1a5YqVKigSZMmSZK6dOmizZs367777tOqVat0/fXXa8yYMWn+3AAAl8Zjqd3dBACApBYtWmjVqlVav379Gf0sDh06pFy5csnj8WjSpElq1aqVXnnlFY0fP97vKESXLl00ceJEHTp06KyP0b59ex09elTff//9GfP69++vn376iSMXABBgHLEAADgZN26cvF6vatasqa+//lobNmzQ2rVr9frrr6tWrVpntC9durS2b9+uzz//XJs2bdLrr7/uOxohScePH1f37t01Z84cbdu2TfPnz9eSJUtUvnx5SVLPnj01bdo0bdmyRcuXL9fs2bN98wAAgUPnbQCAk+joaC1fvlzDhw/Xk08+qb/++kv58uVTjRo19MYbb5zR/vbbb9d//vMfde/eXYmJibr11ls1aNAgPfvss5KkzJkz68CBA7r//vu1d+9e5c2bV61bt9aQIUMkSV6vV7Gxsdq5c6ciIiLUvHlzjR49+ko+ZQDAWXAqFAAAAABnnAoFAAAAwBnBAgAAAIAzggUAAAAAZwQLAAAAAM4IFgAAAACcESwAAAAAOCNYAAAAAHBGsAAAAADgjGABAAAAwBnBAgAAAIAzggUAAAAAZwQLAAAAAM7+H4dbL8N4qi4bAAAAAElFTkSuQmCC\n"},"metadata":{}},{"name":"stderr","text":"[Stage 16:=>             (51 + 4) / 676][Stage 17:>               (0 + 0) / 398]\r","output_type":"stream"}],"execution_count":26},{"cell_type":"code","source":"","metadata":{"trusted":true},"outputs":[],"execution_count":null}]}