{"metadata":{"kernelspec":{"display_name":"Python 3","language":"python","name":"python3"},"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":"gpu","dataSources":[{"sourceId":102335,"databundleVersionId":12518947,"sourceType":"competition"},{"sourceId":491776,"sourceType":"modelInstanceVersion","isSourceIdPinned":true,"modelInstanceId":388379,"modelId":407328}],"dockerImageVersionId":31090,"isInternetEnabled":false,"language":"python","sourceType":"notebook","isGpuEnabled":true}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"markdown","source":"# <div style=\"text-align: center; color: cyan\">IMU Transformer TCN</div>","metadata":{}},{"cell_type":"markdown","source":"I'm currently planning to get the best results I can from IMU.\nBecause, as said in the overview section, 50% of the data is only IMU.\n","metadata":{}},{"cell_type":"markdown","source":"My approach to training the model was to first use k-fold to split the data into train and validation.\nThen, find the best number of epochs.\nAfter that, train my model with that number of epochs on all data.","metadata":{}},{"cell_type":"markdown","source":"All the code is available in the model attached to this notebook, including the train_script.\nI use so many util files, so to manage them, I upload my code alongside the model parameters and scaler parameters to a model to use them.","metadata":{}},{"cell_type":"markdown","source":"## <div style=\"text-align: center; color: lime\">Setup</div>","metadata":{}},{"cell_type":"code","source":"%load_ext autoreload\n%autoreload 2","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-07-27T06:24:28.924056Z","iopub.execute_input":"2025-07-27T06:24:28.924771Z","iopub.status.idle":"2025-07-27T06:24:28.941729Z","shell.execute_reply.started":"2025-07-27T06:24:28.924738Z","shell.execute_reply":"2025-07-27T06:24:28.941023Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"import os\n\nos.environ[\"PYTORCH_ENABLE_MPS_FALLBACK\"] = \"1\"","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-07-27T06:24:30.123794Z","iopub.execute_input":"2025-07-27T06:24:30.124331Z","iopub.status.idle":"2025-07-27T06:24:30.137162Z","shell.execute_reply.started":"2025-07-27T06:24:30.124308Z","shell.execute_reply":"2025-07-27T06:24:30.136545Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"if os.getenv(\"KAGGLE_IS_COMPETITION_RERUN\"):\n    MACHINE = \"KAGGLE_COMPETITION\"\nelif \"KAGGLE_KERNEL_INTEGRATIONS\" in os.environ:\n    MACHINE = \"KAGGLE\"\nelif os.getenv(\"COLAB_RELEASE_TAG\"):\n    MACHINE = \"COLAB\"\nelse:\n    MACHINE = \"PC\"\n\nprint(f\"MACHINE: {MACHINE}\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-07-27T06:24:31.012117Z","iopub.execute_input":"2025-07-27T06:24:31.012418Z","iopub.status.idle":"2025-07-27T06:24:31.026778Z","shell.execute_reply.started":"2025-07-27T06:24:31.012397Z","shell.execute_reply":"2025-07-27T06:24:31.026089Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"if \"KAGGLE\" in MACHINE:\n    import sys\n    CODE_PATH = \"/kaggle/input/a1_tcnt_2/pytorch/default/6\"\n\n    sys.path.append(CODE_PATH)\nelif \"COLAB\" in MACHINE:\n    import kagglehub\n    import sys\n    from pathlib import Path\n\n    path = Path(kagglehub.dataset_download(\"literallytheone/cmi-sensor-kaggle-utils\"))\n\n    path = str(path / \"cmi_sensor_kaggle-0.1.4\")\n\n    sys.path.append(path)\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-07-27T06:24:31.563985Z","iopub.execute_input":"2025-07-27T06:24:31.564823Z","iopub.status.idle":"2025-07-27T06:24:31.578615Z","shell.execute_reply.started":"2025-07-27T06:24:31.564788Z","shell.execute_reply":"2025-07-27T06:24:31.578062Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"## <div style=\"text-align: center; color: lime\">Imports</div>","metadata":{}},{"cell_type":"code","source":"from cmi_sensor_kaggle.models.transformer_tcn import TransformerTCN\nfrom cmi_sensor_kaggle.utils.predicts import predict_sequence\n\nfrom cmi_sensor_kaggle.utils.data_preparation import (\n    DropUnnecessaryColumns,\n    FillNulls,\n    ShrinkSequence,\n    SortData,\n    AddGlobalFeatures,\n    AddMagnitude,\n    NormalizeScaler,\n)\nfrom cmi_sensor_kaggle.utils.transforms import (\n    TTCNTransform,\n    NormalTargetTransform,\n)\nfrom cmi_sensor_kaggle.configs.tcnt_weight_global.a1_tcnt_d_model_128_shrink_0_all import TransformTcnGlobalFeaturesConfig3\n\nimport polars as pl\n\nimport torch\n\nfrom omegaconf import OmegaConf\n\nfrom pathlib import Path\n\nimport joblib\n\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-07-27T06:24:34.925156Z","iopub.execute_input":"2025-07-27T06:24:34.925467Z","iopub.status.idle":"2025-07-27T06:24:40.262301Z","shell.execute_reply.started":"2025-07-27T06:24:34.925444Z","shell.execute_reply":"2025-07-27T06:24:40.261723Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"## <div style=\"text-align: center; color: lime\">Config</div>","metadata":{}},{"cell_type":"code","source":"cfg = OmegaConf.structured(TransformTcnGlobalFeaturesConfig3)\nprint(OmegaConf.to_yaml(cfg))","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-07-27T06:24:40.263198Z","iopub.execute_input":"2025-07-27T06:24:40.263495Z","iopub.status.idle":"2025-07-27T06:24:40.303272Z","shell.execute_reply.started":"2025-07-27T06:24:40.263478Z","shell.execute_reply":"2025-07-27T06:24:40.302678Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"if torch.accelerator.is_available():\n    DEVICE = torch.accelerator.current_accelerator().type  # type: ignore\nelse:\n    DEVICE = \"cpu\"\n\nprint(f\"device: {DEVICE}\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-07-27T06:24:47.585560Z","iopub.execute_input":"2025-07-27T06:24:47.585816Z","iopub.status.idle":"2025-07-27T06:24:47.713528Z","shell.execute_reply.started":"2025-07-27T06:24:47.585797Z","shell.execute_reply":"2025-07-27T06:24:47.712881Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"if \"KAGGLE\" in MACHINE:\n    scalar = joblib.load(f\"{CODE_PATH}/scaler.pkl\")\nelif \"COLAB\" in MACHINE:\n    scalar = joblib.load(\"../scripts/scalers/scaler_a1_tcnt_d_model_128_all_0.pkl\")\nelse:\n    scalar = joblib.load(\"../scripts/scalers/a1_tcnt_d_model_128_all_3_scaler.pkl\")","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-07-27T06:24:47.871330Z","iopub.execute_input":"2025-07-27T06:24:47.871588Z","iopub.status.idle":"2025-07-27T06:24:47.904919Z","shell.execute_reply.started":"2025-07-27T06:24:47.871568Z","shell.execute_reply":"2025-07-27T06:24:47.904069Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"prs = [\n    DropUnnecessaryColumns.from_config(cfg),\n    FillNulls.from_config(cfg),\n    ShrinkSequence.from_config(cfg),\n    SortData.from_config(cfg),\n    AddGlobalFeatures.from_config(cfg),\n    AddMagnitude.from_config(cfg),\n    NormalizeScaler.from_config(cfg, scalar),\n]\n\nval_transforms = [\n    TTCNTransform.from_config(cfg),\n]\n\ntarget_transform = NormalTargetTransform.from_config(cfg)\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-07-27T06:24:48.421520Z","iopub.execute_input":"2025-07-27T06:24:48.421783Z","iopub.status.idle":"2025-07-27T06:24:48.448156Z","shell.execute_reply.started":"2025-07-27T06:24:48.421763Z","shell.execute_reply":"2025-07-27T06:24:48.447662Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"## <div style=\"text-align: center; color: lime\">Load model</div>","metadata":{}},{"cell_type":"code","source":"if \"KAGGLE\" in MACHINE:\n    model_path = Path(f\"{CODE_PATH}/model.pt\")\nelif MACHINE == \"COLAB\":\n    import kagglehub\n\n    model_path = Path(\n        kagglehub.model_download(\"literallytheone/a1_tcnt_1/pyTorch/default\")) / \"best_model_13_f10.5573.pt\"\nelse:\n    model_path = Path(\n        \"../scripts/checkpoints/a1_tcnt_d_model_128_all_3/best_model_53_f1=0.6386.pt\"\n    )","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-07-27T06:24:51.036282Z","iopub.execute_input":"2025-07-27T06:24:51.036949Z","iopub.status.idle":"2025-07-27T06:24:51.062280Z","shell.execute_reply.started":"2025-07-27T06:24:51.036926Z","shell.execute_reply":"2025-07-27T06:24:51.061668Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"model = TransformerTCN.from_config(cfg)\nmodel = model.to(DEVICE)\nmodel.load_state_dict(torch.load(model_path, map_location=DEVICE))\nprint(model)","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-07-27T06:24:51.541395Z","iopub.execute_input":"2025-07-27T06:24:51.541686Z","iopub.status.idle":"2025-07-27T06:24:51.810276Z","shell.execute_reply.started":"2025-07-27T06:24:51.541666Z","shell.execute_reply":"2025-07-27T06:24:51.809622Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"## <div style=\"text-align: center; color: lime\">For Kaggle</div>","metadata":{}},{"cell_type":"code","source":"def predict(sequence: pl.DataFrame, demographics: pl.DataFrame) -> str:\n    return predict_sequence(\n        sequence=sequence,\n        model=model,\n        prs=prs,\n        transforms=val_transforms,\n        label_int_to_category=target_transform.label_int_to_category,\n        device=DEVICE,\n    )","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-07-27T06:24:55.073399Z","iopub.execute_input":"2025-07-27T06:24:55.073873Z","iopub.status.idle":"2025-07-27T06:24:55.099271Z","shell.execute_reply.started":"2025-07-27T06:24:55.073851Z","shell.execute_reply":"2025-07-27T06:24:55.098537Z"}},"outputs":[],"execution_count":null},{"cell_type":"code","source":"if \"KAGGLE\" in MACHINE:\n    import kaggle_evaluation.cmi_inference_server\n\n    inference_server = kaggle_evaluation.cmi_inference_server.CMIInferenceServer(\n        predict\n    )\n\n    if MACHINE == \"KAGGLE_COMPETITION\":\n        inference_server.serve()\n    elif MACHINE == \"KAGGLE\":\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        )\nelse:\n    if MACHINE == \"COLAB\":\n        import kagglehub\n\n        root_data_path = Path(\n            kagglehub.competition_download(\"cmi-detect-behavior-with-sensor-data\")\n        )\n    else:\n        root_data_path = Path(\n            \"/Users/ramin/.cache/kagglehub/competitions/cmi-detect-behavior-with-sensor-data\"\n        )\n\n    df_test = pl.read_csv(root_data_path / \"test.csv\")\n    sequences_test = df_test.group_by(\"sequence_id\").all()\n    for i in range(sequences_test.shape[0]):\n        sequence = sequences_test[i]\n        sequence = sequence.explode(pl.all().exclude(\"sequence_id\"))\n        result = predict(\n            sequence=sequence,\n            demographics=None,\n        )\n        print(result)\n","metadata":{"trusted":true,"execution":{"iopub.status.busy":"2025-07-27T06:24:55.471300Z","iopub.execute_input":"2025-07-27T06:24:55.471962Z","iopub.status.idle":"2025-07-27T06:24:58.263448Z","shell.execute_reply.started":"2025-07-27T06:24:55.471939Z","shell.execute_reply":"2025-07-27T06:24:58.262849Z"}},"outputs":[],"execution_count":null},{"cell_type":"markdown","source":"<p style=\"text-align: center; font-family: \"Trebuchet MS\", sans-serif; color: #888; font-size: 0.9em; margin-top: 2em; border-top: 1px solid #ccc; padding-top: 0.5em;\">\n    @LiterallyTheOne — PhD Candidate in Artificial Intelligence\n</p>\n\n<div style=\"text-align: center\">\n<a style=\"margin: 1em\" href=\"https://literallytheone.github.io\">https://literallytheone.github.io</a>\n</div>\n","metadata":{}}]}