Detailed walkthrough of the three-stage modeling path for predicting per-stroke force curves from video-derived biomechanics. Each stage builds on the last; earlier stages establish floors and baselines that later stages must clear.
TTarget Representation — How Force Curves Are Encoded
Before any model is trained, force curves must be encoded into a learnable form. Two representations are maintained in parallel: direct curve bins (full fidelity) and a low-dimensional shape (compact, smooth, interpretable). The low-dimensional target is either standard PCA on peak-normalized curves or functional PCA (B-spline basis → PCA on coefficients), selectable at dataset-build time via --target-representation {standard, fpca, both}. Stage A models predict the chosen coefficients; Stage B models predict full curves directly.
Force curve target encoding: raw curves → peak-normalized → PCA coefficients (20 components)
Direct bins
Full-fidelity force values at each s-grid point. Used by Stage B sequence models. Masked loss handles variable stroke lengths.
PCA shape
~20 coefficients capture >95% of curve variance. Compact target for Stage A scalar models. Smooth, denoised reconstruction.
Functional PCA option
functional_pca.py projects each curve onto a cubic B-spline basis, then runs PCA on the basis coefficients. Drop-in replacement for standard PCA; chosen per-run with --target-representation fpca.
Artifacts
Either pca_model.joblib or fpca_model.joblib is written alongside s_grid.npy in the training dataset and copied into the inference model bundle.
0Sanity Baselines — The Floor Every Model Must Clear
Before training any biomechanics model, establish two baselines. 0a measures how reproducible force curves are within the same conditions (the irreducible floor). 0b tests how much simple metadata alone can predict. Any model using kinematics must beat 0b on all metrics.
Stage 0: establish the reproducibility floor (0a) and metadata-only prediction baseline (0b)
Why this matters
If force curves are already very consistent within conditions, even a naive model looks good. The reproducibility floor prevents us from over-claiming.
Baseline gate
Stroke rate and length alone explain some force curve shape. Any biomechanics model that fails to beat metadata-only has no justification for its complexity.
AInterpretable Kinematic Models — Do Biomechanics Add Value?
Use stroke-level scalar features (summary statistics + coordination) to predict force-curve PCA (or fPCA) coefficients. Classical ML models that support feature importance analysis. The goal is to verify biomechanics add value beyond metadata and to identify which features dominate. The canonical feature contract (6 unilateral/central angles including head_vs_trunk_deg with mirror normalization) lives in inference/feature_contract.py; Stage A summaries and coordination scalars are assembled in inference/build_training_dataset.py.
Stage A: stroke-level scalar features → classical ML → PCA / fPCA force-curve coefficients
Interpretability
Ridge/Lasso coefficients and tree feature importances directly reveal which biomechanics features drive force curve shape changes.
Must-beat gate
If Stage A cannot beat Stage 0b (metadata-only), there is no evidence that kinematics explain force beyond what stroke rate/length already capture.
BSequence Models — Capturing Full Stroke Dynamics
Use the full progress-aligned kinematic sequences as input. The model sees how joint angles and their derivatives evolve continuously over the drive, capturing nonlinear cross-joint interactions that scalar summaries lose.
Stage B: full kinematic sequence (64×12) → temporal model → predicted force curve (64 bins)
No PCA bottleneck
Stage B predicts the full force curve directly. No information is lost to PCA truncation. The model can capture subtle curve details that PCA misses.
Scalar conditioning
Stroke rate, drive ratio, and (optionally, via --stageB-use-coordination) onset/lag/range-fraction scalars are broadcast as constant extra channels over the s-axis, giving the sequence model global context without a separate head.
Masked + derivative losses
Pointwise MSE is masked to the per-stroke valid force bins; an optional derivative regularizer (--stageB-lambda-deriv) penalizes jaggy predictions when curve smoothness is pathological.
Portable artifacts
Every Stage B run saves state.pt + arch_config.json + feature_norm.npz + target_norm.npz. export_model_bundle.py combines these with the (f)PCA model and Stage A estimator into a self-describing model_bundle/ consumed by predict_force_cli.py.
EEvaluation Protocol — Validation Splits and Metrics
All stages are evaluated on the same held-out strokes using the same metrics. Curve-level statistics (RMSE, correlation) catch gross errors; rowing-relevant metrics (peak force, peak position, impulse) validate that the model gets the things coaches care about right.
Evaluation: consistent splits and metrics across all stages for fair comparison
Stage progression gate: each stage must improve on the previous stage's metrics. If Stage A fails to beat Stage 0, Stage B is not justified.
Cross-representation report
Every run annotates its metrics with target_representation (standard / fpca) and stage_b_arch (tcn / transformer). write_evaluation_report groups and compares results across representations and architectures, merging prior-run artifacts in the same output directory for cumulative comparison.
Architecture-suffixed artifacts
Stage B saves architecture-suffixed copies (e.g. stage_b_tcn.pt, stage_b_transformer.pt) alongside canonical names, so the report can compare TCN and Transformer on the same held-out strokes without clobbering either.