Back to scan

PULSE LAB / SpO₂ EXPERIMENT 01

Archived first attempt, superseded before publication. Current neural model report.

A trained model.
Accuracy remains limited.

Actual training run · 5 October 2026 · Hoffman camera RGB dataset · participant-held-out evaluation.

6participants, kept separate between folds
1,908nonoverlapping six-second RGB windows
6.38 pppooled held-out mean absolute error
Research output only. At reference SpO₂ below 80%, the deployed ratio model overestimated by 11.50 percentage points on average. Its 90th percentile absolute error across all windows was 13.04 points. It cannot provide dependable low-oxygen screening or reassurance. Your iPhone and browser have not been tested.

What was trained

Two candidates were fitted: a regularized regression on three log RGB pulse-amplitude ratios, and a compact residual temporal convolutional network with an RGB waveform encoder and an SpO₂ head. The constant baseline predicts the median training label. The ratio model had the lowest overall error and is used by the website; the CNN is retained as a research candidate.

Ratio regression improves pooled MAE by only 0.37 points (5.5%) over the constant baseline. This is a modest improvement. No confidence or clinical-validation claim follows from it.

Errors on unseen participants

Lower is better. All errors are SpO₂ percentage points; 95% versus 90% differs by 5 points.

RGB ratio regression · initial candidate
6.38
Residual temporal CNN · candidate
7.39
Training-median baseline
6.75
ModelMAERMSESigned biasMean participant MAE
RGB ratio regression · initial candidate6.387.81-0.206.39
Residual temporal CNN · candidate7.399.81+2.117.36
Training-median baseline6.758.13+1.176.82

The model family was chosen after comparing these same folds. Selection is exploratory; an untouched external cohort is still required. Metrics describe individual source-data windows, before the website’s additional provisional signal gates and averaging.

Performance across oxygen ranges

Reference SpO₂WindowsRatio MAERatio bias
70 to <80%34611.50+11.50
80 to <90%6183.72+2.23
90 to 100%9446.24-6.07

Positive bias means overestimation. The model tends toward the middle of the training range and performs poorly near its extremes.

Every participant held out once

Test participantWindowsRatio MAECNN MAEConstant MAE
1000013187.5614.827.75
1000023717.507.736.34
1000033525.594.876.59
1000043364.755.485.33
1000052846.205.207.26
1000062476.726.087.63

Training and evaluation protocol

  1. Use the public per-frame R, G and B means at nominal 30 Hz. Keep both hands from a participant in the same fold.
  2. Discard the first six seconds of every recording, then create six-second windows without overlap. Exclude windows with missing labels, any reference outside 70–100%, invalid RGB, unusable mean exposure, or essentially absent channel variation. No patient-specific calibration or label-guided timing adjustment is used.
  3. Use the mean of six corresponding 1 Hz readings from the dataset’s Masimo SpO2 5 reference. Alignment follows the repository’s simultaneous-start assumption; timing and averaging lag remain limitations.
  4. Remove each RGB channel’s DC level and linear trend. Preserve relative pulse amplitudes: 100 × (RGB / channel mean − 1 − trend). Derive log AC/DC RMS ratios R/G, R/B and G/B. These visible-light camera channels are not a calibrated red/infrared pulse oximeter.
  5. For each outer test participant, select CNN epochs using a different validation participant and the remaining four for fitting. Refit on all five non-test participants using that epoch count. Fit ratio scaling and regression only on those five. No outer test participant enters training, scaling or epoch selection.
  6. Refit deployment weights on all six participants. The CNN uses 34 epochs selected from the median inner-fold epoch count. Deployed ratio regression uses fixed ridge penalty 10. The final all-data fit has no separate test cohort.

What happens on the phone

The camera’s whole-frame RGB means are sampled separately from the existing BP region. Six-second contiguous segments are resampled using measured timestamps. SpO₂ uses all three channels and its own flash, clipping, timing, pulse-variation and training-ratio checks. Three accepted segments produce an experimental average. Rejected segments and gaps are not joined.

Inference runs in the browser. Scans stay in the current tab until exported; this change adds no upload endpoint. A clear waveform, a stable output or a narrow segment range does not establish accuracy. The displayed waveform and later-entered cuff values do not enter SpO₂ inference. BP and SpO₂ retain independent models and validation.

Software verification

Python and browser JavaScript agreed on all 6 exported parity cases. Maximum difference was 0.000000586 points for regression and 0.000001462 for the CNN. These cases test implementation equivalence and were part of the final fit; they are not held-out accuracy evidence.

Checks passed for missing models, flash off, invalid timing, clipped/flat/nonfinite RGB, frame gaps, out-of-domain ratios, real RGB replay, segment separation, contact resets and expiry. Existing simulated camera/BP flows also passed. Physical iPhone capture and browser rendering were not tested in this run.

Known limits

The present run does not implement a jointly trained BP/SpO₂/glucose encoder. The neural candidate is an initial RGB encoder plus SpO₂ head; the better-performing ratio model is the deployed baseline. Personalization remains future work requiring paired, later-session reference data.

Sources and reproducibility

Official Hoffman dataset · Hoffman et al., 2022 · MIT license and attribution

Paper: Smartphone camera oximetry in an induced hypoxemia study, npj Digital Medicine 5, 146. This run is a new baseline implementation; the paper’s reported metrics are not substituted for our measurements.

Dataset commit: c483ae8fe4cd32b0b9ce412d07299b05279fc58f · seed 20261005 · deployed model spo2-hoffman-ratio-20261005.