{"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":"gpu","dataSources":[{"sourceId":59093,"databundleVersionId":7469972,"sourceType":"competition"},{"sourceId":7805987,"sourceType":"datasetVersion","datasetId":4571300},{"sourceId":160700706,"sourceType":"kernelVersion"},{"sourceId":165876189,"sourceType":"kernelVersion"}],"dockerImageVersionId":30674,"isInternetEnabled":false,"language":"python","sourceType":"notebook","isGpuEnabled":true}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"markdown","source":"# Model source: https://www.kaggle.com/code/andreasbis/hms-inference-lb-0-41","metadata":{}},{"cell_type":"code","source":"import gc\nimport os\nimport random\nimport warnings\nimport numpy as np\nimport pandas as pd\nfrom IPython.display import display\n\nimport timm\nimport torch\nimport torch.nn as nn  \nimport torch.optim as optim\nimport torch.nn.functional as F\nimport torchvision.transforms as transforms\n\nfrom scipy import signal\n\nwarnings.filterwarnings('ignore', category=Warning)\ngc.collect()","metadata":{"execution":{"iopub.status.busy":"2024-04-01T20:34:26.563060Z","iopub.execute_input":"2024-04-01T20:34:26.563903Z","iopub.status.idle":"2024-04-01T20:34:26.799069Z","shell.execute_reply.started":"2024-04-01T20:34:26.563874Z","shell.execute_reply":"2024-04-01T20:34:26.798030Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class Config:\n    seed = 3131\n    image_transform = transforms.Resize((512, 512))\n    num_folds = 5\n    dataset_wide_mean = -0.2972692229201065 #From Train notebook\n    dataset_wide_std = 2.5997336315611026 #From Train notebook\n    ownspec_mean = 7.29084372799223e-05 # From Train spectrograms notebook\n    ownspec_std = 4.510082606216031 # From Train spectrograms notebook\n    \ndef set_seed(seed):\n    torch.backends.cudnn.deterministic = True\n    torch.backends.cudnn.benchmark = True\n    \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-04-01T20:34:26.800837Z","iopub.execute_input":"2024-04-01T20:34:26.801129Z","iopub.status.idle":"2024-04-01T20:34:26.808588Z","shell.execute_reply.started":"2024-04-01T20:34:26.801105Z","shell.execute_reply":"2024-04-01T20:34:26.807710Z"},"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\")\n\nsubmission = submission.merge(test_df, on='eeg_id', how='left')\nsubmission['path_spec'] = submission['spectrogram_id'].apply(lambda x: f\"/kaggle/input/hms-harmful-brain-activity-classification/test_spectrograms/{x}.parquet\")\nsubmission['path_eeg'] = submission['eeg_id'].apply(lambda x: f\"/kaggle/input/hms-harmful-brain-activity-classification/test_eegs/{x}.parquet\")\n\ndisplay(submission)\n\ngc.collect()","metadata":{"execution":{"iopub.status.busy":"2024-04-01T20:34:26.809897Z","iopub.execute_input":"2024-04-01T20:34:26.810157Z","iopub.status.idle":"2024-04-01T20:34:27.051968Z","shell.execute_reply.started":"2024-04-01T20:34:26.810133Z","shell.execute_reply":"2024-04-01T20:34:27.050916Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"models = []\n\n# Load in original EfficientnetB0 model\nfor i in range(Config.num_folds):\n    model_effnet_b0 = timm.create_model('efficientnet_b0', pretrained=False, num_classes=6, in_chans=1)\n    model_effnet_b0.load_state_dict(torch.load(f'/kaggle/input/hms-train-efficientnetb0/efficientnet_b0_fold{i}.pth', map_location=torch.device('cpu')))\n    models.append(model_effnet_b0)\n    \nmodels_datawide = []\n# Load in hyperparameter optimized EfficientnetB1\nfor i in range(Config.num_folds):\n    model_effnet_b1 = timm.create_model('efficientnet_b1', pretrained=False, num_classes=6, in_chans=1)\n    model_effnet_b1.load_state_dict(torch.load(f'/kaggle/input/train/efficientnet_b1_fold{i}.pth', map_location=torch.device('cpu')))\n    models_datawide.append(model_effnet_b1)\n    \nmodels_ownspec = []\n# Load in EfficientnetB1 with new spectrograms\nfor i in range(Config.num_folds):\n    model_effnet_b1 = timm.create_model('efficientnet_b1', pretrained=False, num_classes=6, in_chans=1)\n    model_effnet_b1.load_state_dict(torch.load(f'/kaggle/input/efficientnet-b1-ownspectrograms/efficientnet_b1_fold{i}_datawide_CosineAnnealingLR_0.001_False.pth', map_location=torch.device('cpu')))\n    models_ownspec.append(model_effnet_b1)\n    \ngc.collect()","metadata":{"execution":{"iopub.status.busy":"2024-04-01T20:34:27.053207Z","iopub.execute_input":"2024-04-01T20:34:27.053563Z","iopub.status.idle":"2024-04-01T20:34:29.940319Z","shell.execute_reply.started":"2024-04-01T20:34:27.053531Z","shell.execute_reply":"2024-04-01T20:34:29.939406Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"test_predictions = []\n\ndef create_spectrogram(data):\n    \"\"\"Creating a spectrogram\"\"\"\n    nperseg = 150  # Length of each segment\n    noverlap = 128  # Overlap between segments\n    NFFT = max(256, 2 ** int(np.ceil(np.log2(nperseg))))\n\n    # LL Spec = ( spec(Fp1 - F7) + spec(F7 - T3) + spec(T3 - T5) + spec(T5 - O1) )/4\n    freqs, t,spectrum_LL1 = signal.spectrogram(data['Fp1']-data['F7'],nfft=NFFT,noverlap = noverlap,nperseg=nperseg)\n    freqs, t,spectrum_LL2 = signal.spectrogram(data['F7']-data['T3'],nfft=NFFT, noverlap = noverlap,nperseg=nperseg)\n    freqs, t,spectrum_LL3 = signal.spectrogram(data['T3']-data['T5'],nfft=NFFT, noverlap = noverlap,nperseg=nperseg)\n    freqs, t,spectrum_LL4 = signal.spectrogram(data['T5']-data['O1'],nfft=NFFT, noverlap = noverlap,nperseg=nperseg)\n\n    LL = (spectrum_LL1+ spectrum_LL2 +spectrum_LL3 + spectrum_LL4)/4\n\n    # LP Spec = ( spec(Fp1 - F3) + spec(F3 - C3) + spec(C3 - P3) + spec(P3 - O1) )/4\n    freqs, t,spectrum_LP1 = signal.spectrogram(data['Fp1']-data['F3'],nfft=NFFT, noverlap = noverlap,nperseg=nperseg)\n    freqs, t,spectrum_LP2 = signal.spectrogram(data['F3']-data['C3'],nfft=NFFT, noverlap = noverlap,nperseg=nperseg)\n    freqs, t,spectrum_LP3 = signal.spectrogram(data['C3']-data['P3'],nfft=NFFT, noverlap = noverlap,nperseg=nperseg)\n    freqs, t,spectrum_LP4 = signal.spectrogram(data['P3']-data['O1'],nfft=NFFT, noverlap = noverlap,nperseg=nperseg)\n\n    LP = (spectrum_LP1+ spectrum_LP2 +spectrum_LP3 + spectrum_LP4)/4\n\n    # RP Spec = ( spec(Fp2 - F4) + spec(F4 - C4) + spec(C4 - P4) + spec(P4 - O2) )/4\n    freqs, t,spectrum_RP1 = signal.spectrogram(data['Fp2']-data['F4'],nfft=NFFT, noverlap = noverlap,nperseg=nperseg)\n    freqs, t,spectrum_RP2 = signal.spectrogram(data['F4']-data['C4'],nfft=NFFT, noverlap = noverlap,nperseg=nperseg)\n    freqs, t,spectrum_RP3 = signal.spectrogram(data['C4']-data['P4'],nfft=NFFT, noverlap = noverlap,nperseg=nperseg)\n    freqs, t,spectrum_RP4 = signal.spectrogram(data['P4']-data['O2'],nfft=NFFT, noverlap = noverlap,nperseg=nperseg)\n\n    RP = (spectrum_RP1+ spectrum_RP2 +spectrum_RP3 + spectrum_RP4)/4\n\n\n    # RL Spec = ( spec(Fp2 - F8) + spec(F8 - T4) + spec(T4 - T6) + spec(T6 - O2) )/4\n    freqs, t,spectrum_RL1 = signal.spectrogram(data['Fp2']-data['F8'],nfft=NFFT, noverlap = noverlap,nperseg=nperseg)\n    freqs, t,spectrum_RL2 = signal.spectrogram(data['F8']-data['T4'],nfft=NFFT, noverlap = noverlap,nperseg=nperseg)\n    freqs, t,spectrum_RL3 = signal.spectrogram(data['T4']-data['T6'],nfft=NFFT, noverlap = noverlap,nperseg=nperseg)\n    freqs, t,spectrum_RL4 = signal.spectrogram(data['T6']-data['O2'],nfft=NFFT, noverlap = noverlap,nperseg=nperseg)\n    RL = (spectrum_RL1+ spectrum_RL2 +spectrum_RL3 + spectrum_RL4)/4\n    spectogram = np.concatenate((LL, LP,RP,RL), axis=0)\n    return spectogram\n\ndef preprocess_ownspec(path_to_parquet):\n    \"\"\"EEG to spectrogramdata\"\"\"\n    data = pd.read_parquet(path_to_parquet)\n    data = create_spectrogram(data)\n    mask = np.isnan(data)\n    data[mask] = -1\n    data = np.clip(data, np.exp(-6), np.exp(10))\n    data = np.log(data)\n    \n    return data \n\ndef preprocess(path_to_parquet):\n    data = pd.read_parquet(path_to_parquet)\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    return data\n\n\ndef normalize_datawide(data_point):\n    \"\"\"The spectrogram data will be normalized data wide.\"\"\"\n    eps = 1e-6\n\n    data_point = (data_point - Config.dataset_wide_mean) / (Config.dataset_wide_std + eps)\n\n    data_tensor = torch.unsqueeze(torch.Tensor(data_point), dim=0)\n    data_point = Config.image_transform(data_tensor)\n\n    return data_point\n\n\ndef normalize_datawide_ownspec(data):\n    \"\"\"The new spectrogram data will be normalized data wide.\"\"\"\n    eps = 1e-6\n    \n    data = (data - Config.ownspec_mean) / (Config.ownspec_std + eps)\n    data_tensor = torch.unsqueeze(torch.Tensor(data), dim=0)\n    data = Config.image_transform(data_tensor)\n    \n    return data\n\n\ndef normalize_instance_wise(data_point):\n    \"\"\"The spectrogram data will be normalized instance wise.\"\"\"\n    eps = 1e-6\n    \n    data_mean = data_point.mean(axis=(0, 1))\n    data_std = data_point.std(axis=(0, 1))\n    data_point = (data_point - data_mean) / (data_std + eps)\n    \n    data_tensor = torch.unsqueeze(torch.Tensor(data_point), dim=0)\n    data_point = Config.image_transform(data_tensor)\n    \n    return data_point\n\n# Loop over samples\nfor index in submission.index:\n    test_predictions_per_model = []\n    \n    preprocessed_data = preprocess(submission.iloc[index]['path_spec'])\n    preprocessed_data_ownspec = preprocess_ownspec(submission.iloc[index]['path_eeg'])\n    \n    # Predict based on original EfficientnetB0 models. \n    for i in range(len(models)):\n        models[i].eval()\n        \n        current_parquet_data = normalize_instance_wise(preprocessed_data).unsqueeze(0)\n        \n        with torch.no_grad():\n            model_output = models[i](current_parquet_data)\n            current_model_prediction = F.softmax(model_output)[0].detach().cpu().numpy()\n            \n        test_predictions_per_model.append(current_model_prediction)\n    \n    # Predict based on hyperparameter optimized EffcientnetB1.\n    for i in range(len(models_datawide)):\n        models_datawide[i].eval()\n        \n        current_parquet_data = normalize_datawide(preprocessed_data).unsqueeze(0)\n        \n        with torch.no_grad():\n            model_output = models_datawide[i](current_parquet_data)\n            current_model_prediction = F.softmax(model_output)[0].detach().cpu().numpy()\n            \n        test_predictions_per_model.append(current_model_prediction)\n    \n    # Predict based on EfficientnetB1 model with new spectrograms.\n    for i in range(len(models_ownspec)):\n        models_ownspec[i].eval()\n        \n        current_parquet_data = normalize_datawide_ownspec(preprocessed_data_ownspec).unsqueeze(0)\n        \n        with torch.no_grad():\n            model_output = models_ownspec[i](current_parquet_data)\n            current_model_prediction = F.softmax(model_output)[0].detach().cpu().numpy()\n            \n        test_predictions_per_model.append(current_model_prediction)\n    \n    # The mean of all models is taken.\n    ensemble_prediction = np.mean(test_predictions_per_model,axis=0)\n    \n    test_predictions.append(ensemble_prediction)\n\ntest_predictions = np.array(test_predictions)\n\ngc.collect()","metadata":{"execution":{"iopub.status.busy":"2024-04-01T20:34:29.942750Z","iopub.execute_input":"2024-04-01T20:34:29.943049Z","iopub.status.idle":"2024-04-01T20:34:32.887458Z","shell.execute_reply.started":"2024-04-01T20:34:29.943025Z","shell.execute_reply":"2024-04-01T20:34:32.886553Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"preds = test_predictions\npreds","metadata":{"execution":{"iopub.status.busy":"2024-04-01T20:34:32.888808Z","iopub.execute_input":"2024-04-01T20:34:32.889239Z","iopub.status.idle":"2024-04-01T20:34:32.895655Z","shell.execute_reply.started":"2024-04-01T20:34:32.889205Z","shell.execute_reply":"2024-04-01T20:34:32.894782Z"},"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']=preds[:, i]\nsubmission.to_csv(\"submission.csv\",index=None)\ndisplay(submission.head())","metadata":{"execution":{"iopub.status.busy":"2024-04-01T20:34:32.896911Z","iopub.execute_input":"2024-04-01T20:34:32.897260Z","iopub.status.idle":"2024-04-01T20:34:32.917148Z","shell.execute_reply.started":"2024-04-01T20:34:32.897230Z","shell.execute_reply":"2024-04-01T20:34:32.916318Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Sanity Check\nsubmission.iloc[:,-6:].sum(axis=1) == 1","metadata":{"execution":{"iopub.status.busy":"2024-04-01T20:34:32.918305Z","iopub.execute_input":"2024-04-01T20:34:32.918891Z","iopub.status.idle":"2024-04-01T20:34:32.926623Z","shell.execute_reply.started":"2024-04-01T20:34:32.918860Z","shell.execute_reply":"2024-04-01T20:34:32.925709Z"},"trusted":true},"execution_count":null,"outputs":[]}]}