{"metadata":{"kaggle":{"accelerator":"gpu","dataSources":[{"sourceId":53666,"databundleVersionId":6589269,"sourceType":"competition"},{"sourceId":7105903,"sourceType":"datasetVersion","datasetId":4055623},{"sourceId":151724150,"sourceType":"kernelVersion"},{"sourceId":153290450,"sourceType":"kernelVersion"}],"dockerImageVersionId":30588,"isInternetEnabled":false,"language":"python","sourceType":"notebook","isGpuEnabled":true},"kernelspec":{"display_name":"Python 3","language":"python","name":"python3"},"language_info":{"codemirror_mode":{"name":"ipython","version":3},"file_extension":".py","mimetype":"text/x-python","name":"python","nbconvert_exporter":"python","pygments_lexer":"ipython3","version":"3.10.12"}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"markdown","source":"# Child Mind Institute - Detect Sleep States\n\nCredits:\n\n - https://www.kaggle.com/code/itsuki9180/cmi-dss-debertav3-baseline-inference","metadata":{}},{"cell_type":"markdown","source":"# Import modules and Config","metadata":{}},{"cell_type":"code","source":"import pandas as pd\nimport numpy as np\nimport gc\nimport time\nimport json\nfrom datetime import datetime\nimport matplotlib.pyplot as plt\nimport os, glob\nimport joblib\nimport random\nimport math\nfrom tqdm import tqdm \nfrom collections import OrderedDict\n\nfrom scipy.interpolate import interp1d\nfrom scipy import signal\nfrom scipy.signal import argrelmax\n\nfrom sklearn.metrics import mean_squared_error\n\nfrom math import pi, sqrt, exp\nimport sklearn,sklearn.model_selection\nimport torch\nfrom torch import nn,Tensor\nimport torch.nn.functional as F\nfrom torch.utils.data import DataLoader, Dataset, SubsetRandomSampler\nfrom torch.optim import AdamW\nfrom sklearn.metrics import average_precision_score\nfrom timm.scheduler import CosineLRScheduler\n\nfrom transformers import get_cosine_schedule_with_warmup\nfrom transformers import AutoTokenizer, AutoConfig\nfrom transformers import AutoModel\n\nplt.style.use(\"ggplot\")\n\nfrom pyarrow.parquet import ParquetFile\nimport pyarrow as pa \nimport ctypes","metadata":{"execution":{"iopub.status.busy":"2023-11-28T16:44:43.730863Z","iopub.execute_input":"2023-11-28T16:44:43.731624Z","iopub.status.idle":"2023-11-28T16:44:54.745977Z","shell.execute_reply.started":"2023-11-28T16:44:43.731586Z","shell.execute_reply":"2023-11-28T16:44:54.745070Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import warnings\nwarnings.filterwarnings('ignore')","metadata":{"execution":{"iopub.status.busy":"2023-11-28T16:44:54.747615Z","iopub.execute_input":"2023-11-28T16:44:54.748863Z","iopub.status.idle":"2023-11-28T16:44:54.754076Z","shell.execute_reply.started":"2023-11-28T16:44:54.748809Z","shell.execute_reply":"2023-11-28T16:44:54.752372Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Fundamental config\nNOTDEBUG = True # False -> DEBUG, True -> normally train\nWORKERS = os.cpu_count() // 2\nN_FOLDS = 5\nTRAIN_FOLD = 0\n\nSIGMA = 720 #average length of day is 24*60*12 = 17280 for comparison\nSAMPLE_FREQ = 12 # 1 obs per minute\n\nMAX_LEN = (24*60*12) # 1day per chunk\nMAX_CHUNK_LEN = MAX_LEN // SAMPLE_FREQ\nUSE_AMP = False\nSEED = 8620","metadata":{"execution":{"iopub.status.busy":"2023-11-28T16:44:54.755429Z","iopub.execute_input":"2023-11-28T16:44:54.755753Z","iopub.status.idle":"2023-11-28T16:44:54.769607Z","shell.execute_reply.started":"2023-11-28T16:44:54.755716Z","shell.execute_reply":"2023-11-28T16:44:54.768120Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"device = 'cuda' if torch.cuda.is_available() else 'cpu'\ndevice","metadata":{"execution":{"iopub.status.busy":"2023-11-28T16:44:54.772705Z","iopub.execute_input":"2023-11-28T16:44:54.773345Z","iopub.status.idle":"2023-11-28T16:44:54.786541Z","shell.execute_reply.started":"2023-11-28T16:44:54.773309Z","shell.execute_reply":"2023-11-28T16:44:54.785041Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Model","metadata":{}},{"cell_type":"code","source":"class ImprovedLSTM(nn.Module):\n    def __init__(self, input_size, hidden_size, num_layers, output_size, dropout_prob=0.5):\n        super(ImprovedLSTM, self).__init__()\n        self.hidden_size = hidden_size\n        self.num_layers = num_layers\n\n        # Bidirectional LSTM Layer\n        self.lstm = nn.LSTM(input_size, hidden_size, num_layers, \n                            batch_first=True, dropout=dropout_prob, bidirectional=True)\n\n        # Transpose Convolution Layer for Upsampling\n        self.transpose_conv = nn.ConvTranspose1d(in_channels=hidden_size * 2,  # Adjust for bidirectional\n                                                 out_channels=hidden_size * 2,  # Adjust for bidirectional\n                                                 kernel_size=SAMPLE_FREQ, \n                                                 stride=SAMPLE_FREQ)\n\n        # Fully Connected Layer\n        self.fc = nn.Linear(hidden_size * 2, output_size)  # Adjust for bidirectional\n\n        # Layer Normalization\n        self.layer_norm = nn.LayerNorm(hidden_size * 2)  # Adjust for bidirectional\n\n        # Dropout Layer\n        self.dropout = nn.Dropout(dropout_prob)\n\n    def forward(self, x):\n        # Forward propagate LSTM\n        out, _ = self.lstm(x)\n\n        # Apply Layer Normalization\n        out = self.layer_norm(out)\n\n        # Transpose Convolution for Upsampling\n        out = out.permute(0, 2, 1)  # Change to [batch_size, hidden_size * 2, sequence_length]\n        out = self.transpose_conv(out)  # Upsample\n        out = out.permute(0, 2, 1)  # Change back to [batch_size, target_seq_length, hidden_size * 2]\n\n        # Apply Layer Normalization\n        out = self.layer_norm(out)\n        # Apply Dropout\n        out = self.dropout(out)\n        \n        # Fully Connected Layer\n        out = self.fc(out)\n\n        return out\n","metadata":{"execution":{"iopub.status.busy":"2023-11-28T16:44:54.788629Z","iopub.execute_input":"2023-11-28T16:44:54.789049Z","iopub.status.idle":"2023-11-28T16:44:54.803328Z","shell.execute_reply.started":"2023-11-28T16:44:54.789018Z","shell.execute_reply":"2023-11-28T16:44:54.802149Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class LSTM_CNN(nn.Module):\n    def __init__(self, input_size, hidden_size, num_layers, output_size, dropout_prob=0.5, num_channels=34*2, kernel_size=3):\n        super(LSTM_CNN, self).__init__()\n        self.hidden_size = hidden_size\n        self.num_layers = num_layers\n\n        # Bidirectional LSTM Layer\n        self.lstm = nn.LSTM(input_size, hidden_size, num_layers, \n                            batch_first=True, dropout=dropout_prob, bidirectional=True)\n\n        # CNN Layer\n        self.conv1 = nn.Conv1d(in_channels=hidden_size * 2, out_channels=num_channels, kernel_size=kernel_size, padding=kernel_size // 2)\n        self.relu = nn.ReLU()\n\n        # Transpose Convolution Layer for Upsampling\n        self.transpose_conv = nn.ConvTranspose1d(in_channels=num_channels,\n                                                 out_channels=num_channels,\n                                                 kernel_size=SAMPLE_FREQ,\n                                                 stride=SAMPLE_FREQ)\n        \n        # Fully Connected Layer (Adjust output size if needed)\n        self.fc = nn.Linear(num_channels, output_size)\n\n        # Layer Normalization\n        self.layer_norm = nn.LayerNorm(hidden_size * 2)  # Adjust for bidirectional\n\n        # Dropout Layer\n        self.dropout = nn.Dropout(dropout_prob)\n\n    def forward(self, x):\n        # Initialize hidden state and cell state for bidirectional LSTM\n        h0 = torch.zeros(self.num_layers * 2, x.size(0), self.hidden_size, device=x.device)  # * 2 for bidirectional\n        c0 = torch.zeros(self.num_layers * 2, x.size(0), self.hidden_size, device=x.device)  # * 2 for bidirectional\n\n        # Forward propagate LSTM\n        out, _ = self.lstm(x, (h0, c0))\n\n        # Apply Layer Normalization\n        out = self.layer_norm(out)\n\n        # Apply Dropout\n        out = self.dropout(out)\n\n        # CNN\n        out = out.permute(0, 2, 1) # Reshape for CNN [batch_size, features, seq_length]\n        out = self.conv1(out)\n        out = self.relu(out)\n\n        # Transpose Convolution for Upsampling (if needed)\n        out = self.transpose_conv(out)\n\n        # Fully Connected Layer (Adjust output size if needed)\n        out = out.permute(0, 2, 1) # Reshape for FC layer\n        out = self.fc(out)\n\n        return out","metadata":{"execution":{"iopub.status.busy":"2023-11-28T16:44:54.805340Z","iopub.execute_input":"2023-11-28T16:44:54.806321Z","iopub.status.idle":"2023-11-28T16:44:54.824360Z","shell.execute_reply.started":"2023-11-28T16:44:54.806272Z","shell.execute_reply":"2023-11-28T16:44:54.823041Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def add_weight_decay(model, weight_decay=1e-5, skip_list=()):\n    decay = []\n    no_decay = []\n    for name, param in model.named_parameters():\n        if not param.requires_grad:\n            continue\n        if len(param.shape) == 1 or np.any([v in name.lower()  for v in skip_list]):\n            # print(name, 'no decay')\n            no_decay.append(param)\n        else:\n            # print(name, 'decay')\n            decay.append(param)\n    return [\n        {'params': no_decay, 'weight_decay': 0.},\n        {'params': decay, 'weight_decay': weight_decay}]","metadata":{"execution":{"iopub.status.busy":"2023-11-28T16:44:54.826154Z","iopub.execute_input":"2023-11-28T16:44:54.826543Z","iopub.status.idle":"2023-11-28T16:44:54.841908Z","shell.execute_reply.started":"2023-11-28T16:44:54.826509Z","shell.execute_reply":"2023-11-28T16:44:54.840457Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# TEST","metadata":{}},{"cell_type":"markdown","source":"## Load Test Data","metadata":{}},{"cell_type":"code","source":"class SleepTestDataset(Dataset):\n    def __init__(\n        self,\n        test_series,\n        test_ids\n    ):\n        self.enmo_mean = np.load('/kaggle/input/cmi-data-preprocessing/enmo_mean.npy')\n        self.enmo_std = np.load('/kaggle/input/cmi-data-preprocessing/enmo_std.npy')\n\n        self.Xs = self.conv_dfs(test_series, test_ids)\n        \n        self.feat_list = np.load('/kaggle/input/cmi-train/feature_list.npy')\n        self.label_list = ['onset', 'wakeup']\n        \n        self.hour_feat= ['hour']\n        \n            \n    def conv_dfs(self, series, ids):\n        res = []\n        for j, viz_id in tqdm(enumerate(ids), total=len(ids)):\n            viz_series = series.loc[(series.series_id==viz_id)].copy().reset_index()\n            viz_series['dt'] = pd.to_datetime(viz_series.timestamp,format = '%Y-%m-%dT%H:%M:%S%z').astype(\"datetime64[ns, UTC-04:00]\")\n            viz_series['hour'] = viz_series['dt'].dt.hour\n            new_df = viz_series[['step', 'anglez', 'enmo', 'hour']]\n            res.append(new_df)\n\n        return res\n    \n\n    def norm_feat_eng(self, X, init=False):\n        X['anglez'] = X['anglez'] / 90.0\n        X['enmo'] = (X['enmo'] - self.enmo_mean)/ (self.enmo_std + 1e-12)\n        \n        for w in [1, 2, 4, 8, 16]:    \n            X['anglez_shift_pos_' + str(w)] = X['anglez'].shift(w).fillna(0)\n            X['anglez_shift_neg_' + str(w)] = X['anglez'].shift(-w).fillna(0)\n            \n            X['enmo_shift_pos_' + str(w)] = X['enmo'].shift(w).fillna(0)\n            X['enmo_shift_neg_' + str(w)] = X['enmo'].shift(-w).fillna(0)\n            \n            if init:\n                self.feat_list.append('anglez_shift_pos_' + str(w))\n                self.feat_list.append('anglez_shift_neg_' + str(w))\n                \n                self.feat_list.append('enmo_shift_pos_' + str(w))\n                self.feat_list.append('enmo_shift_neg_' + str(w))\n            \n        for r in [17, 33, 65]:\n            tmp_anglez = X['anglez'].rolling(r, center=True)\n            X[f'anglez_mean_{r}'] = tmp_anglez.mean()\n            X[f'anglez_std_{r}'] = tmp_anglez.std()            \n            \n            tmp_enmo = X['enmo'].rolling(r, center=True)\n            X[f'enmo_mean_{r}'] = tmp_enmo.mean()\n            X[f'enmo_std_{r}'] = tmp_enmo.std()\n            \n            if init:\n                self.feat_list.append(f'anglez_mean_{r}')\n                self.feat_list.append(f'anglez_std_{r}')\n\n                self.feat_list.append(f'enmo_mean_{r}')\n                self.feat_list.append(f'enmo_std_{r}')\n                \n        X = X.fillna(0)\n        \n        return X.astype(np.float32)\n\n    def gauss(self,n=SIGMA,sigma=SIGMA*0.15):\n        # guassian distribution function\n        r = range(-int(n/2),int(n/2)+1)\n        return [1 / (sigma * sqrt(2*pi)) * exp(-float(x)**2/(2*sigma**2)) for x in r]\n    \n    def __len__(self):\n        return len(self.Xs)\n    \n    def compress(self, xt, method='mean', sample_freq=SAMPLE_FREQ):\n        x, t = xt\n        seq_len = x.shape[0]\n        if method == 'mean':\n            x = x.reshape(seq_len//sample_freq, sample_freq, -1).mean(1)\n            t = t.reshape(seq_len//sample_freq, sample_freq, 1).mean(1)\n            \n        else:\n            raise NotImplementedError()\n\n        \n        return x.astype(np.float32), t.astype(np.int32)\n\n    def __getitem__(self, index):\n        X = self.Xs[index].copy()\n        X = self.norm_feat_eng(X, init=False)\n        x = X[self.feat_list].values.astype(np.float32)     \n        t = X[self.hour_feat].values.astype(np.int32)\n        \n        if len(X)%SAMPLE_FREQ!=0:\n            res = SAMPLE_FREQ - (len(X)%SAMPLE_FREQ)\n            x = np.pad(x, ((0, res), (0, 0)))\n            t = np.pad(t, ((0, res), (0, 0)))\n            \n        x, t = self.compress((x, t), method='mean')\n                \n        return x, t\n","metadata":{"execution":{"iopub.status.busy":"2023-11-28T16:44:54.843677Z","iopub.execute_input":"2023-11-28T16:44:54.844520Z","iopub.status.idle":"2023-11-28T16:44:54.874230Z","shell.execute_reply.started":"2023-11-28T16:44:54.844482Z","shell.execute_reply":"2023-11-28T16:44:54.872850Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"test_series = pd.read_parquet('/kaggle/input/child-mind-institute-detect-sleep-states/test_series.parquet')\ntest_ids = test_series.series_id.unique()\ntest_ds = SleepTestDataset(test_series, test_ids)","metadata":{"execution":{"iopub.status.busy":"2023-11-28T16:44:54.876302Z","iopub.execute_input":"2023-11-28T16:44:54.876876Z","iopub.status.idle":"2023-11-28T16:44:55.099821Z","shell.execute_reply.started":"2023-11-28T16:44:54.876783Z","shell.execute_reply":"2023-11-28T16:44:55.098592Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"test_dl = DataLoader(\n    test_ds,\n    batch_size=1,\n    pin_memory=True,\n    num_workers=WORKERS,\n    shuffle=False,\n    drop_last=False\n)","metadata":{"execution":{"iopub.status.busy":"2023-11-28T16:44:55.104772Z","iopub.execute_input":"2023-11-28T16:44:55.105657Z","iopub.status.idle":"2023-11-28T16:44:55.113224Z","shell.execute_reply.started":"2023-11-28T16:44:55.105615Z","shell.execute_reply":"2023-11-28T16:44:55.111900Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"del test_series\ngc.collect()","metadata":{"execution":{"iopub.status.busy":"2023-11-28T16:44:55.114956Z","iopub.execute_input":"2023-11-28T16:44:55.115392Z","iopub.status.idle":"2023-11-28T16:44:55.335888Z","shell.execute_reply.started":"2023-11-28T16:44:55.115352Z","shell.execute_reply":"2023-11-28T16:44:55.334946Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Load model & Test","metadata":{}},{"cell_type":"code","source":"input_size = len(test_ds.feat_list)\n# hidden_size = 128\nhidden_size = 256\nnum_layers = 2\noutput_size = len(test_ds.label_list)\n\nmodel = ImprovedLSTM(input_size, hidden_size, num_layers, output_size, dropout_prob=0.3)\n# model = LSTM_CNN(input_size, hidden_size, num_layers, output_size, dropout_prob=0.2)\nmodel\n\n# dropout_prob\n# model_LSTM_Test / model_LSTM_0 / model_LSTM_2 / model_LSTM_3 : dropout_prob = 0.3\n# model_LSTM_1 / model_LSTM_CNN_0 : dropout_prob = 0.2\n\n# hidden_size\n# model_LSTM_3: hidden_size = 256\n# others: hidden_size = 128","metadata":{"execution":{"iopub.status.busy":"2023-11-28T16:44:55.337509Z","iopub.execute_input":"2023-11-28T16:44:55.338149Z","iopub.status.idle":"2023-11-28T16:44:55.469447Z","shell.execute_reply.started":"2023-11-28T16:44:55.338110Z","shell.execute_reply":"2023-11-28T16:44:55.468115Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Load best model/kaggle/input/cmi-model/model_LSTM_4.pth\nload_model_name = \"model_LSTM_4.pth\"\nMODEL_PATH = '/kaggle/input/cmi-model/' + load_model_name\nmodel.load_state_dict(torch.load(MODEL_PATH, map_location=device))","metadata":{"execution":{"iopub.status.busy":"2023-11-28T16:44:55.470745Z","iopub.execute_input":"2023-11-28T16:44:55.471101Z","iopub.status.idle":"2023-11-28T16:44:55.901861Z","shell.execute_reply.started":"2023-11-28T16:44:55.471069Z","shell.execute_reply":"2023-11-28T16:44:55.900916Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def expand(value):\n    expanded = value.cpu().numpy()\n    expanded = np.repeat(expanded, SAMPLE_FREQ, axis=1)\n    return expanded","metadata":{"execution":{"iopub.status.busy":"2023-11-28T16:44:55.904106Z","iopub.execute_input":"2023-11-28T16:44:55.904569Z","iopub.status.idle":"2023-11-28T16:44:55.910052Z","shell.execute_reply.started":"2023-11-28T16:44:55.904533Z","shell.execute_reply":"2023-11-28T16:44:55.908859Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def prediction_CV(N_FOLDS, data, device):\n    with torch.no_grad():\n        id, inputs, steps, len_ = data\n        \n        onset_pred = []\n        wakeup_pred = []\n        input_size = len(test_ds.feat_list)\n        hidden_size = 128\n        num_layers = 2\n        output_size = len(test_ds.label_list)\n\n        for fold in range(N_FOLDS):\n            \n            model = ImprovedLSTM(input_size, hidden_size, num_layers, output_size, dropout_prob=0.3)\n            load_model_name = f'model_LSTM1_CV_{TRAIN_FOLD}.pth'\n            MODEL_PATH = '/kaggle/input/cmi-model/' + load_model_name\n            model.load_state_dict(torch.load(MODEL_PATH, map_location=device))\n            \n            model.eval()\n            model.to(device)\n\n            \n            inputs, steps = inputs.to(device), steps.to(device)\n\n            # Prediction\n            outputs = model(inputs)\n            probabilities = torch.sigmoid(outputs)\n\n            onset_predictions = probabilities[:, :, 0].cpu().numpy()\n            wakeup_predictions = probabilities[:, :, 1].cpu().numpy()\n\n            if fold==0:\n                onset_pred = onset_predictions[0, :len_] / N_FOLDS\n                wakeup_pred = wakeup_predictions[0, :len_] / N_FOLDS\n            else:\n                onset_pred += onset_predictions[0, :len_] / N_FOLDS\n                wakeup_pred += wakeup_predictions[0, :len_] / N_FOLDS       \n                \n            del model\n            gc.collect()\n            torch.cuda.empty_cache()\n\n            \n        onset_pred = decay_ratio(onset_pred)\n        wakeup_pred = decay_ratio(wakeup_pred)\n\n        onset_pred_index = argrelmax(onset_pred, order=12 * 60 * 6)[0]  # 12*60*6 = 6 hours\n        wakeup_pred_index = argrelmax(wakeup_pred, order=12 * 60 * 6)[0]  # 12*60*6 = 6 hours\n        \n        \n        try:\n            onset = pd.DataFrame({'series_id': [id]*len(onset_pred_index),\n                                 'step': onset_pred_index,\n                                 'score': onset_pred[onset_pred_index],\n                                 'event': ['onset']*len(onset_pred_index)})\n                \n        except:\n            onset = pd.DataFrame()            \n\n        try:\n            wakeup = pd.DataFrame({'series_id': [id]*len(wakeup_pred_index),\n                                   'step': wakeup_pred_index,\n                                   'score': wakeup_pred[wakeup_pred_index],\n                                   'event': ['wakeup']*len(wakeup_pred_index)})\n        except:\n            wakeup = pd.DataFrame()\n            \n        \n        return onset, wakeup","metadata":{"execution":{"iopub.status.busy":"2023-11-28T16:44:55.912180Z","iopub.execute_input":"2023-11-28T16:44:55.912986Z","iopub.status.idle":"2023-11-28T16:44:55.929573Z","shell.execute_reply.started":"2023-11-28T16:44:55.912943Z","shell.execute_reply":"2023-11-28T16:44:55.928196Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from scipy.signal import find_peaks\n\ndef prediction_test(model, data, device):\n    with torch.no_grad():\n        model.eval()\n        model.to(device)\n        \n        id, inputs, steps, len_ = data\n        inputs, steps = inputs.to(device), steps.to(device)\n\n        # Prediction\n        outputs = model(inputs)\n        probabilities = torch.sigmoid(outputs)\n\n        onset_predictions = probabilities[:, :, 0].cpu().numpy()\n        wakeup_predictions = probabilities[:, :, 1].cpu().numpy()\n        onset_pred = onset_predictions[0, :len_]\n        wakeup_pred = wakeup_predictions[0, :len_]\n        \n        onset_pred = decay_ratio(onset_pred)\n        wakeup_pred = decay_ratio(wakeup_pred)\n        \n        onset_pred_index = argrelmax(onset_pred, order=12 * 60 * 6)[0]  # 12*60*6 = 6 hours\n        wakeup_pred_index = argrelmax(wakeup_pred, order=12 * 60 * 6)[0]  # 12*60*6 = 6 hours\n        \n#         if len(onset_pred_index) == 0:\n#             onset_pred_index = find_peaks(onset_pred, distance=12 * 60 * 6)[0]\n#         if len(wakeup_pred_index) == 0:\n#             wakeup_pred_index = find_peaks(wakeup_pred, distance=12 * 60 * 6)[0]\n    \n            \n        try:\n            onset = pd.DataFrame({'series_id': [id]*len(onset_pred_index),\n                                 'step': onset_pred_index,\n                                 'score': onset_pred[onset_pred_index],\n                                 'event': ['onset']*len(onset_pred_index)})\n                \n        except:\n            onset = pd.DataFrame()            \n\n        try:\n            wakeup = pd.DataFrame({'series_id': [id]*len(wakeup_pred_index),\n                                   'step': wakeup_pred_index,\n                                   'score': wakeup_pred[wakeup_pred_index],\n                                   'event': ['wakeup']*len(wakeup_pred_index)})\n        except:\n            wakeup = pd.DataFrame()\n            \n        \n        return onset, wakeup","metadata":{"execution":{"iopub.status.busy":"2023-11-28T16:44:55.931255Z","iopub.execute_input":"2023-11-28T16:44:55.932617Z","iopub.status.idle":"2023-11-28T16:44:55.949727Z","shell.execute_reply.started":"2023-11-28T16:44:55.932567Z","shell.execute_reply":"2023-11-28T16:44:55.948586Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def decay_ratio(y_pred, threshold=0.5):\n    before_RMSE = np.sqrt(mean_squared_error(y_pred, np.zeros_like(y_pred)))\n    y_pred_filtered = lpf(y_pred, fe=30, n=1)\n    after_RMSE = np.sqrt(mean_squared_error(y_pred_filtered, np.zeros_like(y_pred_filtered)))\n    decay_ratio_value = before_RMSE / after_RMSE\n    \n\n    for i in range(len(y_pred)):\n        if y_pred[i] < threshold:\n            y_pred[i] = y_pred_filtered[i] * decay_ratio_value\n\n    return y_pred","metadata":{"execution":{"iopub.status.busy":"2023-11-28T16:47:20.202455Z","iopub.execute_input":"2023-11-28T16:47:20.203011Z","iopub.status.idle":"2023-11-28T16:47:20.212695Z","shell.execute_reply.started":"2023-11-28T16:47:20.202962Z","shell.execute_reply":"2023-11-28T16:47:20.211604Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def lpf(wave, fs=12*60*24, fe=30, n=3):\n    nyq = fs / 2.0\n    b, a = signal.butter(1, fe/nyq, btype='low')\n    for i in range(0, n):\n        wave = signal.filtfilt(b, a, wave)\n    return wave","metadata":{"execution":{"iopub.status.busy":"2023-11-28T16:47:20.325968Z","iopub.execute_input":"2023-11-28T16:47:20.326683Z","iopub.status.idle":"2023-11-28T16:47:20.333273Z","shell.execute_reply.started":"2023-11-28T16:47:20.326625Z","shell.execute_reply":"2023-11-28T16:47:20.332307Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from sklearn.preprocessing import MinMaxScaler\n\ndef plot_test(steps, data):\n    ids, test_ds, onset, wakeup = data\n    \n    steps = expand(steps)\n    x_values = np.arange(0, steps[:, :, 0].size, 1)\n    \n    enmo_data = test_ds['enmo']\n    anglez_data = test_ds['anglez']\n\n    scaler = MinMaxScaler()\n    anglez_scaled = scaler.fit_transform(anglez_data.to_numpy().reshape(-1, 1))\n    enmo_scaled = scaler.fit_transform(enmo_data.to_numpy().reshape(-1, 1))\n\n    \n    plt.figure(figsize=(20, 6))\n    plt.plot(anglez_scaled[:,0], label='anglez', linewidth=0.5, linestyle='-', color=\"black\")\n    plt.plot(enmo_scaled[:,0], label='enmo', linewidth=0.5, linestyle='-', color=\"gray\")\n\n\n    # Prediction markers\n    if not onset.empty:\n        plt.scatter(onset['step'], onset['score'], label='Onset Predicted Points', marker='o', s=50, color=\"#FF6347\", alpha=0.8)\n        plt.axvline(onset['step'].values, label='Onset Prediction', linewidth=2, linestyle='-', color=\"#FF6347\", alpha=0.7)\n    if not wakeup.empty:\n        plt.scatter(wakeup['step'], wakeup['score'], label='Wakeup Predicted Points', marker='s', s=50, color=\"#4682B4\", alpha=0.8)\n        plt.axvline(wakeup['step'].values, label='Onset Prediction', linewidth=2, linestyle='-', color=\"#4682B4\", alpha=0.7)\n\n    plt.title(ids, fontsize=16)\n    plt.xlabel('Step', fontsize=14)\n    plt.ylabel('Probabilities', fontsize=14)\n    plt.legend()\n    plt.grid(True)\n    plt.show()","metadata":{"execution":{"iopub.status.busy":"2023-11-28T16:47:20.463610Z","iopub.execute_input":"2023-11-28T16:47:20.464278Z","iopub.status.idle":"2023-11-28T16:47:20.477694Z","shell.execute_reply.started":"2023-11-28T16:47:20.464244Z","shell.execute_reply":"2023-11-28T16:47:20.476767Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"submission = pd.DataFrame()\n\nfor k, (inputs, steps) in enumerate(test_dl):\n    onset, wakeup = prediction_CV(N_FOLDS, [test_ids[k], inputs, steps, len(test_ds.Xs[k]['step'])], device)\n#     onset, wakeup = prediction_test(model, [test_ids[k], inputs, steps, len(test_ds.Xs[k]['step'])], device)\n    if len(test_ds.Xs)==3:\n        plot_test(steps, [test_ids[k], test_ds.Xs[k], onset, wakeup])\n    \n    submission = pd.concat([submission, onset, wakeup], axis=0)","metadata":{"execution":{"iopub.status.busy":"2023-11-28T16:47:20.590444Z","iopub.execute_input":"2023-11-28T16:47:20.591425Z","iopub.status.idle":"2023-11-28T16:47:25.580394Z","shell.execute_reply.started":"2023-11-28T16:47:20.591375Z","shell.execute_reply":"2023-11-28T16:47:25.579001Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"submission = submission.sort_values(['series_id','step']).reset_index(drop=True)\nsubmission['row_id'] = submission.index.astype(int)\nsubmission['score'] = submission['score'].fillna(submission['score'].mean())\nsubmission = submission[['row_id','series_id','step','event','score']]\nsubmission['step'] = submission['step']\nsubmission.to_csv('submission.csv',index=False)","metadata":{"execution":{"iopub.status.busy":"2023-11-28T16:47:25.582775Z","iopub.execute_input":"2023-11-28T16:47:25.583223Z","iopub.status.idle":"2023-11-28T16:47:25.599493Z","shell.execute_reply.started":"2023-11-28T16:47:25.583187Z","shell.execute_reply":"2023-11-28T16:47:25.598026Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"submission","metadata":{"execution":{"iopub.status.busy":"2023-11-28T16:47:25.601252Z","iopub.execute_input":"2023-11-28T16:47:25.602098Z","iopub.status.idle":"2023-11-28T16:47:25.625933Z","shell.execute_reply.started":"2023-11-28T16:47:25.602047Z","shell.execute_reply":"2023-11-28T16:47:25.624129Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]}]}