{"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"},{"sourceId":7392733,"sourceType":"datasetVersion","datasetId":4297749},{"sourceId":7458895,"sourceType":"datasetVersion","datasetId":4341614},{"sourceId":7458914,"sourceType":"datasetVersion","datasetId":4341621},{"sourceId":7458990,"sourceType":"datasetVersion","datasetId":4341638},{"sourceId":7465597,"sourceType":"datasetVersion","datasetId":4345650}],"dockerImageVersionId":30636,"isInternetEnabled":false,"language":"python","sourceType":"notebook","isGpuEnabled":true}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"markdown","source":"# WaveNet Starter using RAW EEG Features!\nThis notebook is a Version 1 of WaveNet starter using raw EEG feautures. Enjoy!","metadata":{}},{"cell_type":"markdown","source":"# Load Train Data","metadata":{}},{"cell_type":"code","source":"import pandas as pd, numpy as np, os\nimport matplotlib.pyplot as plt\n\ntrain = pd.read_csv('/kaggle/input/hms-harmful-brain-activity-classification/train.csv')\nprint( train.shape )\ndisplay( train.head() )\n\n# CHOICE TO CREATE OR LOAD EEGS FROM NOTEBOOK VERSION 1\nCREATE_EEGS = True","metadata":{"execution":{"iopub.status.busy":"2024-01-23T18:11:30.545929Z","iopub.execute_input":"2024-01-23T18:11:30.546563Z","iopub.status.idle":"2024-01-23T18:11:31.895078Z","shell.execute_reply.started":"2024-01-23T18:11:30.546534Z","shell.execute_reply":"2024-01-23T18:11:31.894122Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train['final_eeg_id'] = train.apply(lambda row: str(row['eeg_id']) + str(row['eeg_sub_id']), axis=1)\ntrain.head()","metadata":{"execution":{"iopub.status.busy":"2024-01-23T18:11:46.980750Z","iopub.execute_input":"2024-01-23T18:11:46.981110Z","iopub.status.idle":"2024-01-23T18:11:48.743843Z","shell.execute_reply.started":"2024-01-23T18:11:46.981082Z","shell.execute_reply":"2024-01-23T18:11:48.742904Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Raw EEG Features","metadata":{}},{"cell_type":"code","source":"# df = pd.read_parquet('/kaggle/input/hms-harmful-brain-activity-classification/train_eegs/1000913311.parquet')\n# # FEATS = df.columns\n# # print(f'There are {len(FEATS)} raw eeg features')\n# # print( list(FEATS) )","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# print('We will use the following subset of raw EEG features:')\n# FEATS = ['Fp1','O1','Fp2','O2']\n# FEAT2IDX = {x:y for x,y in zip(FEATS,range(len(FEATS)))}\n# print( list(FEATS) )\n# print(FEAT2IDX)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"eeg = pd.read_parquet('/kaggle/input/hms-harmful-brain-activity-classification/train_eegs/1000913311.parquet')\n\noffset=0\ntemp=eeg.iloc[offset*200:(offset+50)*200].astype('float16')\ntemp=temp.round(2)\ntemp.head()","metadata":{"execution":{"iopub.status.busy":"2024-01-23T18:11:54.145050Z","iopub.execute_input":"2024-01-23T18:11:54.145397Z","iopub.status.idle":"2024-01-23T18:11:54.384774Z","shell.execute_reply.started":"2024-01-23T18:11:54.145368Z","shell.execute_reply":"2024-01-23T18:11:54.383820Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def eeg_from_parquet(parquet_path,offset):\n    count_short=0\n    eeg = pd.read_parquet(parquet_path)\n    eeg=eeg.astype('float16')\n    rows = len(eeg)\n    offset = int(offset)\n    try:\n        eeg = eeg.iloc[offset*200:(offset+50)*200]\n    \n    except:\n        count_short+=1\n        eeg = eeg.iloc[int(offset*200):]\n\n    \n    # CONVERT TO NUMPY\n    data = np.zeros((10_000,20))\n    data=data+999999\n    for j,col in enumerate(eeg.columns):\n        # FILL NAN\n    \n        x = eeg[col].values.astype('float16')\n        m = np.nanmean(x)\n        if np.isnan(x).mean()<1: x = np.nan_to_num(x,nan=m) #we can take mean of neighbouring values\n        else: x[:] = 0\n        \"\"\"\n         if the whole column is empty it will change the whole column to zero else it will \n         fill that with its mean value\n        \"\"\"   \n        if len(x) <= len(data[:, j]):\n    \n            data[:len(x), j] = x\n        else:\n           \n            data[:, j] = x[:len(data[:, j])]\n\n   \n    return data","metadata":{"execution":{"iopub.status.busy":"2024-01-22T22:31:17.922776Z","iopub.execute_input":"2024-01-22T22:31:17.923144Z","iopub.status.idle":"2024-01-22T22:31:17.932698Z","shell.execute_reply.started":"2024-01-22T22:31:17.923113Z","shell.execute_reply":"2024-01-22T22:31:17.931739Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# %%time\n# from tqdm import tqdm\n# all_eegs = {}\n# FINAL_EEG_IDS = train.final_eeg_id.unique()\n\n# PATH = '/kaggle/input/hms-harmful-brain-activity-classification/train_eegs/'\n\n# for i,final_eeg_id in tqdm(enumerate(FINAL_EEG_IDS)):\n#     if (i%100==0)&(i!=0): print(i,', ',end='') \n#     current_offset=train[train.final_eeg_id==final_eeg_id].eeg_label_offset_seconds.iloc[0]\n#     # SAVE EEG TO PYTHON DICTIONARY OF NUMPY ARRAYS\n#     eeg_id=train[train.final_eeg_id==final_eeg_id].eeg_id.iloc[0]\n#     data = eeg_from_parquet(f'{PATH}{eeg_id}.parquet',current_offset)              \n#     all_eegs[final_eeg_id] = data\n            \n\n# np.save('/kaggle/working/eegs.npy',all_eegs)\n\n# # all_eegs = np.load('/kaggle/input/brain-eegs/eeg.npy',allow_pickle=True).item()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_sub1=train[90000:100000]\n","metadata":{"execution":{"iopub.status.busy":"2024-01-22T22:31:23.175763Z","iopub.execute_input":"2024-01-22T22:31:23.176525Z","iopub.status.idle":"2024-01-22T22:31:23.181168Z","shell.execute_reply.started":"2024-01-22T22:31:23.176473Z","shell.execute_reply":"2024-01-22T22:31:23.179926Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import warnings\nall_eegs = {}\nFINAL_EEG_IDS = train.final_eeg_id.unique()\n\nPATH = '/kaggle/input/hms-harmful-brain-activity-classification/train_eegs/'\ndef load_eeg_data(row):\n    warnings.filterwarnings(\"ignore\", category=RuntimeWarning)\n    current_offset = row['eeg_label_offset_seconds']\n    eeg_id = row['eeg_id']\n    data = eeg_from_parquet(f'{PATH}{eeg_id}.parquet', current_offset)\n    return data\n\ntrain_sub1['eeg_data_numpy'] = train_sub1.apply(load_eeg_data, axis=1)","metadata":{"execution":{"iopub.status.busy":"2024-01-22T22:31:27.132451Z","iopub.execute_input":"2024-01-22T22:31:27.132836Z","iopub.status.idle":"2024-01-22T22:36:37.299072Z","shell.execute_reply.started":"2024-01-22T22:31:27.132805Z","shell.execute_reply":"2024-01-22T22:36:37.297969Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# import dask\n# from dask import delayed\n# from tqdm import tqdm\n\n# def load_eeg_data(final_eeg_id, current_offset, eeg_id):\n#     return final_eeg_id, eeg_from_parquet(f'{PATH}{eeg_id}.parquet', current_offset)\n\n# all_eegs = {}\n\n# # Create a list of delayed objects\n# delayed_loads = []\n# for i, final_eeg_id in tqdm(enumerate(FINAL_EEG_IDS)):\n# #     if (i % 100 == 0) and (i != 0):\n# #         print(i, ', ', end='')\n    \n#     current_offset = train[train.final_eeg_id == final_eeg_id].eeg_label_offset_seconds.iloc[0]\n#     eeg_id = train[train.final_eeg_id == final_eeg_id].eeg_id.iloc[0]\n    \n#     delayed_load = delayed(load_eeg_data)(final_eeg_id, current_offset, eeg_id)\n#     delayed_loads.append(delayed_load)\n\n# # Compute the delayed objects in parallel\n# computed_loads = dask.compute(*delayed_loads)\n\n# # Store the results in the dictionary\n# for final_eeg_id, data in computed_loads:\n#     all_eegs[final_eeg_id] = data\n","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import os\nimport pandas as pd\n\n# Path to the folder containing CSV files\nfolder_path = '/kaggle/input/dasccs'\n\n# Get a list of all CSV files in the folder\ncsv_files = [file for file in os.listdir(folder_path) if file.endswith('.csv')]\n\n# Initialize an empty list to store DataFrames\n# dfs = []\n\n# Loop through each CSV file and read it into a DataFrame\nfor file in csv_files:\n    file_path = os.path.join(folder_path, file)\n    df = pd.read_csv(file_path)\n    dfs.append(df)\n\n# Concatenate all DataFrames into one\nmerged_data = pd.concat(dfs, ignore_index=True)\n\nmerged_data\n","metadata":{"execution":{"iopub.status.busy":"2024-01-22T22:46:24.105104Z","iopub.execute_input":"2024-01-22T22:46:24.105558Z","iopub.status.idle":"2024-01-22T22:46:24.248727Z","shell.execute_reply.started":"2024-01-22T22:46:24.105523Z","shell.execute_reply":"2024-01-22T22:46:24.247732Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df_sorted = merged_data.sort_values(by='Unnamed: 0')\ndf_sorted","metadata":{"execution":{"iopub.status.busy":"2024-01-22T22:48:47.182033Z","iopub.execute_input":"2024-01-22T22:48:47.182444Z","iopub.status.idle":"2024-01-22T22:48:47.228447Z","shell.execute_reply.started":"2024-01-22T22:48:47.182410Z","shell.execute_reply":"2024-01-22T22:48:47.227358Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df_sorted.to_csv('eeg_sorted.csv')","metadata":{"execution":{"iopub.status.busy":"2024-01-22T22:49:49.777091Z","iopub.execute_input":"2024-01-22T22:49:49.777506Z","iopub.status.idle":"2024-01-22T22:49:53.406515Z","shell.execute_reply.started":"2024-01-22T22:49:49.777461Z","shell.execute_reply":"2024-01-22T22:49:53.405569Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"eeg_dict = df.set_index('final_eeg_id')['eeg_data_numpy'].to_dict()\nprint(eeg_dict[19268191387])","metadata":{"execution":{"iopub.status.busy":"2024-01-22T22:53:00.121347Z","iopub.execute_input":"2024-01-22T22:53:00.122130Z","iopub.status.idle":"2024-01-22T22:53:00.139292Z","shell.execute_reply.started":"2024-01-22T22:53:00.122094Z","shell.execute_reply":"2024-01-22T22:53:00.138189Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import json\n\n# Save the dictionary to a JSON file\nwith open('eeg_data_dict.json', 'w') as json_file:\n    json.dump(eeg_dict, json_file)\n","metadata":{"execution":{"iopub.status.busy":"2024-01-22T22:54:00.641602Z","iopub.execute_input":"2024-01-22T22:54:00.642478Z","iopub.status.idle":"2024-01-22T22:54:00.681404Z","shell.execute_reply.started":"2024-01-22T22:54:00.642441Z","shell.execute_reply":"2024-01-22T22:54:00.680686Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import json\n\nwith open('/kaggle/input/eeg-json/eeg_data_dict.json', 'r') as json_file:\n    data=json.load(json_file)\n    \ndata\n    ","metadata":{"execution":{"iopub.status.busy":"2024-01-23T18:16:04.937052Z","iopub.execute_input":"2024-01-23T18:16:04.937412Z","iopub.status.idle":"2024-01-23T18:16:05.013872Z","shell.execute_reply.started":"2024-01-23T18:16:04.937382Z","shell.execute_reply":"2024-01-23T18:16:05.012731Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Deduplicate Train EEG Id","metadata":{}},{"cell_type":"code","source":"df = pd.read_csv('/kaggle/input/hms-harmful-brain-activity-classification/train.csv')\ny_data = train[TARGETS].values\ny_data = y_data / y_data.sum(axis=1,keepdims=True)\ntrain[TARGETS] = y_data","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# LOAD TRAIN \ndf = pd.read_csv('/kaggle/input/hms-harmful-brain-activity-classification/train.csv')\nTARGETS = df.columns[-6:]\nTARS = {'Seizure':0, 'LPD':1, 'GPD':2, 'LRDA':3, 'GRDA':4, 'Other':5}\nTARS2 = {x:y for y,x in TARS.items()}\n\ntrain = df.groupby('eeg_id')[['patient_id']].agg('first')\n\ntmp = df.groupby('eeg_id')[TARGETS].agg('sum')\nfor t in TARGETS:\n    train[t] = tmp[t].values\n    \ny_data = train[TARGETS].values\ny_data = y_data / y_data.sum(axis=1,keepdims=True)\ntrain[TARGETS] = y_data\n\ntmp = df.groupby('eeg_id')[['expert_consensus']].agg('first')\ntrain['target'] = tmp\n\ntrain = train.reset_index()\ntrain = train.loc[train.eeg_id.isin(EEG_IDS)]\nprint('Train Data with unique eeg_id shape:', train.shape )\ntrain.head()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Butter Low-Pass Filter","metadata":{}},{"cell_type":"code","source":"from scipy.signal import butter, lfilter\n\ndef butter_lowpass_filter(data, cutoff_freq=20, sampling_rate=200, order=4):\n    nyquist = 0.5 * sampling_rate\n    normal_cutoff = cutoff_freq / nyquist\n    b, a = butter(order, normal_cutoff, btype='low', analog=False)\n    filtered_data = lfilter(b, a, data, axis=0)\n    return filtered_data","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"FREQS = [1,2,4,8,16][::-1]\nx = [all_eegs[EEG_IDS[0]][:,0]]\nfor k in FREQS:\n    x.append( butter_lowpass_filter(x[0], cutoff_freq=k) )\n\nplt.figure(figsize=(20,20))\nplt.plot(range(10_000),x[0], label='without filter')\nfor k in range(1,len(x)):\n    plt.plot(range(10_000),x[k]-k*(x[0].max()-x[0].min()), label=f'with filter {FREQS[k-1]}Hz')\nplt.legend()\nplt.title('Butter Low-Pass Filter Examples',size=18)\nplt.show()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Data Loader with Butter Low-Pass Filter","metadata":{}},{"cell_type":"code","source":"import tensorflow as tf\n\nclass DataGenerator(tf.keras.utils.Sequence):\n    'Generates data for Keras'\n    def __init__(self, data, batch_size=32, shuffle=False, eegs=all_eegs, mode='train'): \n\n        self.data = data\n        self.batch_size = batch_size\n        self.shuffle = shuffle\n        self.eegs = eegs\n        self.mode = mode\n        self.on_epoch_end()\n        \n    def __len__(self):\n        'Denotes the number of batches per epoch'\n        ct = int( np.ceil( len(self.data) / self.batch_size ) )\n        return ct\n\n    def __getitem__(self, index):\n        'Generate one batch of data'\n        indexes = self.indexes[index*self.batch_size:(index+1)*self.batch_size]\n        X, y = self.__data_generation(indexes)\n        return X, y\n\n    def on_epoch_end(self):\n        'Updates indexes after each epoch'\n        self.indexes = np.arange( len(self.data) )\n        if self.shuffle: np.random.shuffle(self.indexes)\n                        \n    def __data_generation(self, indexes):\n        'Generates data containing batch_size samples' \n    \n        X = np.zeros((len(indexes),10_000,2),dtype='float32')\n        y = np.zeros((len(indexes),6),dtype='float32')\n        \n        sample = np.zeros((10_000,X.shape[-1]))\n        for j,i in enumerate(indexes):\n            row = self.data.iloc[i]      \n            data = self.eegs[row.eeg_id]\n            \n            # FEATURE ENGINEER\n            sample[:,0] = data[:,FEAT2IDX['Fp1']] - data[:,FEAT2IDX['O1']]\n            sample[:,1] = data[:,FEAT2IDX['Fp2']] - data[:,FEAT2IDX['O2']]\n            \n            # STANDARDIZE\n            sample = np.clip(sample,-1024,1024)\n            sample = np.nan_to_num(sample, nan=0) / 32.0\n            \n            # BUTTER LOW-PASS FILTER\n            sample = butter_lowpass_filter(sample)\n            \n            X[j,] = sample\n            if self.mode!='test':\n                y[j] = row[TARGETS]\n            \n        return X,y","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Display Data Loader","metadata":{}},{"cell_type":"code","source":"gen = DataGenerator(train, shuffle=False)\n\nfor x,y in gen:\n    for k in range(4):\n        plt.figure(figsize=(20,4))\n        offset = 0\n        for j in range(x.shape[-1]):\n            if j!=0: offset -= x[k,:,j].min()\n            plt.plot(range(10_000),x[k,:,j]+offset,label=f'feature {j+1}')\n            offset += x[k,:,j].max()\n        tt = f'{y[k][0]:0.1f}'\n        for t in y[k][1:]:\n            tt += f', {t:0.1f}'\n        plt.title(f'EEG_Id = {EEG_IDS[k]}\\nTarget = {tt}',size=14)\n        plt.legend()\n        plt.show()\n    break","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Initialize GPUs","metadata":{}},{"cell_type":"code","source":"import os\nos.environ[\"CUDA_VISIBLE_DEVICES\"]=\"0,1\"\nimport tensorflow as tf\nprint('TensorFlow version =',tf.__version__)\n\n# USE MULTIPLE GPUS\ngpus = tf.config.list_physical_devices('GPU')\nif len(gpus)<=1: \n    strategy = tf.distribute.OneDeviceStrategy(device=\"/gpu:0\")\n    print(f'Using {len(gpus)} GPU')\nelse: \n    strategy = tf.distribute.MirroredStrategy()\n    print(f'Using {len(gpus)} GPUs')","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# USE MIXED PRECISION\nMIX = True\nif MIX:\n    tf.config.optimizer.set_experimental_options({\"auto_mixed_precision\": True})\n    print('Mixed precision enabled')\nelse:\n    print('Using full precision')","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Build WaveNet Model","metadata":{}},{"cell_type":"code","source":"# TRAIN SCHEDULE\ndef lrfn(epoch):\n        return [1e-3,1e-3,1e-4,1e-4,1e-5][epoch]\nLR = tf.keras.callbacks.LearningRateScheduler(lrfn, verbose = True)\nEPOCHS = 5","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from tensorflow.keras.layers import Input, Dense, Multiply, Add, Conv1D, Concatenate\n\ndef wave_block(x, filters, kernel_size, n):\n    dilation_rates = [2**i for i in range(n)]\n    x = Conv1D(filters = filters,\n               kernel_size = 1,\n               padding = 'same')(x)\n    res_x = x\n    for dilation_rate in dilation_rates:\n        tanh_out = Conv1D(filters = filters,\n                          kernel_size = kernel_size,\n                          padding = 'same', \n                          activation = 'tanh', \n                          dilation_rate = dilation_rate)(x)\n        sigm_out = Conv1D(filters = filters,\n                          kernel_size = kernel_size,\n                          padding = 'same',\n                          activation = 'sigmoid', \n                          dilation_rate = dilation_rate)(x)\n        x = Multiply()([tanh_out, sigm_out])\n        x = Conv1D(filters = filters,\n                   kernel_size = 1,\n                   padding = 'same')(x)\n        res_x = Add()([res_x, x])\n    return res_x","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def build_model():\n        \n    # INPUT \n    inp = tf.keras.Input(shape=(10_000,2))\n    \n    x = wave_block(inp, 16, 3, 12)\n    x = wave_block(x, 32, 3, 8)\n    x = wave_block(x, 64, 3, 4)\n    x = wave_block(x, 128, 3, 1)\n    \n    # OUTPUT\n    x = tf.keras.layers.GlobalMaxPooling1D()(x)\n    x = tf.keras.layers.Dense(6,activation='softmax',dtype='float32')(x)\n    \n    # COMPILE MODEL\n    model = tf.keras.Model(inputs=inp, outputs=x)\n    opt = tf.keras.optimizers.Adam(learning_rate = 1e-3)\n    loss = tf.keras.losses.KLDivergence()\n    model.compile(loss=loss, optimizer = opt)\n    \n    return model","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Train Group KFold","metadata":{}},{"cell_type":"code","source":"VERBOSE = 1\nFOLDS_TO_TRAIN = 5\nif not os.path.exists('WaveNet_Model'):\n    os.makedirs('WaveNet_Model')\n\nfrom sklearn.model_selection import KFold, GroupKFold\nimport tensorflow.keras.backend as K, gc\n\nall_oof = []; all_oof2 = []; all_true = []\ngkf = GroupKFold(n_splits=5)\nfor i, (train_index, valid_index) in enumerate(gkf.split(train, train.target, train.patient_id)):   \n    \n    print('#'*25)\n    print(f'### Fold {i+1}')\n    train_gen = DataGenerator(train.iloc[train_index], shuffle=True, batch_size=32)\n    valid_gen = DataGenerator(train.iloc[valid_index], shuffle=False, batch_size=64, mode='valid')\n    print(f'### train size {len(train_index)}, valid size {len(valid_index)}')\n    print('#'*25)\n    \n    # TRAIN MODEL\n    K.clear_session()\n    with strategy.scope():\n        model = build_model()\n    model.fit(train_gen, verbose=VERBOSE,\n          validation_data = valid_gen,\n          epochs=EPOCHS, callbacks = [LR])\n    model.save_weights(f'WaveNet_Model/WaveNet_fold{i}.h5')\n    \n    # WAVENET OOF\n    oof = model.predict(valid_gen, verbose=VERBOSE)\n    all_oof.append(oof)\n    all_true.append(train.iloc[valid_index][TARGETS].values)\n    \n    # TRAIN MEAN OOF\n    y_train = train.iloc[train_index][TARGETS].values\n    y_valid = train.iloc[valid_index][TARGETS].values\n    oof = y_valid.copy()\n    for j in range(6):\n        oof[:,j] = y_train[:,j].mean()\n    oof = oof / oof.sum(axis=1,keepdims=True)\n    all_oof2.append(oof)\n    \n    del model, oof, y_train, y_valid\n    gc.collect()\n    \n    if i==FOLDS_TO_TRAIN-1: break\n    \nall_oof = np.concatenate(all_oof)\nall_oof2 = np.concatenate(all_oof2)\nall_true = np.concatenate(all_true)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# CV Score for WaveNet","metadata":{}},{"cell_type":"code","source":"import sys\nsys.path.append('/kaggle/input/kaggle-kl-div')\nfrom kaggle_kl_div import score\n\noof = pd.DataFrame(all_oof.copy())\noof['id'] = np.arange(len(oof))\n\ntrue = pd.DataFrame(all_true.copy())\ntrue['id'] = np.arange(len(true))\n\ncv = score(solution=true, submission=oof, row_id_column_name='id')\nprint('CV Score with EEG Spectrograms =',cv)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# CV Score using Train Means","metadata":{}},{"cell_type":"code","source":"oof = pd.DataFrame(all_oof2.copy())\noof['id'] = np.arange(len(oof))\n\ntrue = pd.DataFrame(all_true.copy())\ntrue['id'] = np.arange(len(true))\n\ncv = score(solution=true, submission=oof, row_id_column_name='id')\nprint('CV Score with EEG Spectrograms =',cv)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Submit to Kaggle LB","metadata":{}},{"cell_type":"code","source":"del all_eegs, train; gc.collect()\ntest = pd.read_csv('/kaggle/input/hms-harmful-brain-activity-classification/test.csv')\nprint('Test shape:',test.shape)\ntest.head()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"all_eegs2 = {}\nDISPLAY = 1\nEEG_IDS2 = test.eeg_id.unique()\nPATH2 = '/kaggle/input/hms-harmful-brain-activity-classification/test_eegs/'\n\nprint('Processing Test EEG parquets...'); print()\nfor i,eeg_id in enumerate(EEG_IDS2):\n        \n    # SAVE EEG TO PYTHON DICTIONARY OF NUMPY ARRAYS\n    data = eeg_from_parquet(f'{PATH2}{eeg_id}.parquet', i<DISPLAY)\n    all_eegs2[eeg_id] = data","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# INFER MLP ON TEST\npreds = []\nmodel = build_model()\ntest_gen = DataGenerator(test, shuffle=False, batch_size=64, eegs=all_eegs2, mode='test')\n\nprint('Inferring test... ',end='')\nfor i in range(FOLDS_TO_TRAIN):\n    print(f'fold {i+1}, ',end='')\n    model.load_weights(f'WaveNet_Model/WaveNet_fold{i}.h5')\n    pred = model.predict(test_gen, verbose=0)\n    preds.append(pred)\npred = np.mean(preds,axis=0)\nprint()\nprint('Test preds shape',pred.shape)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# CREATE SUBMISSION.CSV\nfrom IPython.display import display\n\nsub = pd.DataFrame({'eeg_id':test.eeg_id.values})\nsub[TARGETS] = pred\nsub.to_csv('submission.csv',index=False)\nprint('Submission shape',sub.shape)\ndisplay( sub.head() )\n\n# SANITY CHECK TO CONFIRM PREDICTIONS SUM TO ONE\nprint('Sub row 0 sums to:',sub.iloc[0,-6:].sum())","metadata":{"trusted":true},"execution_count":null,"outputs":[]}]}