Inertia-1 is an open exploration of wearable motion foundation models. Motion sensing is fragmented — datasets disagree on sampling rate, window length, sensor modality, body placement, and even signal format, and nearly every task gets its own bespoke model. Inertia-1 studies the full lifecycle of motion models (data, sensing, objectives, and scale) inside a single, controlled space, asking whether one self-supervised representation learned from raw accelerometry can transfer across the body, devices, and downstream tasks.
- [2026-09-28] Inertia-1 is accepted at NeurIPS 2026!
- [2026-07-06] Project website is live!
- [2026-07-06] Code released on GitHub!
- [2026-07-06] Paper release on arXiv.
- Self-supervised pretraining on raw accelerometry, with the key exploration axes exposed as first-class knobs (uniaxial vs. triaxial, sampling rate, window length).
- Downstream evaluation on human-activity-recognition (HAR) and freezing-of-gait (FoG) datasets via linear probing / full finetuning.
- Patient-level disease & medication detection via attention-based multiple-instance learning (MIL) on frozen embeddings.
motion-fm/
├── inertia1/ # the core package (pip install -e .)
│ ├── run.py # unified entry: pretrain + HAR/FoG finetune
│ ├── config/ # layered YAML configs
│ │ ├── default.yaml
│ │ ├── methods/{ar_transformer,patchtst}.yaml
│ │ └── presets/{small,medium,large}.yaml
│ ├── data/ # pretraining datamodule (subject-grouped windows)
│ ├── methods/ # registry + ar_transformer / patchtst modules
│ ├── models/backbones/patchtst # PatchTST backbone
│ ├── augmentations/ # patch masking
│ ├── eval/ # HAR/FoG downstream probe + split generator
│ │ ├── motion_linear_probe.py
│ │ └── motion_split_analysis.py # generate your own frozen splits
│ └── scripts/eval_nhanes_labels.py # patient-level MIL disease detection
├── motion_dataloader.py # HAR/FoG dataset + windowing + split loading
├── scripts/
│ ├── pretrain/ # pretrain_{ar_transformer,patchtst}.sh
│ ├── eval/eval_motion.sh # HAR/FoG evaluation
│ ├── disease_detection/ # disease MIL eval + placeholder-data generator
│ └── preprocessing/ # HAR/FoG dataset preprocessing (har/, fog/, docs/)
├── pyproject.toml
└── requirements.txt
python -m pip install -e . # reads pyproject.toml
# or: python -m pip install -r requirements.txtPython ≥ 3.10. A CUDA-capable GPU is recommended for pretraining.
Entry point: python -m inertia1.run with layered configs. The three exploration
axes are plain data.* overrides, so a single command covers any ablation:
| Axis | Override | Values |
|---|---|---|
| Window length | data.window_sec |
e.g. 10, 30, 60 |
| Sampling rate | data.hz |
any divisor of data.native_hz (e.g. 20, 10, 5, 1) |
| Uniaxial vs. triaxial | data.axes |
3 (X/Y/Z) or 1 (L2 magnitude, via data.axis_reduce) |
# Triaxial, 30 s @ 20 Hz, small AR-Transformer
DATA_ROOT=./data/pretrain bash scripts/pretrain/pretrain_ar_transformer.sh
# Uniaxial, 60 s @ 10 Hz, PatchTST
WINDOW_SEC=60 HZ=10 AXES=1 DATA_ROOT=./data/pretrain \
bash scripts/pretrain/pretrain_patchtst.sh
# Or call the launcher directly
python -m inertia1.run \
--config inertia1/config/default.yaml \
--config inertia1/config/methods/ar_transformer.yaml \
--config inertia1/config/presets/small.yaml \
run.stage=pretrain data.window_sec=30 data.hz=20 data.axes=3 \
data.data_root=./data/pretrainModel size is set by the preset (small / medium / large).
We pretrained on NHANES accelerometry. NHANES raw accelerometer data is publicly available but governed by its own usage terms, so we do not redistribute it here.
- Download: NHANES (CDC/NCHS)
- Preprocessing: we convert raw NHANES into the per-subject parquet layout using the UKBB-style accelerometer preprocessing pipeline (UK Biobank).
Expected on-disk layout (point data.data_root here):
<data_root>/<subject_id>/**/*.parquet # columns: X, Y, Z (native 20 Hz)
An optional subject-level split CSV (data.split_csv, columns
patient_id,split with split ∈ {train,val}) keeps memory bounded on large
corpora.
We evaluate frozen (linear probe) or finetuned backbones on public HAR and FoG
datasets. The interesting, reusable part is the dataloader
(motion_dataloader.py): per-dataset windowing, label mapping, placement
selection, and frozen, subject-grouped splits. Everything else (the
probe/finetune loop) is deliberately small.
Frozen splits are not shipped (they are derived from non-redistributable
datasets). After preprocessing your own data copies, generate splits with
inertia1/eval/motion_split_analysis.py, then point the evaluation at them:
METHOD=ar_transformer MODE=linear_probe \
CKPT_PATH=./outputs/<run>/checkpoints/last.ckpt \
DATA_ROOT=./data/downstream \
SPLIT_DIR=./splits \
bash scripts/eval/eval_motion.shDatasets covered: wisdm, HHAR, harth, har70plus, PAMAP2_Dataset,
MHEALTHDATASET, OpportunityUCIDataset, wear_dataset, Recofit,
capture24_willetts (HAR) and daphnet_fog, OdayFoG, FoGTurning (FoG).
These datasets are also not redistributable. Download each from its original
source and preprocess into the canonical 20 Hz parquet layout with the scripts
in scripts/preprocessing/:
<data_root>/<dataset_name>/processed/*.parquet
The preprocessing pipeline (resampling, gap handling, label alignment, filename contracts) is fully documented there.
We detect patient-level outcomes (e.g. depression severity, sleep complaints, medication use) by pooling a bag of a patient's accelerometer windows through a positional attention MIL head on top of a frozen backbone.
Internally this runs on NHANES (closed-source, as above), so we ship a
generic placeholder-data loader and keep patient/bag construction high
level. The real pipeline builds per-day bags keyed on wear-time over a fixed 24 h
grid; the shipped loader places each patient's windows onto a fixed grid of
bag_size slots with a learned "missing slot" embedding — the same MIL
mechanics, without NHANES-specific internals.
Run it end-to-end on synthetic placeholder data:
# 1) generate a tiny synthetic dataset (noise; smoke-test only)
python scripts/disease_detection/make_placeholder_data.py --out ./data/disease
# 2) train the MIL probe on a frozen backbone
CKPT_PATH=./outputs/<run>/checkpoints/last.ckpt \
bash scripts/disease_detection/eval_disease.shPlaceholder data format:
<data_root>/<patient_id>.npy # float array [N_windows, C, T]
labels.csv # patient_id,label
split.csv # patient_id,split (train/val/test)
To use real data, replace the placeholder files with your own in this format. NHANES download / preprocessing pointers are the same as in Pretraining data.
If you use Inertia-1 in your research, please cite the paper:
@inproceedings{xu2026inertia1,
title={Inertia-1: An Open Exploration of Wearable Motion Foundation Models},
author={Xu, Zongzhe and Anand, Aakarsh and Jiang, Sarah and Zhuang, Chuntung and Shuai, Zitao and Sankararaman, Sriram and Yang, Yuzhe},
booktitle={Advances in Neural Information Processing Systems (NeurIPS)},
year={2026}
}This project is licensed under the MIT License - see the LICENSE file for details.