Skip to content

About

Multi-task semi-supervised detection of patient-ventilator asynchrony (EUSIPCO 2026)

Resources

Stars

0 stars

Watchers

0 watching

Forks

Repository files navigation

Multi-Task Learning for the Detection of Patient-Ventilator Asynchrony

Code for the EUSIPCO 2026 paper Multi-Task Learning for the Detection of Patient-Ventilator Asynchrony (A. Sabbah, T. H. G. F. Bakkes, A. De Bie, M. Mischi, S. Turco).

The model detects four types of patient-ventilator asynchrony (PVA) from the pressure and flow waveforms of a mechanical ventilator: delayed inspiration (DI), late cycling (LC), early cycling (EC) and ineffective effort (IE). For every mechanical breath, a 1D ResNet predicts when the patient starts and ends inspiration and whether an ineffective effort occurs. DI, LC and EC then follow from comparing the predicted patient timings with the ventilator timings.

The model is trained on labeled simulated breaths together with unlabeled clinical breaths. The unlabeled data enter through an auxiliary task, predicting the start and end of the mechanical cycle, whose targets are always known from the ventilator. This lets the network learn from clinical waveforms without any manual annotation.

This is research code: it is shared so the method can be reused and the results checked, not as a polished package. It is intended for research only and is not a medical device: do not use it for clinical decisions.

Installation

The code uses TensorFlow 2 with Keras 2 and tensorflow-addons. It was developed with TensorFlow 2.10 and tested with Python 3.10 and TensorFlow 2.15. TensorFlow 2.16 and later ship Keras 3 and will not work.

python -m venv venv
source venv/bin/activate          # Windows: venv\Scripts\activate
pip install -r requirements.txt

A GPU is recommended for training but not required.

Data

Simulated data (labeled training set). The simulated pressure support waveforms of van Diepen et al. (2022) are public on 4TU.ResearchData: https://data.4tu.nl/datasets/81220350-0f3d-4e0a-86cf-28c904a1cb09/1. It contains 1405 simulation runs with ARDS, COPD, fibrosis and obese respiratory mechanics.

Clinical data. The clinical datasets used in the paper (an unlabeled training set and an annotated test set) cannot be shared. To use the full method you need your own clinical recordings in the format below: unlabeled recordings for training and, ideally, some annotated recordings for validation and testing.

Expected input format

All inputs are CSV files with a header row, one file per recording. Files that belong to the same recording must sort in the same order in their folders (for example Run1.csv, Run2.csv, … in every folder). Times are in seconds.

Folder Columns Content
Waveforms time, paw, flow, vol Ventilator waveforms sampled at 100 Hz. Extra columns (e.g. pmus) are kept but not used.
Mechanical Reference tim, tem Start (trigger) and end (cycle) of each mechanical breath.
Patient Reference tip, tep Start and end of each patient inspiratory effort (labeled data only).
Simulation settings run, patient_type, … One row per simulation run (simulated data only, used to hold out whole simulated patients).

The 4TU dataset already has this structure. For unlabeled clinical data only the first two folders are needed; the Mechanical Reference may also contain triggering_type and cycling_type columns to keep only pressure support breaths (see preprocess_unlabeled.py --help).

Usage

The pipeline has four steps. Every script has a --help option.

1. Asynchrony labels. Match every mechanical breath to the patient effort that triggered it and flag the asynchronies:

python make_labels.py --mech-ref "SIM/Mechanical Reference" --patient-ref "SIM/Patient Reference" \
    --out "SIM/Mechanical Label"

This script is a reconstruction based on the definitions in the paper (Table I). The labels used for the paper were made with an earlier internal script, so the numbers of breaths per asynchrony are somewhat different.

2. Pre-processing. Cut the recordings into breath segments of 1024 samples, normalise them and save them as parquet files:

# labeled simulated data (training)
python preprocess_labeled.py --waveforms SIM/Waveforms --mech-labels "SIM/Mechanical Label" \
    --patient-ref "SIM/Patient Reference" --settings "SIM/Simulation settings/settings.csv" \
    --out processed_data/sim

# annotated data for validation / testing (same format, without --settings)
python preprocess_labeled.py --waveforms VAL/Waveforms --mech-labels "VAL/Mechanical Label" \
    --patient-ref "VAL/Patient Reference" --out processed_data/val

# unlabeled clinical data
python preprocess_unlabeled.py --waveforms CLIN/Waveforms --mech-ref "CLIN/Mechanical Reference" \
    --out processed_data/unlabeled

3. Training. Train on the simulated and unlabeled data. Use --val to select models on an annotated validation set, or --sim-val to hold out two simulated patients per disease instead. Keep the test set separate from the validation set.

python train.py --labeled processed_data/sim --unlabeled processed_data/unlabeled \
    --val processed_data/val --out models

By default this trains 5 models with seeds 42 to 46. Each run folder contains encoder.h5 (best mean F1 on the validation set), encoder_foc.h5 (lowest timing error) and encoder_latest.h5.

4. Evaluation. Print timing errors, confusion matrices and F1 scores per asynchrony:

python evaluate.py --data processed_data/test --weights models/run0_seed42/encoder.h5

Pre-trained weights

weights/encoder.h5 contains the weights of the proposed model from the paper. To apply it to your own data, run steps 1 and 2 on your recordings and then evaluate.py with --weights weights/encoder.h5.

Repository contents

File Purpose
make_labels.py Per-breath asynchrony labels from ventilator and patient timings
preprocess_labeled.py Breath segmentation and labels for labeled data
preprocess_unlabeled.py Breath segmentation for unlabeled data, including artefact removal
data.py Loading of the processed data
networks.py ResNet-9 feature extractor with CoordConv input and multi-task heads
model.py Multi-task semi-supervised training step, losses and augmentation
callbacks.py Validation metrics and checkpointing
train.py, evaluate.py Training and evaluation scripts
config.py Shared constants (segment length, asynchrony thresholds, …)
docs/code_overview.md Detailed description of the method as implemented

Citation

If you use this code, please cite the paper:

@inproceedings{sabbah2026pva,
  title     = {Multi-Task Learning for the Detection of Patient-Ventilator Asynchrony},
  author    = {Sabbah, A. and Bakkes, T. H. G. F. and De Bie, A. and Mischi, M. and Turco, S.},
  booktitle = {Proceedings of the 34th European Signal Processing Conference (EUSIPCO)},
  address   = {Bruges, Belgium},
  year      = {2026}
}

If you use the simulated data, please also cite:

A. van Diepen, T. H. G. F. Bakkes, A. J. R. De Bie, S. Turco, R. A. Bouwman, P. H. Woerlee and M. Mischi, "A model-based approach to generating annotated pressure support waveforms," Journal of Clinical Monitoring and Computing, vol. 36, no. 6, pp. 1739–1752, 2022. https://doi.org/10.1007/s10877-022-00822-4

License

The code and the pre-trained weights are released under the BSD 3-Clause License (see LICENSE). The simulated dataset is distributed separately by 4TU.ResearchData under its own terms.

Contact

Simona Turco, Eindhoven University of Technology — s.turco@tue.nl

About

Multi-task semi-supervised detection of patient-ventilator asynchrony (EUSIPCO 2026)

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages