{"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":7813932,"sourceType":"datasetVersion","datasetId":4577198},{"sourceId":7814513,"sourceType":"datasetVersion","datasetId":4577660},{"sourceId":7820206,"sourceType":"datasetVersion","datasetId":4581786},{"sourceId":7820928,"sourceType":"datasetVersion","datasetId":4582254},{"sourceId":7821615,"sourceType":"datasetVersion","datasetId":4582761},{"sourceId":7822474,"sourceType":"datasetVersion","datasetId":4583359},{"sourceId":7824285,"sourceType":"datasetVersion","datasetId":4584667},{"sourceId":7829053,"sourceType":"datasetVersion","datasetId":4588087},{"sourceId":7829755,"sourceType":"datasetVersion","datasetId":4588574},{"sourceId":7830451,"sourceType":"datasetVersion","datasetId":4589049},{"sourceId":7838969,"sourceType":"datasetVersion","datasetId":4595274},{"sourceId":7840605,"sourceType":"datasetVersion","datasetId":4596440},{"sourceId":7842771,"sourceType":"datasetVersion","datasetId":4598084}],"dockerImageVersionId":30665,"isInternetEnabled":false,"language":"python","sourceType":"notebook","isGpuEnabled":true}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"import glob\n\nimport pandas as pd\nimport os\nimport numpy as np\n\nimport matplotlib.pyplot as plt\nimport torch\nimport tqdm\nimport albumentations as A\nfrom albumentations.pytorch import ToTensorV2","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","execution":{"iopub.status.busy":"2024-03-15T01:54:58.838423Z","iopub.execute_input":"2024-03-15T01:54:58.838743Z","iopub.status.idle":"2024-03-15T01:55:06.272533Z","shell.execute_reply.started":"2024-03-15T01:54:58.838717Z","shell.execute_reply":"2024-03-15T01:55:06.271535Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"FEATS2 = ['Fp1','T3','C3','O1','Fp2','C4','T4','O2']\n\nDATA_TYPE = 'both'\n\nTARGETS = ['seizure_vote', 'lpd_vote', 'gpd_vote', 'lrda_vote', 'grda_vote', 'other_vote']\n\ntest = pd.read_csv('/kaggle/input/hms-harmful-brain-activity-classification/test.csv')\nprint('Test shape',test.shape)\ntest.head()\n\nPATH2 = '/kaggle/input/hms-harmful-brain-activity-classification/test_spectrograms/'\nfiles2 = os.listdir(PATH2)\nprint(f'There are {len(files2)} test spectrogram parquets')\n\n\nspectrograms2 = {}\nfor i, f in enumerate(files2):\n    if i % 100 == 0: 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 DATA GENERATOR\ntest = test.rename({'spectrogram_id': 'spec_id'}, axis=1)\n\nPATH2 = '/kaggle/input/hms-harmful-brain-activity-classification/test_eegs/'\nDISPLAY = 0\nEEG_IDS2 = test.eeg_id.unique()\nall_eegs2 = {}\n\nprint('Converting Test EEG to Spectrograms...');\nprint()","metadata":{"execution":{"iopub.status.busy":"2024-03-15T01:55:06.274819Z","iopub.execute_input":"2024-03-15T01:55:06.275360Z","iopub.status.idle":"2024-03-15T01:55:06.593813Z","shell.execute_reply.started":"2024-03-15T01:55:06.275323Z","shell.execute_reply":"2024-03-15T01:55:06.593098Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def eeg_from_parquet(parquet_path):\n    eeg = pd.read_parquet(parquet_path, columns=FEATS2)\n    rows = len(eeg)\n    offset = (rows - 10_000) // 2\n    eeg = eeg.iloc[offset:offset + 10_000]\n    data = np.zeros((10_000, len(FEATS2)))\n    for j, col in enumerate(FEATS2):\n\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[:, j] = x\n\n    return data\n\nimport librosa\nimport pywt, librosa\n\n# DENOISE FUNCTION\ndef maddest(d, axis=None):\n    return np.mean(np.absolute(d - np.mean(d, axis)), axis)\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\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']]\ndef spectrogram_from_eeg(parquet_path, display=False):\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((100, 300, 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            # 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            # 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) // 300,\n                                                      n_fft=1024, n_mels=100, fmin=0, fmax=20, win_length=128)\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\n        if display:\n            plt.subplot(2, 2, k + 1)\n            plt.imshow(img[:, :, k], aspect='auto', origin='lower')\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.show()\n\n    return img\n\n\n\nfor i, eeg_id in enumerate(EEG_IDS2):\n    # CREATE SPECTROGRAM FROM EEG PARQUET\n    img = spectrogram_from_eeg(f'{PATH2}{eeg_id}.parquet', i < DISPLAY)\n    all_eegs2[eeg_id] = img\n","metadata":{"execution":{"iopub.status.busy":"2024-03-15T01:55:06.594936Z","iopub.execute_input":"2024-03-15T01:55:06.595339Z","iopub.status.idle":"2024-03-15T01:55:16.550422Z","shell.execute_reply.started":"2024-03-15T01:55:06.595315Z","shell.execute_reply":"2024-03-15T01:55:16.548785Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class DataGenerator():\n    'Generates data for Keras'\n\n    def __init__(self, data, specs=None, eeg_specs=None, raw_eegs=None, augment=False, mode='train',\n                 data_type=DATA_TYPE,trans = None):\n        self.data = data\n        self.augment = augment\n        self.mode = mode\n        self.data_type = data_type\n        self.specs = specs\n        self.eeg_specs = eeg_specs\n        self.raw_eegs = raw_eegs\n        self.on_epoch_end()\n        self.trans = trans\n\n    def __len__(self):\n        return self.data.shape[0]\n\n    def __getitem__(self, index):\n        X, y = self.data_generation(index)\n        if self.augment: X = self.augmentation(X)\n        return X, y\n\n    def __call__(self):\n        for i in range(self.__len__()):\n            yield self.__getitem__(i)\n\n            if i == self.__len__() - 1:\n                self.on_epoch_end()\n\n    def on_epoch_end(self):\n        if self.mode == 'train':\n            self.data = self.data.sample(frac=1).reset_index(drop=True)\n\n    def data_generation(self, index):\n        if self.data_type == 'both':\n            # 入口\n            X, y = self.generate_all_specs(index)\n        elif self.data_type == 'eeg' or self.data_type == 'kaggle':\n\n            X, y = self.generate_specs(index)\n        elif self.data_type == 'raw':\n            X, y = self.generate_raw(index)\n\n        return X, y\n\n    def generate_all_specs(self, index):\n        X = np.zeros((512, 512, 3), dtype='float32')\n        y = np.zeros((6,), dtype='float32')\n\n        row = self.data.iloc[index]\n        if self.mode == 'test':\n            offset = 0\n        else:\n            offset = int(row.offset / 2)\n\n        eeg = self.eeg_specs[row.eeg_id]\n        spec = self.specs[row.spec_id]\n\n        imgs = [spec[offset:offset + 300, k * 100:(k + 1) * 100].T for k in [0, 2, 1, 3]]  # to match kaggle with eeg\n        img = np.stack(imgs, axis=-1)\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        img = np.nan_to_num(img, nan=0.0)\n\n        mn = img.flatten().min()\n        mx = img.flatten().max()\n        ep = 1e-5\n        img = 255 * (img - mn) / (mx - mn + ep)\n\n        X[0 + 56:100 + 56, :256, 0] = img[:, 22:-22, 0]  # LL_k\n        X[100 + 56:200 + 56, :256, 0] = img[:, 22:-22, 2]  # RL_k\n        X[0 + 56:100 + 56, :256, 1] = img[:, 22:-22, 1]  # LP_k\n        X[100 + 56:200 + 56, :256, 1] = img[:, 22:-22, 3]  # RP_k\n        X[0 + 56:100 + 56, :256, 2] = img[:, 22:-22, 2]  # RL_k\n        X[100 + 56:200 + 56, :256, 2] = img[:, 22:-22, 1]  # LP_k\n\n        X[0 + 56:100 + 56, 256:, 0] = img[:, 22:-22, 0]  # LL_k\n        X[100 + 56:200 + 56, 256:, 0] = img[:, 22:-22, 2]  # RL_k\n        X[0 + 56:100 + 56, 256:, 1] = img[:, 22:-22, 1]  # LP_k\n        X[100 + 56:200 + 56, 256:, 1] = img[:, 22:-22, 3]  # RP_K\n\n        # EEG\n        img = eeg\n        mn = img.flatten().min()\n        mx = img.flatten().max()\n        ep = 1e-5\n        img = 255 * (img - mn) / (mx - mn + ep)\n        X[200 + 56:300 + 56, :256, 0] = img[:, 22:-22, 0]  # LL_e\n        X[300 + 56:400 + 56, :256, 0] = img[:, 22:-22, 2]  # RL_e\n        X[200 + 56:300 + 56, :256, 1] = img[:, 22:-22, 1]  # LP_e\n        X[300 + 56:400 + 56, :256, 1] = img[:, 22:-22, 3]  # RP_e\n        X[200 + 56:300 + 56, :256, 2] = img[:, 22:-22, 2]  # RL_e\n        X[300 + 56:400 + 56, :256, 2] = img[:, 22:-22, 1]  # LP_e\n\n        X[200 + 56:300 + 56, 256:, 0] = img[:, 22:-22, 0]  # LL_e\n        X[300 + 56:400 + 56, 256:, 0] = img[:, 22:-22, 2]  # RL_e\n        X[200 + 56:300 + 56, 256:, 1] = img[:, 22:-22, 1]  # LP_e\n        X[300 + 56:400 + 56, 256:, 1] = img[:, 22:-22, 3]  # RP_e\n#         print(X.shape)\n        X = self.trans(image = X)['image']\n        if self.mode != 'test':\n            y[:] = row[TARGETS]\n\n        return X, y\n\n    def generate_specs(self, index):\n        X = np.zeros((512, 512, 3), dtype='float32')\n        y = np.zeros((6,), dtype='float32')\n\n        row = self.data.iloc[index]\n        if self.mode == 'test':\n            offset = 0\n        else:\n            offset = int(row.offset / 2)\n\n        if self.data_type == 'eeg':\n            # print(type(row.eeg_id))\n            img = self.eeg_specs[row.eeg_id]\n        elif self.data_type == 'kaggle':\n            spec = self.specs[row.spec_id]\n            imgs = [spec[offset:offset + 300, k * 100:(k + 1) * 100].T for k in\n                    [0, 2, 1, 3]]  # to match kaggle with eeg\n            img = np.stack(imgs, axis=-1)\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            img = np.nan_to_num(img, nan=0.0)\n\n        mn = img.flatten().min()\n        mx = img.flatten().max()\n        ep = 1e-5\n        img = 255 * (img - mn) / (mx - mn + ep)\n\n        X[0 + 56:100 + 56, :256, 0] = img[:, 22:-22, 0]\n        X[100 + 56:200 + 56, :256, 0] = img[:, 22:-22, 2]\n        X[0 + 56:100 + 56, :256, 1] = img[:, 22:-22, 1]\n        X[100 + 56:200 + 56, :256, 1] = img[:, 22:-22, 3]\n        X[0 + 56:100 + 56, :256, 2] = img[:, 22:-22, 2]\n        X[100 + 56:200 + 56, :256, 2] = img[:, 22:-22, 1]\n\n        X[0 + 56:100 + 56, 256:, 0] = img[:, 22:-22, 0]\n        X[100 + 56:200 + 56, 256:, 0] = img[:, 22:-22, 1]\n        X[0 + 56:100 + 56, 256:, 1] = img[:, 22:-22, 2]\n        X[100 + 56:200 + 56, 256:, 1] = img[:, 22:-22, 3]\n\n        X[200 + 56:300 + 56, :256, 0] = img[:, 22:-22, 0]\n        X[300 + 56:400 + 56, :256, 0] = img[:, 22:-22, 1]\n        X[200 + 56:300 + 56, :256, 1] = img[:, 22:-22, 2]\n        X[300 + 56:400 + 56, :256, 1] = img[:, 22:-22, 3]\n        X[200 + 56:300 + 56, :256, 2] = img[:, 22:-22, 3]\n        X[300 + 56:400 + 56, :256, 2] = img[:, 22:-22, 2]\n\n        X[200 + 56:300 + 56, 256:, 0] = img[:, 22:-22, 0]\n        X[300 + 56:400 + 56, 256:, 0] = img[:, 22:-22, 2]\n        X[200 + 56:300 + 56, 256:, 1] = img[:, 22:-22, 1]\n        X[300 + 56:400 + 56, 256:, 1] = img[:, 22:-22, 3]\n        \n        if self.mode != 'test':\n            y[:] = row[TARGETS]\n\n        return X, y\n","metadata":{"execution":{"iopub.status.busy":"2024-03-15T01:55:16.552809Z","iopub.execute_input":"2024-03-15T01:55:16.553805Z","iopub.status.idle":"2024-03-15T01:55:16.650894Z","shell.execute_reply.started":"2024-03-15T01:55:16.553753Z","shell.execute_reply":"2024-03-15T01:55:16.649528Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"val_transform = A.Compose([\n#     A.Resize(p=1.0, height=512, width=512),\n#     A.Resize(p=1.0, height=896, width=896),\n#     A.Normalize(mean=[0.0,0.0,0.0], std=[1.0,1.0,1.0], p=1.0),\n    ToTensorV2(p=1.0)\n])","metadata":{"execution":{"iopub.status.busy":"2024-03-15T01:55:16.654350Z","iopub.execute_input":"2024-03-15T01:55:16.655072Z","iopub.status.idle":"2024-03-15T01:55:16.662457Z","shell.execute_reply.started":"2024-03-15T01:55:16.655026Z","shell.execute_reply":"2024-03-15T01:55:16.661062Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def run_inference_loop(model, test_gen_both,device):\n    model.to(device)\n    model.eval()\n#     print(model)\n    pred_list = []\n    with torch.no_grad():\n        for batch_data,y in tqdm.tqdm(test_gen_both):\n#             batch_data = torch.from_numpy(batch_data)\n#             batch_data = batch_data.permute(2, 0, 1)\n            batch_data = batch_data.unsqueeze(0)\n            print(batch_data.shape)\n            batch_data = batch_data.to(device)\n            # print(batch_data.shape)\n            y = model(batch_data)\n            \n            pred_list.append(y.softmax(dim=1).detach().cpu().numpy())\n\n    pred_arr = np.concatenate(pred_list)\n    del pred_list\n    return pred_arr\npreds = []\n\ntest_gen_both = DataGenerator(test, mode='test', data_type='both', specs = spectrograms2, eeg_specs = all_eegs2,trans = val_transform)\ndevice = torch.device(\"cuda\")\n\nfor model_path in glob.glob(\"/kaggle/input/model-mixnet-xl-label0-01\"+\"/*/*.pt\"):\n    print(model_path)\n    model = torch.load(model_path)\n    pred = run_inference_loop(model, test_gen_both, device)\n\n    preds.append(pred)\n# print(preds)\n# print(preds)\ntest_pred = np.mean(preds,axis=0)\n# print(test_pred)\n# print(test_pred.shape)\n\nCLASSES = [\"seizure_vote\", \"lpd_vote\", \"gpd_vote\", \"lrda_vote\", \"grda_vote\", \"other_vote\"]\n# test_pred = np.array(preds).mean(axis=0)\n\ntest_pred_df = pd.DataFrame(test_pred, columns=CLASSES)\n\ntest_pred_df = pd.concat([test[[\"eeg_id\"]], test_pred_df], axis=1)\ntest_pred_df.to_csv(\"submission.csv\", index=False)\ntest_pred_df.head()\n# print(test_pred_df)","metadata":{"execution":{"iopub.status.busy":"2024-03-15T01:55:16.664665Z","iopub.execute_input":"2024-03-15T01:55:16.665621Z","iopub.status.idle":"2024-03-15T01:55:25.457051Z","shell.execute_reply.started":"2024-03-15T01:55:16.665570Z","shell.execute_reply":"2024-03-15T01:55:25.456074Z"},"trusted":true},"execution_count":null,"outputs":[]}]}