Сегментация формы волны с использованием глубокого обучения

Этот пример показывает, как сегментировать сигналы электрокардиограммы (ЭКГ) человека с помощью рецидивирующих нейронных сетей для глубокого обучения и частотно-временного анализа.

Введение

Электрическая активность в сердце человека может быть измерена как последовательность амплитуд от базового сигнала. Для одного нормального цикла сердцебиения сигнал ЭКГ может быть разделен на следующие морфологии пульса [1]:

  • P-волна - небольшой прогиб перед комплексом QRS, представляющий деполяризацию предсердий

  • Комплекс QRS - Наибольшая амплитуда фрагмента пульса

  • Т-волна - небольшой прогиб после комплекса QRS, представляющего реполяризацию желудочков

Сегментация этих областей форм волны ЭКГ может обеспечить базис для измерений, полезных для оценки общего состояния здоровья человеческого сердца и наличия аномалий [2]. Вручную аннотирование каждой области сигнала ЭКГ может быть утомительной и длительной задачей. Обработка сигналов и методы глубокого обучения потенциально могут помочь оптимизировать и автоматизировать аннотацию необходимой области.

Этот пример использует сигналы ЭКГ из общедоступной базы данных QT [3] [4]. Данные состоят примерно из 15 минут записей ЭКГ с частотой дискретизации 250 Гц, измеренной от общего числа 105 пациентов. Чтобы получить каждую запись, экзаменаторы поместили два электрода в других местах на груди пациента, получая двухканальный сигнал. База данных обеспечивает метки областей сигнала, сгенерированные автоматизированной экспертной системой [2]. Этот пример направлен на использование решения глубокого обучения, чтобы обеспечить метку для каждой выборки сигнала ЭКГ в соответствии с областью, где расположена выборка. Этот процесс маркировки необходимых областей через сигнал часто упоминается как сегментация формы волны.

Чтобы обучить глубокую нейронную сеть классифицировать области сигнала, можно использовать сеть Long Short-Term Memory (LSTM). Этот пример показывает, как методы предварительной обработки сигналов и частотно-временной анализ могут использоваться, чтобы улучшить эффективность сегментации LSTM. В частности, пример использует Synchrosqueezed преобразование Фурье, чтобы представлять нестационарное поведение сигнала ЭКГ.

Загрузка и подготовка данных

Каждый канал 105 двухканальных сигналов ЭКГ был маркирован независимо автоматизированной экспертной системой и обрабатывается независимо, в общей сложности 210 сигналов ЭКГ, которые хранились вместе с метками области в 210 MAT-файлах. Файлы доступны в следующем расположении: https://www.mathworks.com/supportfiles/SPT/data/QTDatabaseECGData.zip.

Загрузите файлы данных в свою временную директорию, расположение которого задано tempdir MATLAB ® команда. Если вы хотите поместить файлы данных в папку, отличную от tempdirизмените имя директории в последующих инструкциях.

% Download the data
dataURL = 'https://www.mathworks.com/supportfiles/SPT/data/QTDatabaseECGData1.zip';
datasetFolder = fullfile(tempdir,'QTDataset');
zipFile = fullfile(tempdir,'QTDatabaseECGData.zip');
if ~exist(datasetFolder,'dir')
     websave(zipFile,dataURL);
     unzip(zipFile,tempdir);
end

The unzip операция создает QTDatabaseECGData папка во временной директории с 210 MAT-файлами в ней. Каждый файл содержит сигнал ЭКГ в переменной ecgSignal и таблица меток областей в переменных signalRegionLabels. Каждый файл также содержит частоту дискретизации сигнала в переменной Fs. В этом примере все сигналы имеют частоту дискретизации 250 Гц.

Создайте сигнальный datastore для доступа к данным в файлах. Этот пример предполагает, что набор данных был сохранен в вашей временной директории под QTDatabaseECGData папка. Если это не так, измените путь к данным в коде ниже. Укажите имена переменных, которые вы хотите считать из каждого файла, используя SignalVariableNames параметр.

sds = signalDatastore(datasetFolder,'SignalVariableNames',["ecgSignal","signalRegionLabels"])
sds = 
  signalDatastore with properties:

                       Files:{
                             '/tmp/QTDataset/ecg1.mat';
                             '/tmp/QTDataset/ecg10.mat';
                             '/tmp/QTDataset/ecg100.mat'
                              ... and 207 more
                             }
    AlternateFileSystemRoots: [0×0 string]
                    ReadSize: 1
         SignalVariableNames: ["ecgSignal"    "signalRegionLabels"]

datastore возвращает массив ячеек с двумя элементами с сигналом ECG и таблицей меток областей каждый раз, когда вы вызываете read функция. Используйте preview функция datastore, чтобы увидеть, что содержимое первого файла является сигналом ЭКГ длиной 225000 дискретизаций и таблицей, содержащей 3385 меток областей.

data = preview(sds)
data=2×1 cell array
    {225000×1 double}
    {  3385×2 table }

Проверьте первые несколько строк таблицы меток областей и заметьте, что каждая строка содержит индексы пределов областей и значение класса областей (P, T или QRS).

head(data{2})
ans=8×2 table
    ROILimits     Value
    __________    _____

     83    117     P   
    130    153     QRS 
    201    246     T   
    285    319     P   
    332    357     QRS 
    412    457     T   
    477    507     P   
    524    547     QRS 

Визуализируйте метки для первых 1000 выборок с помощью signalMask объект.

M = signalMask(data{2});
plotsigroi(M,data{1}(1:1000))

Обычная процедура классификации машинного обучения является следующей:

  1. Разделите базу данных на обучающие и тестовые наборы данных.

  2. Обучите сеть с помощью обучающего набора данных.

  3. Используйте обученную сеть, чтобы делать предсказания на тестовом наборе данных.

Сеть обучается с 70% данных и тестируется с оставшимися 30%.

Для воспроизводимых результатов сбросьте генератор случайных чисел. Используйте dividerand функция для получения случайных индексов для тасования файлов и subset функция signalDatastore разделить данные на обучающие и тестовые хранилища данных.

rng default
[trainIdx,~,testIdx] = dividerand(numel(sds.Files),0.7,0,0.3);
trainDs = subset(sds,trainIdx);
testDs = subset(sds,testIdx);

В этой задаче сегментации вход в сеть LSTM является сигналом ECG, а выход является последовательностью или маской меток с той же длиной, что и входной сигнал. Сетевая задача состоит в том, чтобы пометить каждую выборку сигнала именем области, к которой она принадлежит. По этой причине необходимо преобразовать метки области на наборе данных в последовательности, содержащие по одной метке на выборку сигнала. Используйте преобразованные datastore и getmask вспомогательная функция для преобразования меток областей. The getmask функция добавляет категорию меток, "n/a", для маркировки выборок, которые не относятся ни к одной необходимой области.

type getmask.m
function outputCell = getmask(inputCell)
%GETMASK Convert region labels to a mask of labels of size equal to the
%size of the input ECG signal.
%
%   inputCell is a two-element cell array containing an ECG signal vector
%   and a table of region labels. 
%
%   outputCell is a two-element cell array containing the ECG signal vector
%   and a categorical label vector mask of the same length as the signal. 

% Copyright 2020 The MathWorks, Inc.

sig = inputCell{1};
roiTable = inputCell{2};
L = length(sig);
M = signalMask(roiTable);

% Get categorical mask and give priority to QRS regions when there is overlap
mask = catmask(M,L,'OverlapAction','prioritizeByList','PriorityList',[2 1 3]);

% Set missing values to "n/a"
mask(ismissing(mask)) = "n/a";

outputCell = {sig,mask};
end

Предварительный просмотр преобразованного datastore, чтобы заметить, что он возвращает вектор сигнала и вектор метки равной длины. Постройте график первого элемента 1000 вектора категориальной маски.

trainDs = transform(trainDs, @getmask);
testDs = transform(testDs, @getmask);

transformedData = preview(trainDs)
transformedData=1×2 cell array
    {224993×1 double}    {224993×1 categorical}

plot(transformedData{2}(1:1000))

Передача очень длинных входных сигналов в сеть LSTM может привести к снижению эффективности оценки и чрезмерному использованию памяти. Чтобы избежать этих эффектов, нарушите сигналы ECG и их соответствующие маски меток с помощью преобразованных datastore и resizeData вспомогательная функция. Функция helper создает как можно больше сегментов с 5000 образцами и отбрасывает оставшиеся выборки. Предварительный просмотр выхода преобразованного datastore показывает, что первый сигнал ECG и его маска метки разбиты на сегменты с 5000 образцами. Обратите внимание, что предварительный просмотр преобразованного datastore показывает только первые 8 элементов обратного floor(224993/5000) = 44 массив ячеек элемента, который получился бы, если бы мы назвали datastore read функция.

trainDs = transform(trainDs,@resizeData);
testDs = transform(testDs,@resizeData);
preview(trainDs)
ans=8×2 cell array
    {1×5000 double}    {1×5000 categorical}
    {1×5000 double}    {1×5000 categorical}
    {1×5000 double}    {1×5000 categorical}
    {1×5000 double}    {1×5000 categorical}
    {1×5000 double}    {1×5000 categorical}
    {1×5000 double}    {1×5000 categorical}
    {1×5000 double}    {1×5000 categorical}
    {1×5000 double}    {1×5000 categorical}

Выбор для обучения сетей или загрузки предварительно обученных сетей

В следующих разделах этого примера сравниваются три различных подхода к обучению сетей LSTM. Из-за большого размера набора данных процесс обучения каждой сети может занять несколько минут. Если на вашей машине есть графический процессор и Parallel Computing Toolbox™, то MATLAB автоматически использует графический процессор для более быстрого обучения. В противном случае используется центральный процессор.

Можно пропустить шаги обучения и загрузить предварительно обученные сети с помощью селектора ниже. Если вы хотите обучить сети в качестве примера запусков, выберите 'Train Networks'. Если вы хотите пропустить шаги обучения, выберите 'Download Networks' и файл, содержащий все три предварительно обученные сети - rawNet, filteredNet, и fsstNet- будет загружен во временную директорию, местоположение которого задано tempdir MATLAB ® команда. Если вы хотите поместить загруженный файл в папку, отличную от tempdirизмените имя директории в последующих инструкциях.

actionFlag = "Train networks";
if actionFlag =  ="Download networks"
    % Download the pre-trained networks
    dataURL = 'https://ssd.mathworks.com/supportfiles/SPT/data/QTDatabaseECGSegmentationNetworks.zip'; %#ok<*UNRCH>
    modelsFolder = fullfile (tempdir,'QTDatabaseECGSegmentationNetworks');
    modelsFile = fullfile (modelsFolder,'trainedNetworks.mat');
    zipFile = fullfile (tempdir,'QTDatabaseECGSegmentationNetworks.zip');
    if ~ существует (modelsFolder,'dir')
        веб-сайт (zipFile, dataURL);
        unzip (zipFile, fullfile (tempdir,'QTDatabaseECGSegmentationNetworks'));
    end
    load (modelsFile)
end

Результаты между загруженными сетями и вновь обученными сетями могут незначительно варьироваться, поскольку сети обучаются с использованием случайных начальных весов.

Входные необработанные сигналы ECG непосредственно в сеть LSTM

Сначала обучите сеть LSTM, используя необработанные сигналы ECG от обучающего набора данных.

Определите сетевую архитектуру перед обучением. Задайте sequenceInputLayer размера 1, чтобы принять одномерные временные ряды. Задайте слой LSTM с 'sequence' выходной режим для обеспечения классификации для каждой выборки в сигнале. Используйте 200 скрытых узлов для оптимальной эффективности. Задайте fullyConnectedLayer с размером выходом 4, по одному для каждого из классов формы волны. Добавление softmaxLayer и a classificationLayer для вывода предполагаемых меток.

layers = [ ...
    sequenceInputLayer(1)
    lstmLayer(200,'OutputMode','sequence')
    fullyConnectedLayer(4)
    softmaxLayer
    classificationLayer];

Выберите опции процесса обучения, которые гарантируют хорошую эффективность сети. Обратитесь к trainingOptions (Deep Learning Toolbox) документация для описания каждого параметра.

options = trainingOptions('adam', ...
    'MaxEpochs',10, ...
    'MiniBatchSize',50, ...
    'InitialLearnRate',0.01, ...
    'LearnRateDropPeriod',3, ...
    'LearnRateSchedule','piecewise', ...
    'GradientThreshold',1, ...
    'Plots','training-progress',...
    'shuffle','every-epoch',...
    'Verbose',0,...
    'DispatchInBackground',true);

Поскольку весь обучающий набор данных помещается в памяти, возможно использовать tall функция datastore, чтобы преобразовать данные параллельно, если доступна Toolbox™ Parallel Computing, и затем собрать их в рабочую область. Обучение нейронной сети итеративно. При каждой итерации datastore считывает данные из файлов и преобразует данные перед обновлением сетевых коэффициентов. Если данные помещаются в память компьютера, импорт данных в рабочую область позволяет ускорить обучение, поскольку данные считываются и преобразуются только один раз. Обратите внимание, что если данные не помещаются в памяти, необходимо передать datastore в функцию обучения, и преобразования выполняются в каждую эпоху обучения.

Создайте длинные массивы как для обучающих, так и для тестовых наборов. В зависимости от системы, количество работников в параллельном пуле, который создает MATLAB, может отличаться.

tallTrainSet = tall(trainDs);
Starting parallel pool (parpool) using the 'local' profile ...
Connected to the parallel pool (number of workers: 8).
tallTestSet = tall(testDs);

Теперь вызовите gather функция длинных массивов для вычисления преобразований по набору данных в целом и получения массивов ячеек с помощью обучающих и тестовых сигналов и меток.

 trainData = gather(tallTrainSet);
Evaluating tall expression using the Parallel Pool 'local':
- Pass 1 of 1: Completed in 11 sec
Evaluation completed in 12 sec
 trainData(1,:)
ans=1×2 cell array
    {1×5000 double}    {1×5000 categorical}

 testData = gather(tallTestSet);
Evaluating tall expression using the Parallel Pool 'local':
- Pass 1 of 1: Completed in 2.9 sec
Evaluation completed in 3.1 sec

Обучите сеть

Используйте trainNetwork команда для обучения сети LSTM.

if actionFlag == "Train networks"
     rawNet = trainNetwork(trainData(:,1),trainData(:,2),layers,options);
end

Подграфики точности и потерь обучения на рисунке отслеживают процесс обучения во всех итерациях. Используя данные необработанного сигнала, сеть правильно классифицирует около 77% выборок как принадлежащие к P-волне, комплексу QRS, T-волне или немеченой области "n/a".

Классификация тестовых данных

Классификация тестовых данных с помощью обученной сети LSTM и classify команда. Задайте мини-пакет размером 50, чтобы соответствовать опциям обучения.

predTest = classify(rawNet,testData(:,1),'MiniBatchSize',50);

Матрица неточностей предоставляет интуитивно понятное и информативное средство для визуализации классификационной эффективности. Используйте confusionchart команда для вычисления общей точности классификации для предсказаний тестовых данных. Для каждого входа преобразуйте массив ячеек категориальных меток в вектор-строку. Задайте нормированное к столбцу отображение, чтобы просмотреть результаты как проценты выборок для каждого класса.

confusionchart([predTest{:}],[testData{:,2}],'Normalization','column-normalized');

Используя необработанный сигнал ЭКГ в качестве входных данных для сети, было правильным только около 60% выборок Т-волны, 40% выборок Р-волны и 60% выборок QRS-комплекса. Чтобы улучшить эффективность, примените некоторые знания о характеристиках сигнала ЭКГ перед входом в нейронную сеть для глубокого обучения для образца базовой линии блуждания, вызванной дыхательным движением пациента.

Применить методы фильтрации для удаления базового блуждания и высокочастотного шума

Три морфологии биений занимают различные полосы частот. Спектр комплекса QRS обычно имеет центральную частоту около 10-25 Гц, а его компоненты находятся ниже 40 Гц. Волны P и T происходят на ещё более низких частотах: компоненты P-волны находятся ниже 20 Гц, а компоненты T-волны - ниже 10 Гц [5].

Базовым блужданием является низкочастотное (< 0,5 Гц) колебание, вызванное дыхательным движением пациента. Это колебание не зависит от морфологий биения и не предоставляет содержательной информации [6].

Создайте полосно-пропускающий фильтр с областью значений частоты полосы пропускания [0,5, 40] Гц, чтобы удалить блуждание и любой шум высокой частоты. Удаление этих компонентов улучшает обучение LSTM, поскольку сеть не учит нерелевантные функции. Использование cellfun на tall data массивов ячеек для параллельной фильтрации набора данных.

% Bandpass filter design
hFilt = designfilt('bandpassiir', 'StopbandFrequency1',0.4215,'PassbandFrequency1', 0.5, ...
    'PassbandFrequency2',40,'StopbandFrequency2',53.345,...
    'StopbandAttenuation1',60,'PassbandRipple',0.1,'StopbandAttenuation2',60,...
    'SampleRate',250,'DesignMethod','ellip');

% Create tall arrays from the transformed datastores and filter the signals
tallTrainSet = tall(trainDs);
tallTestSet = tall(testDs);

filteredTrainSignals = gather(cellfun(@(x)filter(hFilt,x),tallTrainSet(:,1),'UniformOutput',false));
Evaluating tall expression using the Parallel Pool 'local':
- Pass 1 of 1: 0% complete
Evaluation 0% complete

- Pass 1 of 1: Completed in 13 sec
Evaluation completed in 14 sec
trainLabels = gather(tallTrainSet(:,2));
Evaluating tall expression using the Parallel Pool 'local':
- Pass 1 of 1: Completed in 3.6 sec
Evaluation completed in 4 sec
filteredTestSignals = gather(cellfun(@(x)filter(hFilt,x),tallTestSet(:,1),'UniformOutput',false));
Evaluating tall expression using the Parallel Pool 'local':
- Pass 1 of 1: Completed in 2.4 sec
Evaluation completed in 2.5 sec
testLabels = gather(tallTestSet(:,2));
Evaluating tall expression using the Parallel Pool 'local':
- Pass 1 of 1: Completed in 1.9 sec
Evaluation completed in 2 sec

Постройте график необработанных и отфильтрованных сигналов для типового случая.

trainData = gather(tallTrainSet);
Evaluating tall expression using the Parallel Pool 'local':
- Pass 1 of 1: Completed in 4 sec
Evaluation completed in 4.2 sec
figure
subplot(2,1,1)
plot(trainData{95,1}(2001:3000))
title('Raw')
grid
subplot(2,1,2)
plot(filteredTrainSignals{95}(2001:3000))
title('Filtered')
grid

Несмотря на то, что базовая линия отфильтрованных сигналов может запутать врача, который используется для традиционных измерений ЭКГ на медицинских устройствах, сеть фактически выиграет от блуждающего удаления.

Обучите сеть с фильтрованными сигналами ECG

Обучите сеть LSTM по фильтрованным сигналам ECG с помощью той же сетевой архитектуры, что и ранее.

if actionFlag == "Train networks"
    filteredNet = trainNetwork(filteredTrainSignals,trainLabels,layers,options);
end

Предварительная обработка сигналов повышает точность обучения до более 80%.

Классификация фильтрованных сигналов ЭКГ

Классификация предварительно обработанных тестовых данных с обновленной сетью LSTM.

predFilteredTest = classify(filteredNet,filteredTestSignals,'MiniBatchSize',50);

Визуализируйте эффективность классификации как матрицу неточностей.

figure
confusionchart([predFilteredTest{:}],[testLabels{:}],'Normalization','column-normalized');

Простая предварительная обработка улучшает классификацию Т-волн примерно на 15%, и классификацию QRS-комплекса и Р-волн примерно на 10%.

Частотно-временное представление сигналов ЭКГ

Общий подход для успешной классификации данного timeseries состоит в том, чтобы извлечь функции и передать их в сеть вместо исходных данных. Затем сеть изучает шаблоны между временем и частотой одновременно [7].

Synchrosqueezed преобразование Фурье (FSST) вычисляет частотный спектр для каждой выборки сигнала, поэтому он идеально подходит для рассматриваемой задачи сегментации, где нам нужно поддерживать то же временное разрешение, что и исходные сигналы. Используйте fsst функция для проверки преобразования одного из обучающих сигналов. Задайте окно Кайзера длины 128, чтобы обеспечить адекватное разрешение частоты.

data =  preview(trainDs);
figure
fsst(data{1,1},250,kaiser(128),'yaxis')

Вычислите FSST каждого сигнала в обучающем наборе данных в интересующей частотной области значений [0,5, 40] Гц. Относитесь к реальным и мнимым частям FSST как к отдельным функциям и подайте оба компонента в сеть. Кроме того, стандартизируйте функции путем вычитания среднего и деления на стандартное отклонение. Используйте преобразованный datastore, extractFSSTFeatures вспомогательная функция и tall функция для параллельной обработки данных.

fsstTrainDs = transform(trainDs,@(x)extractFSSTFeatures(x,250));
fsstTallTrainSet = tall(fsstTrainDs);
fsstTrainData = gather(fsstTallTrainSet);
Evaluating tall expression using the Parallel Pool 'local':
- Pass 1 of 1: 0% complete
Evaluation 0% complete

- Pass 1 of 1: Completed in 2 min 35 sec
Evaluation completed in 2 min 35 sec

Повторите эту процедуру для данных проверки.

fsstTTestDs = transform(testDs,@(x)extractFSSTFeatures(x,250));
fsstTallTestSet = tall(fsstTTestDs);
fsstTestData = gather(fsstTallTestSet);
Evaluating tall expression using the Parallel Pool 'local':
- Pass 1 of 1: Completed in 1 min 4 sec
Evaluation completed in 1 min 4 sec

Настройка сетевой архитектуры

Измените архитектуру LSTM так, чтобы сеть приняла частотный спектр для каждой выборки вместо одного значения. Проверьте размер FSST, чтобы увидеть количество частот.

size(fsstTrainData{1,1})
ans = 1×2

          40        5000

Задайте sequenceInputLayer из 40 входных функций. Оставьте оставшиеся параметры сети неизменными.

layers = [ ...
    sequenceInputLayer(40)
    lstmLayer(200,'OutputMode','sequence')
    fullyConnectedLayer(4)
    softmaxLayer
    classificationLayer];

Обучите сеть с FSST сигналов ЭКГ

Обучите обновленную сеть LSTM с помощью преобразованного набора данных.

if actionFlag == "Train networks"
    fsstNet = trainNetwork(fsstTrainData(:,1),fsstTrainData(:,2),layers,options);
end

Использование функций повышает точность обучения, которая теперь превышает 90%.

Классификация тестовых данных с помощью FSST

Используя обновленную сеть LSTM и извлеченные функции FSST, классифицируйте данные проверки.

predFsstTest = classify(fsstNet,fsstTestData(:,1),'MiniBatchSize',50);

Визуализируйте эффективность классификации как матрицу неточностей.

confusionchart([predFsstTest{:}],[fsstTestData{:,2}],'Normalization','column-normalized');

Использование представления частота-время улучшает классификацию Т-волн примерно на 25%, классификацию Р-волн примерно на 40% и классификацию QRS-комплекса на 30%, по сравнению с результатами необработанных данных.

Использование signalMask объект для сравнения сетевого предсказания с метками основной истины для одного сигнала ECG. Игнорируйте "n/a" метки при построении графика необходимых областей.

testData = gather(tall(testDs));
Evaluating tall expression using the Parallel Pool 'local':
- Pass 1 of 1: 0% complete
Evaluation 0% complete

- Pass 1 of 1: Completed in 37 sec
Evaluation completed in 37 sec
Mtest = signalMask(testData{1,2}(3000:4000));
Mtest.SpecifySelectedCategories = true;
Mtest.SelectedCategories = find(Mtest.Categories ~= "n/a");

figure
subplot(2,1,1)
plotsigroi(Mtest,testData{1,1}(3000:4000))
title('Ground Truth')

Mpred = signalMask(predFsstTest{1}(3000:4000));
Mpred.SpecifySelectedCategories = true;
Mpred.SelectedCategories = find(Mpred.Categories ~= "n/a");

subplot(2,1,2)
plotsigroi(Mpred,testData{1,1}(3000:4000))
title('Predicted')

Заключение

Этот пример показал, как предварительная обработка сигнала и частотно-временной анализ могут улучшить эффективность сегментации формы сигнала LSTM. Фильтрация полосой пропускания и синхронизация на основе Фурье приводят к среднему улучшению по всем выходным классам с 55% до около 85%.

Ссылки

[1] McSharry, Patrick E., et al. Динамическая модель для генерации синтетических электрокардиограммных сигналов. Транзакции IEEE ® по биомедицинской инженерии. Том 50, № 3, 2003, стр. 289-294.

[2] Лагуна, Пабло, Раймон Жане и Пере Каминаль. «Автоматическое обнаружение контуров волны в многоуровневых сигналах ЭКГ: валидация с базой данных CSE». Компьютеры и биомедицинские исследования. Том 27, № 1, 1994, стр. 45-60.

[3] Голдбергер, Ари Л., Луис А. Н. Амарал, Леон Гласс, Джеффри М. Хаусдорф, Пламен Ч. Иванов, Роджер Г. Марк, Джозеф Е. Миетус, Джордж Б. Муди, Чунг-Канг Пенг PhysioBank, PhysioToolkit и PhysioNet: компоненты нового исследовательского ресурса комплексных физиологических сигналов. Циркуляция. Том 101, № 23, 2000, стр. e215-e220. [Тиражные электронные страницы; http://circ.ahajournals.org/content/101/23/e215.full].

[4] Лагуна, Пабло, Роджер Г. Марк, Ари Л. Голдбергер и Джордж Б. Муди. «База данных для оценки алгоритмов измерения интервалов QT и других сигналов в ЭКГ». Компьютеры в кардиологии. Vol.24, 1997, стр 673–676.

[5] Sörnmo, Leif, and Pablo Laguna. «Обработка сигнала электрокардиограммы (ЭКГ)». Wiley Encyclopedia of Biomedical Engineering, 2006.

[6] Kohler, B-U., Carsten Hennig, and Reinhold Orglmeister. «Принципы обнаружения QRS программного обеспечения». IEEE Engineering in Medicine and Biology Magazine. Том 21, № 1, 2002, стр. 42-57.

[7] Саламон, Джастин и Хуан Пабло Белло. Глубокие сверточные нейронные сети и увеличение данных для классификации звука окружающей среды. Буквы обработки сигналов IEEE. Том 24, № 3, 2017, с. 279-283.

См. также

Функции

Похожие темы