Note: This is an ongoing project. Features, results, and documentation are subject to change.
- Project Overview
- Key Features
- Project Structure
- Technical Architecture
- Dataset Management
- Usage
- Implementation Details
- Research Context
- Performance Evaluation
- Key Dependencies
- Citations
- License
- Author
HeartAnomalyDetector is an end-to-end pipeline for automated arrhythmia detection using ECG recordings from the MIT-BIH Arrhythmia Database. It uses deep learning (1D CNNs) to classify heartbeats into arrhythmia categories, with a focus on robust signal processing and efficient data handling.
- Complete ECG Signal Processing Pipeline: From raw signal ingestion to classification
- Advanced Preprocessing: Multi-stage filtering for noise/artifact removal
- Custom PyTorch Dataset: Memory-efficient, on-demand loading and caching
- Specialized 1D Data Augmentation: Random shifts, scaling, and noise injection
- Detailed Notebooks: For signal analysis, preprocessing, and model evaluation
- Research-Based Implementation: Filtering and augmentation based on best practices
HeartAnomalyDetector/
├── src/ # Core implementation modules
│ ├── data.py # Signal processing and data utilities
│ ├── dataloader.py # Custom PyTorch dataset and data loading
│ ├── model.py # 1D CNN model architecture
│ ├── transforms.py # Custom 1D signal augmentation transforms
│ └── plotter.py # Visualization utilities
├── DataLoading.ipynb # Data loading and preprocessing analysis
├── SignalAnalysisAndDenoising.ipynb # Signal analysis and denoising techniques
├── ModelAnalysis.ipynb # Model training and evaluation
├── dataset/ # Data storage and generation scripts
└── requirements.txt # Python dependencies
The core of the data pipeline is the custom HearbeatsDataset class, designed for efficient and robust ECG signal processing:
- On-Demand Loading & Caching: Signals are loaded and filtered only when needed, with per-patient caching (
signal_store) to minimize memory usage and redundant computation. - Dynamic Heartbeat Extraction: Heartbeat windows are extracted on-the-fly in
__getitem__using R-peak annotations, with intelligent padding to standardize window length (252 samples). - Index-Based Access: Heartbeat locations are stored as indices rather than pre-extracted windows for memory efficiency.
- Patient-Wise Organization: Data is organized by patient, enabling proper train/validation/test splits and preventing data leakage.
- Class-Balanced, Conditional Augmentation: Augmentation is applied selectively to address class imbalance, using boolean flags for each sample.
- Signal Processing Pipeline:
- High-pass (0.5 Hz), notch (60 Hz), and low-pass (40 Hz) filtering
- Artifact detection via rolling variance
- Label mapping: MIT-BIH codes mapped to 4 classes (Normal, SVEB, VEB, Paced)
Unlike torchvision's image-focused transforms, this project implements specialized augmentation techniques for 1D ECG signals:
# Sequential pipeline of custom transforms
DEFAULT_TRANSFORM = Sequential(
RandomShift(max_shift=0.05), # Temporal shifting
RandomScale(min_scale=0.9, max_scale=1.1), # Amplitude scaling
RandomNoise(mean=0., std=0.02), # Gaussian noise injection
)RandomShift: Temporal shifting using torch.roll() for realistic signal variations
- Configurable maximum shift as fraction of signal length
- Preserves signal continuity and temporal relationships
RandomScale: Amplitude scaling to simulate different recording conditions
- Uniform scaling between specified bounds
- Maintains signal morphology while varying amplitude
RandomNoise: Gaussian noise injection for robustness
- Configurable mean and standard deviation
- Simulates real-world recording artifacts and noise
- Class-Balanced Augmentation: Different augmentation frequencies per class to address imbalance
- Conditional Application: Augmentation applied only to specified samples via boolean flags
- Preserves Signal Integrity: All transforms maintain the physiological meaning of ECG signals
The project implements a multi-stage signal processing pipeline:
- Signal Ingestion: Loads ECG recordings from MIT-BIH database (360 Hz sampling rate)
- Noise Filtering:
- High-pass filter (0.5 Hz) for baseline wander removal
- Notch filter (60 Hz) for power line interference
- Low-pass filter (40 Hz) for high-frequency noise
- Beat Segmentation: Extracts individual heartbeats using existing R-peak annotations
- Feature Extraction: Standardizes heartbeat windows to 252 samples with padding
- Signal Normalization: Mean subtraction and amplitude scaling
- Label Mapping: Converts MIT-BIH annotation codes to standardized categories:
N: Normal beats (including bundle branch blocks)SVEB: Supraventricular ectopic beatsVEB: Ventricular ectopic beatsPaced: Paced beats
The SingleHBClassifier implements a 1D CNN architecture:
# Architecture Summary:
# Input: (batch_size, 1, 252) - Single heartbeat signal
# Conv1D(1→30, kernel=10, dilation=2) → BatchNorm → GELU → Dropout(0.2)
# AvgPool1D(kernel=4)
# Conv1D(30→60, kernel=5, dilation=2) → BatchNorm → GELU → Dropout(0.2)
# AvgPool1D(kernel=3)
# Flatten → Linear(960→4) → 4-class classification- 48 patient records (23 from series 100-124, 25 from series 200-234)
- Dual-lead recordings: MLII (Modified Lead II) and V1 precordial lead
- Expert annotations: R-peak locations and beat classifications
- Sampling rate: 360 Hz
- Training: 70% of patients (33/48)
- Validation: 17% of patients (8/48)
- Testing: 13% of patients (7/48)
Training set class proportions:
- Normal beats: 55.05%
- Supraventricular ectopic beats: 21.98%
- Ventricular ectopic beats: 19.32%
- Paced beats: 3.65%
-
Install Dependencies:
pip install -r requirements.txt
-
Download Dataset:
cd dataset chmod +x generate.sh ./generate.sh
from src.dataloader import HearbeatsDataset
from src.model import SingleHBClassifier
import torch
# Load dataset
train_dataset = HearbeatsDataset(patient_names=train_patients, data_dir=data_dir)
# Initialize model
model = SingleHBClassifier()
# Training loop
# (See DataLoading.ipynb for complete training implementation)- DataLoading.ipynb: data loading pipeline, dataset creation, and model training
- SignalAnalysisAndDenoising.ipynb: Signal visualization, noise analysis, and preprocessing techniques
- ModelAnalysis.ipynb: Comprehensive signal metadata analysis and transformation exploration
The HearbeatsDataset implements several innovative design patterns for efficient 1D signal processing:
- Signal Store Pattern: Filtered signals cached by patient name to avoid redundant processing
- Index-Based Access: Heartbeat locations stored as indices rather than pre-extracted windows
- Lazy Evaluation: Heartbeat extraction performed on-demand in
__getitem__method - Patient Isolation: Data organized by patient to prevent cross-contamination in splits
# Efficient signal storage and access
self.signal_store: Dict[str, torch.Tensor] = {} # Patient → filtered signal
self.hb_indices: List[Tuple[str, int, int, bool]] = [] # (patient, start, end, augment)
# Dynamic heartbeat extraction with augmentation
def __getitem__(self, idx):
name, start, end, apply_augment = self.hb_indices[idx]
heartbeat = window_heartbeat(self.signal_store[name], start, end, ...)
if apply_augment and self.transform:
heartbeat = self.transform(heartbeat)
return heartbeat.unsqueeze(0), self.labels[idx]Unlike existing libraries focused on image augmentation, this project implements specialized transforms for 1D signals:
- PyTorch Module Inheritance: All transforms inherit from
torch.nn.Modulefor seamless integration - Sequential Composition: Transforms can be chained using
torch.nn.Sequential - Signal-Preserving Operations: All augmentations maintain physiological signal characteristics
RandomShift: Temporal shifting using circular permutation
def forward(self, signal: torch.Tensor):
max_shift = int(self.max_shift * signal.size(-1))
shift = torch.randint(-max_shift, max_shift + 1, ()).item()
return torch.roll(signal, shifts=shift, dims=-1)RandomScale: Amplitude scaling with uniform distribution
def forward(self, signal: torch.Tensor):
scale = torch.empty(1).uniform_(self.min_scale, self.max_scale).item()
return signal * scaleRandomNoise: Gaussian noise injection for robustness
def forward(self, signal: torch.Tensor):
noise = torch.randn_like(signal) * self.std + self.mean
return signal + noiseapply_filters(): Multi-stage filtering pipeline using SciPy (high-pass, notch, low-pass)rolling_mean_std_dev_and_change(): Variance-based artifact detection with configurable thresholdswindow_heartbeat(): Heartbeat extraction and standardization with intelligent paddingget_heartbeats_start_end_overlapping(): R-peak-based segmentation with overlap handling
- Patient-wise splitting: Prevents data leakage between train/val/test sets
- Class-balanced augmentation: Different augmentation frequencies per arrhythmia class
- On-demand loading: Efficient memory usage for large ECG datasets
- Conditional augmentation: Boolean flags control when augmentation is applied
- 1D Convolutions: Optimized for temporal signal processing
- Dilated convolutions: Increased receptive field without parameter increase
- Batch normalization: Stabilizes training and improves convergence
- GELU activation: Modern activation function for deep networks
Note: Performance evaluation is still in progress.
- Accuracy Metrics: Precision, recall, and F1-score for each arrhythmia class
- Cross-Validation: Patient-wise splitting to prevent data leakage
- PyTorch: Deep learning framework
- NumPy/SciPy: Scientific computing and signal processing
- WFDB: PhysioNet database access
- Matplotlib: Visualization
- Pandas: Data manipulation
Moody GB, Mark RG. The impact of the MIT-BIH Arrhythmia Database. IEEE Eng in Med and Biol 20(3):45-50 (May-June 2001). (PMID: 11446209)
Goldberger, A., Amaral, L., Glass, L., Hausdorff, J., Ivanov, P. C., Mark, R., ... & Stanley, H. E. (2000). PhysioBank, PhysioToolkit, and PhysioNet: Components of a new research resource for complex physiologic signals. Circulation [Online]. 101 (23), pp. e215–e220.
J. A. Van Alste and T. S. Schilder, "Removal of Base-Line Wander and Power-Line Interference from the ECG by an Efficient FIR Filter with a Reduced Number of Taps," in IEEE Transactions on Biomedical Engineering, vol. BME-32, no. 12, pp. 1052-1060, Dec. 1985, doi: 10.1109/TBME.1985.325514.
MIT License - See LICENSE file for details.
Tomás Agustín González Orlando - taomasgonzalez@gmail.com
This project represents a comprehensive approach to automated arrhythmia detection, combining traditional signal processing techniques with modern deep learning methods for robust and interpretable ECG analysis.