VoriaSolutions · 2026

A wearable rhythm-risk model

A small model that flags risky heart-rhythm patterns from a wrist sensor, designed around the INT8 toolchain that has to compile it for an edge health hub.

Goal

The hub reads beat-to-beat intervals, PPG and motion from a Polar Verity Sense on the wrist. It has to flag risky rhythm patterns on the device itself and pass the result to the microcontroller that drives the display and the alarm, so the model had to fit the hub's runtime and survive full-INT8 export.

What I built

Data

I wrote the recording protocol and the script that runs the hub's collector on the board itself, and built up about three weeks of beat-interval, PPG and motion recordings.

Inputs and labels

The model sees 32-second windows of beat intervals resampled to 4 Hz, with motion and a rolling heart-rate-variability measure as extra channels. Labels come from seven heart-rate-variability rules, such as an AF-like irregularity rule and slow or fast heart rates, rather than from clinicians.

Experiments

Over dozens of tracked runs I tried distillation from a forecasting foundation model, self-supervised pretraining, extra public data, label smoothing and mixup. None beat plain training on the rule labels, so the final model is the simple one.

Letting the toolchain choose the head

The first model ended in a bidirectional GRU. Its TFLite export carried loop operators, INT8 quantization of it crashed, and the SNPE converter rejects loops. Replacing the GRU with a fourth depthwise-separable block and global average pooling left a model built only from operators that INT8 TFLite supports.

Model diagram: beat intervals, motion and heart-rate variability from a wrist sensor pass through four depthwise-separable convolution blocks, global average pooling and dense layers to a risk score; a recurrent head was removed because it could not be exported to INT8.
The final model, and the recurrent head it replaced.

Evaluation and export

Windows from the same day are strongly correlated, so models were compared on whole held-out days, with leave-one-day-out cross-validation for the baseline. Export fixes the batch size and calibrates full-INT8 quantization on representative windows, with int8 input and output.

Result

The convolution-only model has fewer than half the parameters of the recurrent one, fits in about 23 KB as a full-INT8 model, and scored higher on the same held-out day (AUC 0.76 against 0.74).

What I learned

  • Designing a model around its deployment toolchain: which layers survive INT8 quantization and vendor conversion, and why recurrent layers often don't.
  • Evaluating on correlated time series by holding out whole days instead of random windows.
  • Running many experiments with tracking and ablations, and dropping ideas that don't pay off.
  • Signal processing for wearables: beat intervals, heart-rate variability features and motion.