Model Zoo¶
DeepECG-Kit includes 26 model architectures for ECG signal classification. All models follow a consistent interface:
All Models¶
| Registry Name | Class | Type | Description |
|---|---|---|---|
afmodel |
AFModel |
CNN | Atrial Fibrillation model optimized for 30s ECG segments |
kanres |
KanResWideX |
CNN+Residual | KAN-ResNet architecture with wide layers |
kanres-deep |
KanResDeepX |
CNN+Residual | Deep KAN-ResNet architecture |
resnet |
ResNet1D |
Residual CNN | 1D ResNet adapted for ECG |
resnet-wang |
ResNetWang |
Residual CNN | ResNet (Wang et al.) for time series |
se-resnet |
SEResNet1D |
Residual+Attention | ResNet with Squeeze-and-Excitation |
xresnet |
XResNet1D |
Residual CNN | XResNet with Mish activation and blur-pool |
xresnet1d-benchmark |
XResNet1dBenchmark |
Residual CNN | XResNet from PTB-XL benchmark |
inception-time |
InceptionTime1D |
Multi-scale CNN | Multi-scale temporal InceptionTime |
convnext-v2 |
ConvNeXtV21D |
Modern CNN | ConvNeXt V2 with depthwise conv and GRN |
deep-res-cnn |
DeepResCNN |
2D Residual CNN | Deep Residual 2D CNN for multi-lead ECG |
fcn-wang |
FCNWang |
FCN | Fully Convolutional Network (Wang et al.) |
simple-cnn |
SimpleCNN |
Lightweight CNN | Lightweight CNN for fast inference |
crnn |
CRNN |
CNN+LSTM | CNN-LSTM hybrid for temporal aggregation |
gru |
GRUECG |
Recurrent | GRU-based sequential ECG model |
lstm |
LSTMECG |
Recurrent | LSTM-based sequential ECG model |
tcn |
TCN |
Temporal CNN | Temporal Convolutional Network with dilated causal convolutions |
transformer |
TransformerECG |
Transformer | Transformer-based ECG classifier |
medformer |
Medformer |
Transformer | Multi-granularity patching Transformer (NeurIPS 2024) |
dualnet |
ECGDualNet |
Hybrid | Dual-path CNN-LSTM + Transformer |
mamba |
Mamba1D |
State Space | Bidirectional Mamba with linear complexity |
mlp-wang |
MLPWang |
MLP | Multilayer perceptron (Wang et al.) on the time-pooled, flattened signal |
rocket |
ROCKET |
Random kernels | Frozen random convolution kernels (PPV and max) with a linear head |
resnet-hannun |
ResNetHannun |
Residual CNN | 34-layer pre-activation ResNet (Hannun et al. 2019) |
xresnet1d101 |
XResNet1d101Benchmark |
Residual CNN | XResNet1d-101 of the PTB-XL benchmark (bottleneck, [3, 4, 23, 3]) |
spectrogram-cnn |
SpectrogramCNN |
Time-frequency CNN | 2-D CNN on per-lead log-magnitude STFT spectrograms |
Choosing a Model¶
Fast inference / small datasets:
simple-cnn— Minimal parameters, fast trainingkanres— Good accuracy/speed trade-off
Non-deep and classical baselines:
rocket— Random convolutional features, only the linear head is trainedmlp-wang— Fully connected baseline of Wang et al.spectrogram-cnn— Time-frequency input instead of the raw signal
Long sequences:
mamba— Linear complexity, handles very long sequences efficientlytcn— Dilated convolutions capture long-range dependencies
Multi-lead ECG (12-lead):
deep-res-cnn— 2D convolutions across leadsxresnet1d-benchmark— Designed for the PTB-XL benchmarkxresnet1d101— The PTB-XL benchmark's deep modelresnet-hannun— The 34-layer rhythm classifier of Hannun et al.
State-of-the-art research:
medformer— Multi-granularity Transformer (NeurIPS 2024)dualnet— Dual-path architecture combining CNN-LSTM and Transformer
Input Length¶
Most architectures pool over time and accept any signal length. A few do not, and
deepecg list-models shows the limits:
afmodelis built for 30-second recordings and needs at least 7971 samples per lead. The datasets cut 10-second segments by default, so train it with--segment-duration 30(segment_duration_seconds=30in Python).transformeranddualnetattend over every sample, with positional encodings up to 5000 samples, andmedformeraccepts up to 5009. Their memory use grows with the square of the signal length; if a run stops with an out-of-memory error, lower--batch-sizefirst, then the sampling rate or segment length.
deepecg train checks the model against the dataset's signal length before training starts.
Pretrained Weights¶
No pretrained weights are published with the package yet. Train a model, or start from a checkpoint of your own:
--weights takes a weights file, a checkpoint, or a run directory, which stands for its best
checkpoint. Whatever fits the model is loaded and the rest is named: a head of another size, as
when the new task has a different number of classes, is left as initialised, and weights that fit
nothing at all are an error.
To distribute weights, register them with a URL you host; the name then works wherever a weight name is accepted:
from deepecgkit.utils import register_weights
register_weights(
"kanres-my-task",
url="https://example.org/kanres-my-task.pt",
model_class="KanResWideX",
model_kwargs={"input_channels": 1, "output_size": 4},
description="KanResWideX trained on my task",
)
Using the Registry¶
from deepecgkit.registry import get_model, get_model_names, get_model_info
print(get_model_names())
info = get_model_info("kanres")
print(info["description"])
model_class = get_model("kanres")
model = model_class(input_channels=1, output_size=4)
Adding Your Own Model¶
Subclass ECGModelBase, which supplies the forward pass, and register the class:
import torch
from torch import nn
from deepecgkit.models import ECGModelBase
from deepecgkit.registry import register_model
@register_model("my-model", description="A small custom CNN", min_input_length=7)
class MyModel(ECGModelBase):
def __init__(self, input_channels: int, output_size: int):
super().__init__()
self.backbone = nn.Conv1d(input_channels, 32, kernel_size=7, padding=3)
self._feature_dim = 32
self.classifier = nn.Linear(32, output_size)
def extract_features(self, x: torch.Tensor) -> torch.Tensor:
return self.backbone(x).mean(dim=-1) # (batch, feature_dim)
The constructor takes input_channels and output_size; extract_features returns a flat
(batch, feature_dim) tensor and the base class applies dropout and the head. Name the head
attribute classifier, or set HEAD_ATTR to the name you use.
Any nn.Module with that constructor can be trained, but feature extraction, probing and
explanation need extract_features and feature_dim, which is what the base class is for.
Registered models work with build_model("my-model", ...) in Python and, through
--import, with every CLI command.
Model Comparison¶
Use the included benchmark script to compare architectures:
This instantiates every model and reports parameter counts, feature dimensions, and inference speed. See the Model Comparison example for details.