{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.7.12","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"gpu","dataSources":[{"sourceId":41880,"databundleVersionId":5677426,"sourceType":"competition"}],"dockerImageVersionId":30461,"isInternetEnabled":false,"language":"python","sourceType":"notebook","isGpuEnabled":true}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"import matplotlib.pyplot as plt\nfrom matplotlib import mlab\nimport torch\nimport torch.nn as nn\nimport torch.optim as optim\nimport numpy as np \nimport pandas as pd\nfrom sklearn.metrics import average_precision_score\nfrom scipy.optimize import minimize_scalar\nfrom sklearn.model_selection import train_test_split\nfrom sklearn.cluster import KMeans\nfrom scipy import signal\nimport os\nimport torch.utils.data as thd\nimport pdb\nimport sys\nimport time\nimport line_profiler\nfrom skimage.restoration import denoise_tv_bregman\nfrom torch.utils.data import Dataset, DataLoader\nfrom torch.nn.utils.rnn import pad_sequence, pack_padded_sequence\nimport torch.nn.functional as F\nfrom tqdm import tqdm\nimport scipy.ndimage as ndimage\nimport warnings\n\n\nDEVICE = torch.device(\"cuda\" if torch.cuda.is_available() else \"cpu\")","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","execution":{"iopub.status.busy":"2023-12-13T11:17:44.36904Z","iopub.execute_input":"2023-12-13T11:17:44.369534Z","iopub.status.idle":"2023-12-13T11:17:48.388812Z","shell.execute_reply.started":"2023-12-13T11:17:44.369492Z","shell.execute_reply":"2023-12-13T11:17:48.387717Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"window_size = 200\nwindow_future = 75\nwindow_past = window_size - window_future\nn_folds = 6\nsep_models = True \ntrain_dir = '/kaggle/input/tlvmc-parkinsons-freezing-gait-prediction/train/'\ntest_dir = '/kaggle/input/tlvmc-parkinsons-freezing-gait-prediction/test/'\nhome_dir = '/kaggle/input/tlvmc-parkinsons-freezing-gait-prediction/'\nacc_cols = ['AccV','AccML','AccAP']\nfs_dict = {'tdcsfog':128, 'defog':100}\nNFFT = 8","metadata":{"execution":{"iopub.status.busy":"2023-12-13T11:17:48.391412Z","iopub.execute_input":"2023-12-13T11:17:48.392096Z","iopub.status.idle":"2023-12-13T11:17:48.39942Z","shell.execute_reply.started":"2023-12-13T11:17:48.392049Z","shell.execute_reply":"2023-12-13T11:17:48.398283Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class FocalLoss(nn.Module):\n    def __init__(self, alpha=None, gamma=2, reduction='mean'):\n        super(FocalLoss, self).__init__()\n        self.alpha = alpha\n        self.gamma = gamma\n        self.reduction = reduction\n\n    def forward(self, inputs, targets):\n        ce_loss = F.cross_entropy(inputs, targets, reduction='none')\n        pt = torch.exp(-ce_loss)\n        if self.alpha is not None:\n            alpha_t = self.alpha[targets]\n            focal_loss = alpha_t * (1 - pt) ** self.gamma * ce_loss\n        else:\n            focal_loss = (1 - pt) ** self.gamma * ce_loss\n\n        if self.reduction == 'mean':\n            return focal_loss.mean()\n        elif self.reduction == 'sum':\n            return focal_loss.sum()\n        else:\n            return focal_loss","metadata":{"execution":{"iopub.status.busy":"2023-12-13T11:17:48.400914Z","iopub.execute_input":"2023-12-13T11:17:48.401278Z","iopub.status.idle":"2023-12-13T11:17:48.418032Z","shell.execute_reply.started":"2023-12-13T11:17:48.401245Z","shell.execute_reply":"2023-12-13T11:17:48.416935Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def iap_loss(y_pred, y_true):\n    batch_size, num_classes = y_pred.shape\n    eps = 1e-5\n   #TRUE AND FALSE + AND - & PRECISION AND RECALL\n    tp = (y_pred * y_true).sum(dim=0) \n    fp = ((1 - y_true) * y_pred).sum(dim=0)\n    fn = (y_true * (1 - y_pred)).sum(dim=0) \n    precision = tp / (tp + fp + eps)\n    recall = tp / (tp + fn + eps)\n    ap = torch.mean(precision[torch.argsort(recall, descending=True)])\n    print(\"metrics are:\")\n    print(tp,fp,fn,precision,recall)\n    interp_precision = torch.zeros((num_classes, 11), device=y_pred.device)\n    interp_recall = torch.linspace(0, 1, 11, device=y_pred.device)\n    for i in range(num_classes):\n        for j in range(10, -1, -1):\n            interp_precision[i, j] = torch.max(precision[i:][recall[i:] >= interp_recall[j]])\n    interp_ap = torch.mean(interp_precision[:, 0])\n    loss = 1 - interp_ap\n    \n    return loss","metadata":{"execution":{"iopub.status.busy":"2023-12-13T11:17:48.419341Z","iopub.execute_input":"2023-12-13T11:17:48.419718Z","iopub.status.idle":"2023-12-13T11:17:48.433261Z","shell.execute_reply.started":"2023-12-13T11:17:48.419678Z","shell.execute_reply":"2023-12-13T11:17:48.431979Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def mAP(preds, actuals, num_grps):\n    return [average_precision_score(y_score=preds[grp,], y_true=actuals[grp,]) for grp in range(num_grps)]\n\ndef normalize_columns(arr):\n    means = np.mean(arr, axis=0)\n    stds = np.std(arr, axis = 0)\n    stds[np.where(stds == 0)] == 1\n    \n    return (arr-means)/stds\n\n# MA FILTER\ndef hp_lp_filter(y, size=75):\n    y_ma = ndimage.uniform_filter1d(y, size=75)\n    y_hp = y - y_ma\n    return np.column_stack([y_hp,y_ma])\n# TV FILTER\ndef total_variance_filter(y, lmbda):\n    n = len(y)\n    def objective(x):\n        return np.sum((x - y)**2) + lmbda * np.sum(np.abs(np.diff(x)))\n    x0 = np.copy(y)\n    result = minimize_scalar(objective)\n    return result.x\n\n# SPECTROGRAM\ndef spec_interp(y, fs, nfft=64):\n    interp_inds = np.array(range(len(y)))/(len(y)-1)\n    # resample 100hz data to 120hz to align spectrograms\n    if fs == 100:\n        t_new = np.arange(0, len(y), 100 / 120)\n        y = np.interp(t_new, np.arange(len(y)), y)\n        fs = 120\n    \n    spec, freqs, t = mlab.specgram(y, NFFT=nfft, Fs=fs, noverlap=nfft//2, detrend='linear')\n    spec = 10 * np.log10(spec + 1e-25)\n    t_inds = np.array(range(len(t)))/(len(t)-1)\n    spec_db_interp = np.array([np.interp(interp_inds, t_inds, spec[i,:]) for i in range(len(spec))])\n    \n    return spec_db_interp\n\n","metadata":{"execution":{"iopub.status.busy":"2023-12-13T11:17:48.437657Z","iopub.execute_input":"2023-12-13T11:17:48.438337Z","iopub.status.idle":"2023-12-13T11:17:48.455418Z","shell.execute_reply.started":"2023-12-13T11:17:48.4383Z","shell.execute_reply":"2023-12-13T11:17:48.45412Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class AccDataset(Dataset):\n    def __init__(self, files_df, patients_df, valid_protocols=['tdcsfog'], tr=True):\n        self.patients_df = patients_df\n        self.valid_protocols = valid_protocols\n        self.files_df = files_df[files_df['Protocol'].isin(self.valid_protocols)] \n        self.files_df.reset_index(inplace=True, drop=True)\n        self.cv_col = cv_col\n        self.tr = tr\n\n        self.acc_feats = {}\n        self.labels = {}\n        self.tr_items = []\n        print('Loading and Processing Data:')\n        for idx in range(len(self.files_df)):\n            if idx % 100 == 0:\n                print(\"{}/{}\".format(idx,len(self.files_df)))\n            filepath = self.files_df.at[idx,'Filepath']\n            protocol = self.files_df.at[idx,'Protocol']\n            acc_feats, labels, tr_items = self.load_and_process(filepath, protocol)\n            self.acc_feats[filepath] = acc_feats\n            self.labels[filepath] = labels\n            self.tr_items.append(tr_items)\n                \n        self.tr_items = pd.concat(self.tr_items)\n        self.feature_dim = np.shape(acc_feats)[0]\n        \n        if not tr:\n            \n            self.cv_subjects = self.patients_df.Subject\n            self.cv_files_df = self.files_df\n            self.cv_tr_items = self.tr_items.to_numpy()\n            \n    def __len__(self):\n        return len(self.cv_tr_items)\n    \n    def __getitem__(self, idx):\n        return self.process_sample(idx)\n\n    \n    def set_cv_idx(self, cv_idx=[None], val=False, protocols=['defog','tdcsfog'], cv_col=['combo_cv'], return_idx=False):\n        self.cv_idx = cv_idx\n        self.protocols = protocols\n        self.cv_col = cv_col\n        self.return_idx = return_idx\n        \n        if val:\n            self.cv_subjects = self.patients_df[self.patients_df[self.cv_col].isin(cv_idx).values].Subject\n        else:\n            self.cv_subjects = self.patients_df[[not s for s in self.patients_df[self.cv_col].isin(cv_idx).values]].Subject\n            \n        \n        self.cv_files_df = self.files_df[self.files_df['Subject'].isin(self.cv_subjects)]\n        self.cv_files_df = self.cv_files_df[self.cv_files_df['Protocol'].isin(protocols)] \n        \n        \n        self.cv_tr_items = self.tr_items[self.tr_items['Filepath'].isin(self.cv_files_df.Filepath)].to_numpy()\n        \n       \n        self.lab_freq = np.zeros(4)\n        for k,v in self.labels.items():\n            if k in self.cv_files_df['Filepath'].values:\n                unique, counts = np.unique(v, return_counts=True)\n                for i in range(len(unique)):\n                    self.lab_freq[unique[i]] += counts[i]\n        self.lab_freq = np.sum(self.lab_freq)/self.lab_freq\n        self.lab_freq = self.lab_freq/np.sum(self.lab_freq)\n    \n    def load_and_process(self, filepath, protocol):\n        sample_df = pd.read_csv(filepath)\n        \n        if self.tr:\n            if protocol == 'defog':\n                \n                sample_df['StartHesitation'] = sample_df.apply(lambda x: x['StartHesitation'] if x['Valid'] == True and x['Task'] == True else 0, axis=1)\n                sample_df['Turn'] = sample_df.apply(lambda x: x['Turn'] if x['Valid'] == True and x['Task'] == True else 0, axis=1)\n                sample_df['Walking'] = sample_df.apply(lambda x: x['Walking'] if x['Valid'] == True and x['Task'] == True else 0, axis=1)\n                sample_df['NoFOG'] = sample_df.apply(lambda x: 0 if x['StartHesitation'] == 1 or x['Turn'] == 1 or x['Walking'] == 1 else 1, axis=1)\n                \n            elif protocol == 'tdcsfog':\n                sample_df['NoFOG'] = sample_df.apply(lambda x: 0 if x['StartHesitation'] == 1 or x['Turn'] == 1 or x['Walking'] == 1 else 1, axis=1)\n\n            labels = torch.t(torch.tensor(sample_df[['StartHesitation','Turn','Walking','NoFOG']].values, dtype=torch.int64))  \n            labels = torch.argmax(labels,dim=0)#.to(torch.int64)\n            labels = torch.unsqueeze(labels,0)\n        else: \n            labels = torch.empty(1,(len(sample_df)), dtype=torch.int64)\n        \n        acc_feats = self.acc_gen_features(sample_df, protocol)\n        item_df = pd.DataFrame({'Filepath':filepath, 'Ind':list(range(len(sample_df)))})\n            \n        return acc_feats, labels, item_df\n    \n    def acc_gen_features(self, sample_df, protocol):\n        acc_feats = sample_df[['AccV','AccML','AccAP']].values\n        fs = fs_dict[protocol]\n        \n        if protocol is not 'tdcsfog':\n            sample_df[acc_cols] = sample_df[acc_cols].applymap(lambda x: x*9.807)\n        \n        acc_filt = np.column_stack([hp_lp_filter(acc_feats[:,i]) for i in range(3)])\n        acc_feats = np.column_stack([acc_feats, acc_filt])\n\n        # spectrogram\n        acc_spec = np.column_stack([np.transpose(spec_interp(acc_feats[:,i], fs, nfft=NFFT)) for i in range(3)])\n        acc_feats = np.column_stack([acc_feats, acc_spec])\n\n        # time features\n        t = np.array(range(len(acc_feats)))/fs\n        t_prop = np.array(range(len(acc_feats)))/(len(acc_feats)-1)\n        acc_feats = np.column_stack([acc_feats, t, t_prop])\n        \n        acc_feats = normalize_columns(acc_feats)\n        return torch.t(torch.tensor(acc_feats,  dtype=torch.float32))\n    \n    def process_sample(self, tr_idx):\n        \n        fp = self.cv_tr_items[tr_idx]\n        acc_feats = self.acc_feats[fp[0]]\n        labels = self.labels[fp[0]]\n        idx = fp[1]\n        x_t = self.window_tensor(acc_feats, idx)\n        y_t = labels[:,idx:(idx+1)]\n\n        if self.tr and not self.return_idx:\n            return x_t, y_t\n        else:\n            k = self.cv_files_df[self.cv_files_df['Filepath'] == fp[0]].Id.values + '_' + str(idx)\n            return x_t, y_t, k.tolist() \n    \n    def window_tensor(self, x_t, pred_idx, w_width=window_size, w_future=window_future, w_past=window_past):\n        num_t = x_t.shape[1]\n        start_idx = max(0, pred_idx - w_past)\n        end_idx = min(num_t-1, pred_idx + w_future)\n\n        # if window extends outside data, pad with closest data \n        i_w = x_t[:,start_idx:end_idx]\n        if pred_idx-w_past < 0:\n            past_pad = x_t[:,0]\n            pad_tensor = past_pad.repeat(abs(pred_idx - w_past), 1)\n            i_w = torch.cat([pad_tensor.transpose(0,1),i_w], dim=1)\n        elif pred_idx + w_future > (num_t - 1):\n            fut_pad = x_t[:,-1]\n            pad_tensor = fut_pad.repeat(pred_idx + w_future - (num_t - 1), 1)\n            i_w = torch.cat([i_w, pad_tensor.transpose(0,1)], dim=1)\n        return i_w\n","metadata":{"execution":{"iopub.status.busy":"2023-12-13T11:17:48.457173Z","iopub.execute_input":"2023-12-13T11:17:48.457586Z","iopub.status.idle":"2023-12-13T11:17:48.509258Z","shell.execute_reply.started":"2023-12-13T11:17:48.457535Z","shell.execute_reply":"2023-12-13T11:17:48.508016Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# MODEL 2\nclass cnn(nn.Module):\n    def __init__(self, input_dim, conv_layers, num_classes, kernel_size, stride, padding, incl_pool=False, dropout_p=0.25, pool_k=2, pool_s=2):\n        super(cnn, self).__init__()\n        self.input_dim = input_dim\n        self.hidden_dim = conv_layers\n        self.num_classes = num_classes\n        self.kernel_size = kernel_size\n        self.stride = stride\n        self.padding = padding\n        self.pool_k = pool_k\n        self.pool_s = pool_s\n        self.pool_reduction = 1\n        \n            \n        self.conv_layers = nn.ModuleList()\n        self.out_layers = nn.ModuleList()\n        self.pool_layers = nn.ModuleList()\n        for i in range(len(conv_layers)):\n            in_channels = input_dim if i == 0 else conv_layers[i-1]\n            out_channels = conv_layers[i]\n            conv_layer = nn.Conv1d(in_channels, out_channels, kernel_size[i], stride[i], padding[i])\n            self.conv_layers.append(conv_layer)\n            self.conv_layers.append(nn.ReLU())\n            self.conv_layers.append(nn.BatchNorm1d(num_features=out_channels))\n            self.conv_layers.append(nn.Dropout(p=dropout_p[i+1]))\n            if incl_pool:\n                self.conv_layers.append(nn.AvgPool1d(kernel_size=pool_k, stride=pool_s, padding=int(np.floor(pool_k/2))))\n                self.pool_reduction = self.pool_reduction/pool_s\n            \n            self.final_dropout = nn.Dropout(p=dropout_p[-1])\n            self.global_avg_pooling = nn.AdaptiveAvgPool1d(output_size=1)\n            self.fc_layer = nn.Linear(conv_layers[-1], self.num_classes)\n    \n    def forward(self, x):\n        batch_size, input_dim, seq_len = x.size()\n        for i_layer in self.conv_layers:\n            x = i_layer(x)\n        \n        x = self.global_avg_pooling(x)\n        x = self.final_dropout(x)\n        x = x.view(batch_size,-1)\n        x = self.fc_layer(x)\n        x = nn.functional.softmax(x, dim=1)\n\n        return x\n        ","metadata":{"execution":{"iopub.status.busy":"2023-12-13T11:17:48.51081Z","iopub.execute_input":"2023-12-13T11:17:48.511193Z","iopub.status.idle":"2023-12-13T11:17:48.530371Z","shell.execute_reply.started":"2023-12-13T11:17:48.511142Z","shell.execute_reply":"2023-12-13T11:17:48.529187Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class Model(nn.Module):\n    def __init__(self, input_dim, conv_layers, num_classes, kernel_size, padding, dropout_p=0.25):\n        super(Model, self).__init__()\n        self.conv_blocks = nn.Sequential()\n        for _ in range(len(conv_layers)):\n            in_channels = input_dim if _ == 0 else conv_layers[_-1]\n            self.conv_blocks.add_module(\"conv1d_\" + str(_), nn.Conv1d(in_channels=in_channels, out_channels=conv_layers[_], kernel_size=kernel_size, padding=padding))\n            self.conv_blocks.add_module(\"batchnorm_\" + str(_), nn.BatchNorm1d(conv_layers[_]))\n            self.conv_blocks.add_module(\"relu_\" + str(_), nn.ReLU())\n            self.conv_blocks.add_module(\"dropout_\" + str(_), nn.Dropout(dropout_p))\n\n        self.global_avg_pooling = nn.AdaptiveAvgPool1d(output_size=1)\n        self.fc = nn.Linear(conv_layers[_], num_classes)\n\n    def forward(self, x):\n        x = self.conv_blocks(x)\n        x = self.global_avg_pooling(x)\n        x = x.view(x.size(0), -1)\n        x = self.fc(x)\n\n        return x","metadata":{"execution":{"iopub.status.busy":"2023-12-13T11:17:48.532368Z","iopub.execute_input":"2023-12-13T11:17:48.532869Z","iopub.status.idle":"2023-12-13T11:17:48.548506Z","shell.execute_reply.started":"2023-12-13T11:17:48.532797Z","shell.execute_reply":"2023-12-13T11:17:48.547256Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"tr_types = ['defog','notype','tdcsfog']\ntr_type_dir = [train_dir + i for i in tr_types]\ntr_files_df = []\nfor dirname, _, filenames in os.walk(train_dir):\n    for filename in filenames:\n        tr_files_df.append(\n            {\n            'Filename': filename,\n            'Filepath': os.path.join(dirname, filename),\n            'Protocol': tr_types[tr_type_dir.index(dirname)]\n            }\n        )\ntr_files_df = pd.DataFrame(tr_files_df)\n\ntdcs_meta = pd.read_csv(home_dir + 'tdcsfog_metadata.csv')\ndefog_meta = pd.read_csv(home_dir + 'defog_metadata.csv')\ndefog_meta['Test'] = 0 \nall_meta = pd.concat([tdcs_meta,defog_meta])\nall_meta['Filename'] = [i + '.csv' for i in all_meta.Id]\n\ntr_files_df = pd.merge(tr_files_df,all_meta,how='left',on='Filename')","metadata":{"execution":{"iopub.status.busy":"2023-12-13T11:17:48.549986Z","iopub.execute_input":"2023-12-13T11:17:48.550442Z","iopub.status.idle":"2023-12-13T11:17:48.894949Z","shell.execute_reply.started":"2023-12-13T11:17:48.550405Z","shell.execute_reply":"2023-12-13T11:17:48.893362Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"test_types = ['defog','tdcsfog']\ntest_type_dir = [test_dir + i for i in tr_types]\ntest_files_df = []\nfor dirname, _, filenames in os.walk(test_dir):\n    for filename in filenames:\n        test_files_df.append(\n            {\n            'Filename': filename,\n            'Filepath': os.path.join(dirname, filename),\n            'Protocol': tr_types[test_type_dir.index(dirname)]\n            }\n        )\ntest_files_df = pd.DataFrame(test_files_df)\n\ntest_files_df = pd.merge(test_files_df,all_meta,how='left',on='Filename')","metadata":{"execution":{"iopub.status.busy":"2023-12-13T11:17:48.896608Z","iopub.execute_input":"2023-12-13T11:17:48.897099Z","iopub.status.idle":"2023-12-13T11:17:48.92541Z","shell.execute_reply.started":"2023-12-13T11:17:48.897047Z","shell.execute_reply":"2023-12-13T11:17:48.924071Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"patients_df = pd.read_csv(home_dir + 'subjects.csv')\n\nfile_counts = tr_files_df.groupby(['Subject','Protocol']).size().reset_index(name='Count')\nfile_counts = file_counts.pivot_table(values = 'Count', index='Subject', columns='Protocol',fill_value =0)\nfile_counts['total_files'] = file_counts[['defog','notype','tdcsfog']].sum(axis=1)\nfile_counts['total_typed'] = file_counts[['defog','tdcsfog']].sum(axis=1)\n\npatients_df = pd.merge(patients_df,file_counts,how='left',on='Subject')\npatients_df[['defog','notype','tdcsfog','total_files','total_typed']] = patients_df[['defog','notype','tdcsfog','total_files','total_typed']].fillna(0)","metadata":{"execution":{"iopub.status.busy":"2023-12-13T11:17:48.926944Z","iopub.execute_input":"2023-12-13T11:17:48.927319Z","iopub.status.idle":"2023-12-13T11:17:48.979984Z","shell.execute_reply.started":"2023-12-13T11:17:48.927285Z","shell.execute_reply":"2023-12-13T11:17:48.978556Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"visit_feats = ['Visit','Test','Medication','Protocol']\npatient_feats = ['Age','Sex','YearsSinceDx','UPDRSIII_On','UPDRSIII_Off','NFOGQ']","metadata":{"execution":{"iopub.status.busy":"2023-12-13T11:17:48.983331Z","iopub.execute_input":"2023-12-13T11:17:48.984724Z","iopub.status.idle":"2023-12-13T11:17:48.992122Z","shell.execute_reply.started":"2023-12-13T11:17:48.984669Z","shell.execute_reply":"2023-12-13T11:17:48.990328Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"events_df = pd.read_csv(home_dir + 'events.csv')\nevents_df['Total_time'] = events_df['Completion'] - events_df['Init']\nevents_df = pd.merge(events_df, tr_files_df[['Id','Subject']], on='Id', how='inner')\nevents_agg = events_df.groupby(['Subject','Type']).agg({'Total_time': 'sum'}).reset_index()\nevents_pivot = events_agg.pivot_table(index='Subject', columns='Type', values='Total_time', fill_value=0).reset_index()\npatients_df = pd.merge(patients_df, events_pivot, on='Subject', how='left').fillna(0)\n\nfold_df = patients_df.groupby(['Subject']).agg({'StartHesitation': 'sum',\n                                                'Walking': 'sum',\n                                                'Turn': 'sum',\n                                                'defog': 'sum',\n                                                'tdcsfog': 'sum',\n                                                'notype': 'sum'}).reset_index()\n\n\nfold_df = fold_df.sort_values(by=['StartHesitation','Walking','Turn','defog'],ascending=True)\nfold_df['defog_cv'] = fold_df.reset_index().index % n_folds\n\n\nfold_df = fold_df.sort_values(by=['StartHesitation','Walking','Turn','tdcsfog'],ascending=True)\nfold_df['tdcsf_cv'] = fold_df.reset_index().index % n_folds\n\n\nfold_df = fold_df.sort_values(by=['StartHesitation','Walking','Turn','defog','tdcsfog'],ascending=True)\n\nfold_df['combo_cv'] = fold_df.reset_index().index % n_folds\n\n\nfold_df = fold_df.sort_values(by=['StartHesitation','Walking','Turn','defog','tdcsfog','notype'],ascending=True)\n\nfold_df['all_labeled_cv'] = fold_df.reset_index().index % n_folds\n\n# Add fold labels to patients_df\npatients_df = patients_df.merge(fold_df[['Subject','defog_cv','tdcsf_cv','combo_cv','all_labeled_cv']], on='Subject', how='left')\n\nvalue_counts = fold_df['Subject'].value_counts()\nvalue_counts = value_counts.sort_values(ascending=False)\nunique_folds = patients_df.groupby('Subject')['all_labeled_cv'].nunique()\nunique_folds.sort_values()\n\n\nprint(\"Check -- \")\nfold_check = events_df.merge(fold_df[['Subject','all_labeled_cv']],on = 'Subject')\nfold_check.groupby(['all_labeled_cv','Type']).agg({'Total_time': 'sum'})","metadata":{"execution":{"iopub.status.busy":"2023-12-13T11:17:48.99519Z","iopub.execute_input":"2023-12-13T11:17:48.995685Z","iopub.status.idle":"2023-12-13T11:17:49.122592Z","shell.execute_reply.started":"2023-12-13T11:17:48.995634Z","shell.execute_reply":"2023-12-13T11:17:49.121288Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"if False:\n    protocols = ['tdcsfog']\n    cv_col = ['tdcsf_cv']\n    cv_idx = [0]\n    cv_dataset = AccDataset(files_df=tr_files_df, patients_df=patients_df, valid_protocols=protocols)\n\n    cv_dataset.set_cv_idx(cv_idx=cv_idx, val=True, protocols=protocols, cv_col=cv_col)\n    i_acc = cv_dataset.acc_feats['/kaggle/input/tlvmc-parkinsons-freezing-gait-prediction/train/tdcsfog/a171e61840.csv']\n    y = i_acc[2,]\n    x = list(range(len(y)))\n\n    y_denoised = denoise_tv_bregman(y, weight=1000)\n    y_ma = ndimage.uniform_filter1d(y, size=75)\n\n    fig, ax = plt.subplots()\n    ax.plot(x, y, label='Noisy')\n    ax.plot(x, y_ma, label='Denoised')\n    ax.legend()\n    plt.show()\n    \n    y_hp = y - y_ma\n    fig, ax = plt.subplots()\n    ax.plot(x, y_hp, label='Noisy')\n    plt.show()\n\n    time = list(range(len(y)))\n   \n    fs = 120 \n    NFFT = 64  \n    spec, freqs, t = mlab.specgram(y_hp, NFFT=32, Fs=fs, noverlap=NFFT//2, detrend='linear')\n    spec_db = 10 * np.log10(spec)\n   \n    plt.pcolormesh(t, freqs, spec_db)\n    plt.ylabel('Frequency [Hz]')\n    plt.xlabel('Time [s]')\n    plt.show()\n\n    t_inds = np.array(range(len(t)))/(len(t)-1)\n    interp_inds = np.array(range(len(y)))/(len(y)-1)\n    spec_db_interp = np.array([np.interp(interp_inds, t_inds, spec[i,:]) for i in range(len(spec))])\n    \n    plt.pcolormesh(interp_inds, freqs, spec_db_interp)\n    plt.pcolormesh(spec_interp(y,120,32))\n    plt.ylabel('Frequency [Hz]')\n    plt.xlabel('Time [s]')\n    plt.show()\n    \n    lab_freq = np.zeros(4)\n    for k,v in cv_dataset.labels.items():\n        if k in cv_dataset.cv_files_df['Filepath'].values:\n            unique, counts = np.unique(v, return_counts=True)\n            for i in range(len(unique)):\n                lab_freq[unique[i]] += counts[i]\n    lab_freq = np.sum(lab_freq)/lab_freq\n    lab_freq = lab_freq/np.sum(lab_freq)","metadata":{"execution":{"iopub.status.busy":"2023-12-13T11:17:49.127084Z","iopub.execute_input":"2023-12-13T11:17:49.127561Z","iopub.status.idle":"2023-12-13T11:17:49.151172Z","shell.execute_reply.started":"2023-12-13T11:17:49.127504Z","shell.execute_reply":"2023-12-13T11:17:49.149619Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def CV_TRAIN():   \n    input_dim = cv_dataset.feature_dim\n    num_classes = 4\n    conv_layers = [32,64,64,128]\n    kernel_size = [9,9,2,1]\n    stride = [1,2,2,1]\n    padding = [0,0,0,0,0]\n    dropout_p=[0,0,0,0,0,0.6]\n    incl_pool=False\n    pool_k=3\n    pool_s=3\n\n    \n    batch_size = 800\n    learning_rate = 1e-5\n    num_epochs = 1\n    max_batches_per_epoch = 10000\n    max_val_batches = 400\n    val_freq = 400\n\n    \n    cv_dataloader = DataLoader(cv_dataset, batch_size=batch_size, shuffle=True, num_workers=0)\n    \n    \n    best_model_list = []\n    \n \n    for i_cv in range(n_folds):\n\n        print('CV: ',i_cv)\n\n        i_train_loss = []\n        i_val_map = []\n        i_val_class_map = []    \n        epoch_loss_l = []\n        val_loss = 0\n        best_val_map = 0\n\n        print('Initializing Model')\n        cv_dataset.set_cv_idx(cv_idx=[i_cv], val=True, protocols=protocols, cv_col=cv_col)\n        print('Num Val Batches: ' + str(len(cv_dataloader)))\n        cv_dataset.set_cv_idx(cv_idx=[i_cv], val=False, protocols=protocols, cv_col=cv_col)\n        num_train_batches = str(len(cv_dataloader))\n        print( 'Num Train Batches: ' + num_train_batches)\n        \n        fog_model = cnn(input_dim, conv_layers, num_classes, kernel_size, stride, padding, incl_pool, dropout_p, pool_k, pool_s)\n        fog_model.to(DEVICE)\n        if use_class_weights:\n            class_weights = torch.tensor(cv_dataset.lab_freq).float()\n        else:\n            class_weights = torch.tensor([1,1,1,1]).float()\n\n        optimizer = optim.Adam(fog_model.parameters(), lr=learning_rate, weight_decay=1e-5)\n        if use_focal_loss:\n            loss_fn = FocalLoss(gamma=5)\n        else:\n            loss_fn = nn.CrossEntropyLoss(weight=class_weights.to(DEVICE))\n        \n        print('Training Model')\n        start_time = time.time()\n        for epoch in range(num_epochs):\n            epoch_loss = 0\n            epoch_map = 0 \n            n_batches_done = 1\n            cv_dataset.set_cv_idx(cv_idx=[i_cv], val=False, protocols=protocols, cv_col=cv_col)\n            \n            for batch in cv_dataloader:\n                x, y = batch\n                x = x.to(DEVICE)\n                y = y.to(DEVICE)\n                y_pred = fog_model(x)\n                with warnings.catch_warnings():\n                    warnings.simplefilter(\"ignore\")\n                    loss = loss_fn(y_pred.to(DEVICE), y.view(-1))\n                    optimizer.zero_grad(set_to_none=True)\n                    loss.backward()\n                    optimizer.step()\n\n               \n                epoch_loss += loss.item()\n                epoch_loss_l.append(loss.item())\n                avg_epoch_loss = epoch_loss*batch_size/(n_batches_done)\n\n                \n                y_one_hot = torch.squeeze(torch.nn.functional.one_hot(torch.squeeze(y,1)),1)\n                batch_mAP = mAP(torch.t(y_pred).cpu().detach().numpy(),torch.t(y_one_hot).cpu().detach().numpy(),3)\n\n                if n_batches_done % val_freq == 0 or n_batches_done == len(cv_dataloader):#n_batches_done == len(cv_dataloader):#\n                    print(\"{} seconds; Epoch: {}; Batch: {}/{}; Loss: {}; Batch mAP: {} {}\".format(round((time.time() - start_time)), epoch, n_batches_done, num_train_batches, round(avg_epoch_loss,4), np.round(np.nanmean(batch_mAP),5), np.round(batch_mAP,5)))\n                    \n                    val_loss = 0\n                    actuals =[]\n                    preds=[]\n                    fog_model.eval()\n                    with torch.no_grad():\n                        cv_dataset.set_cv_idx(cv_idx=[i_cv], val=True, protocols=protocols, cv_col=cv_col)\n                         \n                        n_val_batches = 0\n                        for batch in cv_dataloader:\n                            x_val, y_val = batch\n                            x_val = x_val.to(DEVICE)\n                            y_val = y_val.to(DEVICE)\n                            y_pred_val = fog_model(x_val)\n                            actuals.append(torch.t(torch.nn.functional.one_hot(y_val.squeeze())).cpu().detach().numpy())\n                            preds.append(y_pred_val.squeeze().cpu().detach().numpy())\n                            val_loss += loss_fn(y_pred_val.to(DEVICE), y_val.view(-1))\n                            \n                            n_val_batches += 1\n                            if n_val_batches > max_val_batches:\n                                break\n                    cv_dataset.set_cv_idx(cv_idx=[i_cv], val=False, protocols=protocols, cv_col=cv_col)\n                    val_loss = val_loss/(n_val_batches*batch_size)\n                    \n                    fog_model.train()\n\n                    actuals = np.concatenate(actuals,axis=1)\n                    preds = np.transpose(np.concatenate(preds,axis=0))\n                    val_map = mAP(preds,actuals,3)\n                    i_train_loss.append(np.nanmean(epoch_loss_l))\n                    i_val_map.append(np.round(np.nanmean(val_map),decimals=5))\n                    i_val_class_map.append(val_map)\n\n                    print(\"Validation mAP: {} {};\".format(np.round(np.nanmean(val_map), decimals=5), np.round(val_map, decimals=5)))\n\n                    if np.nanmean(val_map) > best_val_map:\n                        torch.save(fog_model.state_dict(), 'best_{}_cv{}.pt'.format(protocols[0],i_cv))\n                        best_val_map = np.nanmean(val_map)\n                        best_mod_pd = pd.DataFrame({'CV': i_cv, 'Epoch': epoch, 'Batch': n_batches_done, 'Val mAP': best_val_map},index=[i_cv])\n                \n                n_batches_done += 1\n                if n_batches_done > max_batches_per_epoch:\n                    break\n        \n        best_model_list.append(best_mod_pd)\n    best_mods_pd =  pd.concat(best_model_list)\n    print(best_mods_pd)\n\n    return fog_model","metadata":{"execution":{"iopub.status.busy":"2023-12-13T11:17:49.153562Z","iopub.execute_input":"2023-12-13T11:17:49.154143Z","iopub.status.idle":"2023-12-13T11:17:49.204952Z","shell.execute_reply.started":"2023-12-13T11:17:49.15409Z","shell.execute_reply":"2023-12-13T11:17:49.203606Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"import torch\nDEVICE = torch.device('cuda' if torch.cuda.is_available() else 'cpu')\n","metadata":{"execution":{"iopub.status.busy":"2023-12-13T11:17:49.20643Z","iopub.execute_input":"2023-12-13T11:17:49.206866Z","iopub.status.idle":"2023-12-13T11:17:49.220803Z","shell.execute_reply.started":"2023-12-13T11:17:49.206821Z","shell.execute_reply":"2023-12-13T11:17:49.219532Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"protocols = ['tdcsfog']\ncv_col = ['tdcsf_cv']\ncv_dataset = AccDataset(files_df=tr_files_df, patients_df=patients_df, valid_protocols=protocols)\ncv_dataset.set_cv_idx(cv_idx=[0], val=False, protocols=protocols, cv_col=cv_col)\nuse_class_weights = True\nuse_focal_loss = False\n\n# Train model\nwith np.errstate(divide='ignore',invalid='ignore'):\n    fog_model = CV_TRAIN()","metadata":{"execution":{"iopub.status.busy":"2023-12-13T11:17:49.222529Z","iopub.execute_input":"2023-12-13T11:17:49.223331Z","iopub.status.idle":"2023-12-13T12:31:41.786506Z","shell.execute_reply.started":"2023-12-13T11:17:49.223281Z","shell.execute_reply":"2023-12-13T12:31:41.785055Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"\"\"\"\"\ndel cv_dataset\nprotocols = ['defog']\ncv_col = ['defog_cv']\ncv_dataset = AccDataset(files_df=tr_files_df, patients_df=patients_df, valid_protocols=protocols)\ncv_dataset.set_cv_idx(cv_idx=[0], val=False, protocols=protocols, cv_col=cv_col)\nuse_class_weights = False\nuse_focal_loss = True\n\n\nwith np.errstate(divide='ignore',invalid='ignore'):\n    fog_model = CV_TRAIN()\n\"\"\"\"","metadata":{"execution":{"iopub.status.busy":"2023-12-13T13:05:44.208919Z","iopub.execute_input":"2023-12-13T13:05:44.210093Z","iopub.status.idle":"2023-12-13T13:05:44.2171Z","shell.execute_reply.started":"2023-12-13T13:05:44.210047Z","shell.execute_reply":"2023-12-13T13:05:44.215471Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"\"\"\"\"\nfinal_preds = pd.DataFrame(columns=['Id','StartHesitation','Turn','Walking'])\n\nfor i_prot in ['defog','tdcsfog']:\n    test_dataset = AccDataset(files_df=test_files_df, patients_df=patients_df, valid_protocols=[i_prot], tr=False)\n    test_dataloader = DataLoader(test_dataset, batch_size=1024, shuffle=True)\n    for batch in test_dataloader:\n        x, _, k = batch\n        y_pred_ens = np.zeros([np.shape(x)[0],4])\n        for i_model in range(n_folds):\n            fog_model.load_state_dict(torch.load('best_{}_cv{}.pt'.format(i_prot,i_model)))\n\n            with torch.no_grad():\n                fog_model.eval()\n                \n                x = x.to(DEVICE)\n                y_pred = fog_model(x)\n                y_pred = torch.squeeze(y_pred,0).cpu().detach().numpy()\n                y_pred_ens += y_pred/n_folds\n        i_pd = pd.DataFrame({'Id':np.squeeze(k,0),\n                         'StartHesitation':y_pred_ens[:,0],\n                        'Turn':y_pred_ens[:,1],\n                        'Walking':y_pred_ens[:,2]\n                        })\n        final_preds = pd.concat([final_preds, i_pd], axis=0)\n    \n\nfinal_preds.to_csv('submission.csv', index=False, float_format='%.5f')","metadata":{"execution":{"iopub.status.busy":"2023-12-13T13:03:25.995452Z","iopub.status.idle":"2023-12-13T13:03:25.996067Z","shell.execute_reply.started":"2023-12-13T13:03:25.995745Z","shell.execute_reply":"2023-12-13T13:03:25.995776Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]}]}