{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.10.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"},{"sourceId":2378330,"sourceType":"datasetVersion","datasetId":492658},{"sourceId":8013758,"sourceType":"datasetVersion","datasetId":4721254},{"sourceId":8013763,"sourceType":"datasetVersion","datasetId":4721258},{"sourceId":8054288,"sourceType":"datasetVersion","datasetId":4750227},{"sourceId":8061266,"sourceType":"datasetVersion","datasetId":4755160}],"dockerImageVersionId":30665,"isInternetEnabled":false,"language":"python","sourceType":"notebook","isGpuEnabled":true}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"# General\nimport os\nimport gc\nimport sys\nimport cv2\nimport time\nimport json\nimport math\nimport glob\nimport random\nimport numpy as np\nimport pandas as pd\nfrom tqdm.auto import tqdm\n\n# Visiarize\nimport matplotlib.pyplot as plt\nimport seaborn as sns\n\n# torch\nimport torch\nimport torch.nn as nn\nimport torch.nn.functional as F\nfrom torch import optim\nfrom torch.cuda.amp import autocast\nfrom torch.utils.data import Dataset, DataLoader\n\n# Augmentation\nimport albumentations as A\nfrom albumentations.pytorch import ToTensorV2\n\n# timm\nimport timm\n\n# denoise\nimport pywt\n# 音響解析および信号処理\nimport librosa\n\n# type hints\nfrom typing import Dict, List\n\n# Warnings\nimport warnings\nwarnings.filterwarnings(\"ignore\")\n\nos.environ[\"CUDA_VISIBLE_DEVICES\"] = \"0\"","metadata":{"execution":{"iopub.status.busy":"2024-04-08T08:10:06.036162Z","iopub.execute_input":"2024-04-08T08:10:06.036628Z","iopub.status.idle":"2024-04-08T08:10:17.471274Z","shell.execute_reply.started":"2024-04-08T08:10:06.036593Z","shell.execute_reply":"2024-04-08T08:10:17.469936Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"device = torch.device(\"cuda\" if torch.cuda.is_available() else \"cpu\")\nprint(f\"Using Device is {device}\")","metadata":{"execution":{"iopub.status.busy":"2024-04-08T08:10:17.473877Z","iopub.execute_input":"2024-04-08T08:10:17.474620Z","iopub.status.idle":"2024-04-08T08:10:17.482533Z","shell.execute_reply.started":"2024-04-08T08:10:17.474584Z","shell.execute_reply":"2024-04-08T08:10:17.481061Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class CFG:\n    SEED              = 42\n    base_dir          = \"/kaggle/input/hms-harmful-brain-activity-classification\"\n    # KE\n    # GKF\n    ke_model_b4g_dir  = \"/kaggle/input/hms-n-per-ke-groupkf-b4-5fold-models\"\n\n    # Raw (512, 512, 3)\n    # GKF\n    r_model_b3g_dir  = \"/kaggle/input/hms-n-per-rl-groupkf-b3-5fold-models\"\n    r_model_v2sg_dir = \"/kaggle/input/hms-n-per-r-gkf-v2s-5fold-models\"\n    r_model_b4g2_dir = \"/kaggle/input/hms-n-per-r-gkf-b4-5fold-models\"\n\n    # Kaggle Spectrogram\n    use_kaggle_spec   = True\n    \n    # eeg Spectrogram\n    use_eeg_spec      = True\n    \n    # Raw eeg\n    use_raw_eeg       = False\n    downsample_rate   = 5 # 2_000\n\n    \n    batch_size    = 8\n    num_workers   = os.cpu_count()\n    debug         = False\n    \ncf = CFG()\n","metadata":{"execution":{"iopub.status.busy":"2024-04-08T08:10:20.878097Z","iopub.execute_input":"2024-04-08T08:10:20.878558Z","iopub.status.idle":"2024-04-08T08:10:20.886577Z","shell.execute_reply.started":"2024-04-08T08:10:20.878526Z","shell.execute_reply":"2024-04-08T08:10:20.884848Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def seed_everything(seed):\n    random.seed(seed)\n    np.random.seed(seed)\n    torch.manual_seed(seed)\n    os.environ[\"PYTHONHASHSEED\"] = str(seed)\n    if torch.cuda.is_available():\n        torch.cuda.manual_seed(seed)\n        torch.backends.cudnn.deterministic=False # if T4 False else True (speed up)\n        torch.backends.cudnn.benchmark=True     # if T4  True else False (speed up)\n    print(\"Seed Setting Done!\")\nseed_everything(cf.SEED)","metadata":{"execution":{"iopub.status.busy":"2024-04-08T08:10:22.456937Z","iopub.execute_input":"2024-04-08T08:10:22.457397Z","iopub.status.idle":"2024-04-08T08:10:22.469623Z","shell.execute_reply.started":"2024-04-08T08:10:22.457364Z","shell.execute_reply":"2024-04-08T08:10:22.468598Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"test = pd.read_csv(os.path.join(cf.base_dir, \"test.csv\"))\ntest.shape","metadata":{"execution":{"iopub.status.busy":"2024-04-07T04:30:14.399451Z","iopub.execute_input":"2024-04-07T04:30:14.400333Z","iopub.status.idle":"2024-04-07T04:30:14.421711Z","shell.execute_reply.started":"2024-04-07T04:30:14.400140Z","shell.execute_reply":"2024-04-07T04:30:14.420569Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"sub = pd.read_csv(os.path.join(cf.base_dir, \"sample_submission.csv\"))\nsub","metadata":{"execution":{"iopub.status.busy":"2024-04-08T08:10:30.955388Z","iopub.execute_input":"2024-04-08T08:10:30.955903Z","iopub.status.idle":"2024-04-08T08:10:30.992454Z","shell.execute_reply.started":"2024-04-08T08:10:30.955865Z","shell.execute_reply":"2024-04-08T08:10:30.990904Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"label_cols = [col for col in sub.columns if \"_vote\" in col]\nlabel_cols","metadata":{"execution":{"iopub.status.busy":"2024-04-08T08:10:31.321726Z","iopub.execute_input":"2024-04-08T08:10:31.322112Z","iopub.status.idle":"2024-04-08T08:10:31.329046Z","shell.execute_reply.started":"2024-04-08T08:10:31.322083Z","shell.execute_reply":"2024-04-08T08:10:31.327961Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Kaggle Spectrograms","metadata":{}},{"cell_type":"code","source":"spec_paths = os.listdir(os.path.join(cf.base_dir, \"test_spectrograms\"))\nprint(f\"There are {len(spec_paths):,} Spectrogram Parquets\")","metadata":{"execution":{"iopub.status.busy":"2024-04-07T04:30:14.463997Z","iopub.execute_input":"2024-04-07T04:30:14.464496Z","iopub.status.idle":"2024-04-07T04:30:14.477050Z","shell.execute_reply.started":"2024-04-07T04:30:14.464467Z","shell.execute_reply":"2024-04-07T04:30:14.475793Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"if cf.use_kaggle_spec:\n    print(\"Make Kaggle Spectrograms Data\")\n    kaggle_spectrograms = dict()\n    for file_name in tqdm(spec_paths):\n        tmp = pd.read_parquet(os.path.join(cf.base_dir, \"test_spectrograms\", f\"{file_name}\"))\n        name= int(file_name.split(\".\")[0])\n        kaggle_spectrograms[name] = tmp.iloc[:, 1:].values #remove time\nelse:\n    print(\"Not Use kaggle Spectrograms\")\n    kaggle_spectrograms = None","metadata":{"execution":{"iopub.status.busy":"2024-04-07T04:30:14.478670Z","iopub.execute_input":"2024-04-07T04:30:14.479098Z","iopub.status.idle":"2024-04-07T04:30:14.732751Z","shell.execute_reply.started":"2024-04-07T04:30:14.479055Z","shell.execute_reply":"2024-04-07T04:30:14.731960Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"if cf.debug:\n    print(kaggle_spectrograms[853520].shape)","metadata":{"execution":{"iopub.status.busy":"2024-04-07T04:30:14.736821Z","iopub.execute_input":"2024-04-07T04:30:14.737709Z","iopub.status.idle":"2024-04-07T04:30:14.742953Z","shell.execute_reply.started":"2024-04-07T04:30:14.737678Z","shell.execute_reply":"2024-04-07T04:30:14.742093Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def mean_std_standardize_spec(img):\n    img = np.clip(a=img, a_min=np.exp(-4), a_max=np.exp(8))\n    img = np.log(img)\n    ep  = 1e-6\n    mu  = np.nanmean(img.flatten())\n    std = np.nanstd(img.flatten())\n    img = (img-mu)/(std+ep)\n    img = np.nan_to_num(img, nan=0.0)\n    return img\n\ndef min_max_standardize_spec(img):\n    img = np.clip(a=img, a_min=np.exp(-4), a_max=np.exp(8))\n    img = np.log(img)\n    ep  = 1e-5\n    img = np.nan_to_num(img, nan=0.0)\n    mn  = img.flatten().min()\n    mx  = img.flatten().max()\n    img = 255 * (img - mn) / (mx - mn + ep)\n    return img\n\n\ndef mean_std_standardize_eeg(img):\n    mu  = np.nanmean(img.flatten())\n    std = np.nanstd(img.flatten())\n    ep  = 1e-6\n    img = (img-mu)/(std+ep)\n    img = np.nan_to_num(img, nan=0.0)\n    return img\n\ndef min_max_standardize_eeg(img):\n    ep  = 1e-5\n    mn  = img.flatten().min()\n    mx  = img.flatten().max()\n    img = 255 * (img - mn) / (mx - mn + ep)\n    return img","metadata":{"execution":{"iopub.status.busy":"2024-04-07T04:30:14.744422Z","iopub.execute_input":"2024-04-07T04:30:14.745053Z","iopub.status.idle":"2024-04-07T04:30:14.757716Z","shell.execute_reply.started":"2024-04-07T04:30:14.745023Z","shell.execute_reply":"2024-04-07T04:30:14.756675Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def generate_spec_img(kaggle_spec:np.array=None, \n                      eeg_spec:np.array=None\n                     ):\n    if kaggle_spec is not None and eeg_spec is None:\n        if cf.debug:\n            print(\"Use kaggle spectrogram\")\n        imgU = kaggle_spec\n        imgL = kaggle_spec\n    elif kaggle_spec is None and eeg_spec is not None:\n        if cf.debug:\n            print(\"Use eeg    spectrogram\")\n        imgU = eeg_spec\n        imgL = eeg_spec\n    else:\n        if cf.debug:\n            print(\"Use kaggle & eeg Spectrogram\")\n        imgU = kaggle_spec\n        imgL = eeg_spec\n        \n        \n    size      = (512, 512, 3)\n    X         = np.zeros(size, dtype=\"float32\")\n    padding   = 56\n    half_size = size[0]//2\n    \n    \"\"\"\n    upper = 0 => 3, 1 => 3, 2 => 3,\n    lower = 0 => 3, 1 => 3, 3 => 3\n    \n    \"\"\"\n    \n    # 0 upper = LL, LP : LL, RP (0, 1, 0, 2)\n    # 0 lower = LL, RL : LP, LL (0, 3, 1, 0)\n    \n    # 1 upper = LP, RP : LP, RL (1, 2, 1, 3)\n    # 1 lower = RP, LL : RP, LP (2, 0, 2, 1)\n    \n    # 2 upper = RP, RL : RL, LL (2, 3, 3, 0)\n    # 2 lower = RL, LP : RL, RP (3, 1, 3, 2)\n\n    # Chnnel  0 left half upper\n    X[0  +padding : 100+padding, :half_size, 0]  = imgU[:, 22:-22, 0] # LL\n    X[100+padding : 200+padding, :half_size, 0]  = imgU[:, 22:-22, 1] # LP\n    # right\n    X[0  +padding : 100+padding, half_size: , 0] = imgU[:, 22:-22, 0] # LL\n    X[100+padding : 200+padding, half_size: , 0] = imgU[:, 22:-22, 2] # RP\n    \n\n    # Channel 1 left half upper\n    X[0  +padding : 100+padding, :half_size, 1]  = imgU[:, 22:-22, 1] # LP\n    X[100+padding : 200+padding, :half_size, 1]  = imgU[:, 22:-22, 2] # RP\n    # right\n    X[0  +padding : 100+padding, half_size: , 1] = imgU[:, 22:-22, 1] # LP\n    X[100+padding : 200+padding, half_size: , 1] = imgU[:, 22:-22, 3] # RL\n    \n\n    # Channel 2 left half upper\n    X[0  +padding : 100+padding, :half_size, 2]  = imgU[:, 22:-22, 2] # RP\n    X[100+padding : 200+padding, :half_size, 2]  = imgU[:, 22:-22, 3] # RL\n    # right\n    X[0  +padding : 100+padding, half_size: , 2] = imgU[:, 22:-22, 3] # RL\n    X[100+padding : 200+padding, half_size: , 2] = imgU[:, 22:-22, 0] # LL\n    \n    \n    \n    ##### Lower ######\n    \n    # Chnnel  0 left half lower\n    X[200+padding : 300+padding, :half_size, 0]  = imgL[:, 22:-22, 0] # LL\n    X[300+padding : 400+padding, :half_size, 0]  = imgL[:, 22:-22, 3] # RL\n    # right\n    X[200+padding : 300+padding, half_size: , 0] = imgL[:, 22:-22, 1] # RP\n    X[300+padding : 400+padding, half_size: , 0] = imgL[:, 22:-22, 0] # LL\n    \n    # Channel 1 left half lower\n    X[200+padding : 300+padding, :half_size, 1]  = imgL[:, 22:-22, 2] # RP\n    X[300+padding : 400+padding, :half_size, 1]  = imgL[:, 22:-22, 0] # LL\n    # right\n    X[200+padding : 300+padding, half_size: , 1] = imgL[:, 22:-22, 2] # RP\n    X[300+padding : 400+padding, half_size: , 1] = imgL[:, 22:-22, 1] # RP\n\n    # Channel 2 left half lower\n    X[200+padding : 300+padding, :half_size, 2]  = imgL[:, 22:-22, 3] # RL\n    X[300+padding : 400+padding, :half_size, 2]  = imgL[:, 22:-22, 1] # RP\n    # right\n    X[200+padding : 300+padding, half_size: , 2] = imgL[:, 22:-22, 3] # RL\n    X[300+padding : 400+padding, half_size: , 2] = imgL[:, 22:-22, 2] # RP\n    \n    \n    return X","metadata":{"execution":{"iopub.status.busy":"2024-04-07T04:30:14.759445Z","iopub.execute_input":"2024-04-07T04:30:14.759849Z","iopub.status.idle":"2024-04-07T04:30:14.786252Z","shell.execute_reply.started":"2024-04-07T04:30:14.759818Z","shell.execute_reply":"2024-04-07T04:30:14.785076Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"eegs_paths = os.listdir(os.path.join(cf.base_dir, \"test_eegs\"))\nprint(f\"There are {len(eegs_paths):,}  EEG Spectograms\")","metadata":{"execution":{"iopub.status.busy":"2024-04-07T04:30:14.787962Z","iopub.execute_input":"2024-04-07T04:30:14.788392Z","iopub.status.idle":"2024-04-07T04:30:14.803302Z","shell.execute_reply.started":"2024-04-07T04:30:14.788361Z","shell.execute_reply":"2024-04-07T04:30:14.802147Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### EEG Spectrograms","metadata":{}},{"cell_type":"code","source":"def spectrogram_from_eeg(path, EEG_FEATS):\n    eeg    = pd.read_parquet(path)\n    middle = (len(eeg) - 10_000) // 2\n    eeg    = eeg.iloc[middle: middle + 10_000]\n\n    # VARIABLE TO HOLD SPECTROGRAM\n    img = np.zeros((100, 300, 4), dtype='float32')\n\n    for k in range(4):\n        COLS = EEG_FEATS[k]\n\n        for kk in range(4):\n            # FILL NANS\n            x1 = eeg[COLS[kk]].values\n            x2 = eeg[COLS[kk+1]].values\n            m = np.nanmean(x1)\n            if np.isnan(x1).mean()<1: \n                x1 = np.nan_to_num(x1,nan=m)\n            else: \n                x1[:] = 0\n            m = np.nanmean(x2)\n            if np.isnan(x2).mean()<1: \n                x2 = np.nan_to_num(x2,nan=m)\n            else: \n                x2[:] = 0\n\n            # COMPUTE PAIR DIFFERENCES\n            x = x1 - x2\n\n            # RAW SPECTROGRAM\n            mel_spec = librosa.feature.melspectrogram(y=x, \n                                                      sr=200, \n                                                      hop_length=len(x)//300, \n                                                      n_fft=1024, \n                                                      n_mels=100, \n                                                      fmin=0, \n                                                      fmax=20, \n                                                      win_length=128\n                                                     )\n\n            # LOG TRANSFORM\n            width       = (mel_spec.shape[1]//30)*30\n            mel_spec_db = librosa.power_to_db(mel_spec, ref=np.max).astype(np.float32)[:,:width]\n            img[:,:,k] += mel_spec_db\n\n        # AVERAGE THE 4 MONTAGE DIFFERENCES\n        img[:,:,k] /= 4.0\n    return img\n\ndef create_eeg_spec(df, feats, save=False):\n    eeg_id_list = df[\"eeg_id\"].unique()\n    all_eegs = {}\n    for eeg_id in tqdm(eeg_id_list, total=len(eeg_id_list)):\n        path= os.path.join(cf.base_dir, \"test_eegs\", f\"{eeg_id}.parquet\")\n        img = spectrogram_from_eeg(path, feats)\n\n        all_eegs[eeg_id] = img\n    if save:\n        EEG_SPEC_DIR = \"./eeg_spectrogram\"\n        if not os.path.exists(EEG_SPEC_DIR):\n            os.makedirs(EEG_SPEC_DIR)\n        np.save(os.path.join(EEG_SPEC_DIR, \"eeg_specs\"), all_eegs)\n        print(\"Save Done\")\n    return all_eegs","metadata":{"execution":{"iopub.status.busy":"2024-04-07T04:30:14.805230Z","iopub.execute_input":"2024-04-07T04:30:14.806123Z","iopub.status.idle":"2024-04-07T04:30:14.823475Z","shell.execute_reply.started":"2024-04-07T04:30:14.806084Z","shell.execute_reply":"2024-04-07T04:30:14.822451Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# LL = Left  Temporal    Chain\n# LP = Left  Parasagital Chain\n# RP = Right Parasagital Chain\n# RR = Right Temporal    Chain\n\nkaggle_spec_name = ['LL', 'LP', 'RL', 'RP']\n\negg_spec_name    = ['LL', 'LP', 'RP', 'RL']\n\n\nEEG_FEATS = [['Fp1','F7','T3','T5','O1'],\n             ['Fp1','F3','C3','P3','O1'],\n             ['Fp2','F8','T4','T6','O2'],\n             ['Fp2','F4','C4','P4','O2']]","metadata":{"execution":{"iopub.status.busy":"2024-04-07T04:30:14.825292Z","iopub.execute_input":"2024-04-07T04:30:14.826043Z","iopub.status.idle":"2024-04-07T04:30:14.838251Z","shell.execute_reply.started":"2024-04-07T04:30:14.826005Z","shell.execute_reply":"2024-04-07T04:30:14.837183Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"if cf.use_eeg_spec:\n    print(\"Make EEG Spectrogram\")\n    all_eegs = create_eeg_spec(test, EEG_FEATS, save=False)\nelse:\n    print(\"Not Use EEG Spectrogram\")\n    all_eegs = None","metadata":{"execution":{"iopub.status.busy":"2024-04-07T04:30:14.839754Z","iopub.execute_input":"2024-04-07T04:30:14.840408Z","iopub.status.idle":"2024-04-07T04:30:30.310347Z","shell.execute_reply.started":"2024-04-07T04:30:14.840375Z","shell.execute_reply":"2024-04-07T04:30:30.308812Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"if cf.debug:\n    print(all_eegs[3911565283].shape)","metadata":{"execution":{"iopub.status.busy":"2024-04-07T04:30:30.312725Z","iopub.execute_input":"2024-04-07T04:30:30.314246Z","iopub.status.idle":"2024-04-07T04:30:30.326434Z","shell.execute_reply.started":"2024-04-07T04:30:30.314182Z","shell.execute_reply":"2024-04-07T04:30:30.324710Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Raw EEG ","metadata":{}},{"cell_type":"code","source":"RAW_EEG_FEATS = ['Fp1','T3','C3','O1','Fp2','C4','T4','O2']","metadata":{"execution":{"iopub.status.busy":"2024-04-07T04:30:30.329747Z","iopub.execute_input":"2024-04-07T04:30:30.331980Z","iopub.status.idle":"2024-04-07T04:30:30.341840Z","shell.execute_reply.started":"2024-04-07T04:30:30.331919Z","shell.execute_reply":"2024-04-07T04:30:30.340267Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"FEAT2IDX = {k:e for e, k in enumerate(RAW_EEG_FEATS)}\nprint(FEAT2IDX)\nGROUP = [('Fp1', 'T3'), ('T3', 'O1'), \n         ('Fp1', 'C3'), ('C3', 'O1'), \n         ('Fp2', 'C4'), ('C4', 'O2'), \n         ('Fp2', 'T4'), ('T4', 'O2')]","metadata":{"execution":{"iopub.status.busy":"2024-04-07T04:30:30.343652Z","iopub.execute_input":"2024-04-07T04:30:30.344414Z","iopub.status.idle":"2024-04-07T04:30:30.358574Z","shell.execute_reply.started":"2024-04-07T04:30:30.344372Z","shell.execute_reply":"2024-04-07T04:30:30.356890Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from scipy.signal import butter, lfilter, filtfilt, iirnotch\nfrom scipy.ndimage import gaussian_filter\n\n\ndef quantize_data(data, classes):\n    mu_x = mu_law_encoding(data, classes)\n    return mu_x\n\ndef mu_law_encoding(data, mu):\n    mu_x = np.sign(data) * np.log(1 + mu * np.abs(data)) / np.log(mu + 1)\n    return mu_x\n\ndef butter_lowpass_filter(data, cut_off_freq=20, sampling_rate=200, order=4):\n    nyquist        = 0.5 * sampling_rate    # eg 100\n    normal_cut_off = cut_off_freq / nyquist # eg 0.2\n    b, a = butter(N=order,\n                  Wn=normal_cut_off, \n                  btype=\"low\", \n                  analog=False\n                 )\n    filtered_data = lfilter(b, a, data, axis=0)\n    return filtered_data\n\ndef process_sample(sample):\n        # Normalize the sample data\n        #sample = (sample - np.mean(sample, axis=0)) / np.std(sample, axis=0)\n        sample = np.clip(sample, a_min=-1024, a_max=1024)\n        sample = np.nan_to_num(sample, nan=0) / 32.0\n        sample = butter_lowpass_filter(sample)\n        #sample = quantize_data(sample, 1)\n        return sample\n\ndef eeg_from_parquet(eeg_id, feat, mode=\"test\", downsample_rate=cf.downsample_rate):\n    path   = os.path.join(cf.base_dir, f\"{mode}_eegs\", f\"{eeg_id}.parquet\")\n    eeg    = pd.read_parquet(path, columns=feat)\n    size   = 10_000\n    rows   = len(eeg)\n    offset = (rows - size)//2\n    eeg = eeg.iloc[offset : offset + size]\n    \n    assert eeg.shape[0] == size, \"MissMathc length..\"\n    # Cobert to numpy\n    data = np.zeros( (size, len(feat)) )\n    for e, col in enumerate(feat):\n        # fill nan\n        x = eeg[col].values.astype(\"float32\")\n        m = np.nanmean(x)\n        if np.isnan(x).mean() < 1:\n            x = np.nan_to_num(x, nan=m)\n        else:\n            x[:] = 0\n        \n        data[:, e] = x\n    for e, (start, end) in enumerate(GROUP):\n        data[:, e] = data[:, FEAT2IDX[start]] - data[:, FEAT2IDX[end]]\n    \n    data = process_sample(data)\n    data = data[::downsample_rate, :] # (2000, 8)\n    return data\n    \ndef create_raw_eeg(df, save=False, mode=\"test\", select_feat=None):\n    print(f\"Mode : {mode}\")\n    eeg_ids = df[\"eeg_id\"].unique().tolist()\n    if select_feat is None:\n        eeg_df  = pd.read_parquet(os.path.join(cf.base_dir, f\"{mode}_eegs\", f\"{eeg_ids[0]}.parquet\"))\n        eeg_feat= eeg_df.columns\n        del eeg_df\n        _=gc.collect()\n    else:\n        eeg_feat= select_feat\n    print(f\"There are {len(eeg_feat)} raw eeg features\")\n    print(list(eeg_feat))\n    print()\n    \n    print(f\"{mode} data have {len(eeg_ids):,} unique EEG ids\")\n    \n    all_raw_eegs = dict()\n    for eeg_id in tqdm(eeg_ids):\n        data = eeg_from_parquet(eeg_id, eeg_feat, mode)\n        all_raw_eegs[eeg_id] = data\n    if save:\n        RAW_EEG_DIR = \"./raw_eeg\"\n        if not os.path.exists(RAW_EEG_DIR):\n            os.makedirs(RAW_EEG_DIR)\n        np.save(os.path.join(RAW_EEG_DIR, f\"eegs_{len(eeg_feat)}ch\"), all_raw_eegs)\n        \n    return all_raw_eegs","metadata":{"execution":{"iopub.status.busy":"2024-04-07T04:30:30.360954Z","iopub.execute_input":"2024-04-07T04:30:30.361593Z","iopub.status.idle":"2024-04-07T04:30:30.410713Z","shell.execute_reply.started":"2024-04-07T04:30:30.361538Z","shell.execute_reply":"2024-04-07T04:30:30.408683Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"if cf.use_raw_eeg:\n    print(\"Create Raw EEG Data\")\n    raw_eegs = create_raw_eeg(test, mode=\"test\", select_feat=RAW_EEG_FEATS)\nelse:\n    print(\"Not Use Raw EEG Data\")\n    raw_eegs = None","metadata":{"execution":{"iopub.status.busy":"2024-04-07T04:30:30.413923Z","iopub.execute_input":"2024-04-07T04:30:30.415205Z","iopub.status.idle":"2024-04-07T04:30:30.425227Z","shell.execute_reply.started":"2024-04-07T04:30:30.415137Z","shell.execute_reply":"2024-04-07T04:30:30.424019Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### DataSet","metadata":{}},{"cell_type":"code","source":"class CustomDataset(Dataset):\n    def __init__(self, \n                 df:pd.DataFrame,\n                 kaggle_spec:np.array=kaggle_spectrograms,\n                 eeg_spec:np.array=all_eegs, \n                 raw_eeg:np.array=raw_eegs,\n                 mode:str=\"test\",\n                 augment:bool=False\n                ):\n        self.df          = df\n        self.kaggle_spec = kaggle_spec\n        self.eeg_spec    = eeg_spec\n        self.raw_eeg     = raw_eeg\n        self.mode        = mode\n        self.augment     = augment\n        \n    def __len__(self):\n        return len(self.df)\n    \n    def __getitem__(self, index):\n        row = self.df.iloc[index]\n        y   = np.zeros(len(label_cols), dtype=\"float32\")\n        if self.mode != \"test\":\n            y[:] = row[label_cols].values.astype(np.float32)\n            \n        # kaggle spectrogram only    \n        if self.kaggle_spec is not None and self.eeg_spec is None:\n            if cf.debug:\n                print(\"Kaggle Only\")\n            img = self.generate_kaggle_specs_standardize(index, row)\n            X   = generate_spec_img(kaggle_spec=img)\n            \n        # eeg spectrogram only\n        elif self.kaggle_spec is None and self.eeg_spec is not None:\n            if cf.debug:\n                print(\"EEG Only\")\n            img = self.generate_eeg_specs_standardize(index, row)\n            X   = generate_spec_img(eeg_spec=img)\n            \n        # Both kaggle & eeg\n        elif self.kaggle_spec is not None and self.eeg_spec is not None:\n            if cf.debug:\n                print(\"Both\")\n            k_img = self.generate_kaggle_specs_standardize(index, row)\n            e_img = self.generate_eeg_specs_standardize(index, row)\n            X     = generate_spec_img(kaggle_spec=k_img, \n                                      eeg_spec=e_img\n                                     )\n        else:\n            pass\n        \n        # Raw eeg only\n        if self.raw_eeg is not None:\n            if cf.debug:\n                print(\"add Raw eeg\")\n            raw = self.raw_eeg[row[\"eeg_id\"]]\n        \n        # Raw eeg & spec\n        if  self.raw_eeg is not None and (self.eeg_spec is not None or self.kaggle_spec is not None):\n            if cf.debug:\n                print(\"raw eeg & spec\")\n            X = (X, raw)\n            \n            \n        #### Retruns ####\n        \n        # Raw eeg only\n        if self.raw_eeg is not None and (self.kaggle_spec is None and self.eeg_spec is None):\n            if cf.debug:\n                print(\"retrun raw eeg only\")\n            if self.augment:\n                 raw = _transform(raw)\n                    \n            return {\"raw\"   : torch.tensor(raw, dtype=torch.float32),\n                    \"label\" : torch.tensor(y, dtype=torch.float32)\n                   }\n\n        # Raw eeg & spec\n        elif self.raw_eeg is not None and (self.kaggle_spec is not None or self.eeg_spec is not None):\n            if cf.debug:\n                print(\"retrun raw eeg & spec\")\n            if self.augment:\n                spec = _transform(X[0])\n            spec = X[0]\n            raw  = X[1]\n            return {\"img\"   : torch.tensor(spec, dtype=torch.float32),\n                    \"raw\"   : torch.tensor(raw, dtype=torch.float32),\n                    \"label\" : torch.tensor(y, dtype=torch.float32)\n                   }\n        elif self.raw_eeg is None and (self.kaggle_spec is not None or self.eeg_spec is not None):\n            if cf.debug:\n                print(\"return spec only\")\n            if self.augment:\n                X = _transform(X)\n                    \n            return {\"img\"   : torch.tensor(X, dtype=torch.float32),\n                    \"label\" : torch.tensor(y, dtype=torch.float32)\n                   }\n        else:\n            print(\"Error... Non inputs\")\n            \n\n    def generate_kaggle_specs_standardize(self, index, row):\n        \n        if self.mode == \"test\":\n            offset = 0\n        else:\n            offset = int( (row[\"min\"] + row[\"max\"]) // 4 )\n            \n        spec_id    = row[\"spectrogram_id\"]\n        spec       = self.kaggle_spec[spec_id]\n        feat_index = [0, 1, 3, 2]\n        img        = [spec[offset: offset+300, k*100: (k+1)* 100].T for k in feat_index]\n        img        = np.stack(img, axis=-1)\n        img        = min_max_standardize_spec(img)\n        return img\n\n    def generate_eeg_specs_standardize(self, index, row):\n        eeg_id = row[\"eeg_id\"]\n        img    = self.eeg_spec[eeg_id]\n        img    = min_max_standardize_eeg(img)\n        return img\n    \n    def _transform(self, img):\n        params1 = {\n                    \"num_masks_x\"  : 1,    \n                    \"mask_x_length\": (0, 20), # This line changed from fixed  to a range\n                    \"fill_value\"   : (0, 1, 2),\n                    }\n        params2 = {    \n                    \"num_masks_y\"  : 1,    \n                    \"mask_y_length\": (0, 20),\n                    \"fill_value\"   : (0, 1, 2),    \n                    }\n        params3 = {    \n                    \"num_masks_x\"  : (2, 4),\n                    \"num_masks_y\"  : 5,    \n                    \"mask_y_length\": 8,\n                    \"mask_x_length\": (10, 20),\n                    \"fill_value\"   : (0, 1, 2),  \n                    }\n        \n        transforms = A.Compose([A.XYMasking(**params1, p=0.3),\n                                A.XYMasking(**params2, p=0.3),\n                                A.XYMasking(**params3, p=0.3),\n                               ]\n                              )\n        return transforms(image=img)['image']    ","metadata":{"execution":{"iopub.status.busy":"2024-04-07T04:30:30.427063Z","iopub.execute_input":"2024-04-07T04:30:30.427519Z","iopub.status.idle":"2024-04-07T04:30:30.460139Z","shell.execute_reply.started":"2024-04-07T04:30:30.427455Z","shell.execute_reply":"2024-04-07T04:30:30.458763Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def get_dataloaders(df):\n    test_dataset = CustomDataset(df,\n                                 kaggle_spec=kaggle_spectrograms if cf.use_kaggle_spec else None ,\n                                 eeg_spec=all_eegs if cf.use_eeg_spec else None, \n                                 raw_eeg=raw_eegs if cf.use_raw_eeg else None,\n                                 augment=False\n                                 )\n    dataloaders  = dict()\n    \n    dataloaders[\"test\"]  = DataLoader(test_dataset, \n                                      batch_size=cf.batch_size*2,\n                                      shuffle=False, \n                                      num_workers=cf.num_workers,\n                                      pin_memory=True, \n                                      drop_last=False\n                                     )\n    return dataloaders\n","metadata":{"execution":{"iopub.status.busy":"2024-04-07T04:30:30.461420Z","iopub.execute_input":"2024-04-07T04:30:30.462484Z","iopub.status.idle":"2024-04-07T04:30:30.476252Z","shell.execute_reply.started":"2024-04-07T04:30:30.462276Z","shell.execute_reply":"2024-04-07T04:30:30.475302Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"if cf.debug:\n    s_dataloaders = get_dataloaders(test)\n    for s_batch in s_dataloaders[\"test\"]:\n        print(f\"X batch Shape : {s_batch['img'].shape}\")\n        print(f\"y batch Shape : {s_batch['label'].shape}\")\n        break","metadata":{"execution":{"iopub.status.busy":"2024-04-07T04:30:30.478229Z","iopub.execute_input":"2024-04-07T04:30:30.478693Z","iopub.status.idle":"2024-04-07T04:30:30.739677Z","shell.execute_reply.started":"2024-04-07T04:30:30.478646Z","shell.execute_reply":"2024-04-07T04:30:30.738642Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Model","metadata":{}},{"cell_type":"code","source":"class GeM(nn.Module):\n    def __init__(self, p=3, eps=1e-6):\n        super().__init__()\n        self.p   = nn.Parameter(torch.ones(1) * p)\n        self.eps = eps\n\n    def forward(self, x):\n        return self.gem(x, p=self.p, eps=self.eps)\n        \n    def gem(self, x, p=3, eps=1e-6):\n        return F.avg_pool2d(x.clamp(min=eps).pow(p), (x.size(-2), x.size(-1))).pow(1./p)\n        \n    def __repr__(self):\n        return self.__class__.__name__ + \\\n                '(' + 'p=' + '{:.4f}'.format(self.p.data.tolist()[0]) + \\\n                ', ' + 'eps=' + str(self.eps) + ')'\n\nif cf.debug:\n    g = GeM()\n    display(g.__repr__())\n\nclass CustomModel(nn.Module):\n    def __init__(self, cf, model_name, num_classes=6, pretrained=False):\n        super().__init__()\n        \n        self.model = timm.create_model(model_name=model_name, \n                                       pretrained=pretrained\n                                      )\n        in_feat = self.model.classifier.in_features\n        self.model.classifier = nn.Identity()\n        self.model.global_pool= nn.Identity()\n        self.pooling = GeM()\n        self.linear  = nn.Linear(in_feat, num_classes)\n    \n    def forward(self, x):\n        x = x.permute(0, 3, 1, 2) # Shape (batch_size, channel, height, width)\n        x = self.model(x) # torch.Size([6, 1408, 16, 16])\n        x = self.pooling(x).flatten(start_dim=1)\n        #print(f\"pooled : {x.shape}\")\n        x = self.linear(x)\n        return x\n    \nclass FoldModels:\n    def __init__(self):\n        self.models  = list()\n        self.softmax = nn.Softmax(dim=1)\n        \n    def __call__(self, inputs):\n        outputs_list = list()\n        for model in self.models:\n            out = model(inputs)\n            outputs_list.append(self.softmax(out).detach().cpu().numpy())\n        avg_pred = np.mean([out for out in outputs_list], axis=0)\n        \n        del outputs_list, out, inputs\n        _=gc.collect()\n        torch.cuda.empty_cache()\n        return avg_pred\n    \n    def add_model(self, model):\n        self.models.append(model)\n    \ndef build_model(cf, model_check_point_list):\n    model = FoldModels()\n    for check_point in model_check_point_list:\n        print(f\"Check Point : {check_point.split('/')[-1]}\")\n        model_name = check_point.split(\"/\")[-1].split(\"-\")[0]\n        _model = CustomModel(cf, model_name, pretrained=False)\n        state  = torch.load(check_point, map_location=device)\n        _model.load_state_dict(state[\"model\"])\n        _model.to(device)\n        _model.eval()\n        model.add_model(_model)\n        \n        del state\n        _=gc.collect()\n        torch.cuda.empty_cache()\n        print(\"Successfully!!!\")\n        print()\n    return model","metadata":{"execution":{"iopub.status.busy":"2024-04-08T08:10:47.235341Z","iopub.execute_input":"2024-04-08T08:10:47.235767Z","iopub.status.idle":"2024-04-08T08:10:47.259280Z","shell.execute_reply.started":"2024-04-08T08:10:47.235730Z","shell.execute_reply":"2024-04-08T08:10:47.258253Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Inference","metadata":{}},{"cell_type":"code","source":"def inference(dataloaders, model):\n    preds = list()\n    stream= tqdm(dataloaders[\"test\"], total=len(dataloaders[\"test\"]), unit=\"test_batch\", desc=\"Infer\")\n    with torch.no_grad():\n        for batch in stream:\n            with autocast(enabled=False):\n                out = model(batch[\"img\"].to(device))\n            preds.append(out)\n            \n    all_preds = np.concatenate(preds)\n    \n    del preds\n    _=gc.collect()\n    \n    return all_preds","metadata":{"execution":{"iopub.status.busy":"2024-04-08T08:10:48.423543Z","iopub.execute_input":"2024-04-08T08:10:48.424189Z","iopub.status.idle":"2024-04-08T08:10:48.431738Z","shell.execute_reply.started":"2024-04-08T08:10:48.424155Z","shell.execute_reply":"2024-04-08T08:10:48.430195Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Check points","metadata":{}},{"cell_type":"code","source":"def create_model_path(model_dir:str):\n    models = os.listdir(os.path.join(model_dir, \"models\"))\n    model_check_point_list = sorted([os.path.join(model_dir, \"models\", p) for p in models])\n    return model_check_point_list","metadata":{"execution":{"iopub.status.busy":"2024-04-08T08:10:49.908455Z","iopub.execute_input":"2024-04-08T08:10:49.909306Z","iopub.status.idle":"2024-04-08T08:10:49.916203Z","shell.execute_reply.started":"2024-04-08T08:10:49.909266Z","shell.execute_reply":"2024-04-08T08:10:49.914813Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### [KE]","metadata":{}},{"cell_type":"code","source":"ke_b4g_cp  = create_model_path(cf.ke_model_b4g_dir)","metadata":{"execution":{"iopub.status.busy":"2024-04-08T08:10:52.470248Z","iopub.execute_input":"2024-04-08T08:10:52.470697Z","iopub.status.idle":"2024-04-08T08:10:52.491718Z","shell.execute_reply.started":"2024-04-08T08:10:52.470666Z","shell.execute_reply":"2024-04-08T08:10:52.490266Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"ke_b4gmodels  = build_model(cf, ke_b4g_cp)","metadata":{"_kg_hide-output":true,"execution":{"iopub.status.busy":"2024-04-08T08:10:52.775412Z","iopub.execute_input":"2024-04-08T08:10:52.775887Z","iopub.status.idle":"2024-04-08T08:11:02.500704Z","shell.execute_reply.started":"2024-04-08T08:10:52.775853Z","shell.execute_reply":"2024-04-08T08:11:02.499519Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"dataloaders = get_dataloaders(test)\nke_b4gpred  = inference(dataloaders, ke_b4gmodels)\n\n\ndel dataloaders\ndel ke_b4gmodels\n_=gc.collect()","metadata":{"_kg_hide-output":true,"execution":{"iopub.status.busy":"2024-04-07T04:30:42.562392Z","iopub.status.idle":"2024-04-07T04:30:42.563001Z","shell.execute_reply.started":"2024-04-07T04:30:42.562679Z","shell.execute_reply":"2024-04-07T04:30:42.562703Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print(\"del kaggle spec\")\ndel kaggle_spectrograms\n\nprint(\"del eeg spec\")\ndel all_eegs\n\nprint(\"del raw eeg\")\ndel raw_eegs\n\n_=gc.collect()","metadata":{"_kg_hide-output":true,"execution":{"iopub.status.busy":"2024-04-07T04:30:42.564655Z","iopub.status.idle":"2024-04-07T04:30:42.565163Z","shell.execute_reply.started":"2024-04-07T04:30:42.564952Z","shell.execute_reply":"2024-04-07T04:30:42.564972Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Raw EEG","metadata":{}},{"cell_type":"code","source":"test = pd.read_csv(os.path.join(cf.base_dir, \"test.csv\"))\ntest.shape","metadata":{"execution":{"iopub.status.busy":"2024-04-07T04:30:42.567289Z","iopub.status.idle":"2024-04-07T04:30:42.568167Z","shell.execute_reply.started":"2024-04-07T04:30:42.567822Z","shell.execute_reply":"2024-04-07T04:30:42.567891Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"OUTPUT_DIR = \"/kaggle/temp/reduced\"\nif not os.path.exists(OUTPUT_DIR):\n    os.makedirs(OUTPUT_DIR)","metadata":{"execution":{"iopub.status.busy":"2024-04-07T04:30:42.571051Z","iopub.status.idle":"2024-04-07T04:30:42.571493Z","shell.execute_reply.started":"2024-04-07T04:30:42.571291Z","shell.execute_reply":"2024-04-07T04:30:42.571308Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# LL = Left Temporal Chain\n# LP = Left Parasagital Chain\n# RP = Right Parasagital Chain\n# RR = Right Temporal Chain\n\nNAMES = ['LL','LP','RP','RR']\n\nFEATS = [['Fp1','F7','T3','T5','O1'],\n         ['Fp1','F3','C3','P3','O1'],\n         ['Fp2','F8','T4','T6','O2'],\n         ['Fp2','F4','C4','P4','O2']]","metadata":{"execution":{"iopub.status.busy":"2024-04-07T04:30:42.572799Z","iopub.status.idle":"2024-04-07T04:30:42.573386Z","shell.execute_reply.started":"2024-04-07T04:30:42.573105Z","shell.execute_reply":"2024-04-07T04:30:42.573127Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Details About the GPU Used\n!nvidia-smi","metadata":{"_kg_hide-output":true,"execution":{"iopub.status.busy":"2024-04-07T04:30:42.574970Z","iopub.status.idle":"2024-04-07T04:30:42.575506Z","shell.execute_reply.started":"2024-04-07T04:30:42.575234Z","shell.execute_reply":"2024-04-07T04:30:42.575256Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Installation of RAPIDS to Use cuSignal\n!cp ../input/rapids/rapids.0.17.0 /opt/conda/envs/rapids.tar.gz\n!cd /opt/conda/envs/ && tar -xzvf rapids.tar.gz > /dev/null\n!rm /opt/conda/envs/rapids.tar.gz\n\nsys.path += [\"/opt/conda/envs/rapids/lib/python3.7/site-packages\"]\nsys.path += [\"/opt/conda/envs/rapids/lib/python3.7\"]\nsys.path += [\"/opt/conda/envs/rapids/lib\"]\n!cp /opt/conda/envs/rapids/lib/libxgboost.so /opt/conda/lib/\n\nimport cupy as cp\nimport cusignal","metadata":{"_kg_hide-output":true,"execution":{"iopub.status.busy":"2024-04-07T04:30:42.577341Z","iopub.status.idle":"2024-04-07T04:30:42.577897Z","shell.execute_reply.started":"2024-04-07T04:30:42.577609Z","shell.execute_reply":"2024-04-07T04:30:42.577630Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from scipy.ndimage import gaussian_filter\nfrom scipy.signal import butter, filtfilt, iirnotch","metadata":{"execution":{"iopub.status.busy":"2024-04-07T04:30:42.579424Z","iopub.status.idle":"2024-04-07T04:30:42.579973Z","shell.execute_reply.started":"2024-04-07T04:30:42.579679Z","shell.execute_reply":"2024-04-07T04:30:42.579701Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"seed_everything(cf.SEED)","metadata":{"execution":{"iopub.status.busy":"2024-04-07T04:30:42.583028Z","iopub.status.idle":"2024-04-07T04:30:42.583592Z","shell.execute_reply.started":"2024-04-07T04:30:42.583317Z","shell.execute_reply":"2024-04-07T04:30:42.583341Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def create_spectrogram_with_cusignal(eeg_data, \n                                     eeg_id, \n                                     start, \n                                     duration, \n                                     low_cut_freq, \n                                     high_cut_freq,\n                                     order_band, \n                                     spec_size_freq, \n                                     spec_size_time, \n                                     nperseg, \n                                     n_overlap, \n                                     nfft, \n                                     sigma_gaussian, \n                                     mean_montage_names,\n                                     electrode_names=NAMES, \n                                     electrode_pairs=FEATS\n                                    ):\n    # Filter Specifications\n    nyquist_freq = 0.5 * 200 # 100\n    low_cut_freq_normalized = low_cut_freq  / nyquist_freq   # eg: 0.7/100 = 0.007\n    high_cut_freq_normalized= high_cut_freq / nyquist_freq   # eg: 20/100  = 0.2\n    \n    # Babdpass and notch filter\n    bandpass_coefficients = butter(N=order_band, \n                                   Wn=[low_cut_freq_normalized,\n                                       high_cut_freq_normalized\n                                      ],\n                                   btype=\"band\"\n                                   )\n    notch_coefficients = iirnotch(w0=60, \n                                  Q=30, \n                                  fs=200\n                                 )\n    spec_size = duration * 200 # 50 * 200 = 10_000\n    start     = start * 200\n    real_start= start + (10_000//2) - (spec_size//2)\n    eeg_data  = eeg_data.iloc[real_start: real_start + spec_size]\n    \n    # spectrogram parameters\n    fs = 200\n    nperseg = nperseg\n    noverlap= n_overlap\n    nfft    = nfft\n    \n    if spec_size_freq <= 0 or spec_size_time <= 0:\n        frequencias_size = int( (nfft // 2) / 5.15198 ) + 1\n        segmentos        = int( (spec_size - noverlap) / (nperseg - noverlap) )\n    else:\n        frequencias_size = spec_size_freq\n        segmentos        = spec_size_time\n        \n    # Initialize spectorogram conainer\n    if cf.debug:\n        print(frequencias_size, segmentos)\n        \n    spectrogram = cp.zeros( (frequencias_size, segmentos, 4), dtype=\"float32\" )\n    \n    processed_eeg = dict()\n    for e, name in enumerate(electrode_names):\n        cols = electrode_pairs[e]\n        processed_eeg[name] = np.zeros(spec_size)\n        \n        for col in range(4):\n            signal = cp.array(eeg_data[cols[col]].values - eeg_data[cols[col + 1]].values)\n            \n            # Handle Nans\n            mean_signal = cp.nanmean(signal)\n            signal      = cp.nan_to_num(signal, nan=mean_signal) if cp.isnan(signal).mean() < 1 else cp.zeros_like(signal)\n            \n            # Filter babdpass and notch\n            signal_filtered = filtfilt(*notch_coefficients,\n                                       signal.get()\n                                      )\n            signal_filtered = filtfilt(*bandpass_coefficients,\n                                       signal_filtered\n                                      )\n            signal = cp.asarray(signal_filtered)\n            \n            \n            frequencies, times, Sxx = cusignal.spectrogram(signal, \n                                                           fs, \n                                                           nperseg=nperseg, \n                                                           noverlap=noverlap, \n                                                           nfft=nfft)\n\n            # Filter frequency range\n            valid_freqs          = (frequencies >= 0.59) & (frequencies <= 20)\n            frequencies_filtered = frequencies[valid_freqs]\n            Sxx_filtered         = Sxx[valid_freqs, :]\n\n            # Logarithmic transformation and normalization using Cupy\n            spectrogram_slice = cp.clip(Sxx_filtered, cp.exp(-4), cp.exp(6))\n            spectrogram_slice = cp.log10(spectrogram_slice)\n\n            normalization_epsilon = 1e-6\n            mean = spectrogram_slice.mean(axis=(0, 1), keepdims=True)\n            std  = spectrogram_slice.std(axis=(0, 1),  keepdims=True)\n            spectrogram_slice = (spectrogram_slice - mean) / (std + normalization_epsilon)\n            \n            spectrogram[:, :, e] += spectrogram_slice\n            processed_eeg[f'{cols[col]}_{cols[col + 1]}'] = signal.get()\n            processed_eeg[name]  += signal.get()\n        \n        # AVERAGE THE 4 MONTAGE DIFFERENCES\n        if mean_montage_names > 0:\n            spectrogram[:, :, e] /= mean_montage_names\n\n    # Convert to NumPy and apply Gaussian filter\n    spectrogram_np = cp.asnumpy(spectrogram)\n    if sigma_gaussian > 0.0:\n        spectrogram_np = gaussian_filter(spectrogram_np, \n                                         sigma=sigma_gaussian)\n\n    # Filter EKG signal\n    ekg_signal_filtered  = filtfilt(*notch_coefficients, eeg_data[\"EKG\"].values)\n    ekg_signal_filtered  = filtfilt(*bandpass_coefficients, ekg_signal_filtered)\n    processed_eeg['EKG'] = np.array(ekg_signal_filtered)\n\n    return spectrogram_np, processed_eeg","metadata":{"execution":{"iopub.status.busy":"2024-04-07T04:30:42.585687Z","iopub.status.idle":"2024-04-07T04:30:42.586108Z","shell.execute_reply.started":"2024-04-07T04:30:42.585915Z","shell.execute_reply":"2024-04-07T04:30:42.585932Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def create_spectogram_competition(spec_id, seconds_min, mode=\"test\"):\n    spec   = pd.read_parquet(os.path.join(cf.base_dir, f\"{mode}_spectrograms\", f\"{spec_id}.parquet\"))\n    inicio = (seconds_min) // 2\n    img    = spec.fillna(0).values[:, 1: ].T.astype(\"float32\")\n    img    = img[:, inicio: inicio + 300]\n    \n    # Log transform and normalize\n    img = np.clip(img, np.exp(-4), np.exp(6))\n    img = np.log(img)\n    eps = 1e-6\n    img_mean = img.mean()\n    img_std  = img.std()\n    img = (img - img_mean) / (img_std + eps)\n    \n    return img ","metadata":{"execution":{"iopub.status.busy":"2024-04-07T04:30:42.586825Z","iopub.status.idle":"2024-04-07T04:30:42.587208Z","shell.execute_reply.started":"2024-04-07T04:30:42.587029Z","shell.execute_reply":"2024-04-07T04:30:42.587044Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def create_final_image(image_50s, image_10s, image_10m):\n    \"\"\"Combine three images into a single final image.\"\"\"\n    # Initialize an empty image array for the first image composition\n    single_channel_image1 = np.zeros((1068, 501))\n    \n    for i in range(4):\n        start = i * 267\n        end = start + 267\n        single_channel_image1[start:end, :] = image_50s[:, :, i]\n\n    # Initialize an empty image array for the second image composition\n    single_channel_image2 = np.zeros((400, 291))\n    for i in range(4):\n        start = i * 100\n        end = start + 100\n        single_channel_image2[start:end, :] = image_10s[:, :, i]\n\n    # Resize images to fit the final composition\n    resized_image1 = cv2.resize(single_channel_image1, (400, 800), interpolation=cv2.INTER_AREA)\n    resized_image2 = cv2.resize(single_channel_image2, (300, 400), interpolation=cv2.INTER_AREA)\n    resized_image3 = cv2.resize(image_10m, (300, 400), interpolation=cv2.INTER_AREA)\n\n    # Create the final image and place the resized images accordingly\n    final_image = np.zeros((800, 700), dtype=np.float32)\n    \n    final_image[0:800, 0:400]     = resized_image1\n    final_image[0:400, 400:700]   = resized_image2\n    final_image[400:800, 400:700] = resized_image3\n    final_image = final_image[::-1]  # Flip the final image vertically\n    \n    return cv2.resize(final_image, (512, 512), interpolation=cv2.INTER_AREA)","metadata":{"execution":{"iopub.status.busy":"2024-04-07T04:30:42.588432Z","iopub.status.idle":"2024-04-07T04:30:42.588790Z","shell.execute_reply.started":"2024-04-07T04:30:42.588609Z","shell.execute_reply":"2024-04-07T04:30:42.588623Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def process_eegs(df, mode=\"test\"):\n    all_eeg_imgs = dict()\n    for i in tqdm(range(len(df)), total=len(df), desc=\"processing EEGs\"):\n        row          = df.iloc[i]\n        eeg_id       = row[\"eeg_id\"]\n        spec_id      = row[\"spectrogram_id\"]\n        second_min   = int(0)\n        start_second = int(0)\n        if mode == \"train\":\n            key = row[\"new_id\"]\n        else:\n            key = eeg_id   \n        eeg_data = pd.read_parquet(os.path.join(cf.base_dir, f\"{mode}_eegs\", f\"{eeg_id}.parquet\"))\n        \n        image_50s, _ =  create_spectrogram_with_cusignal(eeg_data=eeg_data, \n                                                         eeg_id=eeg_id, \n                                                         start=start_second,\n                                                         duration=50, \n                                                         low_cut_freq=0.7, \n                                                         high_cut_freq=20, \n                                                         order_band=5,\n                                                         spec_size_freq=267, \n                                                         spec_size_time=501, \n                                                         nperseg=1_500, \n                                                         n_overlap=1_483,\n                                                         nfft=2_750,\n                                                         sigma_gaussian=0.0, \n                                                         mean_montage_names=4\n                                                        )\n        \n        image_10s, _ = create_spectrogram_with_cusignal(eeg_data=eeg_data, \n                                                        eeg_id=eeg_id, \n                                                        start=start_second, \n                                                        duration=10,\n                                                        low_cut_freq=0.7, \n                                                        high_cut_freq=20, \n                                                        order_band=5,\n                                                        spec_size_freq=100, \n                                                        spec_size_time=291,\n                                                        nperseg=260, \n                                                        n_overlap=254, \n                                                        nfft=1_030,\n                                                        sigma_gaussian=0.0, \n                                                        mean_montage_names=4\n                                                       )\n        \n        image_10m = create_spectogram_competition(spec_id, \n                                                  second_min, \n                                                  mode=mode\n                                                 )\n        \n        # Create the final combined image\n        final_image = create_final_image(image_50s, \n                                         image_10s, \n                                         image_10m\n                                        )\n        \n        file_path = os.path.join(OUTPUT_DIR, f\"{key}.npz\")\n        np.savez_compressed(file_path, final_image=final_image)\n        \n        del final_image, image_50s, image_10s, image_10m, eeg_data\n        _=gc.collect()\n    \n    #return all_eeg_imgs","metadata":{"execution":{"iopub.status.busy":"2024-04-07T04:30:42.589845Z","iopub.status.idle":"2024-04-07T04:30:42.590230Z","shell.execute_reply.started":"2024-04-07T04:30:42.590047Z","shell.execute_reply":"2024-04-07T04:30:42.590063Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"process_eegs(test)","metadata":{"execution":{"iopub.status.busy":"2024-04-07T04:30:42.591199Z","iopub.status.idle":"2024-04-07T04:30:42.591554Z","shell.execute_reply.started":"2024-04-07T04:30:42.591375Z","shell.execute_reply":"2024-04-07T04:30:42.591390Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class CustomDataset(Dataset):\n    def __init__(self, \n                 df:pd.DataFrame, \n                 mode:str=\"test\",\n                ):\n        self.df      = df\n        self.mode    = mode\n        \n    def __len__(self):\n        return len(self.df)\n    \n    def __getitem__(self, index):\n        y         = np.zeros(len(label_cols), dtype=\"float32\")\n        row       = self.df.iloc[index]\n        file_path = row[\"eeg_id\"]\n        X = np.load(os.path.join(OUTPUT_DIR, f\"{file_path}.npz\"))[\"final_image\"]\n        X = np.repeat(X[:, :, np.newaxis], repeats=3, axis=2)\n        if self.mode != \"test\":\n            y = row[label_cols].values.astype(np.float32)\n        \n        return {\"img\"   : torch.tensor(X, dtype=torch.float32),\n                \"label\" : torch.tensor(y, dtype=torch.float32)\n               }","metadata":{"execution":{"iopub.status.busy":"2024-04-07T04:30:42.593418Z","iopub.status.idle":"2024-04-07T04:30:42.593977Z","shell.execute_reply.started":"2024-04-07T04:30:42.593677Z","shell.execute_reply":"2024-04-07T04:30:42.593699Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def get_dataloaders(df):\n    test_dataset = CustomDataset(df,mode=\"test\")\n    dataloaders  = dict()\n    \n    dataloaders[\"test\"]  = DataLoader(test_dataset, \n                                      batch_size=cf.batch_size*2,\n                                      shuffle=False, \n                                      num_workers=cf.num_workers,\n                                      pin_memory=True, \n                                      drop_last=False\n                                     )\n    return dataloaders","metadata":{"execution":{"iopub.status.busy":"2024-04-07T04:30:42.595582Z","iopub.status.idle":"2024-04-07T04:30:42.596125Z","shell.execute_reply.started":"2024-04-07T04:30:42.595831Z","shell.execute_reply":"2024-04-07T04:30:42.595853Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"if cf.debug:\n    s_dataset = CustomDataset(test)\n    for i in s_dataset:\n        print(f\"Imag  Shape : {i['img'].shape}\")\n        print(f\"Label Shape : {i['label'].shape}\")\n        plt.figure(figsize=(8, 8))\n        plt.title(f\"label : {i['label']}\")\n        plt.imshow(i['img'].detach().cpu().numpy())\n        plt.show()\n        break","metadata":{"execution":{"iopub.status.busy":"2024-04-07T04:30:42.597543Z","iopub.status.idle":"2024-04-07T04:30:42.597946Z","shell.execute_reply.started":"2024-04-07T04:30:42.597729Z","shell.execute_reply":"2024-04-07T04:30:42.597744Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def inference(dataloaders, model):\n    preds = list()\n    stream= tqdm(dataloaders[\"test\"], total=len(dataloaders[\"test\"]), unit=\"test_batch\", desc=\"Infer\")\n    with torch.no_grad():\n        for batch in stream:\n            with autocast(enabled=False):\n                out = model(batch[\"img\"].to(device))\n            preds.append(out)\n            \n    all_preds = np.concatenate(preds)\n    \n    del preds\n    _=gc.collect()\n    \n    return all_preds","metadata":{"execution":{"iopub.status.busy":"2024-04-07T04:30:42.599182Z","iopub.status.idle":"2024-04-07T04:30:42.599540Z","shell.execute_reply.started":"2024-04-07T04:30:42.599362Z","shell.execute_reply":"2024-04-07T04:30:42.599377Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### RAW 512 ✖️ 512 ✖️ 3","metadata":{}},{"cell_type":"code","source":"r_b3g_cp  = create_model_path(cf.r_model_b3g_dir)\nr_v2sg_cp = create_model_path(cf.r_model_v2sg_dir)\nr_b4g2_cp = create_model_path(cf.r_model_b4g2_dir)","metadata":{"execution":{"iopub.status.busy":"2024-04-08T08:11:23.862614Z","iopub.execute_input":"2024-04-08T08:11:23.863079Z","iopub.status.idle":"2024-04-08T08:11:23.900744Z","shell.execute_reply.started":"2024-04-08T08:11:23.863048Z","shell.execute_reply":"2024-04-08T08:11:23.899216Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# raw b3   Model cv : 0.307230 LB : 0.30\nr_b3g_models  = build_model(cf, r_b3g_cp)\nprint()\nr_v2sg_models = build_model(cf, r_v2sg_cp)\nprint()\nr_b4g2_models = build_model(cf, r_b4g2_cp)","metadata":{"_kg_hide-output":true,"execution":{"iopub.status.busy":"2024-04-08T08:11:52.101662Z","iopub.execute_input":"2024-04-08T08:11:52.102195Z","iopub.status.idle":"2024-04-08T08:12:22.082354Z","shell.execute_reply.started":"2024-04-08T08:11:52.102110Z","shell.execute_reply":"2024-04-08T08:12:22.080836Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"dataloaders  = get_dataloaders(test)\nr_b3g_pred   = inference(dataloaders, r_b3g_models)\n\ndataloaders  = get_dataloaders(test)\nr_v2sg_pred  = inference(dataloaders, r_v2sg_models)\n\ndataloaders  = get_dataloaders(test)\nr_b4g2_pred  = inference(dataloaders, r_b4g2_models)\n\ndel dataloaders\ndel r_b3g_models\ndel r_v2sg_models\ndel r_b4g2_models\n\n_=gc.collect()","metadata":{"execution":{"iopub.status.busy":"2024-04-07T04:30:42.604740Z","iopub.status.idle":"2024-04-07T04:30:42.605183Z","shell.execute_reply.started":"2024-04-07T04:30:42.604990Z","shell.execute_reply":"2024-04-07T04:30:42.605006Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Ensemble","metadata":{}},{"cell_type":"code","source":"# # CV : 0.280352 LB : 0.29\n# p = r_b3g_pred * 0.55 +  ke_b4gpred * 0.45\n\n# # CV : 0.271919 LB : 0.29\n# p1 = r_v2sg_pred * 0.55 + r_b3g_pred * 0.45\n# p2 = p1          * 0.7  + ke_b4gpred * 0.3\n\n# CV : 0.271032 : LB ???\np1 = r_v2sg_pred * 0.55 + r_b3g_pred  * 0.45\np2 = p1          * 0.8  + r_b4g2_pred * 0.2\np3 = p2          * 0.7  + ke_b4gpred  * 0.3\n\n\ndel p1, p2\ndel r_v2sg_pred\ndel r_b3g_pred\ndel r_b4g2_pred\ndel ke_b4gpred\n\n_=gc.collect()","metadata":{"execution":{"iopub.status.busy":"2024-04-07T04:30:42.606702Z","iopub.status.idle":"2024-04-07T04:30:42.607240Z","shell.execute_reply.started":"2024-04-07T04:30:42.606973Z","shell.execute_reply":"2024-04-07T04:30:42.606995Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"sub[\"eeg_id\"]   = test[\"eeg_id\"].values\nsub[label_cols] = p3\nsub.to_csv('submission.csv',index=False)","metadata":{"execution":{"iopub.status.busy":"2024-04-07T04:30:42.608592Z","iopub.status.idle":"2024-04-07T04:30:42.609139Z","shell.execute_reply.started":"2024-04-07T04:30:42.608839Z","shell.execute_reply":"2024-04-07T04:30:42.608879Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"sub.head()","metadata":{"execution":{"iopub.status.busy":"2024-04-07T04:30:42.610655Z","iopub.status.idle":"2024-04-07T04:30:42.611232Z","shell.execute_reply.started":"2024-04-07T04:30:42.610956Z","shell.execute_reply":"2024-04-07T04:30:42.610978Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"! head submission.csv","metadata":{"execution":{"iopub.status.busy":"2024-04-07T04:30:42.613769Z","iopub.status.idle":"2024-04-07T04:30:42.614339Z","shell.execute_reply.started":"2024-04-07T04:30:42.614065Z","shell.execute_reply":"2024-04-07T04:30:42.614087Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"if sub.shape[0] == 1:\n    print(np.sum(sub[label_cols].values, axis=1).item())","metadata":{"execution":{"iopub.status.busy":"2024-04-07T04:30:42.615838Z","iopub.status.idle":"2024-04-07T04:30:42.616255Z","shell.execute_reply.started":"2024-04-07T04:30:42.616070Z","shell.execute_reply":"2024-04-07T04:30:42.616086Z"},"trusted":true},"execution_count":null,"outputs":[]}]}