deepecgkit.models¶
Neural network architectures for ECG signal processing. All models are nn.Module subclasses
with a consistent interface: __init__(input_channels, output_size, **kwargs).
Base Class¶
ECGModelBase
¶
Bases: PretrainedMixin, Module
Base class for registered ECG models.
Subclasses must:
- call
super().__init__()first, - set
self._feature_dimto the backbone's output width, - create their head module under the attribute named by
HEAD_ATTR, - implement
extract_features.
A subclass without its own top-level self.dropout inherits the
parameter-free nn.Identity set here, keeping the default forward
(features -> dropout -> head) bit-identical to a model with no dropout.
Source code in deepecgkit/models/base.py
Building and Loading¶
build_model
¶
Instantiate a registered model.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
name
|
str
|
Registered model name |
required |
input_channels
|
int
|
Number of ECG leads the model consumes |
required |
output_size
|
int
|
Number of output units of the classifier head |
required |
**kwargs
|
Any
|
Additional keyword arguments forwarded to the model, overriding any default_kwargs recorded in the registry |
{}
|
Returns:
| Type | Description |
|---|---|
Module
|
The instantiated model. |
Raises:
| Type | Description |
|---|---|
KeyError
|
If the model name is not registered. |
Source code in deepecgkit/models/factory.py
build_model_from_checkpoint
¶
build_model_from_checkpoint(
checkpoint_path: str | Path,
name: str | None = None,
input_channels: int | None = None,
output_size: int | None = None,
map_location: str = "cpu",
) -> tuple[nn.Module, dict[str, Any]]
Build a model matching a checkpoint and load its weights.
The architecture and its shapes are taken from explicit arguments when given, then from the model_config block recorded at save time, then (for shapes) inferred from the weights themselves.
Checkpoints written by ECGTrainer, bare state dicts, and legacy PyTorch Lightning checkpoints are all accepted.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
checkpoint_path
|
str | Path
|
Path to a checkpoint written by ECGTrainer.save_checkpoint |
required |
name
|
str | None
|
Registered model name; optional when the checkpoint records one |
None
|
input_channels
|
int | None
|
Overrides the recorded or inferred lead count |
None
|
output_size
|
int | None
|
Overrides the recorded or inferred output size |
None
|
map_location
|
str
|
Device to map tensors onto while loading |
'cpu'
|
Returns:
| Type | Description |
|---|---|
tuple[Module, dict[str, Any]]
|
Tuple of the loaded model and the checkpoint dictionary. |
Raises:
| Type | Description |
|---|---|
ValueError
|
If the checkpoint holds no weights, names a different architecture than the one requested, does not say which architecture it holds, or the lead count cannot be determined. |
Source code in deepecgkit/models/factory.py
122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 | |
CNN Architectures¶
SimpleCNN
¶
Bases: ECGModelBase
Simple CNN model for ECG signal classification.
A straightforward convolutional neural network with pooling and dropout layers for basic ECG classification tasks.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
input_channels
|
int
|
Number of input channels (default: 1 for single-lead ECG) |
1
|
output_size
|
int
|
Number of output classes |
4
|
dropout_rate
|
float
|
Dropout probability (default: 0.3) |
0.3
|
Example
model = SimpleCNN(input_channels=1, output_size=4) x = torch.randn(32, 1, 3000) output = model(x) print(output.shape)
features = model.extract_features(x) print(features.shape) # (32, 256)
Source code in deepecgkit/models/simple_cnn.py
FCNWang
¶
Bases: ECGModelBase
Fully Convolutional Network for ECG signal classification.
Based on Wang et al.'s FCN architecture for time series classification, using three convolutional blocks with batch normalization and global average pooling. No dense layers except the final classifier.
Reference
Wang Z., Yan W., Oates T. "Time Series Classification from Scratch with Deep Neural Networks: A Strong Baseline" (2017) https://github.com/helme/ecg_ptbxl_benchmarking
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
input_channels
|
int
|
Number of input channels (default: 12 for 12-lead ECG) |
12
|
output_size
|
int
|
Number of output classes |
5
|
filters
|
list[int] | None
|
List of filter counts for each conv block (default: [128, 256, 128]) |
None
|
kernel_sizes
|
list[int] | None
|
List of kernel sizes for each conv block (default: [8, 5, 3]) |
None
|
dropout_rate
|
float
|
Dropout probability before classifier (default: 0.3) |
0.3
|
Example
model = FCNWang(input_channels=12, output_size=5) x = torch.randn(32, 12, 1000) output = model(x) print(output.shape)
features = model.extract_features(x) print(features.shape) # (32, 128)
Source code in deepecgkit/models/fcn_wang.py
AFModel
¶
Bases: ECGModelBase
Atrial Fibrillation classification model.
A convolutional neural network specifically designed for AF detection in ECG signals with configurable recording length support.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
input_channels
|
int
|
Number of input ECG leads (default: 1) |
1
|
output_size
|
int
|
Number of output classes (default: 4) |
4
|
recording_length
|
int
|
Recording length in seconds (must be 6, 10, or 30) |
30
|
Example
model = AFModel(recording_length=30) x = torch.randn(32, 1, 9000) output = model(x) print(output.shape) # (32, 4)
features = model.extract_features(x) print(features.shape) # (32, 196)
Source code in deepecgkit/models/af_classifier.py
46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 | |
min_input_length
property
¶
Smallest signal length the convolutional stack accepts.
Each block narrows the signal by kernel_size - 1 and optionally
halves it, so the bound is obtained by walking the stack backwards from
a single remaining sample.
Returns:
| Type | Description |
|---|---|
int
|
Minimum number of samples per lead. |
extract_features
¶
Return the pooled representation preceding dropout and the head.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
data
|
Tensor
|
Input of shape (batch, leads, time) |
required |
Returns:
| Type | Description |
|---|---|
Tensor
|
Tensor of shape (batch, feature_dim). |
Raises:
| Type | Description |
|---|---|
ValueError
|
If the signal is shorter than :attr: |
Source code in deepecgkit/models/af_classifier.py
Residual Networks¶
ResNet1D
¶
Bases: ECGModelBase
1D ResNet model for ECG signal classification.
A residual network architecture adapted for 1D time-series ECG data, providing deep feature extraction with skip connections.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
input_channels
|
int
|
Number of input channels (default: 1 for single-lead ECG) |
1
|
output_size
|
int
|
Number of output classes |
4
|
base_channels
|
int
|
Base number of channels (default: 64) |
64
|
num_blocks
|
list | None
|
List of number of blocks in each layer (default: [2, 2, 2, 2]) |
None
|
dropout_rate
|
float
|
Dropout probability (default: 0.3) |
0.3
|
Example
model = ResNet1D(input_channels=1, output_size=4) x = torch.randn(32, 1, 3000) output = model(x) print(output.shape)
features = model.extract_features(x) print(features.shape) # (32, 512) with base_channels=64
Source code in deepecgkit/models/resnet1d.py
74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 | |
ResNetWang
¶
Bases: ECGModelBase
ResNet model based on Wang et al.'s architecture for time series classification.
A shallow 3-block residual network without initial pooling, using larger initial channels (128) and asymmetric kernel sizes in residual blocks. This is the standard ResNet baseline from the PTB-XL benchmark.
Reference
Wang Z., Yan W., Oates T. "Time Series Classification from Scratch with Deep Neural Networks: A Strong Baseline" (2017) https://github.com/helme/ecg_ptbxl_benchmarking
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
input_channels
|
int
|
Number of input channels (default: 12 for 12-lead ECG) |
12
|
output_size
|
int
|
Number of output classes |
5
|
base_channels
|
int
|
Base number of channels (default: 128) |
128
|
kernel_size
|
int
|
Primary kernel size for residual blocks (default: 5) |
5
|
kernel_size_stem
|
int
|
Kernel size for the stem convolution (default: 7) |
7
|
dropout_rate
|
float
|
Dropout probability before classifier (default: 0.3) |
0.3
|
Example
model = ResNetWang(input_channels=12, output_size=5) x = torch.randn(32, 12, 1000) output = model(x) print(output.shape)
features = model.extract_features(x) print(features.shape) # (32, 128)
Source code in deepecgkit/models/resnet1d_wang.py
69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 | |
SEResNet1D
¶
Bases: ECGModelBase
SE-ResNet model for ECG signal classification.
Extends ResNet1D with Squeeze-and-Excitation blocks that learn channel attention weights. Particularly effective for multi-lead ECG where the network can learn which leads are most informative for each class.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
input_channels
|
int
|
Number of input channels (default: 1 for single-lead ECG) |
1
|
output_size
|
int
|
Number of output classes |
4
|
base_channels
|
int
|
Base number of channels (default: 64) |
64
|
num_blocks
|
list | None
|
List of number of blocks in each layer (default: [2, 2, 2, 2]) |
None
|
se_reduction
|
int
|
SE reduction ratio (default: 16) |
16
|
dropout_rate
|
float
|
Dropout probability (default: 0.3) |
0.3
|
Example
model = SEResNet1D(input_channels=12, output_size=5) x = torch.randn(32, 12, 5000) output = model(x) print(output.shape)
features = model.extract_features(x) print(features.shape) # (32, 512) with base_channels=64
Source code in deepecgkit/models/se_resnet1d.py
104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 | |
XResNet1D
¶
Bases: ECGModelBase
XResNet model for ECG signal classification.
An improved ResNet incorporating three key enhancements from recent research: (1) a multi-layer stem instead of a single large convolution, (2) Mish activation for smoother gradients, and (3) anti-aliased blur-pool downsampling to reduce aliasing.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
input_channels
|
int
|
Number of input channels (default: 1 for single-lead ECG) |
1
|
output_size
|
int
|
Number of output classes |
4
|
base_channels
|
int
|
Base number of channels (default: 64) |
64
|
num_blocks
|
list | None
|
List of number of blocks in each layer (default: [2, 2, 2, 2]) |
None
|
dropout_rate
|
float
|
Dropout probability (default: 0.3) |
0.3
|
use_blur_pool
|
bool
|
Whether to use anti-aliased downsampling (default: True) |
True
|
Example
model = XResNet1D(input_channels=1, output_size=4) x = torch.randn(32, 1, 3000) output = model(x) print(output.shape)
features = model.extract_features(x) print(features.shape) # (32, 512) with base_channels=64
Source code in deepecgkit/models/xresnet1d.py
115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 | |
XResNet1dBenchmark
¶
Bases: ECGModelBase
XResNet1d adapted from the PTB-XL benchmarking repository.
Key differences from the standard XResNet1D: - Fixed feature dimension across all layers (all blocks use same width) - Concat pooling head (AdaptiveAvgPool + AdaptiveMaxPool concatenated) - Multi-layer stem with configurable kernel size - Supports both BasicBlock (expansion=1) and Bottleneck (expansion=4)
Reference
Strodthoff N., Wagner P., Schaeffter T., Samek W. "Deep Learning for ECG Analysis: Benchmarks and Insights from PTB-XL" (2021) https://github.com/helme/ecg_ptbxl_benchmarking
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
input_channels
|
int
|
Number of input channels (default: 12 for 12-lead ECG) |
12
|
output_size
|
int
|
Number of output classes |
5
|
expansion
|
int
|
Block expansion factor (1=BasicBlock, 4=Bottleneck) |
1
|
layers
|
list[int] | None
|
List of block counts per layer (default: [3, 4, 6, 3] for ResNet-50) |
None
|
base_channels
|
int
|
Fixed channel width for all layers (default: 64) |
64
|
kernel_size
|
int
|
Convolution kernel size (default: 5) |
5
|
kernel_size_stem
|
int
|
Stem convolution kernel size (default: 5) |
5
|
stem_channels
|
tuple[int, ...]
|
Tuple of stem layer channels |
(32, 32, 64)
|
dropout_rate
|
float
|
Dropout probability in head (default: 0.5) |
0.5
|
concat_pooling
|
bool
|
Use avg+max concat pooling (default: True) |
True
|
block_channels
|
tuple[int, ...] | None
|
Per-layer channel widths (before expansion); overrides
the fixed |
None
|
Example
model = XResNet1dBenchmark(input_channels=12, output_size=5) x = torch.randn(32, 12, 1000) output = model(x) print(output.shape)
features = model.extract_features(x) print(features.shape) # (32, 128) with concat_pooling
Source code in deepecgkit/models/xresnet1d_benchmark.py
84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 | |
KanResWideX
¶
Bases: ECGModelBase
KanRes-Wide-X model for ECG signal classification.
A convolutional neural network architecture designed for ECG signal analysis with residual connections and wide blocks for improved feature extraction.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
input_channels
|
int
|
Number of input channels (default: 1 for single-lead ECG) |
1
|
output_size
|
int
|
Number of output classes or regression targets |
4
|
base_channels
|
int
|
Base number of channels for the first layer (default: 64) |
64
|
Example
model = KanResWideX(input_channels=1, output_size=4) x = torch.randn(32, 1, 3000) output = model(x) print(output.shape) # [32, 4]
features = model.extract_features(x) print(features.shape) # (32, 64)
Source code in deepecgkit/models/kanres_wide_x.py
KanResDeepX
¶
Bases: ECGModelBase
KanRes-Deep-X model for ECG signal classification.
A deep residual convolutional neural network architecture designed for ECG signal analysis with 8 residual blocks for improved feature extraction.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
input_channels
|
int
|
Number of input channels (default: 1 for single-lead ECG) |
1
|
output_size
|
int
|
Number of output classes (default: 4) |
4
|
base_channels
|
int
|
Base number of channels for the architecture (default: 32) |
32
|
Example
model = KanResDeepX(input_channels=1, output_size=4, base_channels=32) x = torch.randn(32, 1, 3000) output = model(x) print(output.shape)
features = model.extract_features(x) print(features.shape) # (32, 32)
Source code in deepecgkit/models/kanres_deep_x.py
DeepResCNN
¶
Bases: ECGModelBase
Deep Residual 2D CNN for ECG classification.
Faithful implementation of Elyamani et al. (2022). Uses Conv2d with (1, k) kernels and valid padding to process each ECG lead independently along the time axis, then fuses across leads with a (leads, 1) convolution at the end.
Input convention: (batch, leads, time) -- standard deepecg-kit format. Internally reshaped to (batch, 1, leads, time) for 2D convolution.
The classifier head includes L2 regularization matching the original Keras model. Call l2_regularization_loss() to obtain the penalty term.
Reference
https://github.com/HaneenElyamani/ECG-classification
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
input_channels
|
int
|
Number of ECG leads (default: 12) |
12
|
output_size
|
int
|
Number of output classes (default: 5) |
5
|
dropout_rate
|
float
|
Dropout probability in residual blocks (default: 0.1) |
0.1
|
Example
model = DeepResCNN(input_channels=12, output_size=5) x = torch.randn(32, 12, 1000) output = model(x) print(output.shape)
features = model.extract_features(x) print(features.shape) # (32, 128)
Source code in deepecgkit/models/deep_res_cnn.py
106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 | |
l2_regularization_loss
¶
Return the L2 penalty for the classifier head weights.
Matches the Keras kernel_regularizer=L2(lambda) on the two Dense layers. Add this to the training loss for full equivalence with the original model.
Source code in deepecgkit/models/deep_res_cnn.py
extract_features
¶
Return the pooled representation preceding the classifier head.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
x
|
Tensor
|
Input of shape (batch, leads, time) |
required |
Returns:
| Type | Description |
|---|---|
Tensor
|
Tensor of shape (batch, feature_dim). |
Raises:
| Type | Description |
|---|---|
ValueError
|
If the lead count differs from the configured one. The lead-fusion convolution slides along the lead axis and the adaptive pool absorbs the remainder, so a mismatch would otherwise produce a correctly shaped but meaningless embedding. |
Source code in deepecgkit/models/deep_res_cnn.py
Modern CNN¶
ConvNeXtV21D
¶
Bases: ECGModelBase
ConvNeXtV2 adapted for 1D ECG signals.
A modern convolutional architecture using depthwise separable convolutions, LayerNorm, GELU activation, and Global Response Normalization (GRN).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
input_channels
|
int
|
Number of input channels (default: 1 for single-lead ECG) |
1
|
output_size
|
int
|
Number of output classes |
4
|
dims
|
list | None
|
Channel dimensions for each stage (default: [64, 128, 256, 512]) |
None
|
depths
|
list | None
|
Number of blocks per stage (default: [2, 2, 6, 2]) |
None
|
kernel_size
|
int
|
Kernel size for depthwise convolutions (default: 7) |
7
|
expansion_factor
|
int
|
Expansion ratio for inverted bottleneck (default: 4) |
4
|
dropout_rate
|
float
|
Dropout probability (default: 0.3) |
0.3
|
Example
model = ConvNeXtV21D(input_channels=1, output_size=4) x = torch.randn(32, 1, 3000) output = model(x) print(output.shape)
features = model.extract_features(x) print(features.shape) # (32, 512)
Source code in deepecgkit/models/convnext_v2_1d.py
88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 | |
InceptionTime1D
¶
Bases: ECGModelBase
InceptionTime model adapted for 1D ECG signal classification.
Uses parallel convolutions at multiple temporal scales (short/medium/long kernels) with residual connections to capture both rapid arrhythmia spikes and slow rhythm patterns simultaneously.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
input_channels
|
int
|
Number of input channels (default: 1 for single-lead ECG) |
1
|
output_size
|
int
|
Number of output classes |
4
|
n_filters
|
int
|
Number of filters per Inception branch (default: 32) |
32
|
depth
|
int
|
Number of Inception residual blocks (default: 6) |
6
|
kernel_sizes
|
tuple[int, ...]
|
Tuple of kernel sizes for multi-scale branches |
(5, 15, 41)
|
bottleneck_channels
|
int
|
Channels in bottleneck layers (default: 32) |
32
|
dropout_rate
|
float
|
Dropout probability (default: 0.3) |
0.3
|
Example
model = InceptionTime1D(input_channels=1, output_size=4) x = torch.randn(32, 1, 3000) output = model(x) print(output.shape)
features = model.extract_features(x) print(features.shape) # (32, 128) with n_filters=32
Source code in deepecgkit/models/inception_time.py
TCN
¶
Bases: ECGModelBase
Temporal Convolutional Network for ECG signal classification.
Uses stacked dilated causal convolutions with exponentially growing receptive fields to efficiently model long-range dependencies without recurrence. The causal structure makes it suitable for real-time ECG monitoring applications.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
input_channels
|
int
|
Number of input channels (default: 1 for single-lead ECG) |
1
|
output_size
|
int
|
Number of output classes |
4
|
num_channels
|
list | None
|
List of channel sizes per temporal block (default: [64, 64, 128, 128, 256, 256]) |
None
|
kernel_size
|
int
|
Convolution kernel size (default: 7) |
7
|
dropout_rate
|
float
|
Dropout probability (default: 0.2) |
0.2
|
Example
model = TCN(input_channels=1, output_size=4) x = torch.randn(32, 1, 3000) output = model(x) print(output.shape)
features = model.extract_features(x) print(features.shape) # (32, 256) with default num_channels
Source code in deepecgkit/models/tcn.py
Recurrent Networks¶
CRNN
¶
Bases: ECGModelBase
Convolutional Recurrent Neural Network for ECG classification.
Uses a CNN front-end for local feature extraction followed by a bidirectional LSTM for temporal aggregation, combining the strengths of both architectures.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
input_channels
|
int
|
Number of input channels (default: 1 for single-lead ECG) |
1
|
output_size
|
int
|
Number of output classes |
4
|
cnn_channels
|
list | None
|
List of channel sizes for CNN stages (default: [32, 64, 128, 256]) |
None
|
lstm_hidden_size
|
int
|
Size of LSTM hidden state (default: 128) |
128
|
lstm_num_layers
|
int
|
Number of LSTM layers (default: 2) |
2
|
bidirectional
|
bool
|
Use bidirectional LSTM (default: True) |
True
|
dropout_rate
|
float
|
Dropout probability (default: 0.3) |
0.3
|
Example
model = CRNN(input_channels=1, output_size=4) x = torch.randn(32, 1, 3000) output = model(x) print(output.shape)
features = model.extract_features(x) print(features.shape) # (32, 256)
Source code in deepecgkit/models/crnn.py
9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 | |
GRUECG
¶
Bases: ECGModelBase
GRU-based model for ECG signal classification.
A recurrent neural network using GRU layers with concat pooling (adaptive avg + adaptive max + last hidden state) for ECG classification. Based on the RNN architecture from the PTB-XL benchmark.
Reference
https://github.com/helme/ecg_ptbxl_benchmarking
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
input_channels
|
int
|
Number of input channels (default: 12 for 12-lead ECG) |
12
|
output_size
|
int
|
Number of output classes |
5
|
hidden_size
|
int
|
Size of GRU hidden state (default: 256) |
256
|
num_layers
|
int
|
Number of GRU layers (default: 2) |
2
|
dropout_rate
|
float
|
Dropout probability (default: 0.3) |
0.3
|
bidirectional
|
bool
|
Use bidirectional GRU (default: False) |
False
|
Example
model = GRUECG(input_channels=12, output_size=5) x = torch.randn(32, 12, 1000) output = model(x) print(output.shape)
features = model.extract_features(x) print(features.shape) # (32, 768) with hidden_size=256, unidirectional
Source code in deepecgkit/models/gru_model.py
LSTMECG
¶
Bases: ECGModelBase
LSTM-based model for ECG signal classification.
A recurrent neural network using bidirectional LSTM layers for temporal pattern recognition in ECG signals.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
input_channels
|
int
|
Number of input channels (default: 1 for single-lead ECG) |
1
|
output_size
|
int
|
Number of output classes |
4
|
hidden_size
|
int
|
Size of LSTM hidden state (default: 128) |
128
|
num_layers
|
int
|
Number of LSTM layers (default: 2) |
2
|
dropout_rate
|
float
|
Dropout probability (default: 0.3) |
0.3
|
bidirectional
|
bool
|
Use bidirectional LSTM (default: True) |
True
|
Example
model = LSTMECG(input_channels=1, output_size=4) x = torch.randn(32, 1, 3000) output = model(x) print(output.shape)
features = model.extract_features(x) print(features.shape) # (32, 256) with bidirectional=True
Source code in deepecgkit/models/lstm_model.py
Transformers & Attention¶
TransformerECG
¶
Bases: ECGModelBase
Transformer-based model for ECG signal classification.
A transformer architecture that uses self-attention mechanisms to capture long-range dependencies in ECG signals.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
input_channels
|
int
|
Number of input channels (default: 1 for single-lead ECG) |
1
|
output_size
|
int
|
Number of output classes |
4
|
d_model
|
int
|
Dimension of the model (default: 128) |
128
|
nhead
|
int
|
Number of attention heads (default: 8) |
8
|
num_encoder_layers
|
int
|
Number of transformer encoder layers (default: 4) |
4
|
dim_feedforward
|
int
|
Dimension of feedforward network (default: 512) |
512
|
dropout_rate
|
float
|
Dropout probability (default: 0.1) |
0.1
|
max_len
|
int
|
Maximum sequence length (default: 5000) |
5000
|
Example
model = TransformerECG(input_channels=1, output_size=4) x = torch.randn(32, 1, 3000) output = model(x) print(output.shape)
features = model.extract_features(x) print(features.shape) # (32, 128) with d_model=128
Source code in deepecgkit/models/transformer_ecg.py
Medformer
¶
Bases: ECGModelBase
Medformer: Multi-Granularity Patching Transformer for medical time series.
Uses multiple patch sizes to capture fine, medium, and coarse temporal patterns, with intra-granularity self-attention and inter-granularity cross-attention for information fusion.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
input_channels
|
int
|
Number of input channels (default: 1 for single-lead ECG) |
1
|
output_size
|
int
|
Number of output classes |
4
|
d_model
|
int
|
Transformer model dimension (default: 128) |
128
|
patch_sizes
|
tuple[int, ...]
|
Tuple of patch sizes for different granularities (default: (10, 25, 50)) |
(10, 25, 50)
|
num_encoder_layers
|
int
|
Number of encoder layers (default: 2) |
2
|
nhead
|
int
|
Number of attention heads (default: 8) |
8
|
dim_feedforward
|
int
|
Feedforward dimension (default: 256) |
256
|
dropout_rate
|
float
|
Dropout probability (default: 0.1) |
0.1
|
max_patches
|
int
|
Maximum number of patches per granularity (default: 500) |
500
|
Example
model = Medformer(input_channels=1, output_size=4) x = torch.randn(32, 1, 3000) output = model(x) print(output.shape)
features = model.extract_features(x) print(features.shape) # (32, 384)
Source code in deepecgkit/models/medformer.py
121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 | |
Hybrid & State Space¶
ECGDualNet
¶
Bases: ECGModelBase
Dual-path ECG classification network.
Runs a CNN-LSTM branch and a Transformer branch in parallel, then fuses their outputs via concatenation and a fusion head.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
input_channels
|
int
|
Number of input channels (default: 1 for single-lead ECG) |
1
|
output_size
|
int
|
Number of output classes |
4
|
cnn_channels
|
int
|
CNN output channels in CNN-LSTM branch (default: 128) |
128
|
lstm_hidden
|
int
|
LSTM hidden size in CNN-LSTM branch (default: 128) |
128
|
lstm_layers
|
int
|
Number of LSTM layers (default: 1) |
1
|
d_model
|
int
|
Transformer model dimension (default: 128) |
128
|
nhead
|
int
|
Number of attention heads (default: 8) |
8
|
transformer_layers
|
int
|
Number of transformer encoder layers (default: 2) |
2
|
dim_feedforward
|
int
|
Transformer feedforward dimension (default: 256) |
256
|
dropout_rate
|
float
|
Dropout probability (default: 0.3) |
0.3
|
Example
model = ECGDualNet(input_channels=1, output_size=4) x = torch.randn(32, 1, 3000) output = model(x) print(output.shape)
features = model.extract_features(x) print(features.shape) # (32, 384)
Source code in deepecgkit/models/ecg_dualnet.py
122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 | |
Mamba1D
¶
Bases: ECGModelBase
Bidirectional Mamba model for ECG classification.
Uses selective state space models with linear complexity as an alternative to Transformer self-attention. The SSM is implemented from scratch in pure PyTorch with no external dependencies.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
input_channels
|
int
|
Number of input channels (default: 1 for single-lead ECG) |
1
|
output_size
|
int
|
Number of output classes |
4
|
d_model
|
int
|
Model dimension (default: 128) |
128
|
d_state
|
int
|
State space dimension (default: 16) |
16
|
d_conv
|
int
|
Local convolution width (default: 4) |
4
|
expansion_factor
|
int
|
Inner dimension expansion (default: 2) |
2
|
num_layers
|
int
|
Number of bidirectional Mamba layers (default: 4) |
4
|
patch_size
|
int
|
Patch size for input tokenization (default: 50) |
50
|
dropout_rate
|
float
|
Dropout probability (default: 0.1) |
0.1
|
max_patches
|
int
|
Maximum number of patches (default: 500) |
500
|
Example
model = Mamba1D(input_channels=1, output_size=4) x = torch.randn(32, 1, 3000) output = model(x) print(output.shape)
features = model.extract_features(x) print(features.shape) # (32, 128)
Source code in deepecgkit/models/mamba1d.py
142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 | |
Pretrained Weights¶
PretrainedMixin
¶
Adds pretrained weight loading to a registered model.
Mix into any model whose constructor follows the shared
(input_channels, output_size, **kwargs) convention.
Example
model = KanResWideX.from_pretrained("kanres-af-30s") model = KanResWideX.from_pretrained("kanres-af-30s", map_location="cuda") model = KanResWideX.from_pretrained("/path/to/weights.pt", output_size=2) model = AFModel.from_pretrained("/path/to/trained.ckpt")
Source code in deepecgkit/models/pretrained.py
from_pretrained
classmethod
¶
from_pretrained(
weights: str | Path,
map_location: str | device | None = None,
force_download: bool = False,
**kwargs: Any,
) -> T
Build the model and load pretrained weights into it.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
weights
|
str | Path
|
Name of registered pretrained weights, or a path to a weights file, an ECGTrainer checkpoint, or a legacy PyTorch Lightning checkpoint |
required |
map_location
|
str | device | None
|
Device to map the weights onto while loading |
None
|
force_download
|
bool
|
Re-download registered weights even if cached |
False
|
**kwargs
|
Any
|
Constructor arguments, overriding anything recorded in the checkpoint or the weight registry |
{}
|
Returns:
| Type | Description |
|---|---|
T
|
The model with the weights loaded. |
Raises:
| Type | Description |
|---|---|
ValueError
|
If the weights name is unknown, or the file holds no recognisable weights. |
Source code in deepecgkit/models/pretrained.py
from_pretrained
¶
from_pretrained(
model_name: str,
weights: str | Path,
map_location: str | device | None = None,
force_download: bool = False,
**kwargs: Any,
) -> nn.Module
Build a registered model by name and load pretrained weights into it.
The callers that hold a model name rather than a class, such as the CLI and the feature extractor, use this instead of the classmethod.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
model_name
|
str
|
Registered model name |
required |
weights
|
str | Path
|
Name of registered pretrained weights, or a path to a weights file or checkpoint |
required |
map_location
|
str | device | None
|
Device to map the weights onto while loading |
None
|
force_download
|
bool
|
Re-download registered weights even if cached |
False
|
**kwargs
|
Any
|
Constructor arguments forwarded to the model |
{}
|
Returns:
| Type | Description |
|---|---|
Module
|
The model with the weights loaded. |
Raises:
| Type | Description |
|---|---|
KeyError
|
If the model name is not registered. |
TypeError
|
If the model does not support pretrained weight loading. |
Source code in deepecgkit/models/pretrained.py
model_name_for_weights
¶
Return the registry name of the model a set of pretrained weights targets.
The weight registry records the model's class name while the model registry is keyed on its short registry name, so the two need bridging.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
weight_name
|
str
|
Key into the pretrained weight registry |
required |
Returns:
| Type | Description |
|---|---|
str | None
|
The registered model name, or None if the weights are unknown or their |
str | None
|
class is not registered. |