Skip to content

taomasgonzalez/HeartAnomalyDetector

Repository files navigation

HeartAnomalyDetector

Note: This is an ongoing project. Features, results, and documentation are subject to change.

Table of Contents

Project Overview

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.

Key Features

  • 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

Project Structure

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

Technical Architecture

Custom PyTorch Dataset: HeartbeatsDataset

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)

Custom Data Augmentation Pipeline

Unlike torchvision's image-focused transforms, this project implements specialized augmentation techniques for 1D ECG signals:

1D Signal-Specific Transforms

# 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
)

Transform Implementations

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

Augmentation Strategy

  • 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

Signal Processing Pipeline

The project implements a multi-stage signal processing pipeline:

  1. Signal Ingestion: Loads ECG recordings from MIT-BIH database (360 Hz sampling rate)
  2. 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
  3. Beat Segmentation: Extracts individual heartbeats using existing R-peak annotations
  4. Feature Extraction: Standardizes heartbeat windows to 252 samples with padding

Data Preprocessing

  • 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 beats
    • VEB: Ventricular ectopic beats
    • Paced: Paced beats

Deep Learning Model

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

Dataset Management

MIT-BIH Arrhythmia Database

  • 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

Data Splits

  • Training: 70% of patients (33/48)
  • Validation: 17% of patients (8/48)
  • Testing: 13% of patients (7/48)

Class Distribution

Training set class proportions:

  • Normal beats: 55.05%
  • Supraventricular ectopic beats: 21.98%
  • Ventricular ectopic beats: 19.32%
  • Paced beats: 3.65%

Usage

Environment Setup

  1. Install Dependencies:

    pip install -r requirements.txt
  2. Download Dataset:

    cd dataset
    chmod +x generate.sh
    ./generate.sh

Core Usage

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)

Jupyter Notebooks

  1. DataLoading.ipynb: data loading pipeline, dataset creation, and model training
  2. SignalAnalysisAndDenoising.ipynb: Signal visualization, noise analysis, and preprocessing techniques
  3. ModelAnalysis.ipynb: Comprehensive signal metadata analysis and transformation exploration

Implementation Details

Custom PyTorch Dataset Architecture

The HearbeatsDataset implements several innovative design patterns for efficient 1D signal processing:

Memory Management Strategy

  • 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

Key Implementation Features

# 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]

Custom 1D Signal Augmentation Pipeline

Unlike existing libraries focused on image augmentation, this project implements specialized transforms for 1D signals:

Transform Architecture

  • PyTorch Module Inheritance: All transforms inherit from torch.nn.Module for seamless integration
  • Sequential Composition: Transforms can be chained using torch.nn.Sequential
  • Signal-Preserving Operations: All augmentations maintain physiological signal characteristics

Transform Implementations

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 * scale

RandomNoise: Gaussian noise injection for robustness

def forward(self, signal: torch.Tensor):
    noise = torch.randn_like(signal) * self.std + self.mean
    return signal + noise

Signal Processing Functions

  • apply_filters(): Multi-stage filtering pipeline using SciPy (high-pass, notch, low-pass)
  • rolling_mean_std_dev_and_change(): Variance-based artifact detection with configurable thresholds
  • window_heartbeat(): Heartbeat extraction and standardization with intelligent padding
  • get_heartbeats_start_end_overlapping(): R-peak-based segmentation with overlap handling

Data Loading Strategy

  • 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

Model Architecture

  • 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

Research Context

Performance Evaluation

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

Key Dependencies

  • PyTorch: Deep learning framework
  • NumPy/SciPy: Scientific computing and signal processing
  • WFDB: PhysioNet database access
  • Matplotlib: Visualization
  • Pandas: Data manipulation

Citations

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.

License

MIT License - See LICENSE file for details.

Author

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.

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages