{"metadata":{"kernelspec":{"display_name":"Python 3","language":"python","name":"python3"},"language_info":{"name":"python","pygments_lexer":"ipython3"},"kaggle":{"accelerator":"nvidiaTeslaT4","dataSources":[{"sourceType":"competition","sourceId":59093,"databundleVersionId":7469972,"isSourceIdPinned":false},{"sourceType":"datasetVersion","sourceId":8048710,"datasetId":4746291,"databundleVersionId":8162657},{"sourceType":"datasetVersion","sourceId":9923007,"datasetId":6098761,"databundleVersionId":10182107},{"sourceType":"datasetVersion","sourceId":7392733,"datasetId":4297749,"databundleVersionId":7483738},{"sourceType":"datasetVersion","sourceId":7402356,"datasetId":4304475,"databundleVersionId":7493457},{"sourceType":"datasetVersion","sourceId":8064454,"datasetId":4757588,"databundleVersionId":8179596},{"sourceType":"datasetVersion","sourceId":8057855,"datasetId":4752740,"databundleVersionId":8172576},{"sourceType":"datasetVersion","sourceId":8057847,"datasetId":4752734,"databundleVersionId":8172568},{"sourceType":"datasetVersion","sourceId":8057843,"datasetId":4752731,"databundleVersionId":8172564},{"sourceType":"kernelVersion","sourceId":158958765,"isSourceIdPinned":false}],"dockerImageVersionId":31329,"isInternetEnabled":false,"language":"python","sourceType":"notebook","isGpuEnabled":true}},"nbformat_minor":4,"nbformat":4,"cells":[{"id":"8a25b280","cell_type":"markdown","source":"**EFFICIENT NET (Olga-style, clean notebook)**\n\n- Без “Copied from …”\n- Працює з `Internet Off`\n- Шукає competition data через `resolve_data_dir`\n- Зберігає `submission.csv` з **pred1** (ансамбль по фолдах)","metadata":{}},{"id":"ff70d6c5","cell_type":"code","source":"import os, gc\nos.environ[\"CUDA_VISIBLE_DEVICES\"] = \"0,1\"\n\nimport tensorflow as tf\nimport pandas as pd, numpy as np\nimport matplotlib.pyplot as plt\n\nprint('TensorFlow version =', tf.__version__)\n\n# USE MULTIPLE GPUS\ngpus = tf.config.list_physical_devices('GPU')\nif len(gpus) <= 1:\n    strategy = tf.distribute.OneDeviceStrategy(device=\"/gpu:0\")\n    print(f'Using {len(gpus)} GPU')\nelse:\n    strategy = tf.distribute.MirroredStrategy()\n    print(f'Using {len(gpus)} GPUs')\n\nVER = 3\n\n# Helpers: locate attached datasets regardless of exact mount name\n\ndef _walk_candidates(base: str, *, max_depth: int = 4):\n    if not os.path.isdir(base):\n        return\n    for name in sorted(os.listdir(base)):\n        top = os.path.join(base, name)\n        if not os.path.isdir(top):\n            continue\n        yield top\n        for dirpath, dirnames, filenames in os.walk(top):\n            depth = dirpath[len(top) :].count(os.sep)\n            if depth > max_depth:\n                dirnames[:] = []\n                continue\n            yield dirpath\n\n\ndef resolve_dir_by_hint(hints: list[str], *, must_contain: list[str] | None = None) -> str:\n    \"\"\"Find a directory under /kaggle/input (or nested) matching hints.\n\n    - hints: list of substrings that should appear in folder name (case-insensitive)\n    - must_contain: list of files that must exist inside the folder\n    \"\"\"\n    base = \"/kaggle/input\"\n    hints_l = [h.lower() for h in hints]\n    must_contain = must_contain or []\n\n    best = None\n    best_score = -1\n\n    for d in _walk_candidates(base, max_depth=4):\n        bn = os.path.basename(d).lower()\n        score = sum(1 for h in hints_l if h in bn)\n        if score <= 0:\n            continue\n        ok = True\n        for f in must_contain:\n            if not os.path.exists(os.path.join(d, f)):\n                ok = False\n                break\n        if not ok:\n            continue\n        if score > best_score or (score == best_score and best and len(d) < len(best)):\n            best = d\n            best_score = score\n\n    if best is None:\n        raise FileNotFoundError(\n            f\"Could not resolve dataset dir for hints={hints}. \"\n            \"Attach the required dataset(s) in 'Add data'.\"\n        )\n\n    return best if best.endswith('/') else best + '/'\n\n\n# Resolve model/weight datasets by hints (use your mounted names)\nLOAD_MODELS_FROMb0 = resolve_dir_by_hint([\"two\", \"step\", \"b0\", \"hms\"], must_contain=[f\"EffNet_v{VER}_f0.h5\"])\nLOAD_MODELS_FROMb1 = resolve_dir_by_hint([\"b1\", \"two\", \"step\", \"hms\"], must_contain=[f\"EffNet_v{VER}_f0.h5\"])\nLOAD_MODELS_FROMb2 = resolve_dir_by_hint([\"b2\", \"two\", \"step\", \"hms\"], must_contain=[f\"EffNet_v{VER}_f0.h5\"])\nLOAD_MODELS_FROMb3 = resolve_dir_by_hint([\"b3\", \"two\", \"step\", \"hms\"], must_contain=[f\"EffNet_v{VER}_f0.h5\"])\n\nTF_EFN_WHL_DIR = resolve_dir_by_hint([\"tf\", \"efficientnet\", \"whl\"], must_contain=[\"efficientnet-1.1.1-py3-none-any.whl\"])\nTF_EFN_IMAGENET_DIR = resolve_dir_by_hint([\"tf\", \"efficientnet\", \"imagenet\", \"weights\"], must_contain=[])\n\nprint('LOAD_MODELS_FROMb0', LOAD_MODELS_FROMb0)\nprint('LOAD_MODELS_FROMb1', LOAD_MODELS_FROMb1)\nprint('LOAD_MODELS_FROMb2', LOAD_MODELS_FROMb2)\nprint('LOAD_MODELS_FROMb3', LOAD_MODELS_FROMb3)\nprint('TF_EFN_WHL_DIR', TF_EFN_WHL_DIR)\nprint('TF_EFN_IMAGENET_DIR', TF_EFN_IMAGENET_DIR)\n\n# Competition root resolver (works with /kaggle/input/competitions/... mounts too)\ndef resolve_data_dir(preferred: str) -> str:\n    def is_hms_root(path: str) -> bool:\n        return (\n            os.path.exists(os.path.join(path, 'train.csv'))\n            and os.path.exists(os.path.join(path, 'test.csv'))\n            and os.path.exists(os.path.join(path, 'sample_submission.csv'))\n            and os.path.isdir(os.path.join(path, 'train_spectrograms'))\n            and os.path.isdir(os.path.join(path, 'test_spectrograms'))\n            and os.path.isdir(os.path.join(path, 'test_eegs'))\n        )\n\n    if is_hms_root(preferred):\n        return preferred\n\n    kaggle_input = '/kaggle/input'\n    if not os.path.isdir(kaggle_input):\n        return preferred\n\n    candidates = []\n\n    # direct children\n    for name in sorted(os.listdir(kaggle_input)):\n        root = os.path.join(kaggle_input, name)\n        if os.path.isdir(root) and is_hms_root(root):\n            candidates.append(root)\n\n    # shallow walk\n    max_depth = 4\n    for top_name in sorted(os.listdir(kaggle_input)):\n        top = os.path.join(kaggle_input, top_name)\n        if not os.path.isdir(top):\n            continue\n        for dirpath, dirnames, filenames in os.walk(top):\n            depth = dirpath[len(top):].count(os.sep)\n            if depth > max_depth:\n                dirnames[:] = []\n                continue\n            if is_hms_root(dirpath):\n                candidates.append(dirpath)\n\n    candidates = sorted(set(candidates), key=len)\n    if not candidates:\n        mounts = sorted(os.listdir(kaggle_input))\n        raise FileNotFoundError(\n            'Could not locate HMS dataset root.\\n'\n            'Fix: Add data -> Competition data -> HMS - Harmful Brain Activity Classification\\n'\n            f'Tried preferred path: {preferred}\\n'\n            f'/kaggle/input mounts: {mounts[:50]}'\n        )\n\n    for c in candidates:\n        bn = os.path.basename(c).lower()\n        if 'hms' in bn and 'harmful' in bn:\n            return c\n\n    return candidates[0]\n\nDATA_DIR = resolve_data_dir('/kaggle/input/hms-harmful-brain-activity-classification')\nprint('Using DATA_DIR =', DATA_DIR)","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"id":"d2607aad","cell_type":"code","source":"# USE MIXED PRECISION\nMIX = True\nif MIX:\n    tf.config.optimizer.set_experimental_options({\"auto_mixed_precision\": True})\n    print('Mixed precision enabled')\nelse:\n    print('Using full precision')","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"id":"b6b315a0","cell_type":"code","source":"df = pd.read_csv(f'{DATA_DIR}/train.csv')\nTARGETS = df.columns[-6:]\nprint('TARGETS:', list(TARGETS))","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"id":"96cfe51f","cell_type":"code","source":"import albumentations as albu\nTARS = {'Seizure':0, 'LPD':1, 'GPD':2, 'LRDA':3, 'GRDA':4, 'Other':5}\nTARS2 = {x:y for y,x in TARS.items()}\n\nclass DataGenerator(tf.keras.utils.Sequence):\n    'Generates data for Keras'\n    def __init__(self, data, batch_size=32, shuffle=False, augment=False, mode='train',\n                 specs = None, eeg_specs = None): \n\n        self.data = data\n        self.batch_size = batch_size\n        self.shuffle = shuffle\n        self.augment = augment\n        self.mode = mode\n        self.specs = specs\n        self.eeg_specs = eeg_specs\n        self.on_epoch_end()\n        \n    def __len__(self):\n        'Denotes the number of batches per epoch'\n        ct = int( np.ceil( len(self.data) / self.batch_size ) )\n        return ct\n\n    def __getitem__(self, index):\n        'Generate one batch of data'\n        indexes = self.indexes[index*self.batch_size:(index+1)*self.batch_size]\n        X, y = self.__data_generation(indexes)\n        if self.augment: X = self.__augment_batch(X) \n        return X, y\n\n    def on_epoch_end(self):\n        'Updates indexes after each epoch'\n        self.indexes = np.arange( len(self.data) )\n        if self.shuffle: np.random.shuffle(self.indexes)\n                        \n    def __data_generation(self, indexes):\n        'Generates data containing batch_size samples' \n        \n        X = np.zeros((len(indexes),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,0,32)\n                img = np.nan_to_num(img, nan=0.0)\n                img = img / 32\n                \n                # CROP TO 256 TIME STEPS\n                X[j,14:-14,:,k] = img[:,22:-22]\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        ])\n        return composition(image=img)['image']\n            \n    def __augment_batch(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":{"trusted":true},"outputs":[],"execution_count":null},{"id":"e08541f8","cell_type":"code","source":"!pip install --no-index --find-links={TF_EFN_WHL_DIR} {TF_EFN_WHL_DIR}efficientnet-1.1.1-py3-none-any.whl","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"id":"6a355da7","cell_type":"code","source":"USE_KAGGLE_SPECTROGRAMS=True\nUSE_EEG_SPECTROGRAMS=True","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"id":"62b74d5e","cell_type":"code","source":"import efficientnet.tfkeras as efn\n\ndef build_modelb0():\n    \n    inp = tf.keras.Input(shape=(128,256,8))\n    base_model = efn.EfficientNetB0(include_top=False, weights=None, input_shape=None)\n    base_model.load_weights(f'{TF_EFN_IMAGENET_DIR}efficientnet-b0_weights_tf_dim_ordering_tf_kernels_autoaugment_notop.h5')\n    \n    # RESHAPE INPUT 128x256x8 => 512x512x3 MONOTONE IMAGE\n    # KAGGLE SPECTROGRAMS\n    x1 = [inp[:,:,:,i:i+1] for i in range(4)]\n    x1 = tf.keras.layers.Concatenate(axis=1)(x1)\n    # EEG SPECTROGRAMS\n    x2 = [inp[:,:,:,i+4:i+5] for i in range(4)]\n    x2 = tf.keras.layers.Concatenate(axis=1)(x2)\n    # MAKE 512X512X3\n    if USE_KAGGLE_SPECTROGRAMS & USE_EEG_SPECTROGRAMS:\n        x = tf.keras.layers.Concatenate(axis=2)([x1,x2])\n    elif USE_EEG_SPECTROGRAMS: x = x2\n    else: x = x1\n    x = tf.keras.layers.Concatenate(axis=3)([x,x,x])\n    \n    # OUTPUT\n    x = base_model(x)\n    x = tf.keras.layers.GlobalAveragePooling2D()(x)\n    x = tf.keras.layers.Dense(6,activation='softmax', dtype='float32')(x)\n        \n    # COMPILE MODEL\n    model = tf.keras.Model(inputs=inp, outputs=x)\n    opt = tf.keras.optimizers.Adam(learning_rate = 1e-3)\n    loss = tf.keras.losses.KLDivergence()\n\n    model.compile(loss=loss, optimizer = opt) \n        \n    return model","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"id":"1eb8fb44","cell_type":"code","source":"def build_modelb1():\n    \n    inp = tf.keras.Input(shape=(128,256,8))\n    base_model = efn.EfficientNetB1(include_top=False, weights=None, input_shape=None)\n    base_model.load_weights(f'{TF_EFN_IMAGENET_DIR}efficientnet-b1_weights_tf_dim_ordering_tf_kernels_autoaugment_notop.h5')\n    \n    # RESHAPE INPUT 128x256x8 => 512x512x3 MONOTONE IMAGE\n    # KAGGLE SPECTROGRAMS\n    x1 = [inp[:,:,:,i:i+1] for i in range(4)]\n    x1 = tf.keras.layers.Concatenate(axis=1)(x1)\n    # EEG SPECTROGRAMS\n    x2 = [inp[:,:,:,i+4:i+5] for i in range(4)]\n    x2 = tf.keras.layers.Concatenate(axis=1)(x2)\n    # MAKE 512X512X3\n    if USE_KAGGLE_SPECTROGRAMS & USE_EEG_SPECTROGRAMS:\n        x = tf.keras.layers.Concatenate(axis=2)([x1,x2])\n    elif USE_EEG_SPECTROGRAMS: x = x2\n    else: x = x1\n    x = tf.keras.layers.Concatenate(axis=3)([x,x,x])\n    \n    # OUTPUT\n    x = base_model(x)\n    x = tf.keras.layers.GlobalAveragePooling2D()(x)\n    x = tf.keras.layers.Dense(6,activation='softmax', dtype='float32')(x)\n        \n    # COMPILE MODEL\n    model = tf.keras.Model(inputs=inp, outputs=x)\n    opt = tf.keras.optimizers.Adam(learning_rate = 1e-3)\n    loss = tf.keras.losses.KLDivergence()\n\n    model.compile(loss=loss, optimizer = opt) \n        \n    return model","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"id":"7b6d237a","cell_type":"code","source":"def build_modelb2():\n    \n    inp = tf.keras.Input(shape=(128,256,8))\n    base_model = efn.EfficientNetB2(include_top=False, weights=None, input_shape=None)\n    base_model.load_weights(f'{TF_EFN_IMAGENET_DIR}efficientnet-b2_weights_tf_dim_ordering_tf_kernels_autoaugment_notop.h5')\n    \n    # RESHAPE INPUT 128x256x8 => 512x512x3 MONOTONE IMAGE\n    # KAGGLE SPECTROGRAMS\n    x1 = [inp[:,:,:,i:i+1] for i in range(4)]\n    x1 = tf.keras.layers.Concatenate(axis=1)(x1)\n    # EEG SPECTROGRAMS\n    x2 = [inp[:,:,:,i+4:i+5] for i in range(4)]\n    x2 = tf.keras.layers.Concatenate(axis=1)(x2)\n    # MAKE 512X512X3\n    if USE_KAGGLE_SPECTROGRAMS & USE_EEG_SPECTROGRAMS:\n        x = tf.keras.layers.Concatenate(axis=2)([x1,x2])\n    elif USE_EEG_SPECTROGRAMS: x = x2\n    else: x = x1\n    x = tf.keras.layers.Concatenate(axis=3)([x,x,x])\n    \n    # OUTPUT\n    x = base_model(x)\n    x = tf.keras.layers.GlobalAveragePooling2D()(x)\n    x = tf.keras.layers.Dense(6,activation='softmax', dtype='float32')(x)\n        \n    # COMPILE MODEL\n    model = tf.keras.Model(inputs=inp, outputs=x)\n    opt = tf.keras.optimizers.Adam(learning_rate = 1e-3)\n    loss = tf.keras.losses.KLDivergence()\n\n    model.compile(loss=loss, optimizer = opt) \n        \n    return model","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"id":"39f03ccf","cell_type":"code","source":"def build_modelb3():\n    \n    inp = tf.keras.Input(shape=(128,256,8))\n    base_model = efn.EfficientNetB3(include_top=False, weights=None, input_shape=None)\n    base_model.load_weights(f'{TF_EFN_IMAGENET_DIR}efficientnet-b3_weights_tf_dim_ordering_tf_kernels_autoaugment_notop.h5')\n    \n    # RESHAPE INPUT 128x256x8 => 512x512x3 MONOTONE IMAGE\n    # KAGGLE SPECTROGRAMS\n    x1 = [inp[:,:,:,i:i+1] for i in range(4)]\n    x1 = tf.keras.layers.Concatenate(axis=1)(x1)\n    # EEG SPECTROGRAMS\n    x2 = [inp[:,:,:,i+4:i+5] for i in range(4)]\n    x2 = tf.keras.layers.Concatenate(axis=1)(x2)\n    # MAKE 512X512X3\n    if USE_KAGGLE_SPECTROGRAMS & USE_EEG_SPECTROGRAMS:\n        x = tf.keras.layers.Concatenate(axis=2)([x1,x2])\n    elif USE_EEG_SPECTROGRAMS: x = x2\n    else: x = x1\n    x = tf.keras.layers.Concatenate(axis=3)([x,x,x])\n    \n    # OUTPUT\n    x = base_model(x)\n    x = tf.keras.layers.GlobalAveragePooling2D()(x)\n    x = tf.keras.layers.Dense(6,activation='softmax', dtype='float32')(x)\n        \n    # COMPILE MODEL\n    model = tf.keras.Model(inputs=inp, outputs=x)\n    opt = tf.keras.optimizers.Adam(learning_rate = 1e-3)\n    loss = tf.keras.losses.KLDivergence()\n\n    model.compile(loss=loss, optimizer = opt) \n        \n    return model","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"id":"52be90e1","cell_type":"markdown","source":"infer test for efficient net models","metadata":{}},{"id":"aa89e452","cell_type":"code","source":"test = pd.read_csv(f'{DATA_DIR}/test.csv')\nprint('Test shape', test.shape)\ntest.head()","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"id":"f2406cbd","cell_type":"code","source":"# READ ALL SPECTROGRAMS\nPATH2 = f'{DATA_DIR}/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: 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":{"trusted":true},"outputs":[],"execution_count":null},{"id":"fe50b0a2","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# 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    \n    return ret\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":{"trusted":true},"outputs":[],"execution_count":null},{"id":"54f01fda","cell_type":"code","source":"# READ ALL EEG SPECTROGRAMS\nPATH2 = f'{DATA_DIR}/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":{"trusted":true},"outputs":[],"execution_count":null},{"id":"3fb9d951","cell_type":"code","source":"# INFER EFFICIENTNET ON TEST\npreds = []\nmodelb0 = build_modelb0()\nmodelb1 = build_modelb1()\nmodelb2 = build_modelb2()\nmodelb3 = build_modelb3()\n\ntest_gen = DataGenerator(test, shuffle=False, batch_size=128, mode='test',\n                         specs = spectrograms2, eeg_specs = all_eegs2)\n\nfor i in range(5):\n    print(f'Fold {i+1}')\n    modelb0.load_weights(f'{LOAD_MODELS_FROMb0}EffNet_v{VER}_f{i}.h5')\n    modelb1.load_weights(f'{LOAD_MODELS_FROMb1}EffNet_v{VER}_f{i}.h5')\n    modelb2.load_weights(f'{LOAD_MODELS_FROMb2}EffNet_v{VER}_f{i}.h5')\n    modelb3.load_weights(f'{LOAD_MODELS_FROMb3}EffNet_v{VER}_f{i}.h5')\n\n    pred = (\n        modelb0.predict(test_gen, verbose=1)\n        + modelb1.predict(test_gen, verbose=1)\n        + modelb2.predict(test_gen, verbose=1)\n        + modelb3.predict(test_gen, verbose=1)\n    ) / 4\n\n    preds.append(pred)\n\npred1 = np.mean(preds,axis=0)\nprint()\nprint('Test preds shape', pred1.shape)","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"id":"707a1a90","cell_type":"code","source":"pred1","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"id":"8bfcc496","cell_type":"code","source":"pred1.sum(axis=1)","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"id":"c111033b","cell_type":"code","source":"sub = pd.DataFrame({'eeg_id':test.eeg_id.values})\nsub[TARGETS] = pred1  # FIX: use ensemble preds\nsub.to_csv('submission.csv',index=False)\nprint('Submission shape',sub.shape)\nsub.head()","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"id":"2d8ed6fe","cell_type":"code","source":"sub.iloc[:,-6:].sum(axis=1)","metadata":{"trusted":true},"outputs":[],"execution_count":null},{"id":"f0ea666b","cell_type":"markdown","source":"**CATBOOST**","metadata":{}}]}