{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.10.12","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"nvidiaTeslaT4","dataSources":[{"sourceId":59093,"databundleVersionId":7469972,"sourceType":"competition"}],"dockerImageVersionId":30635,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":true}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"markdown","source":"# Harmful Brain Activity\n\nNotebook by Kyle Lacson on January 12, 2024\n\nReferences: \n'LSTM RNN Sequence Classification': https://machinelearningmastery.com/sequence-classification-lstm-recurrent-neural-networks-python-keras/\n\n'Multimodal Deep Learning' : https://www.v7labs.com/blog/multimodal-deep-learning-guide\n\n'Multi_input Model:' : https://machinelearningmastery.com/keras-functional-api-deep-learning/\n\nTwo seperate networks into one.","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19"}},{"cell_type":"markdown","source":"## 1. Libraries","metadata":{}},{"cell_type":"code","source":"import pandas as pd \nimport numpy as np\nimport seaborn as sns\nimport matplotlib.pyplot as plt \nfrom pathlib import Path\nimport timeit\nimport os \nimport warnings\nimport gc\nwarnings.filterwarnings('ignore')\n\nplt.style.use('ggplot')","metadata":{"execution":{"iopub.status.busy":"2024-01-18T01:41:45.002509Z","iopub.execute_input":"2024-01-18T01:41:45.002862Z","iopub.status.idle":"2024-01-18T01:41:45.808023Z","shell.execute_reply.started":"2024-01-18T01:41:45.002834Z","shell.execute_reply":"2024-01-18T01:41:45.807325Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## 2. Importing Data","metadata":{}},{"cell_type":"code","source":"working_dir = Path('/kaggle/input/hms-harmful-brain-activity-classification')\ndef setup(working_dir = working_dir):\n    os.chdir(working_dir)\n    train = pd.read_csv(working_dir / 'train.csv')\n    test = pd.read_csv(working_dir / 'test.csv')\n    \n    for file in os.listdir(os.getcwd()):\n        if 'csv' not in file:\n            print(file)\n            \n    return train, test\n    \ntrain, test = setup() # train and test metadata","metadata":{"execution":{"iopub.status.busy":"2024-01-18T01:41:45.809884Z","iopub.execute_input":"2024-01-18T01:41:45.810261Z","iopub.status.idle":"2024-01-18T01:41:46.050199Z","shell.execute_reply.started":"2024-01-18T01:41:45.810234Z","shell.execute_reply":"2024-01-18T01:41:46.049326Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# creating probability columns for target\ntarget_cols = ['seizure_vote','lpd_vote','gpd_vote','lrda_vote','grda_vote','other_vote'] # target columns\nprob_targets = train[target_cols].apply(lambda x: x/x.sum(), axis = 1)\nprob_targets","metadata":{"execution":{"iopub.status.busy":"2024-01-18T01:41:46.051406Z","iopub.execute_input":"2024-01-18T01:41:46.051737Z","iopub.status.idle":"2024-01-18T01:42:03.514641Z","shell.execute_reply.started":"2024-01-18T01:41:46.051709Z","shell.execute_reply":"2024-01-18T01:42:03.513749Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"'''\nFunction: For every unique eeg_id, there should be a unique spec_variable, making sure that this is consistent with this function.\n'''\n\nnum_of_inputs = 1000\n\ndef eeg_spec_confirmation(range_input = num_of_inputs):\n    eeg_variable = ''\n    spec_variable = ''\n    eeg_list = []\n    spec_list = []\n    for i in range(range_input):\n        if i == 0:\n            eeg_variable = train.iloc[i]['eeg_id']\n            spec_variable = train.iloc[i]['spectrogram_id']\n\n            eeg_list.append(train.iloc[i]['eeg_id'])\n            spec_list.append(train.iloc[i]['spectrogram_id'])\n        else:\n            if train.iloc[i]['eeg_id'] == eeg_variable:\n                continue\n            else:\n                eeg_variable = train.iloc[i]['eeg_id']\n                spec_variable = train.iloc[i]['spectrogram_id']\n\n                eeg_list.append(eeg_variable)\n                spec_list.append(spec_variable)\n    return eeg_list, spec_list\n    \neeg_list, spec_list = eeg_spec_confirmation()","metadata":{"execution":{"iopub.status.busy":"2024-01-18T01:42:03.515923Z","iopub.execute_input":"2024-01-18T01:42:03.516679Z","iopub.status.idle":"2024-01-18T01:42:03.60961Z","shell.execute_reply.started":"2024-01-18T01:42:03.516642Z","shell.execute_reply":"2024-01-18T01:42:03.608932Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"len(set(eeg_list)), len(set(spec_list)) # spectrograms are not exclusive to each eeg_list","metadata":{"execution":{"iopub.status.busy":"2024-01-18T01:42:03.612463Z","iopub.execute_input":"2024-01-18T01:42:03.612752Z","iopub.status.idle":"2024-01-18T01:42:03.618224Z","shell.execute_reply.started":"2024-01-18T01:42:03.612729Z","shell.execute_reply":"2024-01-18T01:42:03.617343Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# extracting first 1000 eeg_id\ndef eeg_spectrogram_dicts(total_unique_ids = num_of_inputs, eeg_min_rows = 10000):\n    eeg_ids_datasets = {}\n    for idx,i in enumerate(train.eeg_id.unique()):\n        if idx < total_unique_ids: # first 1000 unique eeg_id\n            ds = pd.read_parquet(working_dir / 'train_eegs' / (str(i) + '.parquet'),engine = 'pyarrow')\n            ds = ds.iloc[:eeg_min_rows,:]\n            eeg_ids_datasets[str(i)] = ds\n\n    # for every eeg_id, pulling its unique spectrogram (1000 samples)\n\n    spec_ids_datasets = {}\n    for idx,i in enumerate(train.spectrogram_id.unique()):\n        if idx < total_unique_ids:\n            ds = pd.read_parquet(working_dir / 'train_spectrograms' / (str(i) + '.parquet'), engine = 'pyarrow')\n            spec_ids_datasets[str(i)] = ds\n    return eeg_ids_datasets, spec_ids_datasets\n\neeg_ids_datasets, spec_ids_datasets = eeg_spectrogram_dicts()","metadata":{"execution":{"iopub.status.busy":"2024-01-18T01:42:03.619508Z","iopub.execute_input":"2024-01-18T01:42:03.619892Z","iopub.status.idle":"2024-01-18T01:43:02.976126Z","shell.execute_reply.started":"2024-01-18T01:42:03.619854Z","shell.execute_reply":"2024-01-18T01:43:02.975332Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"len(spec_ids_datasets.keys()), len(eeg_ids_datasets.keys())","metadata":{"execution":{"iopub.status.busy":"2024-01-18T01:43:02.977205Z","iopub.execute_input":"2024-01-18T01:43:02.977501Z","iopub.status.idle":"2024-01-18T01:43:02.983648Z","shell.execute_reply.started":"2024-01-18T01:43:02.977475Z","shell.execute_reply":"2024-01-18T01:43:02.982756Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train['expert_consensus'].value_counts().plot(kind = 'bar');","metadata":{"execution":{"iopub.status.busy":"2024-01-18T01:43:02.984676Z","iopub.execute_input":"2024-01-18T01:43:02.984949Z","iopub.status.idle":"2024-01-18T01:43:03.30024Z","shell.execute_reply.started":"2024-01-18T01:43:02.984927Z","shell.execute_reply":"2024-01-18T01:43:03.299352Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"cols = ['eeg_id','spectrogram_id','patient_id','expert_consensus']\ntrain_cleaned = train[cols].drop_duplicates().reset_index(drop = True)","metadata":{"execution":{"iopub.status.busy":"2024-01-18T01:43:03.301529Z","iopub.execute_input":"2024-01-18T01:43:03.302182Z","iopub.status.idle":"2024-01-18T01:43:03.326885Z","shell.execute_reply.started":"2024-01-18T01:43:03.302148Z","shell.execute_reply":"2024-01-18T01:43:03.32621Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_cleaned.head()","metadata":{"execution":{"iopub.status.busy":"2024-01-18T01:43:03.327771Z","iopub.execute_input":"2024-01-18T01:43:03.328012Z","iopub.status.idle":"2024-01-18T01:43:03.33712Z","shell.execute_reply.started":"2024-01-18T01:43:03.327991Z","shell.execute_reply":"2024-01-18T01:43:03.336104Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"gc.collect()","metadata":{"execution":{"iopub.status.busy":"2024-01-18T01:43:03.338504Z","iopub.execute_input":"2024-01-18T01:43:03.338902Z","iopub.status.idle":"2024-01-18T01:43:03.420329Z","shell.execute_reply.started":"2024-01-18T01:43:03.338871Z","shell.execute_reply":"2024-01-18T01:43:03.419278Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# GOOD UNTIL HERE","metadata":{"execution":{"iopub.status.busy":"2024-01-15T03:58:16.227256Z","iopub.execute_input":"2024-01-15T03:58:16.227855Z","iopub.status.idle":"2024-01-15T03:58:16.233633Z","shell.execute_reply.started":"2024-01-15T03:58:16.227787Z","shell.execute_reply":"2024-01-15T03:58:16.232518Z"}}},{"cell_type":"markdown","source":"## Testing eeg_id LSTM model","metadata":{"execution":{"iopub.status.busy":"2024-01-15T03:42:44.495851Z","iopub.execute_input":"2024-01-15T03:42:44.496279Z","iopub.status.idle":"2024-01-15T03:42:44.501781Z","shell.execute_reply.started":"2024-01-15T03:42:44.496248Z","shell.execute_reply":"2024-01-15T03:42:44.500553Z"}}},{"cell_type":"code","source":"# tensorflow libraries \nimport tensorflow as tf\nfrom sklearn.preprocessing import LabelEncoder, StandardScaler,MinMaxScaler\nfrom sklearn.impute import KNNImputer\n\n# gpu instantiation\ntf.config.list_physical_devices('GPU')\n\n# datasets: eeg_ids_datasets, spec_ids_datasets","metadata":{"execution":{"iopub.status.busy":"2024-01-18T01:43:03.421581Z","iopub.execute_input":"2024-01-18T01:43:03.42193Z","iopub.status.idle":"2024-01-18T01:43:14.694884Z","shell.execute_reply.started":"2024-01-18T01:43:03.42189Z","shell.execute_reply":"2024-01-18T01:43:14.693945Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# split: training, validation, test \ndef split_eeg_dataset(dataset = train_cleaned): \n    \n    # initialize preprocessing and imputer functions \n    mm = MinMaxScaler()\n    imp = KNNImputer(n_neighbors = 2)\n    \n    # train and output\n    X = dataset['eeg_id'] # train features - eeg_id\n    y = dataset['expert_consensus']\n    \n    # encoding output layers\n    le = LabelEncoder()\n    y_encoded = le.fit_transform(y)\n    y_classes = le.classes_\n    # encoding output\n    y = tf.keras.utils.to_categorical(y = y_encoded, num_classes = y.nunique())\n    \n    # splitting data\n    X_train, X_val, X_test = X[:int(num_of_inputs*0.8)], X[int(num_of_inputs*0.8):int(num_of_inputs*0.9)], X[int(num_of_inputs*0.9):num_of_inputs]\n    y_train, y_val, y_test = y[:int(num_of_inputs*0.8)], y[int(num_of_inputs*0.8):int(num_of_inputs*0.9)], y[int(num_of_inputs*0.9):num_of_inputs]\n\n    # convert dataframe to arrays\n    X_train = np.array([mm.fit_transform(imp.fit_transform(eeg_ids_datasets[str(i)].to_numpy())) for i in X_train])\n    X_val = np.array([mm.fit_transform(imp.fit_transform(eeg_ids_datasets[str(i)].to_numpy())) for i in X_val])\n    X_test = np.array([mm.fit_transform(imp.fit_transform(eeg_ids_datasets[str(i)].to_numpy())) for i in X_test])\n\n    return X_train, X_val, X_test, y_train, y_val, y_test, y_classes\n\nX_train_eeg, X_val_eeg, X_test_eeg, y_train, y_val, y_test, y_classes = split_eeg_dataset()","metadata":{"execution":{"iopub.status.busy":"2024-01-18T01:43:14.696139Z","iopub.execute_input":"2024-01-18T01:43:14.696852Z","iopub.status.idle":"2024-01-18T01:43:25.450212Z","shell.execute_reply.started":"2024-01-18T01:43:14.696817Z","shell.execute_reply":"2024-01-18T01:43:25.449341Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def split_spectrogram_dataset(dataset = train_cleaned):\n    \n    # initialize preprocessing and imputer functions \n    mm = MinMaxScaler()\n    imp = KNNImputer(n_neighbors = 2)\n    \n    # train and output\n    X = dataset['spectrogram_id']\n#     y = dataset['expert_consensus']\n    \n    # splitting data\n    X_train, X_val, X_test = X[:int(num_of_inputs*0.8)], X[int(num_of_inputs*0.8):int(num_of_inputs*0.9)], X[int(num_of_inputs*0.9):num_of_inputs]\n#     y_train, y_val, y_test = y[:700], y[700:900], y[900:1000]\n    \n    # dataframe to arrays\n    X_train = np.array([mm.fit_transform(imp.fit_transform(spec_ids_datasets[str(i)].drop(columns = 'time').iloc[:300,:].to_numpy())) for i in X_train]) \n    X_val = np.array([mm.fit_transform(imp.fit_transform(spec_ids_datasets[str(i)].drop(columns = 'time').iloc[:300,:].to_numpy())) for i in X_val])\n    X_test = np.array([mm.fit_transform(imp.fit_transform(spec_ids_datasets[str(i)].drop(columns = 'time').iloc[:300,:].to_numpy())) for i in X_test])\n    return X_train, X_val, X_test\n    \nX_train_spec, X_val_spec, X_test_spec = split_spectrogram_dataset()","metadata":{"execution":{"iopub.status.busy":"2024-01-18T01:43:25.454278Z","iopub.execute_input":"2024-01-18T01:43:25.454569Z","iopub.status.idle":"2024-01-18T01:43:42.470522Z","shell.execute_reply.started":"2024-01-18T01:43:25.454546Z","shell.execute_reply":"2024-01-18T01:43:42.469708Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# lstm model\nbatch_size = 64\noputput_size = len(y_train[0])\n# optimizer = tf.keras.optimizers.Adam(learning_rate = 0.001)\noptimizer = tf.keras.optimizers.SGD()\nloss_fn = 'categorical_crossentropy'\nmetric_list = ['accuracy']\n\ndef lstm_model(batch_size = batch_size, output_size = len(y_train[0]), optimizer = optimizer, loss_fn = loss_fn):\n    \n    # eeg_input\n    input_model_eeg = tf.keras.Input(shape = X_train_eeg.shape[1:], batch_size = batch_size, name = 'input_layer_eeg')\n    norm_layer_eeg = tf.keras.layers.BatchNormalization(name = 'normalization_layer_eeg')(input_model_eeg)\n    lstm_layer_eeg = tf.keras.layers.Bidirectional(tf.keras.layers.LSTM(64, name = 'lstm_layer_eeg'))(norm_layer_eeg)\n    dropout_layer_eeg = tf.keras.layers.Dropout(0.15)(lstm_layer_eeg)\n    eeg_model = tf.keras.Model(inputs = input_model_eeg, outputs = dropout_layer_eeg, name = 'eeg_model')\n    \n    # spectrogram input\n    input_model_spectrogram = tf.keras.Input(shape = (X_train_spec.shape[1:]), batch_size = batch_size, name = 'input_layer_spectrogram')\n    norm_layer_spec = tf.keras.layers.BatchNormalization(name ='normalization_layer_spec')(input_model_spectrogram)\n    lstm_layer_spec = tf.keras.layers.Bidirectional(tf.keras.layers.LSTM(64, name = 'lstm_layer_spec'))(norm_layer_spec)\n    dropout_layer_spec = tf.keras.layers.Dropout(0.15)(lstm_layer_spec)\n    spec_model = tf.keras.Model(inputs = input_model_spectrogram, outputs = dropout_layer_spec, name = 'spectrogram_model')\n    \n    # concatenate \n    combined_models = tf.keras.layers.concatenate(inputs = [eeg_model.output,spec_model.output],axis = 1)\n    \n    # output layer\n    output_layer = tf.keras.layers.Dense(units = output_size, activation = 'sigmoid', name = 'output_layer')(combined_models) # softmax or sigmoid?\n    \n    # instantiate model\n    model = tf.keras.Model(inputs = [input_model_eeg,input_model_spectrogram], outputs = output_layer, name = 'eeg_model')\n    \n    # compile optimizer, loss function, and metrics\n    model.compile(optimizer = optimizer, loss = loss_fn, metrics = metric_list)\n    \n    # early stopping \n    callback = tf.keras.callbacks.EarlyStopping(monitor = 'val_accuracy', patience = 5)\n    # fit and train model \n    history = model.fit(x = [X_train_eeg,X_train_spec], \n                        y = y_train,\n                        epochs = 10, \n                        batch_size = batch_size,\n                        validation_data = ([X_val_eeg,X_val_spec], y_val), \n                        workers = -1, \n                        callbacks = [callback],\n                        use_multiprocessing = True) # apply early stopping?\n\n    return model,history\n\n# with tf.config.list_physical_devices('GPU'):\ntf.random.set_seed(42)\n# comb_model,history = lstm_model()","metadata":{"execution":{"iopub.status.busy":"2024-01-18T01:43:42.471608Z","iopub.execute_input":"2024-01-18T01:43:42.47187Z","iopub.status.idle":"2024-01-18T01:43:43.038717Z","shell.execute_reply.started":"2024-01-18T01:43:42.471848Z","shell.execute_reply":"2024-01-18T01:43:43.03776Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# comb_model.summary()","metadata":{"execution":{"iopub.status.busy":"2024-01-18T01:43:43.04008Z","iopub.execute_input":"2024-01-18T01:43:43.040594Z","iopub.status.idle":"2024-01-18T01:43:43.044966Z","shell.execute_reply.started":"2024-01-18T01:43:43.040559Z","shell.execute_reply":"2024-01-18T01:43:43.044109Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Playground: Standardizing Beforehand","metadata":{}},{"cell_type":"code","source":"# split: training, validation, test \n### scaling\nfrom sklearn.impute import KNNImputer\n\ndef split_eeg_dataset(dataset = train_cleaned): \n    \n    # train and output\n    X = dataset['eeg_id'] # train features - eeg_id\n    y = dataset['expert_consensus']\n    \n    # encoding output layers\n    le = LabelEncoder()\n    y_encoded = le.fit_transform(y)\n    y_classes = le.classes_\n    # encoding output\n    y = tf.keras.utils.to_categorical(y = y_encoded, num_classes = y.nunique())\n    \n    # splitting data\n    X_train, X_val, X_test = X[:int(num_of_inputs*0.8)], X[int(num_of_inputs*0.8):int(num_of_inputs*0.9)], X[int(num_of_inputs*0.9):num_of_inputs]\n    y_train, y_val, y_test = y[:int(num_of_inputs*0.8)], y[int(num_of_inputs*0.8):int(num_of_inputs*0.9)], y[int(num_of_inputs*0.9):num_of_inputs]\n\n    # convert dataframe to arrays and standardizes\n#     sc = StandardScaler()\n    sc = MinMaxScaler()\n    imp = KNNImputer(n_neighbors = 2) # deal with missing values\n    \n    X_train = np.array([sc.fit_transform(imp.fit_transform(eeg_ids_datasets[str(i)].to_numpy())) for i in X_train])\n    X_val = np.array([sc.fit_transform(imp.fit_transform(eeg_ids_datasets[str(i)].to_numpy())) for i in X_val])\n    X_test = np.array([sc.fit_transform(imp.fit_transform(eeg_ids_datasets[str(i)].to_numpy())) for i in X_test])\n\n    return X_train, X_val, X_test, y_train, y_val, y_test, y_classes\n\nX_train_sc, X_val_sc, X_test_sc, y_train, y_val, y_test, y_classes = split_eeg_dataset()","metadata":{"execution":{"iopub.status.busy":"2024-01-18T01:43:43.046219Z","iopub.execute_input":"2024-01-18T01:43:43.046649Z","iopub.status.idle":"2024-01-18T01:43:53.445839Z","shell.execute_reply.started":"2024-01-18T01:43:43.046618Z","shell.execute_reply":"2024-01-18T01:43:53.444915Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"np.isnan(X_train_sc).sum(), np.isnan(X_val_sc).sum(), np.isnan(X_test_sc).sum()# missing/null values","metadata":{"execution":{"iopub.status.busy":"2024-01-18T01:43:53.4469Z","iopub.execute_input":"2024-01-18T01:43:53.447794Z","iopub.status.idle":"2024-01-18T01:43:53.662771Z","shell.execute_reply.started":"2024-01-18T01:43:53.447767Z","shell.execute_reply":"2024-01-18T01:43:53.661673Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"**Note:** Apply soome padding to datsets? We might be losing information - reduction in variance ~\n\nhttps://www.tensorflow.org/guide/keras/understanding_masking_and_padding","metadata":{}},{"cell_type":"code","source":"def scaled_eeg_model():\n    \n    input_lay = tf.keras.Input(shape = X_train_sc.shape[1:], batch_size = 128)\n    lstm_lay = tf.keras.layers.Bidirectional(tf.keras.layers.LSTM(128, return_sequences = True))(input_lay)\n    dense_lay = tf.keras.layers.Dense(64, activation = 'relu')(lstm_lay)\n    output_lay = tf.keras.layers.Dense(units = len(y_train[0]), activation = 'sigmoid')(dense_lay)\n    \n    model = tf.keras.Model(inputs = input_lay, outputs = output_lay)\n    \n    model.compile(optimizer = 'adam', loss = 'categorical_crossentropy', metrics = ['accuracy'])\n    \n    callback = tf.keras.callbacks.EarlyStopping(monitor = 'val_loss', patience = 3)\n    history = model.fit(x = X_train_sc,\n                       y = y_train,\n                       epochs = 100,\n                       batch_size = 128,\n                       validation_data = [X_val_sc,y_val],\n                       workers = -1,\n                       use_multiprocessing = True,\n                       callbacks = callback)\n    \n    return history, model\n\nhistory, model = scaled_eeg_model()","metadata":{"execution":{"iopub.status.busy":"2024-01-18T01:53:17.161968Z","iopub.execute_input":"2024-01-18T01:53:17.162354Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def cnn_model():\n    # input layer\n    input_layer = tf.keras.Input(shape = X_train_sc.shape[1:], batch_size = 128)\n    \n    # convolutional\n    conv1d_1 = tf.keras.layers.Conv1D(filters = 32, kernel_size = 3, padding = 'valid', activation = 'relu', name = 'conv1d_1')(input_layer)\n    max_pool_1 = tf.keras.layers.MaxPooling1D(name = 'max_pool_1')(conv1d_1)\n    batch_norm_1 = tf.keras.layers.BatchNormalization(name = 'b_norm_1')(max_pool_1)\n    \n    dropout_1 = tf.keras.layers.Dropout(0.2)(batch_norm_1)\n    \n    conv1d_2 = tf.keras.layers.Conv1D(filters = 64, kernel_size = 3, padding = 'valid', activation = 'relu', name = 'conv1d_2')(dropout_1)\n    max_pool_2 = tf.keras.layers.MaxPooling1D(name = 'max_pool_2')(conv1d_2)\n    batch_norm_2 = tf.keras.layers.BatchNormalization(name = 'b_norm_2')(max_pool_2)\n    \n    dropout_2 = tf.keras.layers.Dropout(0.2)(batch_norm_2)\n    # flatten\n    flatten = tf.keras.layers.Flatten(name = 'flatten_layer')(dropout_2)\n    dropout_3 = tf.keras.layers.Dropout(0.2, name = 'dropout_layer')(flatten)\n    \n    # dense layer\n    dense_layer = tf.keras.layers.Dense(128, activation = 'relu', name = 'dense_layer')(dropout_3)\n    output_layer = tf.keras.layers.Dense(len(y_train[0]), activation = 'sigmoid', name = 'output_layer')(dense_layer)\n    \n    # model \n    tf.random.set_seed(42)\n    model = tf.keras.Model(inputs = input_layer, outputs = output_layer, name = 'model_eeg')\n    \n    model.compile(optimizer = 'adam', loss = 'categorical_crossentropy', metrics = ['accuracy'])\n    \n    callback = tf.keras.callbacks.EarlyStopping(monitor = 'val_loss', patience = 5)\n    history = model.fit(x = X_train_sc,\n                       y = y_train,\n                       epochs = 100,\n                       batch_size = 128,\n                       validation_data = [X_val_sc,y_val],\n                       workers = -1,\n                       use_multiprocessing = True,\n                       callbacks = callback)\n    return history,model\n\n# history,model = cnn_model()","metadata":{"execution":{"iopub.status.busy":"2024-01-18T01:51:32.780047Z","iopub.execute_input":"2024-01-18T01:51:32.780308Z","iopub.status.idle":"2024-01-18T01:51:55.595499Z","shell.execute_reply.started":"2024-01-18T01:51:32.780268Z","shell.execute_reply":"2024-01-18T01:51:55.594644Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model.summary() # convoluted networks are no good for sequential data here","metadata":{"execution":{"iopub.status.busy":"2024-01-18T01:51:32.741241Z","iopub.execute_input":"2024-01-18T01:51:32.741961Z","iopub.status.idle":"2024-01-18T01:51:32.778682Z","shell.execute_reply.started":"2024-01-18T01:51:32.741923Z","shell.execute_reply":"2024-01-18T01:51:32.77782Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]}]}