{"metadata":{"kernelspec":{"name":"python3","display_name":"Python 3","language":"python"},"language_info":{"name":"python","version":"3.11.13","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"nvidiaTeslaT4","dataSources":[{"sourceId":102335,"databundleVersionId":12518947,"sourceType":"competition"},{"sourceId":12703912,"sourceType":"datasetVersion","datasetId":8028914},{"sourceId":12800933,"sourceType":"datasetVersion","datasetId":8040013},{"sourceId":12801314,"sourceType":"datasetVersion","datasetId":8070016}],"dockerImageVersionId":31090,"isInternetEnabled":false,"language":"python","sourceType":"notebook","isGpuEnabled":true},"papermill":{"default_parameters":{},"duration":1314.829712,"end_time":"2025-08-10T21:14:25.450769","environment_variables":{},"exception":null,"input_path":"__notebook__.ipynb","output_path":"__notebook__.ipynb","parameters":{},"start_time":"2025-08-10T20:52:30.621057","version":"2.6.0"}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"is_train = False\nMODEL_SAVE_PATH = 'best_gesture_classifier_05.pth'\nMODEL_KAGGLE_DIR = '/kaggle/input/cmi2025-model-weight/'","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-08-18T20:07:25.021304Z","iopub.execute_input":"2025-08-18T20:07:25.021931Z","iopub.status.idle":"2025-08-18T20:07:25.028323Z","shell.execute_reply.started":"2025-08-18T20:07:25.021906Z","shell.execute_reply":"2025-08-18T20:07:25.027507Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"# 1. 読み込み","metadata":{}},{"cell_type":"code","source":"import os\nimport sys\nimport numpy as np\nimport pandas as pd\nimport polars as pl\nimport torch\nfrom tqdm import tqdm\nimport matplotlib.pyplot as plt\n\nis_kaggle_kernel = os.path.isdir(\"/kaggle/working/\")\ndevice = torch.device(\"cuda\" if torch.cuda.is_available() else \"cpu\")\nprint(device)\n\nif is_kaggle_kernel:\n    folder_path = \"/kaggle/input/cmi-detect-behavior-with-sensor-data/\"\n    split_data_path = \"/kaggle/input/cmi2025-split-train-data/\"\n    MODEL_READ_PATH = MODEL_KAGGLE_DIR + MODEL_SAVE_PATH\nelse:\n    folder_path = \"../../../../data/cmi-detect-behavior-with-sensor-data/\"\n    split_data_path = folder_path + \"split_train_data/\"\n    MODEL_READ_PATH = MODEL_SAVE_PATH\nsys.path.append(folder_path)\nimport kaggle_evaluation.cmi_inference_server\n\ntrain_demo = pd.read_csv(f\"{folder_path}/train_demographics.csv\")\ntrain = pd.read_csv(f\"{split_data_path}/train_1.csv\")\nval_demo = train_demo.copy()\nval = pd.read_csv(f\"{split_data_path}/val_1.csv\")\ntest_demo = pd.read_csv(f\"{folder_path}/test_demographics.csv\")\ntest = pd.read_csv(f\"{folder_path}/test.csv\")","metadata":{"execution":{"iopub.status.busy":"2025-08-18T20:07:25.029519Z","iopub.execute_input":"2025-08-18T20:07:25.029772Z","iopub.status.idle":"2025-08-18T20:08:08.085738Z","shell.execute_reply.started":"2025-08-18T20:07:25.029748Z","shell.execute_reply":"2025-08-18T20:08:08.085091Z"},"papermill":{"duration":29.521905,"end_time":"2025-08-10T20:53:04.282709","exception":false,"start_time":"2025-08-10T20:52:34.760804","status":"completed"},"tags":[],"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import torch\nimport numpy as np\nimport pandas as pd\nimport random\nimport os\n\ndef set_seed(seed):\n    \"\"\"\n    主要なライブラリの乱数シードを固定する関数。\n    \"\"\"\n    os.environ['PYTHONHASHSEED'] = str(seed)\n    random.seed(seed)\n    np.random.seed(seed)\n    torch.manual_seed(seed)\n    if torch.cuda.is_available():\n        torch.cuda.manual_seed(seed)\n        torch.cuda.manual_seed_all(seed)  # 複数のGPUを使用する場合\n        # CUDNN関連のシードも固定して、決定論的挙動を保証\n        torch.backends.cudnn.deterministic = True\n        torch.backends.cudnn.benchmark = False\n    \n    print(f\"乱数シードを {seed} に設定しました。\")\n\nSEED = 42\nset_seed(SEED)","metadata":{"execution":{"iopub.status.busy":"2025-08-18T20:08:08.086522Z","iopub.execute_input":"2025-08-18T20:08:08.086827Z","iopub.status.idle":"2025-08-18T20:08:08.101140Z","shell.execute_reply.started":"2025-08-18T20:08:08.086796Z","shell.execute_reply":"2025-08-18T20:08:08.100459Z"},"papermill":{"duration":4.106889,"end_time":"2025-08-10T20:53:08.393266","exception":false,"start_time":"2025-08-10T20:53:04.286377","status":"completed"},"tags":[],"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"# 2. 前処理","metadata":{}},{"cell_type":"markdown","source":"## 2.1. 全体前処理","metadata":{}},{"cell_type":"code","source":"cols_to_nan = [c for c in val.columns if c.startswith(\"tof\") or c.startswith(\"thm\")]\nval_imu_only = val.copy()\nval_imu_only[cols_to_nan] = np.nan","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-08-18T20:08:08.102806Z","iopub.execute_input":"2025-08-18T20:08:08.102996Z","iopub.status.idle":"2025-08-18T20:08:08.292563Z","shell.execute_reply.started":"2025-08-18T20:08:08.102980Z","shell.execute_reply":"2025-08-18T20:08:08.291789Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"if is_kaggle_kernel:\n    sys.path.append('/kaggle/input/cmi2025-utils')\nfrom utils.preprocess_global import preprocess_global\n\ntrain, train_demo = preprocess_global(train, train_demo)\nval, val_demo = preprocess_global(val, val_demo)\nval_imu_only, val_demo = preprocess_global(val_imu_only, val_demo)\ntest, test_demo = preprocess_global(test, test_demo, have_labels=False)","metadata":{"execution":{"iopub.status.busy":"2025-08-18T20:08:08.293440Z","iopub.execute_input":"2025-08-18T20:08:08.293737Z","iopub.status.idle":"2025-08-18T20:11:30.792036Z","shell.execute_reply.started":"2025-08-18T20:08:08.293705Z","shell.execute_reply":"2025-08-18T20:11:30.791439Z"},"papermill":{"duration":164.587533,"end_time":"2025-08-10T20:55:53.000944","exception":false,"start_time":"2025-08-10T20:53:08.413411","status":"completed"},"tags":[],"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"## 2.2. 個別前処理・EDA\n個別シークエンスに施す，時系列依存の前処理（例えば時系列方向での正規化）する関数を，Dataset1に入れる。","metadata":{}},{"cell_type":"code","source":"from utils.dataset import Dataset1\nfrom utils.preprocess_sequence import preprocess_sequence\n\n# train_dataset_eda = Dataset1(train_demo, train, preprocess=preprocess_sequence)\ntrain_dataset_eda = Dataset1(train_demo, train, preprocess=preprocess_sequence)\nval_dataset_eda = Dataset1(val_demo, val, preprocess=preprocess_sequence)\nval_dataset_imu_only_eda = Dataset1(val_demo, val_imu_only, preprocess=preprocess_sequence)\ntest_dataset_eda = Dataset1(test_demo, test, preprocess=preprocess_sequence)","metadata":{"execution":{"iopub.status.busy":"2025-08-18T20:11:30.792811Z","iopub.execute_input":"2025-08-18T20:11:30.793191Z","iopub.status.idle":"2025-08-18T20:11:34.659434Z","shell.execute_reply.started":"2025-08-18T20:11:30.793169Z","shell.execute_reply":"2025-08-18T20:11:34.658847Z"},"papermill":{"duration":3.878015,"end_time":"2025-08-10T20:55:57.114149","exception":false,"start_time":"2025-08-10T20:55:53.236134","status":"completed"},"tags":[],"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# EDA\ndemo_df, seq_df, label = train_dataset_eda[0]  # DataFrame 形式\ndemo_df","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-08-18T20:11:34.660241Z","iopub.execute_input":"2025-08-18T20:11:34.660498Z","iopub.status.idle":"2025-08-18T20:11:34.684893Z","shell.execute_reply.started":"2025-08-18T20:11:34.660473Z","shell.execute_reply":"2025-08-18T20:11:34.684300Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"demo_df, seq_df, label = val_dataset_eda[0]","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-08-18T20:11:34.685665Z","iopub.execute_input":"2025-08-18T20:11:34.685945Z","iopub.status.idle":"2025-08-18T20:11:34.690692Z","shell.execute_reply.started":"2025-08-18T20:11:34.685917Z","shell.execute_reply":"2025-08-18T20:11:34.690145Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"seq_df","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-08-18T20:11:34.692744Z","iopub.execute_input":"2025-08-18T20:11:34.693310Z","iopub.status.idle":"2025-08-18T20:11:34.723242Z","shell.execute_reply.started":"2025-08-18T20:11:34.693292Z","shell.execute_reply":"2025-08-18T20:11:34.722549Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"## 2.3. Tensor化","metadata":{}},{"cell_type":"code","source":"from utils.dataset import Dataset2, mix_dataset\n\ntrain_dataset = Dataset2(train_dataset_eda)\nval_dataset = Dataset2(val_dataset_eda)\nval_dataset_imu_only = Dataset2(val_dataset_imu_only_eda)\nval_dataset_mix = mix_dataset(val_dataset, val_dataset_imu_only)\ntest_dataset = Dataset2(test_dataset_eda)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-08-18T20:11:34.724035Z","iopub.execute_input":"2025-08-18T20:11:34.724757Z","iopub.status.idle":"2025-08-18T20:11:34.789831Z","shell.execute_reply.started":"2025-08-18T20:11:34.724740Z","shell.execute_reply":"2025-08-18T20:11:34.789332Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"## 2.4. DataLoader","metadata":{}},{"cell_type":"code","source":"from torch.utils.data import DataLoader\nfrom utils.dataset import custom_collate_fn\n\nBATCH_SIZE = 32\nNUM_WORKERS = 0\n\ntrain_loader = DataLoader(train_dataset, batch_size=BATCH_SIZE, shuffle=True, collate_fn=custom_collate_fn, num_workers=NUM_WORKERS)\nval_loader = DataLoader(val_dataset, batch_size=BATCH_SIZE, shuffle=False, collate_fn=custom_collate_fn, num_workers=NUM_WORKERS)\nval_loader_imu_only = DataLoader(val_dataset_imu_only, batch_size=BATCH_SIZE, shuffle=False, collate_fn=custom_collate_fn, num_workers=NUM_WORKERS)\nval_loader_mix = DataLoader(val_dataset_mix, batch_size=BATCH_SIZE, shuffle=False, collate_fn=custom_collate_fn, num_workers=NUM_WORKERS)\ntest_loader = DataLoader(test_dataset, batch_size=BATCH_SIZE, shuffle=False, collate_fn=custom_collate_fn, num_workers=NUM_WORKERS)","metadata":{"execution":{"iopub.status.busy":"2025-08-18T20:11:34.790387Z","iopub.execute_input":"2025-08-18T20:11:34.790618Z","iopub.status.idle":"2025-08-18T20:11:34.795666Z","shell.execute_reply.started":"2025-08-18T20:11:34.790602Z","shell.execute_reply":"2025-08-18T20:11:34.795107Z"},"papermill":{"duration":0.009997,"end_time":"2025-08-10T20:55:57.130195","exception":false,"start_time":"2025-08-10T20:55:57.120198","status":"completed"},"tags":[],"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"# 3. Model\n複数のモデルの構造を読み込む。非訓練時は，訓練済みパラメータも読み込む。","metadata":{}},{"cell_type":"code","source":"# モデルのインポート\nfrom utils.models import HybridGestureClassifier","metadata":{"execution":{"iopub.status.busy":"2025-08-18T20:11:34.796389Z","iopub.execute_input":"2025-08-18T20:11:34.796589Z","iopub.status.idle":"2025-08-18T20:11:34.822463Z","shell.execute_reply.started":"2025-08-18T20:11:34.796574Z","shell.execute_reply":"2025-08-18T20:11:34.821864Z"},"papermill":{"duration":0.012179,"end_time":"2025-08-10T20:55:57.147110","exception":false,"start_time":"2025-08-10T20:55:57.134931","status":"completed"},"tags":[],"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import torch.optim as optim\nfrom torch import nn\n\nDEMO_INPUT_DIM = train_dataset[0][0].shape[0]\nSEQ_INPUT_CHANNELS = train_dataset[0][1].shape[0]\nNUM_CLASSES = 18","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-08-18T20:11:34.823074Z","iopub.execute_input":"2025-08-18T20:11:34.823287Z","iopub.status.idle":"2025-08-18T20:11:34.867630Z","shell.execute_reply.started":"2025-08-18T20:11:34.823266Z","shell.execute_reply":"2025-08-18T20:11:34.867144Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# モデルのインスタンスを作成\nmodel = HybridGestureClassifier(\n    num_sequence_features=SEQ_INPUT_CHANNELS,\n    sequence_length=300,\n    num_subject_features=DEMO_INPUT_DIM,\n    num_classes=NUM_CLASSES\n    )","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-08-18T20:11:34.868265Z","iopub.execute_input":"2025-08-18T20:11:34.868510Z","iopub.status.idle":"2025-08-18T20:11:34.958895Z","shell.execute_reply.started":"2025-08-18T20:11:34.868486Z","shell.execute_reply":"2025-08-18T20:11:34.958247Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"if not is_train:\n    from utils.load_model import load_model\n    load_model(model, MODEL_READ_PATH, device)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-08-18T20:11:34.959694Z","iopub.execute_input":"2025-08-18T20:11:34.959926Z","iopub.status.idle":"2025-08-18T20:11:34.963225Z","shell.execute_reply.started":"2025-08-18T20:11:34.959911Z","shell.execute_reply":"2025-08-18T20:11:34.962565Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"model.to(device)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-08-18T20:11:34.964116Z","iopub.execute_input":"2025-08-18T20:11:34.964780Z","iopub.status.idle":"2025-08-18T20:11:35.384372Z","shell.execute_reply.started":"2025-08-18T20:11:34.964758Z","shell.execute_reply":"2025-08-18T20:11:35.383789Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"# 4. 訓練","metadata":{}},{"cell_type":"code","source":"print(val_dataset_eda.gesture_to_id)\nid_to_gesture = {v: k for k, v in val_dataset_eda.gesture_to_id.items()}\nprint(id_to_gesture)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-08-18T20:11:35.385066Z","iopub.execute_input":"2025-08-18T20:11:35.385322Z","iopub.status.idle":"2025-08-18T20:11:35.389769Z","shell.execute_reply.started":"2025-08-18T20:11:35.385295Z","shell.execute_reply":"2025-08-18T20:11:35.388824Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"from utils.train import train\n\nNUM_EPOCHS = 200\ncriterion = nn.CrossEntropyLoss()\noptimizer = optim.Adam(model.parameters(), lr=0.001)\n\nif is_train:\n      train(model,\n            train_loader,\n            val_loader,\n            val_loader_imu_only,\n            val_loader_mix,\n            num_epochs=NUM_EPOCHS,\n            criterion=criterion,\n            optimizer=optimizer,\n            device=device,\n            save_path=MODEL_SAVE_PATH,\n            patience=NUM_EPOCHS, # 早期終了無効\n            min_delta=0.0001,\n            visualize_training_graph=True, # train,val,val_imu_only,val_mixのloss,acc,scoreの推移グラフ\n            show_progress=False, # loss,acc,scoreの進捗を表示\n            eval_interval=1, # 結果を評価するepoch頻度(学習が進んだかどうかの判断,進捗表示,グラフ描画に影響)\n            id_to_gesture=id_to_gesture)","metadata":{"execution":{"iopub.status.busy":"2025-08-18T20:11:35.390718Z","iopub.execute_input":"2025-08-18T20:11:35.391017Z","iopub.status.idle":"2025-08-18T20:12:08.041235Z","shell.execute_reply.started":"2025-08-18T20:11:35.391001Z","shell.execute_reply":"2025-08-18T20:12:08.040481Z"},"papermill":{"duration":1091.9157,"end_time":"2025-08-10T21:14:14.613716","exception":false,"start_time":"2025-08-10T20:56:02.698016","status":"completed"},"tags":[],"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"# 5. Scoring","metadata":{"papermill":{"duration":0.438833,"end_time":"2025-08-10T21:14:15.446914","exception":false,"start_time":"2025-08-10T21:14:15.008081","status":"completed"},"tags":[]}},{"cell_type":"code","source":"if is_train:\n    from utils.load_model import load_model\n    load_model(model, MODEL_SAVE_PATH, device)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-08-18T20:12:08.042097Z","iopub.execute_input":"2025-08-18T20:12:08.042530Z","iopub.status.idle":"2025-08-18T20:12:08.090237Z","shell.execute_reply.started":"2025-08-18T20:12:08.042501Z","shell.execute_reply":"2025-08-18T20:12:08.089429Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"from utils.train import evaluate\navg_val_loss, val_accuracy, competition_score = evaluate(model, val_loader, criterion, device, id_to_gesture=id_to_gesture, compute_score=True)\nprint(f\"Val Loss: {avg_val_loss:.4f}, Val Acc: {val_accuracy:.4f}\")\nprint(f\"Score: {competition_score:.4f}\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-08-18T20:12:08.091228Z","iopub.execute_input":"2025-08-18T20:12:08.091932Z","iopub.status.idle":"2025-08-18T20:12:09.934363Z","shell.execute_reply.started":"2025-08-18T20:12:08.091905Z","shell.execute_reply":"2025-08-18T20:12:09.933585Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# IMU only score\nfrom utils.train import evaluate\navg_val_loss, val_accuracy, competition_score = evaluate(model, val_loader_imu_only, criterion, device, id_to_gesture=id_to_gesture, compute_score=True)\nprint(\"IMU only\")\nprint(f\"Val Loss: {avg_val_loss:.4f}, Val Acc: {val_accuracy:.4f}\")\nprint(f\"Score: {competition_score:.4f}\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-08-18T20:12:09.935048Z","iopub.execute_input":"2025-08-18T20:12:09.935243Z","iopub.status.idle":"2025-08-18T20:12:11.777308Z","shell.execute_reply.started":"2025-08-18T20:12:09.935226Z","shell.execute_reply":"2025-08-18T20:12:11.776486Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"# 半分が IMU only\nfrom utils.train import evaluate\navg_val_loss, val_accuracy, competition_score = evaluate(model, val_loader_mix, criterion, device, id_to_gesture=id_to_gesture, compute_score=True)\nprint(\"半分が IMU only\")\nprint(f\"Val Loss: {avg_val_loss:.4f}, Val Acc: {val_accuracy:.4f}\")\nprint(f\"Score: {competition_score:.4f}\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-08-18T20:12:11.778229Z","iopub.execute_input":"2025-08-18T20:12:11.778745Z","iopub.status.idle":"2025-08-18T20:12:13.677583Z","shell.execute_reply.started":"2025-08-18T20:12:11.778724Z","shell.execute_reply":"2025-08-18T20:12:13.676831Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"# 6. submit prediction","metadata":{"papermill":{"duration":0.441105,"end_time":"2025-08-10T21:14:19.355148","exception":false,"start_time":"2025-08-10T21:14:18.914043","status":"completed"},"tags":[]}},{"cell_type":"code","source":"import torch.nn.functional as F\nfrom utils.preprocess_global import preprocess_global\nfrom utils.preprocess_sequence import preprocess_sequence\nfrom utils.dataset import Dataset1, Dataset2\n\n\ndef predict(seq, demo):\n    if type(seq) != pd.DataFrame:\n        seq = seq.to_pandas()\n        demo = demo.to_pandas()\n\n    seq, demo = preprocess_global(seq, demo, have_labels=False)\n    test_dataset_eda = Dataset1(demo, seq, preprocess=preprocess_sequence)\n    test_dataset = Dataset2(test_dataset_eda)\n\n    test_loader = DataLoader(test_dataset, batch_size=BATCH_SIZE, shuffle=False, collate_fn=custom_collate_fn, num_workers=NUM_WORKERS)\n    demo_data, seq_data, _ = next(iter(test_loader))\n\n    demo_data, seq_data = demo_data.to(device), seq_data.to(device)\n    outputs = model(demo_data, seq_data)\n\n    # 1. ロジットをSoftmaxにかけて確率に変換\n    # dim=1 はクラスの次元を指定\n    probabilities = F.softmax(outputs, dim=1)\n    \n    # 2. 最も確率の高いクラスのインデックス（ID）を取得\n    # .argmax(dim=1) で各サンプルの最大値のインデックスを取得\n    # .item() でテンソルからPythonのスカラ値に変換\n    predicted_id = torch.argmax(probabilities, dim=1).item()\n    \n    # 3. 逆引き辞書を使って文字列に変換\n    predicted_gesture = id_to_gesture[predicted_id]\n\n    return predicted_gesture","metadata":{"execution":{"iopub.status.busy":"2025-08-18T20:12:13.678484Z","iopub.execute_input":"2025-08-18T20:12:13.679016Z","iopub.status.idle":"2025-08-18T20:12:13.684815Z","shell.execute_reply.started":"2025-08-18T20:12:13.678989Z","shell.execute_reply":"2025-08-18T20:12:13.684106Z"},"papermill":{"duration":0.451471,"end_time":"2025-08-10T21:14:20.198907","exception":false,"start_time":"2025-08-10T21:14:19.747436","status":"completed"},"tags":[],"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import os\n\ninference_server = kaggle_evaluation.cmi_inference_server.CMIInferenceServer(predict)\n\nif os.getenv('KAGGLE_IS_COMPETITION_RERUN'):\n    inference_server.serve()\nelse:\n    inference_server.run_local_gateway(\n        data_paths=(\n            '/kaggle/input/cmi-detect-behavior-with-sensor-data/test.csv',\n            '/kaggle/input/cmi-detect-behavior-with-sensor-data/test_demographics.csv',\n        )\n    )","metadata":{"execution":{"iopub.status.busy":"2025-08-18T20:12:13.687371Z","iopub.execute_input":"2025-08-18T20:12:13.687548Z","iopub.status.idle":"2025-08-18T20:12:15.851057Z","shell.execute_reply.started":"2025-08-18T20:12:13.687534Z","shell.execute_reply":"2025-08-18T20:12:15.850461Z"},"papermill":{"duration":1.875807,"end_time":"2025-08-10T21:14:22.459089","exception":false,"start_time":"2025-08-10T21:14:20.583282","status":"completed"},"tags":[],"trusted":true},"outputs":[],"execution_count":null},{"cell_type":"code","source":"","metadata":{"trusted":true},"outputs":[],"execution_count":null}]}