{"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":7392775,"sourceType":"datasetVersion","datasetId":4297782},{"sourceId":7402356,"sourceType":"datasetVersion","datasetId":4304475},{"sourceId":7403069,"sourceType":"datasetVersion","datasetId":4304949},{"sourceId":7447509,"sourceType":"datasetVersion","datasetId":4334995},{"sourceId":7450712,"sourceType":"datasetVersion","datasetId":4336944},{"sourceId":7581697,"sourceType":"datasetVersion","datasetId":4413439},{"sourceId":7581715,"sourceType":"datasetVersion","datasetId":4413451},{"sourceId":7581720,"sourceType":"datasetVersion","datasetId":4413454},{"sourceId":7585255,"sourceType":"datasetVersion","datasetId":4415285,"isSourceIdPinned":true},{"sourceId":7828317,"sourceType":"datasetVersion","datasetId":4587588},{"sourceId":158958765,"sourceType":"kernelVersion"},{"sourceId":159333316,"sourceType":"kernelVersion"},{"sourceId":159396114,"sourceType":"kernelVersion"}],"dockerImageVersionId":30636,"isInternetEnabled":false,"language":"python","sourceType":"notebook","isGpuEnabled":true}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"markdown","source":"## ℹ️Update Info\n\n* **2024/02/10 forked original great work kernels**\n    * [Blend][Inference] https://www.kaggle.com/code/kitsuha/3-model-ensemble-lb-0-38\n    * [Blend][Inference] https://www.kaggle.com/code/andreasbis/hms-inference-lb-0-41\n    * [Single][Inference] https://www.kaggle.com/code/yunsuxiaozi/hms-baseline-resnet34d-512-512-inference-6-models\n    * [Single][Inference] https://www.kaggle.com/code/crackle/efficientnetb0-pytorch-starter-lb-0-40\n    \n\n* **2024/02/16**\n    * add Blend Weights. Use param by https://www.kaggle.com/code/kitsuha/3-model-ensemble-lb-0-37https://www.kaggle.com/code/kitsuha/3-model-ensemble-lb-0-37\n\n* **2024/03/13**\n    * add Resnet1d GRU[LB.37] by https://www.kaggle.com/code/konstantinboyko/hms-resnet1d-gru-1-stage-inference-1-5-signal/notebook","metadata":{}},{"cell_type":"markdown","source":"---\n# **《《《　Model 1　》》》**\n---","metadata":{}},{"cell_type":"code","source":"import os\nimport sys\nimport gc\nsys.path.append('/kaggle/input/kaggle-kl-div')\nfrom kaggle_kl_div import score\n\nimport torch\nfrom torch import nn\nimport torch.nn.functional as F\nfrom torch.utils.data import Dataset, DataLoader\nfrom torchvision.models import efficientnet_b0, EfficientNet_B0_Weights\nimport pytorch_lightning as pl\nimport pandas as pd, numpy as np\nimport matplotlib.pyplot as plt\nimport albumentations as albu\nfrom sklearn.model_selection import KFold, GroupKFold","metadata":{"execution":{"iopub.status.busy":"2024-03-13T10:48:59.945024Z","iopub.execute_input":"2024-03-13T10:48:59.945276Z","iopub.status.idle":"2024-03-13T10:49:10.353200Z","shell.execute_reply.started":"2024-03-13T10:48:59.945254Z","shell.execute_reply":"2024-03-13T10:49:10.352274Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"VER = 5\n# IF THIS EQUALS NONE, THEN WE TRAIN NEW MODELS\n# IF THIS EQUALS DISK PATH, THEN WE LOAD PREVIOUSLY TRAINED MODELS\nLOAD_MODELS_FROM = '/kaggle/input/hms-efficientnetb0-pt-ckpts/'\n\nUSE_KAGGLE_SPECTROGRAMS = True\nUSE_EEG_SPECTROGRAMS = True","metadata":{"execution":{"iopub.status.busy":"2024-03-13T10:49:10.354944Z","iopub.execute_input":"2024-03-13T10:49:10.355425Z","iopub.status.idle":"2024-03-13T10:49:10.360412Z","shell.execute_reply.started":"2024-03-13T10:49:10.355394Z","shell.execute_reply":"2024-03-13T10:49:10.359404Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"df = pd.read_csv('/kaggle/input/hms-harmful-brain-activity-classification/train.csv')\nTARGETS = df.columns[-6:]\nprint('Train shape:', df.shape )\nprint('Targets', list(TARGETS))\ndf.head()","metadata":{"execution":{"iopub.status.busy":"2024-03-13T10:49:10.361493Z","iopub.execute_input":"2024-03-13T10:49:10.361829Z","iopub.status.idle":"2024-03-13T10:49:10.627495Z","shell.execute_reply.started":"2024-03-13T10:49:10.361795Z","shell.execute_reply":"2024-03-13T10:49:10.626520Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train = df.groupby('eeg_id')[\n    ['spectrogram_id', 'spectrogram_label_offset_seconds']\n].agg({'spectrogram_id': 'first', 'spectrogram_label_offset_seconds': 'min'})\ntrain.columns = ['spec_id', 'min']\n\ntmp = df.groupby('eeg_id')[\n    ['spectrogram_id','spectrogram_label_offset_seconds']\n].agg({'spectrogram_label_offset_seconds' :'max'})\ntrain['max'] = tmp\n\ntmp = df.groupby('eeg_id')[['patient_id']].agg('first')\ntrain['patient_id'] = tmp\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()\nprint('Train non-overlapp eeg_id shape:', train.shape )\ntrain.head()","metadata":{"execution":{"iopub.status.busy":"2024-03-13T10:49:10.630145Z","iopub.execute_input":"2024-03-13T10:49:10.630443Z","iopub.status.idle":"2024-03-13T10:49:10.731777Z","shell.execute_reply.started":"2024-03-13T10:49:10.630418Z","shell.execute_reply":"2024-03-13T10:49:10.730840Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"READ_SPEC_FILES = False\n\n# READ ALL SPECTROGRAMS\nPATH = '/kaggle/input/hms-harmful-brain-activity-classification/train_spectrograms/'\nfiles = os.listdir(PATH)\nprint(f'There are {len(files)} spectrogram parquets')\n\nif READ_SPEC_FILES:    \n    spectrograms = {}\n    for i,f in enumerate(files):\n        if i % 100 == 0:\n            print(i, ', ', end='')\n        tmp = pd.read_parquet(f'{PATH}{f}')\n        name = int(f.split('.')[0])\n        spectrograms[name] = tmp.iloc[:,1:].values\nelse:\n    spectrograms = np.load('/kaggle/input/brain-spectrograms/specs.npy',allow_pickle=True).item()","metadata":{"execution":{"iopub.status.busy":"2024-03-13T10:49:10.733366Z","iopub.execute_input":"2024-03-13T10:49:10.733760Z","iopub.status.idle":"2024-03-13T10:50:10.784616Z","shell.execute_reply.started":"2024-03-13T10:49:10.733716Z","shell.execute_reply":"2024-03-13T10:50:10.783746Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"READ_EEG_SPEC_FILES = False\n\nif READ_EEG_SPEC_FILES:\n    all_eegs = {}\n    for i,e in enumerate(train.eeg_id.values):\n        if i % 100 == 0:\n            print(i, ', ', end='')\n        x = np.load(f'/kaggle/input/brain-eeg-spectrograms/EEG_Spectrograms/{e}.npy')\n        all_eegs[e] = x\nelse:\n    all_eegs = np.load('/kaggle/input/brain-eeg-spectrograms/eeg_specs.npy',allow_pickle=True).item()","metadata":{"execution":{"iopub.status.busy":"2024-03-13T10:50:10.785787Z","iopub.execute_input":"2024-03-13T10:50:10.786079Z","iopub.status.idle":"2024-03-13T10:51:25.637056Z","shell.execute_reply.started":"2024-03-13T10:50:10.786054Z","shell.execute_reply":"2024-03-13T10:51:25.636187Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"TARS = {'Seizure':0, 'LPD':1, 'GPD':2, 'LRDA':3, 'GRDA':4, 'Other':5}\nTARS2 = {x: y for y, x in TARS.items()}\n\n\nclass EEGDataset(Dataset):\n    \n    def __init__(self, data, augment=False, mode='train', specs=spectrograms, eeg_specs=all_eegs): \n        self.data = data\n        self.augment = augment\n        self.mode = mode\n        self.specs = specs\n        self.eeg_specs = eeg_specs\n        \n    def __len__(self):\n        return len(self.data)\n    \n    def __getitem__(self, index):\n        return self.__getitems__([index])\n    \n    def __getitems__(self, indices):\n        X, y = self._generate_data(indices)\n        if self.augment:\n            X = self._augment(X) \n        if self.mode == 'train':\n            return list(zip(X, y))\n        else:\n            return X\n    \n    def _generate_data(self, indexes):\n        X = np.zeros((len(indexes), 128, 256, 8),dtype='float32')\n        y = np.zeros((len(indexes), 6),dtype='float32')\n        img = np.ones((128, 256),dtype='float32')\n        \n        for j, i in enumerate(indexes):\n            row = self.data.iloc[i]\n            if self.mode == 'test': \n                r = 0\n            else: \n                r = int((row['min'] + row['max'])//4)\n\n            for k in range(4):\n                # EXTRACT 300 ROWS OF SPECTROGRAM\n                img = self.specs[row.spec_id][r:r+300, k*100:(k+1)*100].T\n                \n                # LOG TRANSFORM SPECTROGRAM\n                img = np.clip(img, np.exp(-4), np.exp(8))\n                img = np.log(img)\n                \n                # STANDARDIZE PER IMAGE\n                ep = 1e-6\n                m = np.nanmean(img.flatten())\n                s = np.nanstd(img.flatten())\n                img = (img - m) / (s + ep)\n                img = np.nan_to_num(img, nan=0.0)\n                \n                # CROP TO 256 TIME STEPS\n                X[j, 14:-14, :, k] = img[:, 22:-22] / 2.0\n        \n            # EEG SPECTROGRAMS\n            img = self.eeg_specs[row.eeg_id]\n            X[j, :, :, 4:] = img\n                \n            if self.mode != 'test':\n                y[j,] = row[TARGETS]\n            \n        return X, y\n    \n    def _random_transform(self, img):\n        composition = albu.Compose([\n            albu.HorizontalFlip(p=0.5),\n            # albu.CoarseDropout(max_holes=8,max_height=32,max_width=32,fill_value=0,p=0.5),\n        ])\n        return composition(image=img)['image']\n            \n    def __augment(self, img_batch):\n        for i in range(img_batch.shape[0]):\n            img_batch[i,] = self._random_transform(img_batch[i,])\n        return img_batch","metadata":{"execution":{"iopub.status.busy":"2024-03-13T10:51:25.638638Z","iopub.execute_input":"2024-03-13T10:51:25.638965Z","iopub.status.idle":"2024-03-13T10:51:25.655807Z","shell.execute_reply.started":"2024-03-13T10:51:25.638938Z","shell.execute_reply":"2024-03-13T10:51:25.654930Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"dataset = EEGDataset(train)\ndataloader = DataLoader(dataset, batch_size=32, shuffle=False)","metadata":{"execution":{"iopub.status.busy":"2024-03-13T10:51:25.657133Z","iopub.execute_input":"2024-03-13T10:51:25.657541Z","iopub.status.idle":"2024-03-13T10:51:25.670956Z","shell.execute_reply.started":"2024-03-13T10:51:25.657477Z","shell.execute_reply":"2024-03-13T10:51:25.670020Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"ROWS = 2\nCOLS = 3\nBATCHES = 2\n\nfor i, (x, y) in enumerate(dataloader):\n    plt.figure(figsize=(20, 8))\n    for j in range(ROWS):\n        for k in range(COLS):\n            plt.subplot(ROWS, COLS, j*COLS + k + 1)\n            t = y[j*COLS + k]\n            img = torch.flip(x[j*COLS+k, :, :, 0], (0,))\n            mn = img.flatten().min()\n            mx = img.flatten().max()\n            img = (img-mn)/(mx-mn)\n            plt.imshow(img)\n            tars = f'[{t[0]:0.2f}]'\n            for s in t[1:]:\n                tars += f', {s:0.2f}'\n            eeg = train.eeg_id.values[i*32+j*COLS+k]\n            plt.title(f'EEG = {eeg}\\nTarget = {tars}',size=12)\n            plt.yticks([])\n            plt.ylabel('Frequencies (Hz)',size=14)\n            plt.xlabel('Time (sec)',size=16)\n    plt.show()\n    if i == BATCHES-1:\n        break","metadata":{"execution":{"iopub.status.busy":"2024-03-13T10:51:25.672114Z","iopub.execute_input":"2024-03-13T10:51:25.672404Z","iopub.status.idle":"2024-03-13T10:51:28.791985Z","shell.execute_reply.started":"2024-03-13T10:51:25.672380Z","shell.execute_reply":"2024-03-13T10:51:28.791117Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"del dataset, dataloader\ngc.collect()","metadata":{"execution":{"iopub.status.busy":"2024-03-13T10:51:28.796412Z","iopub.execute_input":"2024-03-13T10:51:28.796759Z","iopub.status.idle":"2024-03-13T10:51:28.973741Z","shell.execute_reply.started":"2024-03-13T10:51:28.796728Z","shell.execute_reply":"2024-03-13T10:51:28.972751Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"WEIGHTS_FILE = '/kaggle/input/hms-efficientnetb0-pt-ckpts/efficientnet_b0_rwightman-7f5810bc.pth'\n\n\nclass EEGEffnetB0(pl.LightningModule):\n    \n    def __init__(self):\n        super().__init__()\n        self.base_model = efficientnet_b0()\n        self.base_model.load_state_dict(torch.load(WEIGHTS_FILE))\n        self.base_model.classifier[1] = nn.Linear(self.base_model.classifier[1].in_features, 6, dtype=torch.float32)\n        self.prob_out = nn.Softmax()\n        \n    def forward(self, x):\n        x1 = [x[:, :, :, i:i+1] for i in range(4)]\n        x1 = torch.concat(x1, dim=1)\n        x2 = [x[:, :, :, i+4:i+5] for i in range(4)]\n        x2 = torch.concat(x2, dim=1)\n        \n        if USE_KAGGLE_SPECTROGRAMS & USE_EEG_SPECTROGRAMS:\n            x = torch.concat([x1, x2], dim=2)\n        elif USE_EEG_SPECTROGRAMS:\n            x = x2\n        else:\n            x = x1\n        x = torch.concat([x, x, x], dim=3)\n        x = x.permute(0, 3, 1, 2)\n        \n        out = self.base_model(x)\n        return out\n    \n    def training_step(self, batch, batch_idx):\n        x, y = batch\n        out = self.forward(x)\n        out = F.log_softmax(out, dim=1)\n        kl_loss = nn.KLDivLoss(reduction='batchmean')\n        loss = kl_loss(out, y)\n        return loss\n    \n    def predict_step(self, batch, batch_idx, dataloader_idx=0):\n        return F.softmax(self(batch), dim=1)\n    \n    def configure_optimizers(self):\n        optimizer = torch.optim.Adam(self.parameters(), lr=1e-3)\n        return optimizer","metadata":{"execution":{"iopub.status.busy":"2024-03-13T10:51:28.975030Z","iopub.execute_input":"2024-03-13T10:51:28.975387Z","iopub.status.idle":"2024-03-13T10:51:28.988393Z","shell.execute_reply.started":"2024-03-13T10:51:28.975355Z","shell.execute_reply":"2024-03-13T10:51:28.987612Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"all_oof = []\nall_true = []\nvalid_loaders = []\n\ngkf = GroupKFold(n_splits=5)\nfor i, (train_index, valid_index) in enumerate(gkf.split(train, train.target, train.patient_id)):  \n    print('#'*25)\n    print(f'### Fold {i+1}')\n    \n    train_ds = EEGDataset(train.iloc[train_index])\n    train_loader = DataLoader(train_ds, shuffle=True, batch_size=32, num_workers=3)\n    valid_ds = EEGDataset(train.iloc[valid_index], mode='valid')\n    valid_loader = DataLoader(valid_ds, shuffle=False, batch_size=64, num_workers=3)\n    \n    print(f'### Train size: {len(train_index)}, Valid size: {len(valid_index)}')\n    print('#'*25)\n    \n    trainer = pl.Trainer(max_epochs=4)\n    model = EEGEffnetB0()\n    if LOAD_MODELS_FROM is None:\n        trainer.fit(model=model, train_dataloaders=train_loader)\n        trainer.save_checkpoint(f'EffNet_v{VER}_f{i}.ckpt')\n\n    valid_loaders.append(valid_loader)\n    all_true.append(train.iloc[valid_index][TARGETS].values)\n    del trainer, model\n    gc.collect()","metadata":{"execution":{"iopub.status.busy":"2024-03-13T10:51:28.989492Z","iopub.execute_input":"2024-03-13T10:51:28.989816Z","iopub.status.idle":"2024-03-13T10:51:31.997937Z","shell.execute_reply.started":"2024-03-13T10:51:28.989787Z","shell.execute_reply":"2024-03-13T10:51:31.997161Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"device = torch.device(\"cuda\" if torch.cuda.is_available() else \"cpu\")","metadata":{"execution":{"iopub.status.busy":"2024-03-13T10:51:32.002959Z","iopub.execute_input":"2024-03-13T10:51:32.003218Z","iopub.status.idle":"2024-03-13T10:51:32.007563Z","shell.execute_reply.started":"2024-03-13T10:51:32.003195Z","shell.execute_reply":"2024-03-13T10:51:32.006678Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"for i in range(5):\n    print('#'*25)\n    print(f'### Validating Fold {i+1}')\n\n    ckpt_file = f'EffNet_v{VER}_f{i}.ckpt' if LOAD_MODELS_FROM is None else f'{LOAD_MODELS_FROM}/EffNet_v{VER}_f{i}.ckpt'\n    model = EEGEffnetB0.load_from_checkpoint(ckpt_file)\n    model.to(device).eval()\n    with torch.inference_mode():\n        for val_batch in valid_loaders[i]:\n            val_batch = val_batch.to(device)\n            oof = torch.softmax(model(val_batch), dim=1).cpu().numpy()\n            all_oof.append(oof)\n    del model\n    gc.collect()\n\nall_oof = np.concatenate(all_oof)\nall_true = np.concatenate(all_true)","metadata":{"execution":{"iopub.status.busy":"2024-03-13T10:51:32.008727Z","iopub.execute_input":"2024-03-13T10:51:32.009044Z","iopub.status.idle":"2024-03-13T10:53:26.270842Z","shell.execute_reply.started":"2024-03-13T10:51:32.009019Z","shell.execute_reply":"2024-03-13T10:53:26.269935Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"oof = 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 KL-Div for EfficientNetB2 =',cv)","metadata":{"execution":{"iopub.status.busy":"2024-03-13T10:53:26.272859Z","iopub.execute_input":"2024-03-13T10:53:26.273182Z","iopub.status.idle":"2024-03-13T10:53:26.335267Z","shell.execute_reply.started":"2024-03-13T10:53:26.273154Z","shell.execute_reply":"2024-03-13T10:53:26.334388Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"del all_eegs, spectrograms\ngc.collect()\n\ntest = pd.read_csv('/kaggle/input/hms-harmful-brain-activity-classification/test.csv')\nprint('Test shape',test.shape)\ntest.head()","metadata":{"execution":{"iopub.status.busy":"2024-03-13T10:53:26.336256Z","iopub.execute_input":"2024-03-13T10:53:26.336515Z","iopub.status.idle":"2024-03-13T10:53:26.514585Z","shell.execute_reply.started":"2024-03-13T10:53:26.336492Z","shell.execute_reply":"2024-03-13T10:53:26.513698Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# READ ALL SPECTROGRAMS\nPATH2 = '/kaggle/input/hms-harmful-brain-activity-classification/test_spectrograms/'\nfiles2 = os.listdir(PATH2)\nprint(f'There are {len(files2)} test spectrogram parquets')\n    \nspectrograms2 = {}\nfor i, f in enumerate(files2):\n    if i % 100 == 0:\n        print(i, ', ',end='')\n    tmp = pd.read_parquet(f'{PATH2}{f}')\n    name = int(f.split('.')[0])\n    spectrograms2[name] = tmp.iloc[:, 1:].values\n    \n# RENAME FOR DATALOADER\ntest = test.rename({'spectrogram_id': 'spec_id'}, axis=1)","metadata":{"execution":{"iopub.status.busy":"2024-03-13T10:53:26.515890Z","iopub.execute_input":"2024-03-13T10:53:26.516674Z","iopub.status.idle":"2024-03-13T10:53:26.793685Z","shell.execute_reply.started":"2024-03-13T10:53:26.516639Z","shell.execute_reply":"2024-03-13T10:53:26.792916Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import pywt, librosa\n\nUSE_WAVELET = None \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']]\n\n\n# DENOISE FUNCTION\ndef maddest(d, axis=None):\n    return np.mean(np.absolute(d - np.mean(d, axis)), axis)\n\n\ndef denoise(x, wavelet='haar', level=1):    \n    coeff = pywt.wavedec(x, wavelet, mode=\"per\")\n    sigma = (1/0.6745) * maddest(coeff[-level])\n\n    uthresh = sigma * np.sqrt(2*np.log(len(x)))\n    coeff[1:] = (pywt.threshold(i, value=uthresh, mode='hard') for i in coeff[1:])\n\n    ret=pywt.waverec(coeff, wavelet, mode='per')\n    \n    return ret\n\n\ndef spectrogram_from_eeg(parquet_path, display=False):\n    \n    # LOAD MIDDLE 50 SECONDS OF EEG SERIES\n    eeg = pd.read_parquet(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((128,256,4),dtype='float32')\n    \n    if display: plt.figure(figsize=(10,7))\n    signals = []\n    for k in range(4):\n        COLS = FEATS[k]\n        \n        for kk in range(4):\n        \n            # COMPUTE PAIR DIFFERENCES\n            x = eeg[COLS[kk]].values - eeg[COLS[kk+1]].values\n\n            # FILL NANS\n            m = np.nanmean(x)\n            if np.isnan(x).mean()<1: x = np.nan_to_num(x,nan=m)\n            else: x[:] = 0\n\n            # DENOISE\n            if USE_WAVELET:\n                x = denoise(x, wavelet=USE_WAVELET)\n            signals.append(x)\n\n            # RAW SPECTROGRAM\n            mel_spec = librosa.feature.melspectrogram(y=x, sr=200, hop_length=len(x)//256, \n                  n_fft=1024, n_mels=128, fmin=0, fmax=20, win_length=128)\n\n            # LOG TRANSFORM\n            width = (mel_spec.shape[1]//32)*32\n            mel_spec_db = librosa.power_to_db(mel_spec, ref=np.max).astype(np.float32)[:,:width]\n\n            # STANDARDIZE TO -1 TO 1\n            mel_spec_db = (mel_spec_db+40)/40 \n            img[:,:,k] += mel_spec_db\n                \n        # AVERAGE THE 4 MONTAGE DIFFERENCES\n        img[:,:,k] /= 4.0\n        \n        if display:\n            plt.subplot(2,2,k+1)\n            plt.imshow(img[:,:,k],aspect='auto',origin='lower')\n            plt.title(f'EEG {eeg_id} - Spectrogram {NAMES[k]}')\n            \n    if display: \n        plt.show()\n        plt.figure(figsize=(10,5))\n        offset = 0\n        for k in range(4):\n            if k>0: offset -= signals[3-k].min()\n            plt.plot(range(10_000),signals[k]+offset,label=NAMES[3-k])\n            offset += signals[3-k].max()\n        plt.legend()\n        plt.title(f'EEG {eeg_id} Signals')\n        plt.show()\n        print(); print('#'*25); print()\n        \n    return img","metadata":{"execution":{"iopub.status.busy":"2024-03-13T10:53:26.795277Z","iopub.execute_input":"2024-03-13T10:53:26.795636Z","iopub.status.idle":"2024-03-13T10:53:26.817842Z","shell.execute_reply.started":"2024-03-13T10:53:26.795604Z","shell.execute_reply":"2024-03-13T10:53:26.817117Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# READ ALL EEG SPECTROGRAMS\nPATH2 = '/kaggle/input/hms-harmful-brain-activity-classification/test_eegs/'\nDISPLAY = 1\nEEG_IDS2 = test.eeg_id.unique()\nall_eegs2 = {}\n\nprint('Converting Test EEG to Spectrograms...'); print()\nfor i, eeg_id in enumerate(EEG_IDS2):\n        \n    # CREATE SPECTROGRAM FROM EEG PARQUET\n    img = spectrogram_from_eeg(f'{PATH2}{eeg_id}.parquet', i < DISPLAY)\n    all_eegs2[eeg_id] = img","metadata":{"execution":{"iopub.status.busy":"2024-03-13T10:53:26.818948Z","iopub.execute_input":"2024-03-13T10:53:26.819196Z","iopub.status.idle":"2024-03-13T10:53:37.761829Z","shell.execute_reply.started":"2024-03-13T10:53:26.819175Z","shell.execute_reply":"2024-03-13T10:53:37.760921Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# INFER EFFICIENTNET ON TEST\npreds = []\ntest_ds = EEGDataset(test, mode='test', specs=spectrograms2, eeg_specs=all_eegs2)\ntest_loader = DataLoader(test_ds, shuffle=False, batch_size=64, num_workers=3)\n\nfor i in range(5):\n    print('#'*25)\n    print(f'### Testing Fold {i+1}')\n\n    ckpt_file = f'EffNet_v{VER}_f{i}.ckpt' if LOAD_MODELS_FROM is None else f'{LOAD_MODELS_FROM}/EffNet_v{VER}_f{i}.ckpt'\n    model = EEGEffnetB0.load_from_checkpoint(ckpt_file)\n    model.to(device).eval()\n    fold_preds = []\n\n    with torch.inference_mode():\n        for test_batch in test_loader:\n            test_batch = test_batch.to(device)\n            pred = torch.softmax(model(test_batch), dim=1).cpu().numpy()\n            fold_preds.append(pred)\n        fold_preds = np.concatenate(fold_preds)\n\n    preds.append(fold_preds)\n\npred = np.mean(preds,axis=0)\nprint()\nprint('Test preds shape',pred.shape)","metadata":{"execution":{"iopub.status.busy":"2024-03-13T10:53:37.763324Z","iopub.execute_input":"2024-03-13T10:53:37.764280Z","iopub.status.idle":"2024-03-13T10:53:44.457955Z","shell.execute_reply.started":"2024-03-13T10:53:37.764241Z","shell.execute_reply":"2024-03-13T10:53:44.456489Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"sub1 = pd.DataFrame({'eeg_id':test.eeg_id.values})\nsub1[TARGETS] = pred\nprint('Submission shape',sub1.shape)\nsub1.head()","metadata":{"execution":{"iopub.status.busy":"2024-03-13T10:53:44.460151Z","iopub.execute_input":"2024-03-13T10:53:44.461156Z","iopub.status.idle":"2024-03-13T10:53:44.481052Z","shell.execute_reply.started":"2024-03-13T10:53:44.461111Z","shell.execute_reply":"2024-03-13T10:53:44.480104Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"sub1 = pd.DataFrame({'eeg_id':test.eeg_id.values})\nsub1[TARGETS] = pred\nprint('Submission shape',sub1.shape)\nsub1.head()","metadata":{"execution":{"iopub.status.busy":"2024-03-13T10:53:44.482548Z","iopub.execute_input":"2024-03-13T10:53:44.483575Z","iopub.status.idle":"2024-03-13T10:53:44.500008Z","shell.execute_reply.started":"2024-03-13T10:53:44.483533Z","shell.execute_reply":"2024-03-13T10:53:44.499036Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"preds_combine = pred\npreds_combine","metadata":{"execution":{"iopub.status.busy":"2024-03-13T10:53:44.501137Z","iopub.execute_input":"2024-03-13T10:53:44.501411Z","iopub.status.idle":"2024-03-13T10:53:44.510460Z","shell.execute_reply.started":"2024-03-13T10:53:44.501387Z","shell.execute_reply":"2024-03-13T10:53:44.509644Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# SANITY CHECK TO CONFIRM PREDICTIONS SUM TO ONE\nsub1.iloc[:,-6:].sum(axis=1)","metadata":{"execution":{"iopub.status.busy":"2024-03-13T10:53:44.511796Z","iopub.execute_input":"2024-03-13T10:53:44.512478Z","iopub.status.idle":"2024-03-13T10:53:44.523848Z","shell.execute_reply.started":"2024-03-13T10:53:44.512441Z","shell.execute_reply":"2024-03-13T10:53:44.522927Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"---\n# **《《《　Model 2　》》》**\n---","metadata":{}},{"cell_type":"code","source":"#https://www.kaggle.com/code/ttahara/hms-hbac-resnet34d-baseline-training\n#https://www.kaggle.com/code/ttahara/hms-hbac-resnet34d-baseline-inference\n#necessary\nimport pandas as pd#导入csv文件的库\nimport numpy as np#进行矩阵运算的库\nimport torch #一个深度学习的库Pytorch\nimport torch.nn as nn#neural network,神经网络\nimport torch.nn.functional as F#神经网络函数库\nimport torchvision.transforms as transforms#Pytorch下面的图像处理库,用于对图像进行数据增强\n#设置随机种子\nimport random\nimport warnings#避免一些可以忽略的报错\nwarnings.filterwarnings('ignore')#filterwarnings()方法是用于设置警告过滤器的方法，它可以控制警告信息的输出方式和级别。","metadata":{"execution":{"iopub.status.busy":"2024-03-13T10:53:44.524831Z","iopub.execute_input":"2024-03-13T10:53:44.525106Z","iopub.status.idle":"2024-03-13T10:53:44.533544Z","shell.execute_reply.started":"2024-03-13T10:53:44.525084Z","shell.execute_reply":"2024-03-13T10:53:44.532744Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class Config:\n    seed=2024\n    image_transform=transforms.Resize((512, 512))\n    num_folds=5","metadata":{"execution":{"iopub.status.busy":"2024-03-13T10:53:44.534520Z","iopub.execute_input":"2024-03-13T10:53:44.535162Z","iopub.status.idle":"2024-03-13T10:53:44.543899Z","shell.execute_reply.started":"2024-03-13T10:53:44.535106Z","shell.execute_reply":"2024-03-13T10:53:44.542865Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"models=[]\nfor i in range(Config.num_folds):\n    model = torch.load(f'/kaggle/input/hms-baseline-resnet34d-512-512-training-5-folds/HMS_resnet_fold{i}.pth')\n    models.append(model)\n# model = torch.load(\"/kaggle/input/hms-baseline-resnet34d-512-512-training/HMS_resnet.pth\")\n# models.append(model)","metadata":{"execution":{"iopub.status.busy":"2024-03-13T10:53:44.545233Z","iopub.execute_input":"2024-03-13T10:53:44.545538Z","iopub.status.idle":"2024-03-13T10:53:50.278678Z","shell.execute_reply.started":"2024-03-13T10:53:44.545513Z","shell.execute_reply":"2024-03-13T10:53:50.277768Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def seed_everything(seed):\n    torch.backends.cudnn.deterministic = True#将cuda加速的随机数生成器设为确定性模式\n    torch.backends.cudnn.benchmark = True#关闭CuDNN框架的自动寻找最优卷积算法的功能，以避免不同的算法对结果产生影响\n    torch.manual_seed(seed)#pytorch的随机种子\n    np.random.seed(seed)#numpy的随机种子\n    random.seed(seed)#python内置的随机种子\nseed_everything(Config.seed)","metadata":{"execution":{"iopub.status.busy":"2024-03-13T10:53:50.285088Z","iopub.execute_input":"2024-03-13T10:53:50.285403Z","iopub.status.idle":"2024-03-13T10:53:50.292017Z","shell.execute_reply.started":"2024-03-13T10:53:50.285375Z","shell.execute_reply":"2024-03-13T10:53:50.291088Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"test_df=pd.read_csv(\"/kaggle/input/hms-harmful-brain-activity-classification/test.csv\")\nsubmission=pd.read_csv(\"/kaggle/input/hms-harmful-brain-activity-classification/sample_submission.csv\")\nsubmission=submission.merge(test_df,on='eeg_id',how='left')\nsubmission['path']=submission['spectrogram_id'].apply(lambda x: \"/kaggle/input/hms-harmful-brain-activity-classification/test_spectrograms/\"+str(x)+\".parquet\" )\nsubmission.head()","metadata":{"execution":{"iopub.status.busy":"2024-03-13T10:53:50.293191Z","iopub.execute_input":"2024-03-13T10:53:50.293577Z","iopub.status.idle":"2024-03-13T10:53:50.330532Z","shell.execute_reply.started":"2024-03-13T10:53:50.293551Z","shell.execute_reply":"2024-03-13T10:53:50.329580Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"paths=submission['path'].values\ntest_preds=[]\nfor path in paths:\n    eps=1e-6\n    data=pd.read_parquet(path)\n    #这里最小值是0,故用-1填充.第一列是时间列,故去掉 ,行是不同列,列是时间\n    data = data.fillna(-1).values[:,1:].T\n    #选取一段时间的数据进行训练\n    data=data[:,0:300]#(400,300)\n    data=np.clip(data,np.exp(-6),np.exp(10))#最大值为89209464.0\n    data= np.log(data)#对数变换\n    #对数据进行归一化\n    data_mean=data.mean(axis=(0,1))\n    data_std=data.std(axis=(0,1))\n    data=(data-data_mean)/(data_std+eps)\n    data_tensor = torch.unsqueeze(torch.Tensor(data), dim=0)\n    data=Config.image_transform(data_tensor)\n    test_pred=[]\n    for model in models:\n        model.eval()\n        with torch.no_grad():\n            pred=F.softmax(model(data.unsqueeze(0)))[0]\n            pred=pred.detach().cpu().numpy()\n        test_pred.append(pred)\n    test_pred=np.array(test_pred).mean(axis=0)\n    test_preds.append(test_pred)\ntest_preds=np.array(test_preds)\ntest_preds","metadata":{"execution":{"iopub.status.busy":"2024-03-13T10:53:50.332054Z","iopub.execute_input":"2024-03-13T10:53:50.332311Z","iopub.status.idle":"2024-03-13T10:53:51.782034Z","shell.execute_reply.started":"2024-03-13T10:53:50.332288Z","shell.execute_reply":"2024-03-13T10:53:51.780925Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"sub2=pd.read_csv(\"/kaggle/input/hms-harmful-brain-activity-classification/sample_submission.csv\")\nlabels=['seizure','lpd','gpd','lrda','grda','other']\nfor i in range(len(labels)):\n    sub2[f'{labels[i]}_vote']=test_preds[:,i]\nsub2.head()","metadata":{"execution":{"iopub.status.busy":"2024-03-13T10:53:51.783651Z","iopub.execute_input":"2024-03-13T10:53:51.784030Z","iopub.status.idle":"2024-03-13T10:53:51.803047Z","shell.execute_reply.started":"2024-03-13T10:53:51.783998Z","shell.execute_reply":"2024-03-13T10:53:51.802182Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"---\n# **《《《　Model 3　》》》**\n---","metadata":{}},{"cell_type":"code","source":"# Importing essential libraries\nimport gc\nimport os\nimport random\nimport warnings\nimport numpy as np\nimport pandas as pd\nfrom IPython.display import display\n\n# PyTorch for deep learning\nimport timm\nimport torch\nimport torch.nn as nn  \nimport torch.optim as optim\nimport torch.nn.functional as F\n\n# torchvision for image processing and augmentation\nimport torchvision.transforms as transforms\n\n# Suppressing minor warnings to keep the output clean\nwarnings.filterwarnings('ignore', category=Warning)\n\n# Reclaim memory no longer in use.\ngc.collect()","metadata":{"execution":{"iopub.status.busy":"2024-03-13T10:53:51.804662Z","iopub.execute_input":"2024-03-13T10:53:51.804946Z","iopub.status.idle":"2024-03-13T10:53:52.105289Z","shell.execute_reply.started":"2024-03-13T10:53:51.804923Z","shell.execute_reply":"2024-03-13T10:53:52.104115Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class Config:\n    seed=42\n    image_transform=transforms.Resize((512, 512))\n    num_folds=5\n    \n# Set the seed for reproducibility across multiple libraries\ndef set_seed(seed):\n    torch.backends.cudnn.deterministic = True\n    torch.backends.cudnn.benchmark = True\n    torch.manual_seed(seed)\n    np.random.seed(seed)\n    random.seed(seed)\n    \nset_seed(Config.seed)","metadata":{"execution":{"iopub.status.busy":"2024-03-13T10:53:52.107956Z","iopub.execute_input":"2024-03-13T10:53:52.108284Z","iopub.status.idle":"2024-03-13T10:53:52.116284Z","shell.execute_reply.started":"2024-03-13T10:53:52.108257Z","shell.execute_reply":"2024-03-13T10:53:52.115488Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Load and store the trained models for each fold into a list\nmodels = []\n\n# Load ResNet34d\nfor i in range(Config.num_folds):\n    # Create the same model architecture as during training\n    model_resnet = timm.create_model('resnet34d', pretrained=False, num_classes=6, in_chans=1)\n    \n    # Load the trained weights from the corresponding file\n    model_resnet.load_state_dict(torch.load(f'/kaggle/input/resnet34d/hms-train-resnet34d/resnet34d_fold{i}.pth', map_location=torch.device('cpu')))\n    \n    # Append the loaded model to the models list\n    models.append(model_resnet)\n\n# Reclaim memory no longer in use.\ngc.collect()\n\n# Load EfficientNetB0\nfor j in range(Config.num_folds):\n    # Create the same model architecture as during training\n    model_effnet_b0 = timm.create_model('efficientnet_b0', pretrained=False, num_classes=6, in_chans=1)\n    \n    # Load the trained weights from the corresponding file\n    model_effnet_b0.load_state_dict(torch.load(f'/kaggle/input/efficientnetb0/hms-train-efficientnetb0/efficientnet_b0_fold{j}.pth', map_location=torch.device('cpu')))\n    \n    # Append the loaded model to the models list\n    models.append(model_effnet_b0)\n    \n# Reclaim memory no longer in use.\ngc.collect()\n    \n# Load EfficientNetB1\nfor k in range(Config.num_folds):\n    # Create the same model architecture as during training\n    model_effnet_b1 = timm.create_model('efficientnet_b1', pretrained=False, num_classes=6, in_chans=1)\n    \n    # Load the trained weights from the corresponding file\n    model_effnet_b1.load_state_dict(torch.load(f'/kaggle/input/efficientnetb1/hms-train-efficientnetb1/efficientnet_b1_fold{k}.pth', map_location=torch.device('cpu')))\n    \n    # Append the loaded model to the models list\n    models.append(model_effnet_b1)\n\n# Reclaim memory no longer in use.\ngc.collect()","metadata":{"execution":{"iopub.status.busy":"2024-03-13T10:53:52.117475Z","iopub.execute_input":"2024-03-13T10:53:52.117836Z","iopub.status.idle":"2024-03-13T10:54:02.269063Z","shell.execute_reply.started":"2024-03-13T10:53:52.117810Z","shell.execute_reply":"2024-03-13T10:54:02.268094Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Load test data and sample submission dataframe\ntest_df = pd.read_csv(\"/kaggle/input/hms-harmful-brain-activity-classification/test.csv\")\nsubmission = pd.read_csv(\"/kaggle/input/hms-harmful-brain-activity-classification/sample_submission.csv\")\n\n# Merge the submission dataframe with the test data on EEG IDs\nsubmission = submission.merge(test_df, on='eeg_id', how='left')\n\n# Generate file paths for each spectrogram based on the EEG data in the submission dataframe\nsubmission['path'] = submission['spectrogram_id'].apply(lambda x: f\"/kaggle/input/hms-harmful-brain-activity-classification/test_spectrograms/{x}.parquet\")\n\n# Display the first few rows of the submission dataframe\ndisplay(submission.head())\n\n# Reclaim memory no longer in use\ngc.collect()","metadata":{"execution":{"iopub.status.busy":"2024-03-13T10:54:02.270568Z","iopub.execute_input":"2024-03-13T10:54:02.270965Z","iopub.status.idle":"2024-03-13T10:54:02.570597Z","shell.execute_reply.started":"2024-03-13T10:54:02.270928Z","shell.execute_reply":"2024-03-13T10:54:02.569445Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Define the weights for each model\nweight_resnet34d = 0.25\nweight_effnetb0 = 0.42\nweight_effnetb1 = 0.33\n\n# Get file paths for test spectrograms\npaths = submission['path'].values\ntest_predss = []\n\n# Generate predictions for each spectrogram using all models\nfor path in paths:\n    eps = 1e-6\n    # Read and preprocess spectrogram data\n    data = pd.read_parquet(path)\n    data = data.fillna(-1).values[:, 1:].T\n    data = np.clip(data, np.exp(-6), np.exp(10))\n    data = np.log(data)\n    \n    # Normalize the data\n    data_mean = data.mean(axis=(0, 1))\n    data_std = data.std(axis=(0, 1))\n    data = (data - data_mean) / (data_std + eps)\n    data_tensor = torch.unsqueeze(torch.Tensor(data), dim=0)\n    data = Config.image_transform(data_tensor)\n\n    test_pred = []\n    \n    # Generate predictions using all models\n    for model in models:\n        model.eval()\n        with torch.no_grad():\n            pred = F.softmax(model(data.unsqueeze(0)))[0]\n            pred = pred.detach().cpu().numpy()\n        test_pred.append(pred)\n        \n    # Combine predictions from all models using weighted voting\n    weighted_pred = weight_resnet34d * np.mean(test_pred[:Config.num_folds], axis=0) + \\\n                     weight_effnetb0 * np.mean(test_pred[Config.num_folds:2*Config.num_folds], axis=0) + \\\n                     weight_effnetb1 * np.mean(test_pred[2*Config.num_folds:], axis=0)\n    \n    test_predss.append(weighted_pred)\n\n# Convert the list of predictions to a NumPy array for further processing\ntest_predss = np.array(test_predss)\n\n# Reclaim memory no longer in use\ngc.collect()","metadata":{"execution":{"iopub.status.busy":"2024-03-13T10:54:02.573096Z","iopub.execute_input":"2024-03-13T10:54:02.573360Z","iopub.status.idle":"2024-03-13T10:54:05.778731Z","shell.execute_reply.started":"2024-03-13T10:54:02.573336Z","shell.execute_reply":"2024-03-13T10:54:05.777532Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"test_predss","metadata":{"execution":{"iopub.status.busy":"2024-03-13T10:54:05.779943Z","iopub.execute_input":"2024-03-13T10:54:05.780236Z","iopub.status.idle":"2024-03-13T10:54:05.788770Z","shell.execute_reply.started":"2024-03-13T10:54:05.780209Z","shell.execute_reply":"2024-03-13T10:54:05.786716Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"---\n# **《《《　Model 4　》》》**\n---","metadata":{}},{"cell_type":"code","source":"import os\nimport gc\nimport sys\nimport math\nimport time\nimport random\nimport datetime as dt\nimport numpy as np\nimport pandas as pd\n\nfrom glob import glob\nfrom pathlib import Path\nfrom typing import Dict, List, Union\nfrom scipy.signal import butter, lfilter, freqz\nfrom matplotlib import pyplot as plt\nfrom tqdm.auto import tqdm\n\nimport torch\nimport torch.nn as nn\nimport torch.nn.functional as F\nfrom torch.optim import Adam, SGD, AdamW\nfrom torch.utils.data import DataLoader, Dataset\n\nsys.path.append(\"/kaggle/input/kaggle-kl-div\")\nfrom kaggle_kl_div import score\n\nimport warnings\n\nwarnings.filterwarnings(\"ignore\")\n\ndevice = torch.device(\"cuda\")\nos.environ[\"CUDA_VISIBLE_DEVICES\"] = \"0,1\"\n\n!cat /etc/os-release | grep -oP \"PRETTY_NAME=\\\"\\K([^\\\"]*)\"\nprint(f\"BUILD_DATE={os.environ['BUILD_DATE']}, CONTAINER_NAME={os.environ['CONTAINER_NAME']}\")\n\ntry:\n    print(\n        f\"PyTorch Version:{torch.__version__}, CUDA is available:{torch.cuda.is_available()}, Version CUDA:{torch.version.cuda}\"\n    )\n    print(\n        f\"Device Capability:{torch.cuda.get_device_capability()}, {torch.cuda.get_arch_list()}\"\n    )\n    print(\n        f\"CuDNN Enabled:{torch.backends.cudnn.enabled}, Version:{torch.backends.cudnn.version()}\"\n    )\nexcept Exception:\n    pass","metadata":{"execution":{"iopub.status.busy":"2024-03-13T10:54:05.790223Z","iopub.execute_input":"2024-03-13T10:54:05.790591Z","iopub.status.idle":"2024-03-13T10:54:07.172323Z","shell.execute_reply.started":"2024-03-13T10:54:05.790556Z","shell.execute_reply":"2024-03-13T10:54:07.171166Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class CFG:\n    VERSION = 75\n\n    model_name = \"resnet1d_gru\"\n\n    seed = 2024\n    batch_size = 32\n    num_workers = 0\n\n    fixed_kernel_size = 5\n    # kernels = [3, 5, 7, 9]\n    # linear_layer_features = 424\n    kernels = [3, 5, 7, 9, 11]\n    #linear_layer_features = 448  # Full Signal = 10_000\n    #linear_layer_features = 352  # Half Signal = 5_000\n    linear_layer_features = 304   # 1/5  Signal = 2_000\n\n    seq_length = 50  # Second's\n    sampling_rate = 200  # Hz\n    nsamples = seq_length * sampling_rate  # Число семплов\n    out_samples = nsamples // 5\n\n    # bandpass_filter = {\"low\": 0.5, \"high\": 20, \"order\": 2}\n    # rand_filter = {\"probab\": 0.1, \"low\": 10, \"high\": 20, \"band\": 1.0, \"order\": 2}\n    freq_channels = []  # [(8.0, 12.0)]; [(0.5, 4.5)]\n    filter_order = 2\n    random_close_zone = 0.0  # 0.2\n        \n    target_cols = [\n        \"seizure_vote\",\n        \"lpd_vote\",\n        \"gpd_vote\",\n        \"lrda_vote\",\n        \"grda_vote\",\n        \"other_vote\",\n    ]\n\n    # target_preds = [x + \"_pred\" for x in target_cols]\n    # label_to_num = {\"Seizure\": 0, \"LPD\": 1, \"GPD\": 2, \"LRDA\": 3, \"GRDA\": 4, \"Other\": 5}\n    # num_to_label = {v: k for k, v in label_to_num.items()}\n\n    map_features = [\n        (\"Fp1\", \"T3\"),\n        (\"T3\", \"O1\"),\n        (\"Fp1\", \"C3\"),\n        (\"C3\", \"O1\"),\n        (\"Fp2\", \"C4\"),\n        (\"C4\", \"O2\"),\n        (\"Fp2\", \"T4\"),\n        (\"T4\", \"O2\"),\n        #('Fz', 'Cz'), ('Cz', 'Pz'),        \n    ]\n\n    eeg_features = [\"Fp1\", \"T3\", \"C3\", \"O1\", \"Fp2\", \"C4\", \"T4\", \"O2\"]  # 'Fz', 'Cz', 'Pz']\n        # 'F3', 'P3', 'F7', 'T5', 'Fz', 'Cz', 'Pz', 'F4', 'P4', 'F8', 'T6', 'EKG']                    \n    feature_to_index = {x: y for x, y in zip(eeg_features, range(len(eeg_features)))}\n    simple_features = []  # 'Fz', 'Cz', 'Pz', 'EKG'\n\n    # eeg_features = [row for row in feature_to_index]\n    # eeg_feat_size = len(eeg_features)\n    \n    n_map_features = len(map_features)\n    in_channels = n_map_features + n_map_features * len(freq_channels) + len(simple_features)\n    target_size = len(target_cols)\n    \n    PATH = \"/kaggle/input/hms-harmful-brain-activity-classification/\"\n    test_eeg = \"/kaggle/input/hms-harmful-brain-activity-classification/test_eegs/\"\n    test_csv = \"/kaggle/input/hms-harmful-brain-activity-classification/test.csv\"","metadata":{"execution":{"iopub.status.busy":"2024-03-13T10:54:07.174225Z","iopub.execute_input":"2024-03-13T10:54:07.174543Z","iopub.status.idle":"2024-03-13T10:54:07.185530Z","shell.execute_reply.started":"2024-03-13T10:54:07.174515Z","shell.execute_reply":"2024-03-13T10:54:07.184682Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"koef_1 = 1.0\nmodel_weights = [\n    {\n        'bandpass_filter':{'low':0.5, 'high':20, 'order':2}, \n        'file_data': \n        [\n            {'koef':koef_1, 'file_mask':\"/kaggle/input/hms-resnet1d-gru-weights-v102/pop_1_weight_oof/*_best.pth\"},\n            #{'koef':koef_1, 'file_mask':\"/kaggle/input/hms-resnet1d-gru-weights-v102/pop_2_weight_oof/*_best.pth\"},\n        ]\n    },\n]","metadata":{"execution":{"iopub.status.busy":"2024-03-13T10:54:07.186549Z","iopub.execute_input":"2024-03-13T10:54:07.186843Z","iopub.status.idle":"2024-03-13T10:54:07.200427Z","shell.execute_reply.started":"2024-03-13T10:54:07.186820Z","shell.execute_reply":"2024-03-13T10:54:07.199559Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def init_logger(log_file=\"./test.log\"):\n    from logging import getLogger, INFO, FileHandler, Formatter, StreamHandler\n\n    logger = getLogger(__name__)\n    logger.setLevel(INFO)\n    handler1 = StreamHandler()\n    handler1.setFormatter(Formatter(\"%(message)s\"))\n    handler2 = FileHandler(filename=log_file)\n    handler2.setFormatter(Formatter(\"%(message)s\"))\n    logger.addHandler(handler1)\n    logger.addHandler(handler2)\n    return logger\n\n\ndef asMinutes(s):\n    m = math.floor(s / 60)\n    s -= m * 60\n    return \"%dm %ds\" % (m, s)\n\n\ndef timeSince(since, percent):\n    now = time.time()\n    s = now - since\n    es = s / (percent)\n    rs = es - s\n    return \"%s (remain %s)\" % (asMinutes(s), asMinutes(rs))\n\n\ndef quantize_data(data, classes):\n    mu_x = mu_law_encoding(data, classes)\n    return mu_x  # quantized\n\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\n\ndef mu_law_expansion(data, mu):\n    s = np.sign(data) * (np.exp(np.abs(data) * np.log(mu + 1)) - 1) / mu\n    return s\n\n\ndef butter_bandpass(lowcut, highcut, fs, order=5):\n    return butter(order, [lowcut, highcut], fs=fs, btype=\"band\")\n\n\ndef butter_bandpass_filter(data, lowcut, highcut, fs, order=5):\n    b, a = butter_bandpass(lowcut, highcut, fs, order=order)\n    y = lfilter(b, a, data)\n    return y\n\n\ndef butter_lowpass_filter(\n    data, cutoff_freq=20, sampling_rate=CFG.sampling_rate, order=4\n):\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\n\n\ndef denoise_filter(x):\n    # Частота дискретизации и желаемые частоты среза (в Гц).\n    # Отфильтруйте шумный сигнал\n    y = butter_bandpass_filter(x, CFG.lowcut, CFG.highcut, CFG.sampling_rate, order=6)\n    y = (y + np.roll(y, -1) + np.roll(y, -2) + np.roll(y, -3)) / 4\n    y = y[0:-1:4]\n    return y","metadata":{"execution":{"iopub.status.busy":"2024-03-13T10:54:07.201579Z","iopub.execute_input":"2024-03-13T10:54:07.201818Z","iopub.status.idle":"2024-03-13T10:54:07.217592Z","shell.execute_reply.started":"2024-03-13T10:54:07.201798Z","shell.execute_reply":"2024-03-13T10:54:07.216694Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def eeg_from_parquet(\n    parquet_path: str, display: bool = False, seq_length=CFG.seq_length\n) -> np.ndarray:\n    \"\"\"\n    Эта функция читает файл паркета и извлекает средние 50 секунд показаний. Затем он заполняет значения NaN\n    со средним значением (игнорируя NaN).\n        :param parquet_path: путь к файлу паркета.\n        :param display: отображать графики ЭЭГ или нет.\n        :return data: np.array формы (time_steps, eeg_features) -> (10_000, 8)\n    \"\"\"\n\n    # Вырезаем среднюю 50 секундную часть\n    eeg = pd.read_parquet(parquet_path, columns=CFG.eeg_features)\n    rows = len(eeg)\n\n    # начало смещения данных, чтобы забрать середину\n    offset = (rows - CFG.nsamples) // 2\n\n    # средние 50 секунд, имеет одинаковое количество показаний слева и справа\n    eeg = eeg.iloc[offset : offset + CFG.nsamples]\n\n    if display:\n        plt.figure(figsize=(10, 5))\n        offset = 0\n\n    # Конвертировать в numpy\n\n    # создать заполнитель той же формы с нулями\n    data = np.zeros((CFG.nsamples, len(CFG.eeg_features)))\n\n    for index, feature in enumerate(CFG.eeg_features):\n        x = eeg[feature].values.astype(\"float32\")  # конвертировать в float32\n\n        # Вычисляет среднее арифметическое вдоль указанной оси, игнорируя NaN.\n        mean = np.nanmean(x)\n        nan_percentage = np.isnan(x).mean()  # percentage of NaN values in feature\n\n        # Заполнение значения Nan\n        # Поэлементная проверка на NaN и возврат результата в виде логического массива.\n        if nan_percentage < 1:  # если некоторые значения равны Nan, но не все\n            x = np.nan_to_num(x, nan=mean)\n        else:  # если все значения — Nan\n            x[:] = 0\n        data[:, index] = x\n\n        if display:\n            if index != 0:\n                offset += x.max()\n            plt.plot(range(CFG.nsamples), x - offset, label=feature)\n            offset -= x.min()\n\n    if display:\n        plt.legend()\n        name = parquet_path.split(\"/\")[-1].split(\".\")[0]\n        plt.yticks([])\n        plt.title(f\"EEG {name}\", size=16)\n        plt.show()\n    return data","metadata":{"execution":{"iopub.status.busy":"2024-03-13T10:54:07.219070Z","iopub.execute_input":"2024-03-13T10:54:07.219332Z","iopub.status.idle":"2024-03-13T10:54:07.232494Z","shell.execute_reply.started":"2024-03-13T10:54:07.219310Z","shell.execute_reply":"2024-03-13T10:54:07.231664Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class EEGDataset(Dataset):\n    def __init__(\n        self,\n        df: pd.DataFrame,\n        batch_size: int,\n        eegs: Dict[int, np.ndarray],\n        mode: str = \"train\",\n        downsample: int = None,\n        bandpass_filter: Dict[str, Union[int, float]] = None,\n        rand_filter: Dict[str, Union[int, float]] = None,\n    ):\n        self.df = df\n        self.batch_size = batch_size\n        self.mode = mode\n        self.eegs = eegs\n        self.downsample = downsample\n        self.bandpass_filter = bandpass_filter\n        self.rand_filter = rand_filter\n        \n    def __len__(self):\n        \"\"\"\n        Length of dataset.\n        \"\"\"\n        # Обозначает количество пакетов за эпоху\n        return len(self.df)\n\n    def __getitem__(self, index):\n        \"\"\"\n        Get one item.\n        \"\"\"\n        # Сгенерировать один пакет данных\n        X, y_prob = self.__data_generation(index)\n        if self.downsample is not None:\n            X = X[:: self.downsample, :]\n        output = {\n            \"eeg\": torch.tensor(X, dtype=torch.float32),\n            \"labels\": torch.tensor(y_prob, dtype=torch.float32),\n        }\n        return output\n\n    def __data_generation(self, index):\n        # Генерирует данные, содержащие образцы размера партии\n        X = np.zeros(\n            (CFG.out_samples, CFG.in_channels), dtype=\"float32\"\n        )  # Size=(10000, 14)\n\n        row = self.df.iloc[index]  # Строка Pandas\n        data = self.eegs[row.eeg_id]  # Size=(10000, 8)\n        if CFG.nsamples != CFG.out_samples:\n            if self.mode != \"train\":\n                offset = (CFG.nsamples - CFG.out_samples) // 2\n            else:\n                #offset = random.randint(0, CFG.nsamples - CFG.out_samples)                \n                offset = ((CFG.nsamples - CFG.out_samples) * random.randint(0, 1000)) // 1000\n            data = data[offset:offset+CFG.out_samples,:]\n\n        for i, (feat_a, feat_b) in enumerate(CFG.map_features):\n            if self.mode == \"train\" and CFG.random_close_zone > 0 and random.uniform(0.0, 1.0) <= CFG.random_close_zone:\n                continue\n                \n            diff_feat = (\n                data[:, CFG.feature_to_index[feat_a]]\n                - data[:, CFG.feature_to_index[feat_b]]\n            )  # Size=(10000,)\n\n            if not self.bandpass_filter is None:\n                diff_feat = butter_bandpass_filter(\n                    diff_feat,\n                    self.bandpass_filter[\"low\"],\n                    self.bandpass_filter[\"high\"],\n                    CFG.sampling_rate,\n                    order=self.bandpass_filter[\"order\"],\n                )\n                    \n            if (\n                self.mode == \"train\"\n                and not self.rand_filter is None\n                and random.uniform(0.0, 1.0) <= self.rand_filter[\"probab\"]\n            ):\n                lowcut = random.randint(\n                    self.rand_filter[\"low\"], self.rand_filter[\"high\"]\n                )\n                highcut = lowcut + self.rand_filter[\"band\"]\n                diff_feat = butter_bandpass_filter(\n                    diff_feat,\n                    lowcut,\n                    highcut,\n                    CFG.sampling_rate,\n                    order=self.rand_filter[\"order\"],\n                )\n\n            X[:, i] = diff_feat\n\n        n = CFG.n_map_features\n        if len(CFG.freq_channels) > 0:\n            for i in range(CFG.n_map_features):\n                diff_feat = X[:, i]\n                for j, (lowcut, highcut) in enumerate(CFG.freq_channels):\n                    band_feat = butter_bandpass_filter(\n                        diff_feat, lowcut, highcut, CFG.sampling_rate, order=CFG.filter_order,  # 6\n                    )\n                    X[:, n] = band_feat\n                    n += 1\n\n        for spml_feat in CFG.simple_features:\n            feat_val = data[:, CFG.feature_to_index[spml_feat]]\n            \n            if not self.bandpass_filter is None:\n                feat_val = butter_bandpass_filter(\n                    feat_val,\n                    self.bandpass_filter[\"low\"],\n                    self.bandpass_filter[\"high\"],\n                    CFG.sampling_rate,\n                    order=self.bandpass_filter[\"order\"],\n                )\n\n            if (\n                self.mode == \"train\"\n                and not self.rand_filter is None\n                and random.uniform(0.0, 1.0) <= self.rand_filter[\"probab\"]\n            ):\n                lowcut = random.randint(\n                    self.rand_filter[\"low\"], self.rand_filter[\"high\"]\n                )\n                highcut = lowcut + self.rand_filter[\"band\"]\n                feat_val = butter_bandpass_filter(\n                    feat_val,\n                    lowcut,\n                    highcut,\n                    CFG.sampling_rate,\n                    order=self.rand_filter[\"order\"],\n                )\n\n            X[:, n] = feat_val\n            n += 1\n            \n        # Обрезать края превышающие значения [-1024, 1024]\n        X = np.clip(X, -1024, 1024)\n\n        # Замените NaN нулем и разделить все на 32\n        X = np.nan_to_num(X, nan=0) / 32.0\n\n        # обрезать полосовым фильтром верхнюю границу в 20 Hz.\n        X = butter_lowpass_filter(X, order=CFG.filter_order)  # 4\n\n        y_prob = np.zeros(CFG.target_size, dtype=\"float32\")  # Size=(6,)\n        if self.mode != \"test\":\n            y_prob = row[CFG.target_cols].values.astype(np.float32)\n\n        return X, y_prob","metadata":{"execution":{"iopub.status.busy":"2024-03-13T10:54:07.233974Z","iopub.execute_input":"2024-03-13T10:54:07.234283Z","iopub.status.idle":"2024-03-13T10:54:07.259012Z","shell.execute_reply.started":"2024-03-13T10:54:07.234259Z","shell.execute_reply":"2024-03-13T10:54:07.258187Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class ResNet_1D_Block(nn.Module):\n    def __init__(\n        self,\n        in_channels,\n        out_channels,\n        kernel_size,\n        stride,\n        padding,\n        downsampling,\n        dilation=1,\n        groups=1,\n        dropout=0.0,\n    ):\n        super(ResNet_1D_Block, self).__init__()\n\n        self.bn1 = nn.BatchNorm1d(num_features=in_channels)\n        # self.relu = nn.ReLU(inplace=False)\n        # self.relu_1 = nn.PReLU()\n        # self.relu_2 = nn.PReLU()\n        self.relu_1 = nn.Hardswish()\n        self.relu_2 = nn.Hardswish()\n\n        self.dropout = nn.Dropout(p=dropout, inplace=False)\n        self.conv1 = nn.Conv1d(\n            in_channels=in_channels,\n            out_channels=out_channels,\n            kernel_size=kernel_size,\n            stride=stride,\n            padding=padding,\n            dilation=dilation,\n            groups=groups,\n            bias=False,\n        )\n\n        self.bn2 = nn.BatchNorm1d(num_features=out_channels)\n        self.conv2 = nn.Conv1d(\n            in_channels=out_channels,\n            out_channels=out_channels,\n            kernel_size=kernel_size,\n            stride=stride,\n            padding=padding,\n            dilation=dilation,\n            groups=groups,\n            bias=False,\n        )\n\n        self.maxpool = nn.MaxPool1d(\n            kernel_size=2,\n            stride=2,\n            padding=0,\n            dilation=dilation,\n        )\n        self.downsampling = downsampling\n\n    def forward(self, x):\n        identity = x\n\n        out = self.bn1(x)\n        out = self.relu_1(out)\n        out = self.dropout(out)\n        out = self.conv1(out)\n        out = self.bn2(out)\n        out = self.relu_2(out)\n        out = self.dropout(out)\n        out = self.conv2(out)\n\n        out = self.maxpool(out)\n        identity = self.downsampling(x)\n\n        out += identity\n        return out\n\n\nclass EEGNet(nn.Module):\n    def __init__(\n        self,\n        kernels,\n        in_channels,\n        fixed_kernel_size,\n        num_classes,\n        linear_layer_features,\n        dilation=1,\n        groups=1,\n    ):\n        super(EEGNet, self).__init__()\n        self.kernels = kernels\n        self.planes = 24\n        self.parallel_conv = nn.ModuleList()\n        self.in_channels = in_channels\n\n        for i, kernel_size in enumerate(list(self.kernels)):\n            sep_conv = nn.Conv1d(\n                in_channels=in_channels,\n                out_channels=self.planes,\n                kernel_size=(kernel_size),\n                stride=1,\n                padding=0,\n                dilation=dilation,\n                groups=groups,\n                bias=False,\n            )\n            self.parallel_conv.append(sep_conv)\n\n        self.bn1 = nn.BatchNorm1d(num_features=self.planes)\n        # self.relu = nn.ReLU(inplace=False)\n        # self.relu_1 = nn.ReLU()\n        # self.relu_2 = nn.ReLU()\n        self.relu_1 = nn.SiLU()\n        self.relu_2 = nn.SiLU()\n\n        self.conv1 = nn.Conv1d(\n            in_channels=self.planes,\n            out_channels=self.planes,\n            kernel_size=fixed_kernel_size,\n            stride=2,\n            padding=2,\n            dilation=dilation,\n            groups=groups,\n            bias=False,\n        )\n\n        self.block = self._make_resnet_layer(\n            kernel_size=fixed_kernel_size,\n            stride=1,\n            dilation=dilation,\n            groups=groups,\n            padding=fixed_kernel_size // 2,\n        )\n        self.bn2 = nn.BatchNorm1d(num_features=self.planes)\n        self.avgpool = nn.AvgPool1d(kernel_size=6, stride=6, padding=2)\n\n        self.rnn = nn.GRU(\n            input_size=self.in_channels,\n            hidden_size=128,\n            num_layers=1,\n            bidirectional=True,\n            # dropout=0.2,\n        )\n\n        self.fc = nn.Linear(in_features=linear_layer_features, out_features=num_classes)\n\n    def _make_resnet_layer(\n        self,\n        kernel_size,\n        stride,\n        dilation=1,\n        groups=1,\n        blocks=9,\n        padding=0,\n        dropout=0.0,\n    ):\n        layers = []\n        downsample = None\n        base_width = self.planes\n\n        for i in range(blocks):\n            downsampling = nn.Sequential(\n                nn.MaxPool1d(kernel_size=2, stride=2, padding=0)\n            )\n            layers.append(\n                ResNet_1D_Block(\n                    in_channels=self.planes,\n                    out_channels=self.planes,\n                    kernel_size=kernel_size,\n                    stride=stride,\n                    padding=padding,\n                    downsampling=downsampling,\n                    dilation=dilation,\n                    groups=groups,\n                    dropout=dropout,\n                )\n            )\n        return nn.Sequential(*layers)\n\n    def extract_features(self, x):\n        x = x.permute(0, 2, 1)\n        out_sep = []\n\n        for i in range(len(self.kernels)):\n            sep = self.parallel_conv[i](x)\n            out_sep.append(sep)\n\n        out = torch.cat(out_sep, dim=2)\n        out = self.bn1(out)\n        out = self.relu_1(out)\n        out = self.conv1(out)\n\n        out = self.block(out)\n        out = self.bn2(out)\n        out = self.relu_2(out)\n        out = self.avgpool(out)\n\n        out = out.reshape(out.shape[0], -1)\n        rnn_out, _ = self.rnn(x.permute(0, 2, 1))\n        new_rnn_h = rnn_out[:, -1, :]  # <~~\n\n        new_out = torch.cat([out, new_rnn_h], dim=1)\n        return new_out\n\n    def forward(self, x):\n        new_out = self.extract_features(x)\n        result = self.fc(new_out)\n        return result","metadata":{"execution":{"iopub.status.busy":"2024-03-13T10:54:07.260235Z","iopub.execute_input":"2024-03-13T10:54:07.260471Z","iopub.status.idle":"2024-03-13T10:54:07.286501Z","shell.execute_reply.started":"2024-03-13T10:54:07.260451Z","shell.execute_reply":"2024-03-13T10:54:07.285624Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def inference_function(test_loader, model, device):\n    model.eval()  # set model in evaluation mode\n    softmax = nn.Softmax(dim=1)\n    prediction_dict = {}\n    preds = []\n    with tqdm(test_loader, unit=\"test_batch\", desc=\"Inference\") as tqdm_test_loader:\n        for step, batch in enumerate(tqdm_test_loader):\n            X = batch.pop(\"eeg\").to(device)  # send inputs to `device`\n            batch_size = X.size(0)\n            with torch.no_grad():\n                y_preds = model(X)  # forward propagation pass\n            y_preds = softmax(y_preds)\n            preds.append(y_preds.to(\"cpu\").numpy())  # save predictions\n\n    prediction_dict[\"predictions\"] = np.concatenate(\n        preds\n    )  # np.array() of shape (fold_size, target_cols)\n    return prediction_dict","metadata":{"execution":{"iopub.status.busy":"2024-03-13T10:54:07.287468Z","iopub.execute_input":"2024-03-13T10:54:07.287729Z","iopub.status.idle":"2024-03-13T10:54:07.301155Z","shell.execute_reply.started":"2024-03-13T10:54:07.287706Z","shell.execute_reply":"2024-03-13T10:54:07.300233Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"test_df = pd.read_csv(CFG.test_csv)\nprint(f\"Test dataframe shape is: {test_df.shape}\")\ntest_df.head()","metadata":{"execution":{"iopub.status.busy":"2024-03-13T10:54:07.302225Z","iopub.execute_input":"2024-03-13T10:54:07.302471Z","iopub.status.idle":"2024-03-13T10:54:07.325681Z","shell.execute_reply.started":"2024-03-13T10:54:07.302450Z","shell.execute_reply":"2024-03-13T10:54:07.324766Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"test_eeg_parquet_paths = glob(CFG.test_eeg + \"*.parquet\")\ntest_eeg_df = pd.read_parquet(test_eeg_parquet_paths[0])\ntest_eeg_features = test_eeg_df.columns\nprint(f\"There are {len(test_eeg_features)} raw eeg features\")\nprint(list(test_eeg_features))\ndel test_eeg_df\n_ = gc.collect()\n\n# %%time\nall_eegs = {}\neeg_ids = test_df.eeg_id.unique()\nfor i, eeg_id in tqdm(enumerate(eeg_ids)):\n    # Save EEG to Python dictionary of numpy arrays\n    eeg_path = CFG.test_eeg + str(eeg_id) + \".parquet\"\n    data = eeg_from_parquet(eeg_path)\n    all_eegs[eeg_id] = data","metadata":{"execution":{"iopub.status.busy":"2024-03-13T10:54:07.326942Z","iopub.execute_input":"2024-03-13T10:54:07.327310Z","iopub.status.idle":"2024-03-13T10:54:07.711865Z","shell.execute_reply.started":"2024-03-13T10:54:07.327284Z","shell.execute_reply":"2024-03-13T10:54:07.710930Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"koef_sum = 0\nkoef_count = 0\npredictions = []\nfiles = []\n    \nfor model_block in model_weights:\n    test_dataset = EEGDataset(\n        df=test_df,\n        batch_size=CFG.batch_size,\n        mode=\"test\",\n        eegs=all_eegs,\n        bandpass_filter=model_block['bandpass_filter']\n    )\n\n    if len(predictions) == 0:\n        output = test_dataset[0]\n        X = output[\"eeg\"]\n        print(f\"X shape: {X.shape}\")\n                \n    test_loader = DataLoader(\n        test_dataset,\n        batch_size=CFG.batch_size,\n        shuffle=False,\n        num_workers=CFG.num_workers,\n        pin_memory=True,\n        drop_last=False,\n    )\n\n    model = EEGNet(\n        kernels=CFG.kernels,\n        in_channels=CFG.in_channels,\n        fixed_kernel_size=CFG.fixed_kernel_size,\n        num_classes=CFG.target_size,\n        linear_layer_features=CFG.linear_layer_features,\n    )\n\n    for file_line in model_block['file_data']:\n        koef = file_line['koef']\n        for weight_model_file in glob(file_line['file_mask']):\n            files.append(weight_model_file)\n            checkpoint = torch.load(weight_model_file, map_location=device)\n            model.load_state_dict(checkpoint[\"model\"])\n            model.to(device)\n            prediction_dict = inference_function(test_loader, model, device)\n            predict = prediction_dict[\"predictions\"]\n            predict *= koef\n            koef_sum += koef\n            koef_count += 1\n            predictions.append(predict)\n            torch.cuda.empty_cache()\n            gc.collect()\n\npredictions = np.array(predictions)\nkoef_sum /= koef_count\npredictions /= koef_sum\npredictions = np.mean(predictions, axis=0)\npredictions","metadata":{"execution":{"iopub.status.busy":"2024-03-13T10:54:07.712872Z","iopub.execute_input":"2024-03-13T10:54:07.713224Z","iopub.status.idle":"2024-03-13T10:54:09.949516Z","shell.execute_reply.started":"2024-03-13T10:54:07.713195Z","shell.execute_reply":"2024-03-13T10:54:09.948510Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"---\n# **《《《　Sub　》》》**\n---","metadata":{}},{"cell_type":"code","source":"preds_combine","metadata":{"execution":{"iopub.status.busy":"2024-03-13T10:54:09.951001Z","iopub.execute_input":"2024-03-13T10:54:09.951646Z","iopub.status.idle":"2024-03-13T10:54:09.958121Z","shell.execute_reply.started":"2024-03-13T10:54:09.951608Z","shell.execute_reply":"2024-03-13T10:54:09.957154Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"submission=pd.read_csv(\"/kaggle/input/hms-harmful-brain-activity-classification/sample_submission.csv\")\nlabels=['seizure','lpd','gpd','lrda','grda','other']\nfor i in range(len(labels)):\n    submission[f'{labels[i]}_vote']=(test_preds[:,i]*0.05\n                                     + preds_combine[:, i]*0.25 \n                                     + test_predss[:, i]*0.35\n                                     + predictions[:, i]*0.35)\nsubmission.to_csv(\"submission.csv\",index=None)\ndisplay(submission.head())","metadata":{"execution":{"iopub.status.busy":"2024-03-13T10:54:09.959227Z","iopub.execute_input":"2024-03-13T10:54:09.959488Z","iopub.status.idle":"2024-03-13T10:54:09.984958Z","shell.execute_reply.started":"2024-03-13T10:54:09.959466Z","shell.execute_reply":"2024-03-13T10:54:09.984140Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# SANITY CHECK TO CONFIRM PREDICTIONS SUM TO ONE\nsubmission.iloc[:,-6:].sum(axis=1)","metadata":{"execution":{"iopub.status.busy":"2024-03-13T10:54:09.985970Z","iopub.execute_input":"2024-03-13T10:54:09.986301Z","iopub.status.idle":"2024-03-13T10:54:09.994122Z","shell.execute_reply.started":"2024-03-13T10:54:09.986268Z","shell.execute_reply":"2024-03-13T10:54:09.993097Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]}]}