HuBERT-ECG: A Self-Supervised Foundation Model for Broad and Scalable Cardiac Application
Original code at (https://github.com/Edoar-do/HuBERT-ECG)
License: CC BY-NC 4.0
Abstract
Deep learning models have shown remarkable performance in electrocardiogram (ECG) analysis, but their success has been constrained by the limited availability and size of ECG datasets, resulting in systems that are more task specialists than versatile generalists. In this work, we introduce HuBERT-ECG, a foundation ECG model pre-trained in a self-supervised manner on a large and diverse dataset of 9.1 million 12-lead ECGs encompassing 164 cardiovascular conditions. By simply adding an output layer, HuBERT-ECG can be fine-tuned for a wide array of downstream tasks, from diagnosing diseases to predicting future cardiovascular events. Across diverse real-world scenarios, HuBERT-ECG achieves AUROCs from 84.3% in low-data settings to 99% in large-scale setups. When trained to detect 164 overlapping conditions simultaneously, our model delivers AUROCs above 90% and 95% for 140 and 94 diseases, respectively. HuBERT-ECG also predicts death events within a 2-year follow-up with an AUROC of 93.4%. We release models and code.
Models
This repository contains:
- SMALL/BASE/LARGE HuBERTECG model sizes ready to be fine-tuned on any downstream dataset or to be used as feature extractor
- SMALL/BASE/LARGE HuBERTECG model sizes fine-tuned on Cardio-Learning for a more disease-oriented baseline to futher fine-tune.
Cardio-Learning is the name we gave to the union of several 12-lead ECG datasets including PTB, PTB-XL, CPSC, CPSC-Extra, Georgia, Chapman, Ningbo, SPH, CODE, SaMi-Trop, Hefei. This dataset, counting 2.4 million ECGs from millions of patients in 4 countries, encompasses 164 different heart-related conditions for which the ECG is either the primary or a supportive diagnostic tool, or is used to estimate the risk of future adverse cardiovascular events.
Usage
Input signals must be 5-second 12-lead ECGs sampled at 100 HZ. The leads are concatenated to each other
import torch
from hubert_ecg import HuBERTECG
path = "path/to/your/hubert-ecg-model.pt"
checkpoint = torch.load(path, map_location='cpu')
config = checkpoint['model_config']
hubert_ecg = HuBERTECG(config)
hubert_ecg.load_state_dict(checkpoint['model_state_dict']) # pre-trained model ready to be fine-tuned or used as feature extractor
import torch
from hubert_ecg import HuBERTECG
from hubert_ecg_classification import HuBERTForECGClassification
path = "path/to/your/finetuned-hubert-ecg-model.pt"
checkpoint = torch.load(path, map_location='cpu')
config = checkpoint['model_config']
hubert_ecg = HuBERTECG(config)
hubert_ecg = HuBERTForECGClassification(hubert_ecg)
hubert_ecg.load_state_dict(checkpoint['model_state_dict']) # fine-tuned model ready to be used or further fine-tuned
Easier usage
(for pre-trained models only)
from transformers import AutoModel
size = 'small' # any size from small, base, large
hubert_ecg = AutoModel.from_pretrained(f"Edoardo-BS/hubert-ecg-{size}", trust_remote_code=True)
π Citation
If you use our models or find our work useful, please consider citing us:
doi: https://doi.org/10.1101/2024.11.14.24317328