Skip to content

Latest commit

 

History

1 Commit

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Physiological Signal Foundation Models (PPG + BCG)

Portfolio implementation aligned with a Machine Learning Engineer — Physiological Signal Foundation Models role: self-supervised pretraining on PPG/BCG windows, signal-quality assessment, and a downstream vital (heart rate), with subject-independent evaluation.

Synthetic paired PPG+BCG is the default so the repo trains offline. Swap in public corpora through ppgfm.data.real when you have licensed files.

What this covers

Role requirement Where it lives
Foundation / representation learning Contrastive SimCLR on fused embeddings (ppgfm.models.ssl)
Signal processing + time-series Bandpass, windowing, SQI, cardiac-band PSD (ppgfm.signal)
Computer vision + multimodal Log-STFT CNN fused with 1D PPG and 1D BCG encoders
Quality assessment Morphological/spectral SQI + linear probe (QualityHead)
Downstream health task Heart-rate regression from the frozen SSL backbone
Robust pipelines Subject-wise splits, config-driven train/eval, NPZ export

Architecture

PPG waveform ──► 1D Conv / Patch Transformer ─┐
BCG waveform ──► 1D Conv / Patch Transformer ─┼─► fuse ─► embedding
PPG STFT     ──► 2D CNN (spectrogram)        ─┘
                                              ├─► SimCLR projector (pretrain)
                                              ├─► quality classifier (poor / acceptable / good)
                                              └─► HR regressor (bpm)

SSL views use gain, Gaussian noise, respiratory-like baseline wander, and random time crop-and-resize. Spectrograms are recomputed on each view so the vision branch sees the same augmentation.

Quick start

Python 3.10+ recommended. CPU is enough for configs/demo.yaml (a few minutes). If pytest stalls on import, GPU driver init is usually the cause; the test config already forces CPU.

cd "C:\Users\Ebi-Mhdl\Desktop\PPG Machin Learning"
python -m pip install -e ".[dev]"
python scripts/demo.py --config configs/demo.yaml
python -m pytest -q

scripts/demo.py generates a synthetic cohort, pretrains the backbone, linear-probes quality and HR, and writes:

  • outputs/demo/ssl_backbone.pt
  • outputs/demo/metrics.json
  • outputs/demo/example_windows.png
  • outputs/demo/synthetic_windows.npz

On a CPU demo run: SSL loss 2.74 → 1.86; held-out quality accuracy ~0.96 / macro-F1 ~0.94; HR MAE ~6.4 bpm. These numbers are synthetic and subject-split; they are a pipeline check, not a clinical claim.

Longer training (still synthetic):

python scripts/train_ssl.py --config configs/default.yaml
python scripts/train_downstream.py --config configs/default.yaml --ckpt outputs/default/ssl_backbone.pt --task quality
python scripts/train_downstream.py --config configs/default.yaml --ckpt outputs/default/ssl_backbone.pt --task hr

Set model.encoder_type: patch in a config to use a patch-time Transformer instead of the 1D CNN.

Evaluation rule that matters

Windows from the same subject never cross train/val/test. Random window splits leak identity (pulse morphology, sensor coupling) and overstate foundation-model quality. tests/test_splits.py locks this in.

Interview map

Why PPG and BCG together. PPG is an optical peripheral pulse; BCG is mechanical cardiac motion. They share a cardiac timeline but fail differently (motion vs contact vs perfusion). A foundation model that still works when one modality is noisy is the product story.

Why spectrograms. A log-STFT is a 2D image of the same physiology. The CNN branch is the computer-vision / multimodal bullet: time-frequency structure (HR harmonic, motion bands) that a 1D net can underuse.

Quality before vitals. Downstream HR/AF/sleep models must know when a window is unusable. SQI features (perfusion, relative cardiac power, template correlation) are the classical baseline; the SSL embedding is the learned replacement.

Foundation-model protocol. Unlabeled (or weakly labeled) pretrain → freeze encoder → linear probe. If the probe works, the embedding is the asset. Fine-tune only after the probe is honest.

What a hiring manager may ask next. Device shift, missing-modality tokens, longer context, masked modeling vs contrastive, leakage via overlapping windows, and how you would attach AF or BP heads without retraining the backbone.

Real data

ppgfm.data.real.records_from_arrays accepts already-windowed [N, T] PPG (and optional BCG) plus subject_id. Natural next corpora: PPG-DaLiA, PulseDB/MIMIC-PPG, BUT PPG (quality labels). Keep licenses and subject splits intact.

Layout

configs/          demo.yaml (fast) and default.yaml (larger)
src/ppgfm/        signal, data, models, training, eval
scripts/          demo.py, train_ssl.py, train_downstream.py
tests/            SQI sanity + subject-split leakage checks

About

Multimodal PPG/BCG ML pipeline with self-supervised SimCLR, CNN/Transformer encoders, STFT vision branch, subject-wise evaluation and tests.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages