{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"pygments_lexer":"ipython3","nbconvert_exporter":"python","version":"3.6.4","file_extension":".py","codemirror_mode":{"name":"ipython","version":3},"name":"python","mimetype":"text/x-python"}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"markdown","source":"2023CCUML_Assignment_5_611410089_林伯修","metadata":{"_kg_hide-input":true}},{"cell_type":"code","source":"import os\nimport gc\nimport random\nimport time\n\nimport json\nfrom tqdm import tqdm\nimport glob\nimport numpy as np\nimport pandas as pd\n\nimport torch\nimport torch.nn as nn\n\nfrom torch.utils.data import Dataset, DataLoader\nfrom torchvision import transforms\n\nfrom sklearn.model_selection import train_test_split, StratifiedGroupKFold\nfrom sklearn.metrics import accuracy_score, average_precision_score\n\nimport warnings\nwarnings.filterwarnings(action='ignore')","metadata":{"execution":{"iopub.status.busy":"2023-06-06T14:22:26.490138Z","iopub.execute_input":"2023-06-06T14:22:26.490838Z","iopub.status.idle":"2023-06-06T14:22:34.019852Z","shell.execute_reply.started":"2023-06-06T14:22:26.490795Z","shell.execute_reply":"2023-06-06T14:22:34.018768Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"> Config","metadata":{}},{"cell_type":"code","source":"class Config:\n    train_dir1 = \"/kaggle/input/tlvmc-parkinsons-freezing-gait-prediction/train/defog\"\n    train_dir2 = \"/kaggle/input/tlvmc-parkinsons-freezing-gait-prediction/train/tdcsfog\"\n\n    batch_size = 2048                                                        #batch size大小\n    window_size = 32                                                         #每次Input的總時序資料長度\n    window_future = 8                                                        #取目標時間點後多少為Input\n    window_past = window_size - window_future                                #取目標時間點前多少為Input\n    \n    wx = 8                                                                   #資料padding長度的參數\n    \n    optimizer_name = \"Adam\"                                                  #optimizer\n    loss_function = \"BCEWithLogitsLoss\"                                      #loss function\n    \n    model_dropout = 0.2                                                      #dropout機率\n    model_hidden = 128                                                        #每層linear layer的神經元數\n    model_nblocks = 3                                                        #model內的block數\n    \n    lr = 0.00015                                                             #learning rate\n    num_epochs = 5                                                           #訓練的epochs數\n    device = 'cuda:0' if torch.cuda.is_available() else 'cpu'                #裝置(GPU)設定\n    \n    feature_list = ['AccV', 'AccML', 'AccAP']\n    label_list = ['StartHesitation', 'Turn', 'Walking']\n    \n    \ncfg = Config()","metadata":{"execution":{"iopub.status.busy":"2023-06-06T14:22:34.021898Z","iopub.execute_input":"2023-06-06T14:22:34.022382Z","iopub.status.idle":"2023-06-06T14:22:34.098211Z","shell.execute_reply.started":"2023-06-06T14:22:34.022355Z","shell.execute_reply":"2023-06-06T14:22:34.097077Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"cfg.device","metadata":{"execution":{"iopub.status.busy":"2023-06-06T14:22:34.100312Z","iopub.execute_input":"2023-06-06T14:22:34.101091Z","iopub.status.idle":"2023-06-06T14:22:34.119035Z","shell.execute_reply.started":"2023-06-06T14:22:34.101050Z","shell.execute_reply":"2023-06-06T14:22:34.117867Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"> Stratified Group K Fold","metadata":{}},{"cell_type":"markdown","source":"tdcsfog preprocessing","metadata":{}},{"cell_type":"code","source":"# Analysis of positive instances in each fold of our CV folds\n\nn1_sum = []\nn2_sum = []\nn3_sum = []\ncount = []\n\n# Here I am using the metadata file available during training. Since the code will run again during submission, if \n# I used the usual file from the competition folder, it would have been updated with the test files too.\nmetadata = pd.read_csv(\"/kaggle/input/copy-train-metadata/tdcsfog_metadata.csv\")\n\nfor f in tqdm(metadata['Id']):\n    fpath = f\"/kaggle/input/tlvmc-parkinsons-freezing-gait-prediction/train/tdcsfog/{f}.csv\"\n    df = pd.read_csv(fpath)\n    \n    n1_sum.append(np.sum(df['StartHesitation']))\n    n2_sum.append(np.sum(df['Turn']))\n    n3_sum.append(np.sum(df['Walking']))\n    count.append(len(df))\n    \nprint(f\"32 files have positive values in all 3 classes\")\n\nmetadata['n1_sum'] = n1_sum\nmetadata['n2_sum'] = n2_sum\nmetadata['n3_sum'] = n3_sum\nmetadata['count'] = count\n\nsgkf = StratifiedGroupKFold(n_splits=5, random_state=42, shuffle=True)\nfor i, (train_index, valid_index) in enumerate(sgkf.split(X=metadata['Id'], y=[1]*len(metadata), groups=metadata['Subject'])):\n    print(f\"Fold = {i}\")\n    train_ids = metadata.loc[train_index, 'Id']\n    valid_ids = metadata.loc[valid_index, 'Id']\n    \n    print(f\"Length of Train = {len(train_index)}, Length of Valid = {len(valid_index)}\")\n    n1_sum = metadata.loc[train_index, 'n1_sum'].sum()\n    n2_sum = metadata.loc[train_index, 'n2_sum'].sum()\n    n3_sum = metadata.loc[train_index, 'n3_sum'].sum()\n    print(f\"Train classes: {n1_sum:,}, {n2_sum:,}, {n3_sum:,}\")\n    \n    n1_sum = metadata.loc[valid_index, 'n1_sum'].sum()\n    n2_sum = metadata.loc[valid_index, 'n2_sum'].sum()\n    n3_sum = metadata.loc[valid_index, 'n3_sum'].sum()\n    print(f\"Valid classes: {n1_sum:,}, {n2_sum:,}, {n3_sum:,}\")\n    \n# FOLD 2 is the most well balanced\n# The actual train-test split (based on Fold 2)\n\nmetadata = pd.read_csv(\"/kaggle/input/copy-train-metadata/tdcsfog_metadata.csv\")\nsgkf = StratifiedGroupKFold(n_splits=5, random_state=42, shuffle=True)\nfor i, (train_index, valid_index) in enumerate(sgkf.split(X=metadata['Id'], y=[1]*len(metadata), groups=metadata['Subject'])):\n    if i != 2:\n        continue\n    print(f\"Fold = {i}\")\n    train_ids = metadata.loc[train_index, 'Id']\n    valid_ids = metadata.loc[valid_index, 'Id']\n    print(f\"Length of Train = {len(train_ids)}, Length of Valid = {len(valid_ids)}\")\n    \n    if i == 2:\n        break\n        \ntrain_fpaths_tdcs = [f\"/kaggle/input/tlvmc-parkinsons-freezing-gait-prediction/train/tdcsfog/{_id}.csv\" for _id in train_ids]\nvalid_fpaths_tdcs = [f\"/kaggle/input/tlvmc-parkinsons-freezing-gait-prediction/train/tdcsfog/{_id}.csv\" for _id in valid_ids]","metadata":{"execution":{"iopub.status.busy":"2023-06-06T14:22:34.122263Z","iopub.execute_input":"2023-06-06T14:22:34.122757Z","iopub.status.idle":"2023-06-06T14:22:52.475575Z","shell.execute_reply.started":"2023-06-06T14:22:34.122720Z","shell.execute_reply":"2023-06-06T14:22:52.474490Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"> defog preprocessing","metadata":{}},{"cell_type":"code","source":"# Analysis of positive instances in each fold of our CV folds\n\nn1_sum = []\nn2_sum = []\nn3_sum = []\ncount = []\n\n# Here I am using the metadata file available during training. Since the code will run again during submission, if \n# I used the usual file from the competition folder, it would have been updated with the test files too.\nmetadata = pd.read_csv(\"/kaggle/input/copy-train-metadata/defog_metadata.csv\")\nmetadata['n1_sum'] = 0\nmetadata['n2_sum'] = 0\nmetadata['n3_sum'] = 0\nmetadata['count'] = 0\n\nfor f in tqdm(metadata['Id']):\n    fpath = f\"/kaggle/input/tlvmc-parkinsons-freezing-gait-prediction/train/defog/{f}.csv\"\n    if os.path.exists(fpath) == False:\n        continue\n        \n    df = pd.read_csv(fpath)\n    metadata.loc[metadata['Id'] == f, 'n1_sum'] = np.sum(df['StartHesitation'])\n    metadata.loc[metadata['Id'] == f, 'n2_sum'] = np.sum(df['Turn'])\n    metadata.loc[metadata['Id'] == f, 'n3_sum'] = np.sum(df['Walking'])\n    metadata.loc[metadata['Id'] == f, 'count'] = len(df)\n    \nmetadata = metadata[metadata['count'] > 0].reset_index()\n\nsgkf = StratifiedGroupKFold(n_splits=5, random_state=42, shuffle=True)\nfor i, (train_index, valid_index) in enumerate(sgkf.split(X=metadata['Id'], y=[1]*len(metadata), groups=metadata['Subject'])):\n    print(f\"Fold = {i}\")\n    train_ids = metadata.loc[train_index, 'Id']\n    valid_ids = metadata.loc[valid_index, 'Id']\n    \n    print(f\"Length of Train = {len(train_index)}, Length of Valid = {len(valid_index)}\")\n    n1_sum = metadata.loc[train_index, 'n1_sum'].sum()\n    n2_sum = metadata.loc[train_index, 'n2_sum'].sum()\n    n3_sum = metadata.loc[train_index, 'n3_sum'].sum()\n    print(f\"Train classes: {n1_sum:,}, {n2_sum:,}, {n3_sum:,}\")\n    \n    n1_sum = metadata.loc[valid_index, 'n1_sum'].sum()\n    n2_sum = metadata.loc[valid_index, 'n2_sum'].sum()\n    n3_sum = metadata.loc[valid_index, 'n3_sum'].sum()\n    print(f\"Valid classes: {n1_sum:,}, {n2_sum:,}, {n3_sum:,}\")\n    \n# FOLD 2 is the most well balanced\n# The actual train-test split (based on Fold 2)\n\nsgkf = StratifiedGroupKFold(n_splits=5, random_state=42, shuffle=True)\nfor i, (train_index, valid_index) in enumerate(sgkf.split(X=metadata['Id'], y=[1]*len(metadata), groups=metadata['Subject'])):\n    if i != 1:\n        continue\n    print(f\"Fold = {i}\")\n    train_ids = metadata.loc[train_index, 'Id']\n    valid_ids = metadata.loc[valid_index, 'Id']\n    print(f\"Length of Train = {len(train_ids)}, Length of Valid = {len(valid_ids)}\")\n    \n    if i == 2:\n        break\n        \ntrain_fpaths_de = [f\"/kaggle/input/tlvmc-parkinsons-freezing-gait-prediction/train/defog/{_id}.csv\" for _id in train_ids]\nvalid_fpaths_de = [f\"/kaggle/input/tlvmc-parkinsons-freezing-gait-prediction/train/defog/{_id}.csv\" for _id in valid_ids]","metadata":{"execution":{"iopub.status.busy":"2023-06-06T14:22:52.478034Z","iopub.execute_input":"2023-06-06T14:22:52.478430Z","iopub.status.idle":"2023-06-06T14:23:16.045893Z","shell.execute_reply.started":"2023-06-06T14:22:52.478392Z","shell.execute_reply":"2023-06-06T14:23:16.044938Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_fpaths = [(f, 'de') for f in train_fpaths_de] + [(f, 'tdcs') for f in train_fpaths_tdcs]\nvalid_fpaths = [(f, 'de') for f in valid_fpaths_de] + [(f, 'tdcs') for f in valid_fpaths_tdcs]","metadata":{"execution":{"iopub.status.busy":"2023-06-06T14:23:16.047427Z","iopub.execute_input":"2023-06-06T14:23:16.048708Z","iopub.status.idle":"2023-06-06T14:23:16.054536Z","shell.execute_reply.started":"2023-06-06T14:23:16.048670Z","shell.execute_reply":"2023-06-06T14:23:16.053250Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"> DataLoader","metadata":{}},{"cell_type":"code","source":"class FOGDataset(Dataset):\n    def __init__(self, fpaths, scale=9.806, split=\"train\"):\n        super(FOGDataset, self).__init__()\n        tm = time.time()\n        self.split = split\n        self.scale = scale\n        \n        self.fpaths = fpaths\n        self.dfs = [self.read(f[0], f[1]) for f in fpaths]\n        self.f_ids = [os.path.basename(f[0])[:-4] for f in self.fpaths]\n        \n        self.end_indices = []\n        self.shapes = []\n        _length = 0\n        for df in self.dfs:\n            self.shapes.append(df.shape[0])\n            _length += df.shape[0]\n            self.end_indices.append(_length)\n        \n        self.dfs = np.concatenate(self.dfs, axis=0).astype(np.float16)\n        self.length = self.dfs.shape[0]\n        \n        shape1 = self.dfs.shape[1]\n        \n        self.dfs = np.concatenate([np.zeros((cfg.wx*cfg.window_past, shape1)), self.dfs, np.zeros((cfg.wx*cfg.window_future, shape1))], axis=0)\n        print(f\"Dataset initialized in {time.time() - tm} secs!\")\n        gc.collect()\n        \n    def read(self, f, _type):\n        df = pd.read_csv(f)\n        if self.split == \"test\":\n            return np.array(df)\n        \n        if _type ==\"tdcs\":\n            df['Valid'] = 1\n            df['Task'] = 1\n            df['tdcs'] = 1\n        else:\n            df['tdcs'] = 0\n        \n        return np.array(df)\n            \n    def __getitem__(self, index):\n        if self.split == \"train\":\n            row_idx = random.randint(0, self.length-1) + cfg.wx*cfg.window_past\n        elif self.split == \"test\":\n            for i,e in enumerate(self.end_indices):\n                if index >= e:\n                    continue\n                df_idx = i\n                break\n\n            row_idx_true = self.shapes[df_idx] - (self.end_indices[df_idx] - index)\n            _id = self.f_ids[df_idx] + \"_\" + str(row_idx_true)\n            row_idx = index + cfg.wx*cfg.window_past\n        else:\n            row_idx = index + cfg.wx*cfg.window_past\n            \n        #scale = 9.806 if self.dfs[row_idx, -1] == 1 else 1.0\n        x = self.dfs[row_idx - cfg.wx*cfg.window_past : row_idx + cfg.wx*cfg.window_future, 1:4]\n        x = x[::cfg.wx, :][::-1, :]\n        x = torch.tensor(x.astype('float'))#/scale\n        \n        t = self.dfs[row_idx, -3]*self.dfs[row_idx, -2]\n        \n        if self.split == \"test\":\n            return _id, x, t\n        \n        y = self.dfs[row_idx, 4:7].astype('float')\n        y = torch.tensor(y)\n        \n        return x, y, t\n    \n    def __len__(self):\n        # return self.length\n        if self.split == \"train\":\n            return 5_000_000\n        return self.length","metadata":{"execution":{"iopub.status.busy":"2023-06-06T14:23:16.056146Z","iopub.execute_input":"2023-06-06T14:23:16.056425Z","iopub.status.idle":"2023-06-06T14:23:16.076782Z","shell.execute_reply.started":"2023-06-06T14:23:16.056399Z","shell.execute_reply":"2023-06-06T14:23:16.075812Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"gc.collect()","metadata":{"execution":{"iopub.status.busy":"2023-06-06T14:23:16.078304Z","iopub.execute_input":"2023-06-06T14:23:16.078814Z","iopub.status.idle":"2023-06-06T14:23:16.258148Z","shell.execute_reply.started":"2023-06-06T14:23:16.078779Z","shell.execute_reply":"2023-06-06T14:23:16.257098Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"> Model","metadata":{}},{"cell_type":"code","source":"def _block(in_features, out_features, drop_rate):\n    return nn.Sequential(\n        nn.Linear(in_features, out_features),      #全連接層\n        nn.BatchNorm1d(out_features),\n        nn.ReLU(),\n        nn.Dropout(drop_rate)\n    )\n\nclass FOGModel(nn.Module):\n    def __init__(self, p=cfg.model_dropout, dim=cfg.model_hidden, nblocks=cfg.model_nblocks):\n        super(FOGModel, self).__init__()\n        self.dropout = nn.Dropout(p)\n        self.in_layer = nn.Linear(cfg.window_size*3, dim)\n        self.blocks = nn.Sequential(*[_block(dim, dim, p) for _ in range(nblocks)])\n        self.out_layer = nn.Linear(dim, 3)\n        \n                                                   # dim=32\n    def forward(self, x):                          # x.Size([1024,32,3]) \n        x = x.view(-1, cfg.window_size*3)          # x.Size([1024,96])\n        x = self.in_layer(x)                       # x.Size([1024,32])\n        for block in self.blocks:\n            x = block(x)                           # x.Size([1024,32])\n        x = self.out_layer(x)                      # x.Size([1024,3])\n        return x","metadata":{"execution":{"iopub.status.busy":"2023-06-06T14:23:16.259519Z","iopub.execute_input":"2023-06-06T14:23:16.260046Z","iopub.status.idle":"2023-06-06T14:23:16.271334Z","shell.execute_reply.started":"2023-06-06T14:23:16.260008Z","shell.execute_reply":"2023-06-06T14:23:16.270422Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def count_parameters(model):\n    return sum(p.numel() for p in model.parameters() if p.requires_grad)","metadata":{"execution":{"iopub.status.busy":"2023-06-06T14:23:16.275259Z","iopub.execute_input":"2023-06-06T14:23:16.276235Z","iopub.status.idle":"2023-06-06T14:23:16.282023Z","shell.execute_reply.started":"2023-06-06T14:23:16.276200Z","shell.execute_reply":"2023-06-06T14:23:16.281075Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"> Training","metadata":{}},{"cell_type":"code","source":"from torch.cuda.amp import GradScaler\n\ndef train_one_epoch(model, loader, optimizer, criterion):\n    loss_sum = 0.\n    scaler = GradScaler()\n    \n    model.train()\n    for x,y,t in tqdm(loader):                               #從DataLoader中取得一個Batch size的資料\n        x = x.to(cfg.device).float()\n        y = y.to(cfg.device).float()\n        t = t.to(cfg.device).float()\n        \n        y_pred = model(x)                                    #將Input x丟入模型，得到y_pred\n        loss = criterion(y_pred, y)                          #計算預測結果y_pred與GT y的loss\n        loss = torch.mean(loss*t.unsqueeze(-1), dim=1)\n        \n        t_sum = torch.sum(t)\n        if t_sum > 0:\n            loss = torch.sum(loss)/t_sum\n        else:\n            loss = torch.sum(loss)*0.\n        \n        # loss.backward()\n        scaler.scale(loss).backward()                        #根據loss做反向傳播\n        # optimizer.step()\n        scaler.step(optimizer)                               #優化器優化模型參數\n        scaler.update()                                      \n        \n        optimizer.zero_grad()                                #優化器歸零\n        \n        loss_sum += loss.item()\n    \n    print(f\"Train Loss: {(loss_sum/len(loader)):.04f}\")\n    \n\ndef validation_one_epoch(model, loader, criterion):\n    loss_sum = 0.\n    y_true_epoch = []\n    y_pred_epoch = []\n    t_valid_epoch = []\n    \n    model.eval()\n    for x,y,t in tqdm(loader):\n        x = x.to(cfg.device).float()\n        y = y.to(cfg.device).float()\n        t = t.to(cfg.device).float()\n        \n        with torch.no_grad():                                #沒有反向傳播\n            y_pred = model(x)\n            loss = criterion(y_pred, y)\n            loss = torch.mean(loss*t.unsqueeze(-1), dim=1)\n            \n            t_sum = torch.sum(t)\n            if t_sum > 0:\n                loss = torch.sum(loss)/t_sum\n            else:\n                loss = torch.sum(loss)*0.\n        \n        loss_sum += loss.item()\n        y_true_epoch.append(y.cpu().numpy())\n        y_pred_epoch.append(y_pred.cpu().numpy())\n        t_valid_epoch.append(t.cpu().numpy())\n        \n    y_true_epoch = np.concatenate(y_true_epoch, axis=0)\n    y_pred_epoch = np.concatenate(y_pred_epoch, axis=0)\n    \n    t_valid_epoch = np.concatenate(t_valid_epoch, axis=0)\n    y_true_epoch = y_true_epoch[t_valid_epoch > 0, :]\n    y_pred_epoch = y_pred_epoch[t_valid_epoch > 0, :]\n    \n    scores = [average_precision_score(y_true_epoch[:,i], y_pred_epoch[:,i]) for i in range(3)]\n    mean_score = np.mean(scores)\n    print(f\"Validation Loss: {(loss_sum/len(loader)):.04f}, Validation Score: {mean_score:.03f}, ClassWise: {scores[0]:.03f},{scores[1]:.03f},{scores[2]:.03f}\")\n    \n    return mean_score","metadata":{"execution":{"iopub.status.busy":"2023-06-06T14:23:16.283657Z","iopub.execute_input":"2023-06-06T14:23:16.284061Z","iopub.status.idle":"2023-06-06T14:23:16.300953Z","shell.execute_reply.started":"2023-06-06T14:23:16.284026Z","shell.execute_reply":"2023-06-06T14:23:16.299987Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"model = FOGModel().to(cfg.device)\nprint(f\"Number of parameters in model - {count_parameters(model):,}\")\n\ntrain_dataset = FOGDataset(train_fpaths, split=\"train\")\nvalid_dataset = FOGDataset(valid_fpaths, split=\"valid\")\nprint(f\"lengths of datasets: train - {len(train_dataset)}, valid - {len(valid_dataset)}\")\n\ntrain_loader = DataLoader(train_dataset, batch_size=cfg.batch_size, num_workers=5, shuffle=True)\nvalid_loader = DataLoader(valid_dataset, batch_size=cfg.batch_size, num_workers=5)\n\noptimizer = getattr(torch.optim, cfg.optimizer_name)(model.parameters(), lr=cfg.lr)\ncriterion = getattr(torch.nn, cfg.loss_function)(reduction='none').to(cfg.device)\n# sched = torch.optim.lr_scheduler.StepLR(optimizer, step_size=1, gamma=0.85)\n\nmax_score = 0.0\n\nprint(\"=\"*50)\nfor epoch in range(cfg.num_epochs):\n    print(f\"Epoch: {epoch}\")\n    train_one_epoch(model, train_loader, optimizer, criterion)\n    score = validation_one_epoch(model, valid_loader, criterion)\n    # sched.step()\n\n    if score > max_score:\n        max_score = score\n        torch.save(model.state_dict(), \"best_model_state.h5\")      #儲存最好的模型參數\n        print(\"Saving Model ...\")\n\n    print(\"=\"*50)\n    \ngc.collect()","metadata":{"execution":{"iopub.status.busy":"2023-06-06T14:23:16.302280Z","iopub.execute_input":"2023-06-06T14:23:16.302677Z","iopub.status.idle":"2023-06-06T14:50:32.009539Z","shell.execute_reply.started":"2023-06-06T14:23:16.302643Z","shell.execute_reply":"2023-06-06T14:50:32.008441Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"> Submission","metadata":{}},{"cell_type":"code","source":"model = FOGModel().to(cfg.device)\nmodel.load_state_dict(torch.load(\"/kaggle/working/best_model_state.h5\"))             #取得最好的模型參數\nmodel.eval()\n\ntest_defog_paths = glob.glob(\"/kaggle/input/tlvmc-parkinsons-freezing-gait-prediction/test/defog/*.csv\")\ntest_tdcsfog_paths = glob.glob(\"/kaggle/input/tlvmc-parkinsons-freezing-gait-prediction/test/tdcsfog/*.csv\")\ntest_fpaths = [(f, 'de') for f in test_defog_paths] + [(f, 'tdcs') for f in test_tdcsfog_paths]\n\ntest_dataset = FOGDataset(test_fpaths, split=\"test\")\ntest_loader = DataLoader(test_dataset, batch_size=cfg.batch_size, num_workers=5)\n\nids = []\npreds = []\n\nfor _id, x, _ in tqdm(test_loader):\n    x = x.to(cfg.device).float()\n    with torch.no_grad():\n        y_pred = model(x)*0.1\n    \n    ids.extend(_id)\n    preds.extend(list(np.nan_to_num(y_pred.cpu().numpy())))","metadata":{"execution":{"iopub.status.busy":"2023-06-06T14:50:32.011470Z","iopub.execute_input":"2023-06-06T14:50:32.012162Z","iopub.status.idle":"2023-06-06T14:50:38.487789Z","shell.execute_reply.started":"2023-06-06T14:50:32.012126Z","shell.execute_reply":"2023-06-06T14:50:38.486538Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"sample_submission = pd.read_csv(\"/kaggle/input/tlvmc-parkinsons-freezing-gait-prediction/sample_submission.csv\")\nsample_submission.shape","metadata":{"execution":{"iopub.status.busy":"2023-06-06T14:50:38.489899Z","iopub.execute_input":"2023-06-06T14:50:38.490343Z","iopub.status.idle":"2023-06-06T14:50:38.759478Z","shell.execute_reply.started":"2023-06-06T14:50:38.490301Z","shell.execute_reply":"2023-06-06T14:50:38.758487Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"preds = np.array(preds)\nsubmission = pd.DataFrame({'Id': ids, 'StartHesitation': np.round(preds[:,0],5), \\\n                           'Turn': np.round(preds[:,1],5), 'Walking': np.round(preds[:,2],5)})\n\nsubmission = pd.merge(sample_submission[['Id']], submission, how='left', on='Id').fillna(0.0)\nsubmission.to_csv(\"submission.csv\", index=False)","metadata":{"execution":{"iopub.status.busy":"2023-06-06T14:50:38.761072Z","iopub.execute_input":"2023-06-06T14:50:38.761409Z","iopub.status.idle":"2023-06-06T14:50:40.740057Z","shell.execute_reply.started":"2023-06-06T14:50:38.761377Z","shell.execute_reply":"2023-06-06T14:50:40.738998Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print(submission.shape)\nsubmission.head()","metadata":{"execution":{"iopub.status.busy":"2023-06-06T14:50:40.741631Z","iopub.execute_input":"2023-06-06T14:50:40.742008Z","iopub.status.idle":"2023-06-06T14:50:40.761402Z","shell.execute_reply.started":"2023-06-06T14:50:40.741970Z","shell.execute_reply":"2023-06-06T14:50:40.760376Z"},"trusted":true},"execution_count":null,"outputs":[]}]}