Package: torch-ecg
torch_ecgECG Deep Learning Framework Implemented using PyTorch.Documentation (under development):GitHub PagesRead the Docslatest versionThe system design is depicted as followsInstallationMain ModulesAugmentersPreprocessorsDatabasesImplemented Neural Network ArchitecturesQuick ExampleCustom ModelCNN BackbonesImplementedOngoingTODOComponentsLoggersOutputsMetricsTrainerOther Useful ToolsR peaks detection algorithmsUsage ExamplesCAUTIONWork in progressCitationThanksInstallationtorch_ecgrequires Python 3.6+ and is available through pip:python-mpipinstalltorch-ecgOne can download the development version hosted atGitHubviagitclonehttps://github.com/DeepPSP/torch_ecg.gitcdtorch_ecg
python-mpipinstall.or use pip directly viapython-mpipinstallgit+https://github.com/DeepPSP/torch_ecg.gitMain ModulesAugmentersClick to expand!Augmenters are classes (subclasses oftorchModule) that perform data augmentation in a uniform way and are managed by theAugmenterManager(also a subclass oftorchModule). Augmenters and the manager share a common signature of theformwardmethod:forward(self,sig:Tensor,label:Optional[Tensor]=None,*extra_tensors:Sequence[Tensor],**kwargs:Any)->Tuple[Tensor,...]:The following augmenters are implemented:baseline wander (adding sinusoidal and gaussian noises)cutmixmixuprandom fliprandom maskingrandom renormalizestretch-or-compress (scaling)label smooth (not actually for data augmentation, but has simimlar behavior)Usage example (this example uses all augmenters except cutmix, each with default config):importtorchfromtorch_ecg.cfgimportCFGfromtorch_ecg.augmentersimportAugmenterManagerconfig=CFG(random=False,fs=500,baseline_wander={},label_smooth={},mixup={},random_flip={},random_masking={},random_renormalize={},stretch_compress={},)am=AugmenterManager.from_config(config)sig,label,mask=torch.rand(2,12,5000),torch.rand(2,26),torch.rand(2,5000,1)sig,label,mask=am(sig,label,mask)Augmenters can be stochastic along the batch dimension and (or) the channel dimension (ref. theget_indicesmethod of theAugmenterbase class).:point_right:Back to TOCPreprocessorsClick to expand!Alsopreprecessorsacting onnumpyarrays. Similarly, preprocessors are monitored by a managerimporttorchfromtorch_ecg.cfgimportCFGfromtorch_ecg._preprocessorsimportPreprocManagerconfig=CFG(random=False,resample={"fs":500},bandpass={},normalize={},)ppm=PreprocManager.from_config(config)sig=torch.rand(12,80000).numpy()sig,fs=ppm(sig,200)The following preprocessors are implementedbaseline removal (detrend)normalize (z-score, min-max, naïve)bandpassresampleFor more examples, see theREADME file) of thepreprecessorsmodule.:point_right:Back to TOCDatabasesClick to expand!This module include classes that manipulate the io of the ECG signals and labels in an ECG database, and maintains metadata (statistics, paths, plots, list of records, etc.) of it. This module is migrated and improved fromDeepPSP/database_readerAfter migration, all should be tested again, the progression:DatabaseSourceTestedAFDBPhysioNet:heavy_check_mark:ApneaECGPhysioNet:x:CinC2017PhysioNet:x:CinC2018PhysioNet:x:CinC2020PhysioNet:heavy_check_mark:CinC2021PhysioNet:heavy_check_mark:LTAFDBPhysioNet:x:LUDBPhysioNet:heavy_check_mark:MITDBPhysioNet:heavy_check_mark:SHHSNSRR:x:CPSC2018CPSC:heavy_check_mark:CPSC2019CPSC:heavy_check_mark:CPSC2020CPSC:heavy_check_mark:CPSC2021CPSC:heavy_check_mark:SPHFigshare:heavy_check_mark:NOTE that these classes should not be confused with atorchDataset, which is strongly related to the task (or the model). However, one can buildDatasets based on these classes, for example theDatasetfor the The 4th China Physiological Signal Challenge 2021 (CPSC2021).One can use the built-inDatasets intorch_ecg.databases.datasetsas followsfromtorch_ecg.databases.datasets.cinc2021importCINC2021Dataset,CINC2021TrainCfgconfig=deepcopy(CINC2021TrainCfg)config.db_dir="some/path/to/db"dataset=CINC2021Dataset(config,training=True,lazy=False):point_right:Back to TOCImplemented Neural Network ArchitecturesClick to expand!CRNN, both for classification and sequence tagging (segmentation)U-NetRR-LSTMA typical signature of the instantiation (__init__) function of a model is as follows__init__(self,classes:Sequence[str],n_leads:int,config:Optional[CFG]=None,**kwargs:Any)->Noneif aconfigis not specified, then the default config will be used (stored in themodel_configsmodule).Quick ExampleA quick example is as follows:importtorchfromtorch_ecg.utils.utils_nnimportadjust_cnn_filter_lengthsfromtorch_ecg.model_configsimportECG_CRNN_CONFIGfromtorch_ecg.models.ecg_crnnimportECG_CRNNconfig=adjust_cnn_filter_lengths(ECG_CRNN_CONFIG,fs=400)# change the default CNN backbone# bottleneck with global context attention variant of Nature Communications ResNetconfig.cnn.name="resnet_nature_comm_bottle_neck_gc"classes=["NSR","AF","PVC","SPB"]n_leads=12model=ECG_CRNN(classes,n_leads,config)model(torch.rand(2,12,4000))# signal length 4000, batch size 2Then a model for the classification of 4 classes, namely "NSR", "AF", "PVC", "SPB", on 12-lead ECGs is created. One can check the size of a model, in terms of the number of parameters viamodel.module_sizeor in terms of memory consumption viamodel.module_size_Custom ModelOne can adjust the configs to create a custom model. For example, the building blocks of the 4 stages of aTResNetbackbone arebasic,basic,bottleneck,bottleneck. If one wants to change the second block to be abottleneckblock with sequeeze and excitation (SE) attention, thenfromcopyimportdeepcopyfromtorch_ecg.models.ecg_crnnimportECG_CRNNfromtorch_ecg.model_configsimport(ECG_CRNN_CONFIG,tresnetF,resnet_bottle_neck_se,)my_resnet=deepcopy(tresnetP)my_resnet.building_block[1]="bottleneck"my_resnet.block[1]=resnet_bottle_neck_seThe convolutions in aTResNetare anti-aliasing convolutions, if one wants further to change the convolutions to normal convolutions, thenforbinmy_resnet.block:b.conv_type=Noneor change them to separable convolutions viaforbinmy_resnet.block:b.conv_type="separable"Finally, replace the default CNN backbone viamy_model_config=deepcopy(ECG_CRNN_CONFIG)my_model_config.cnn.name="my_resnet"my_model_config.cnn.my_resnet=my_resnetmodel=ECG_CRNN(["NSR","AF","PVC","SPB"],12,my_model_config):point_right:Back to TOCCNN BackbonesClick to expand!ImplementedVGGResNet (including vanilla ResNet, ResNet-B, ResNet-C, ResNet-D, ResNeXT, TResNet,Stanford ResNet,Nature Communications ResNet, etc.)MultiScopicNet (CPSC2019 SOTA)DenseNet (CPSC2020 SOTA)XceptionIn general, variants of ResNet are the most commonly used architectures, as can be inferred fromCinC2020andCinC2021.OngoingMobileNetDarkNetEfficientNetTODOHarDNetHO-ResNetU-Net++U-Squared Netetc.More details and a list of references can be found in theREADME fileof this module.:point_right:Back to TOCComponentsClick to expand!This module consists of frequently used components such as loggers, trainers, etc.LoggersLoggers includingCSV loggertext loggertensorboard logger
are implemented and manipulated uniformly by a manager.OutputsTheOutputclasses implemented in this module serve as containers for ECG downstream task model outputs, includingClassificationOutputMultiLabelClassificationOutputSequenceTaggingOutputWaveDelineationOutputRPeaksDetectionOutputeach having some required fields (keys), and is able to hold an arbitrary number of custom fields. These classes are useful for the computation of metrics.MetricsThis module has the following pre-defined (built-in)Metricsclasses:ClassificationMetricsRPeaksDetectionMetricsWaveDelineationMetricsThese metrics are computed according to eitherWikipedia, or some published literatures.TrainerAn abstract base classBaseTraineris implemented, in which some common steps in building a training pipeline (workflow) are impemented. A few task specific methods are assigned asabstractmethods, for example the methodevaluate(self,data_loader:DataLoader)->Dict[str,float]for evaluation on the validation set during training and perhaps further for model selection and early stopping.:point_right:Back to TOC:point_right:Back to TOCOther Useful ToolsClick to expand!R peaks detection algorithmsThis is a collection of traditional (non deep learning) algorithms for R peaks detection collected fromWFDBandBioSPPy.:point_right:Back to TOCUsage ExamplesClick to expand!See case studies in thebenchmarks folder.a large part of the case studies are migrated from other DeepPSP repositories, some are implemented in the old fasion, being inconsistent with the new system architecture oftorch_ecg, hence need updating and testingBenchmarkArchitectureSourceFinishedUpdatedTestedCinC2020CRNNDeepPSP/cinc2020:heavy_check_mark::heavy_check_mark::heavy_check_mark:CinC2021CRNNDeepPSP/cinc2021:heavy_check_mark::heavy_check_mark::heavy_check_mark:CinC2022[^1]Multi Task Learning (MTL)DeepPSP/cinc2022:heavy_check_mark::heavy_check_mark::heavy_check_mark:CPSC2019SequenceTagging/U-NetNA:heavy_check_mark::heavy_check_mark::heavy_check_mark:CPSC2020CRNN/SequenceTaggingDeepPSP/cpsc2020:heavy_check_mark::x::x:CPSC2021CRNN/SequenceTagging/LSTMDeepPSP/cpsc2021:heavy_check_mark::heavy_check_mark::heavy_check_mark:LUDBU-NetNA:heavy_check_mark::heavy_check_mark::heavy_check_mark:[^1]: AlthoughCinC2022dealt with acoustic cardiac signals (phonocardiogram, PCG), the tasks and signals can be treated similarly.TakingCPSC2021for example, the steps areWrite aDatasetto fit the training data for the model(s) and the training workflow. Or directly use the built-inDatasets intorch_ecg.databases.datasets. In this example, 3 tasks are considered, 2 of which use aMaskedBCEWithLogitsLossfunction, hence theDatasetproduces an extra tensor for these 2 tasksdef__getitem__(self,index:int)->Tuple[np.ndarray,...]:ifself.lazy:ifself.taskin["qrs_detection"]:returnself.fdr[index][:2]else:returnself.fdr[index]else:ifself.taskin["qrs_detection"]:returnself._all_data[index],self._all_labels[index]else:returnself._all_data[index],self._all_labels[index],self._all_masks[index]Inherit abase modelto createtask specific models, along withtailored model configsInherit theBaseTrainerto build thetraining pipeline, with theabstractmethods (_setup_dataloaders,run_one_step,evaluate,batch_dim, etc.) implemented.:point_right:Back to TOCCAUTIONFor the most of the time, but not always, after updates, I will run the notebooks in thebenchmarksmanually. If someone finds some bug, please raise an issue. The test workflow is to be enhanced and automated, seethis project.:point_right:Back to TOCWork in progressSee theprojects page.:point_right:Back to TOCCitation@misc{torch_ecg,
      title ={{torch\_ecg: An ECG Deep Learning Framework Implemented using PyTorch}},
     author ={WEN, Hao and KANG, Jingsu},
        doi ={10.5281/ZENODO.6435048},
        url ={https://zenodo.org/record/6435048},
  publisher ={Zenodo},
       year ={2022},
  copyright ={{MIT License}}}@article{torch_ecg_paper,
      title ={{A Novel Deep Learning Package for Electrocardiography Research}},
     author ={Hao Wen and Jingsu Kang},
    journal ={{Physiological Measurement}},
        doi ={10.1088/1361-6579/ac9451},
       year ={2022},
      month ={11},
  publisher ={{IOP Publishing}},
     volume ={43},
     number ={11},
      pages ={115006}}:point_right:Back to TOCThanksMuch is learned, especially the modular design, from the adversarial NLP libraryTextAttackand from Hugging Facetransformers.:point_right:Back to TOC