В этом примере показано, как сегментировать сигналы электрокардиограммы человека (ЭКГ) с использованием повторяющихся сетей глубокого обучения и частотно-временного анализа.
Электрическая активность в человеческом сердце может быть измерена как последовательность амплитуд от базового сигнала. Для одного нормального цикла сердцебиения сигнал ЭКГ можно разделить на следующие морфологии биений [1]:
P wave - небольшой прогиб перед комплексом QRS, представляющим собой деполяризацию предсердий;
Комплекс QRS - часть пульса с наибольшей амплитудой
T wave - небольшой прогиб после комплекса QRS, представляющий реполяризацию желудочков
Сегментация этих областей ЭКГ-сигналов может служить основой для измерений, полезных для оценки общего состояния здоровья сердца человека и наличия аномалий [2]. Аннотирование вручную каждой области сигнала ЭКГ может быть утомительной и трудоемкой задачей. Обработка сигналов и методы глубокого обучения потенциально могут помочь упростить и автоматизировать аннотацию региона интересов.
В этом примере используются сигналы ЭКГ из общедоступной базы данных QT [3] [4]. Данные состоят примерно из 15 минут записей ЭКГ с частотой выборки 250 Гц, измеренной от общего числа 105 пациентов. Чтобы получить каждую запись, экзаменаторы разместили два электрода в разных местах на груди пациента, что привело к двухканальному сигналу. База данных предоставляет метки области сигнала, генерируемые автоматизированной экспертной системой [2]. Этот пример направлен на использование решения глубокого обучения для обеспечения метки для каждого образца сигнала ЭКГ в соответствии с областью, где находится образец. Этот процесс маркировки областей, представляющих интерес для сигнала, часто называют сегментацией формы сигнала.
Для обучения глубокой нейронной сети классификации сигнальных областей можно использовать сеть Long Short-Term Memory (LSTM). В этом примере показано, как методы предварительной обработки сигнала и частотно-временной анализ могут быть использованы для улучшения характеристик сегментации LSTM. В частности, в примере используется синхронизированное преобразование Фурье для представления нестационарного поведения сигнала ЭКГ.
Каждый канал из 105 двухканальных ЭКГ-сигналов был помечен независимо автоматизированной экспертной системой и обработан независимо, в общей сложности, 210 ЭКГ-сигналов, которые были сохранены вместе с метками области в 210 MAT-файлах. Файлы доступны в следующем расположении: https://www.mathworks.com/supportfiles/SPT/data/QTDatabaseECGData.zip.
Загрузите файлы данных во временный каталог, местоположение которого определяется параметрами MATLAB ® tempdir команда. Если вы хотите поместить файлы данных в папку, отличную от 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
unzip операция создает QTDatabaseECGData папка во временном каталоге с 210 MAT-файлами в нем. Каждый файл содержит сигнал ЭКГ в переменной ecgSignal и таблица меток областей в переменной signalRegionLabels. Каждый файл также содержит частоту дискретизации сигнала в переменной Fs. В этом примере все сигналы имеют частоту дискретизации 250 Гц.
Создайте хранилище данных сигнала для доступа к данным в файлах. В этом примере предполагается, что набор данных был сохранен во временном каталоге 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"]
Хранилище данных возвращает двухэлементный массив ячеек с сигналом ЭКГ и таблицей меток областей при каждом вызове read функция. Используйте preview функция хранилища данных, чтобы видеть, что содержание первого файла представляет собой 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))
Обычная процедура классификации машинного обучения состоит в следующем:
Разбейте базу данных на наборы данных обучения и тестирования.
Обучение сети с использованием набора учебных данных.
Используйте обученную сеть для прогнозирования тестового набора данных.
Сеть обучена 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 представляет собой сигнал ЭКГ, а выход представляет собой последовательность или маску меток той же длины, что и входной сигнал. Задача сети - маркировать каждый образец сигнала именем региона, которому он принадлежит. По этой причине необходимо преобразовать метки области в наборе данных в последовательности, содержащие одну метку на выборку сигнала. Используйте преобразованное хранилище данных и getmask вспомогательная функция для преобразования меток области. getmask функция добавляет категорию меток, "n/a", для маркировки образцов, которые не принадлежат какой-либо интересующей области.
type getmask.mfunction 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
Просмотрите преобразованное хранилище данных, чтобы убедиться, что оно возвращает вектор сигнала и вектор метки одинаковой длины. Постройте график первого 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 может привести к снижению производительности оценки и чрезмерному использованию памяти. Чтобы избежать этих эффектов, разрушайте сигналы ЭКГ и их соответствующие маски меток с помощью преобразованного хранилища данных и resizeData функция помощника. Вспомогательная функция создает как можно больше сегментов из 5000 образцов и отбрасывает оставшиеся образцы. Предварительный просмотр выходных данных преобразованного хранилища данных показывает, что первый сигнал ЭКГ и его маска метки разбиты на 5000 сегментов выборки. Обратите внимание, что предварительный просмотр преобразованного хранилища данных показывает только первые 8 элементов в противном случае floor(224993/5000) = 44 элемента массива ячеек, что приведет к вызову хранилища данных 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. Из-за большого размера набора данных процесс обучения каждой сети может занять несколько минут. Если компьютер имеет графический процессор и Toolbox™ параллельных вычислений, MATLAB автоматически использует графический процессор для более быстрого обучения. В противном случае используется ЦП.
Вы можете пропустить этапы обучения и загрузить предварительно обученные сети, используя селектор ниже. Если требуется обучить сети по мере выполнения примера, выберите «Train Networks». Если вы хотите пропустить этапы обучения, выберите «Download Networks» и файл, содержащий все три предварительно обученные сети -rawNet, filteredNet, и fsstNet- будет загружен во временный каталог, местоположение которого указано в документах MATLAB ® tempdir команда. Если вы хотите поместить загруженный файл в папку, отличную от 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 ~exist(modelsFolder,'dir') websave(zipFile,dataURL); unzip(zipFile,fullfile(tempdir,'QTDatabaseECGSegmentationNetworks')); end load(modelsFile) end
Результаты между загруженными сетями и недавно обученными сетями могут незначительно изменяться, поскольку сети обучаются с использованием случайных начальных весов.
Во-первых, обучить сеть LSTM, используя необработанные сигналы ЭКГ из обучающего набора данных.
Определите архитектуру сети перед обучением. Укажите sequenceInputLayer размера 1 для принятия одномерных временных рядов. Укажите уровень LSTM с помощью 'sequence' режим вывода для обеспечения классификации каждого образца в сигнале. Для оптимальной производительности используйте 200 скрытых узлов. Укажите fullyConnectedLayer с размером выходного сигнала 4, по одному для каждого из классов формы сигнала. Добавить softmaxLayer и classificationLayer для вывода оценочных меток.
layers = [ ... sequenceInputLayer(1) lstmLayer(200,'OutputMode','sequence') fullyConnectedLayer(4) softmaxLayer classificationLayer];
Выберите параметры процесса обучения, обеспечивающие хорошую производительность сети. См. раздел trainingOptions для описания каждого параметра.
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 функция хранилища данных для параллельного преобразования данных, если доступна функция Parallel Computing Toolbox™, и последующего их сбора в рабочую область. Обучение нейронной сети итеративно. При каждой итерации хранилище данных считывает данные из файлов и преобразует их перед обновлением сетевых коэффициентов. Если данные помещаются в память компьютера, импорт данных в рабочую область ускоряет обучение, поскольку данные считываются и преобразуются только один раз. Обратите внимание, что если данные не помещаются в память, необходимо передать хранилище данных в обучающую функцию, и преобразования выполняются в каждом учебном периоде.
Создайте массивы tall как для обучающих, так и для тестовых наборов. В зависимости от системы количество работников в параллельном пуле, создаваемом 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 функция массивов tall для вычисления преобразований по всему набору данных и получения массивов ячеек с обучающими и тестовыми сигналами и метками.
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 Гц. Р - и Т-волны возникают на еще более низких частотах: Р-волновые составляющие ниже 20 Гц, а Т-волновые составляющие ниже 10 Гц [5].
Базовое странствие - низкочастотное (< 0,5 Гц) колебание, вызванное дыхательным движением пациента. Это колебание не зависит от морфологии биений и не дает значимой информации [6].
Сконструируйте полосовой фильтр с частотным диапазоном полосы пропускания [0,5, 40] Гц для удаления блуждающего устройства и любого высокочастотного шума. Удаление этих компонентов улучшает обучение LSTM, поскольку сеть не изучает неактуальные функции. Использовать cellfun в массивах ячеек с высоким уровнем данных для параллельной фильтрации набора данных.
% 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
Даже если базовая линия отфильтрованных сигналов может запутать врача, который используется для традиционных измерений ЭКГ на медицинских устройствах, сеть фактически выиграет от удаления блуждающих.
Обучение сети LSTM отфильтрованным сигналам ЭКГ с использованием той же архитектуры сети, что и раньше.
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');
Простая предварительная обработка улучшает классификацию T-волн примерно на 15%, а QRS-комплекс и классификацию P-волн примерно на 10%.
Общим подходом для успешной классификации данных временных рядов является извлечение частотно-временных характеристик и передача их в сеть вместо исходных данных. Затем сеть изучает шаблоны по времени и частоте одновременно [7].
Синхронизированное преобразование Фурье (FSST) вычисляет частотный спектр для каждой выборки сигнала, так что оно идеально подходит для рассматриваемой проблемы сегментации, где мы должны поддерживать то же разрешение по времени, что и исходные сигналы. Используйте fsst функция для проверки преобразования одного из обучающих сигналов. Укажите окно Кайзера длиной 128, чтобы обеспечить адекватное разрешение по частоте.
data = preview(trainDs);
figure
fsst(data{1,1},250,kaiser(128),'yaxis')
Вычислите FSST каждого сигнала в обучающем наборе данных в интересующем диапазоне частот, [0,5, 40] Гц. Рассматривайте реальную и мнимую части FSST как отдельные функции и подавайте оба компонента в сеть. Кроме того, стандартизируйте обучающие признаки путем вычитания среднего значения и деления на стандартное отклонение. Используйте преобразованное хранилище данных, 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];
Обучение обновленной сети LSTM преобразованному набору данных.
if actionFlag == "Train networks" fsstNet = trainNetwork(fsstTrainData(:,1),fsstTrainData(:,2),layers,options); end

Использование частотно-временных характеристик повышает точность обучения, которая теперь превышает 90%.
Используя обновленную сеть LSTM и извлеченные функции FSST, классифицируйте данные тестирования.
predFsstTest = classify(fsstNet,fsstTestData(:,1),'MiniBatchSize',50);Визуализируйте характеристики классификации как матрицу путаницы.
confusionchart([predFsstTest{:}],[fsstTestData{:,2}],'Normalization','column-normalized');
Использование частотно-временного представления улучшает классификацию T-волн примерно на 25%, классификацию P-волн примерно на 40% и классификацию QRS-комплекса на 30% по сравнению с исходными данными.
Использовать signalMask объект для сравнения предсказания сети с метками истинности земли для одного сигнала ЭКГ. Игнорировать "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] Макшарри, Патрик Э., и др. «Динамическая модель для генерации синтетических сигналов электрокардиограммы». Транзакции 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] Сёрнмо, Лейф и Пабло Лагуна. «Обработка сигналов электрокардиограммы (ЭКГ)». Энциклопедия биомедицинской инженерии Уайли, 2006 год.
[6] Колер, Би-У., Карстен Хенниг и Рейнгольд Орглмейстер. «Принципы обнаружения QRS программного обеспечения». IEEE Engineering in Medicine and Biology Magazine. Том 21, № 1, 2002, стр. 42-57.
[7] Саламон, Джастин и Хуан Пабло Белло. «Глубокие сверточные нейронные сети и увеличение данных для классификации экологического звука». Письма обработки сигналов IEEE. т. 24, № 3, 2017, стр. 279-283.
confusionchart | lstmLayer | trainingOptions | trainNetwork | fsst (Панель инструментов обработки сигналов) | labeledSignalSet(Панель инструментов обработки сигналов)