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

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

Введение

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

  • P волна — маленькое отклонение перед комплексом QRS представление предсердной деполяризации

  • Комплекс QRS — Само-амплитудный фрагмент heartbeat

  • T волна — маленькое отклонение после комплекса QRS представление желудочковой реполяризации

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

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

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

Загрузите и подготовьте данные

Первый шаг должен загрузить данные из Репозитория GitHub. Все браузеры имеют директорию Downloads, которая может быть идентифицирована через Настройки. Найдите файл QT_Database-master.zip в той директории и перемещении это к папке, где у вас есть разрешение записи. Этот пример принимает, что вы поместили файл в свою временную директорию, местоположение которой задано tempdir MATLAB® команда. Если у вас есть данные в папке, отличающейся от tempdir, измените имя каталога в последующих инструкциях. Запустите путем разархивации файла данных.

unzip(fullfile(tempdir,'QT_Database-master.zip'),tempdir)

Разархивация создает папку QT_Database-master в вашей временной директории. Эта папка содержит текстовый файл README.md и следующие файлы:

  • QTData.mat

  • Modified_physionet_data.txt

  • License.txt

QTData.mat содержит данные, используемые в этом примере. Файл Modified_physionet_data.txt обеспечивает исходные приписывания для данных, и описание операций применилось к каждой необработанной записи ECG.

load(fullfile(tempdir,'QT_Database-master','QTData.mat'))
QTData
QTData = 
  labeledSignalSet with properties:

             Source: {105×1 cell}
         NumMembers: 105
    TimeInformation: "sampleRate"
         SampleRate: 250
             Labels: [105×2 table]
        Description: ""

 Use labelDefinitionsHierarchy to see a list of labels and sublabels.
 Use setLabelValue to add data to the set.

QTData labeledSignalSet это содержит исходные сигналы ECG и соответствующие метки формы волны вместе в отдельном объекте. 105 двухканальных сигналов ECG содержатся в Source свойство. Labels свойство содержит таблицу меток формы волны. Каждый канал был помечен независимо автоматизированной экспертной системой и обработан независимо для в общей сложности 210 сигналов ECG. Метки формы волны задают каждую выборку сигнала как принадлежащий одному из следующих классов: P, QRS, T, и N/A. Значение N/A соответствует выборкам за пределами волны P, комплекса QRS или волны T.

Используйте head команда, чтобы смотреть первые несколько строк таблицы, содержавшейся в Labels свойство QTData.

head(QTData.Labels)
ans=8×2 table
                 WaveformLabels_Chan1    WaveformLabels_Chan2
                 ____________________    ____________________

    Member{1}      [225000×2 table]        [225000×2 table]  
    Member{2}      [225000×2 table]        [225000×2 table]  
    Member{3}      [225000×2 table]        [225000×2 table]  
    Member{4}      [225000×2 table]        [225000×2 table]  
    Member{5}      [225000×2 table]        [225000×2 table]  
    Member{6}      [225000×2 table]        [225000×2 table]  
    Member{7}      [225000×2 table]        [225000×2 table]  
    Member{8}      [225000×2 table]        [225000×2 table]  

Каждая строка таблицы соответствует пациенту, и каждый столбец таблицы соответствует каналу. Используйте getSignal функционируйте, чтобы извлечь данные сигнала для первого пациента. Используйте getLabelValues функционируйте, чтобы извлечь метки для первого канала. Визуализируйте метки для первых 1 000 выборок с помощью displayWaveformLabels функция помощника.

patientID = 1;
signalVals = getSignal(QTData,patientID);
labelVals = getLabelValues(QTData,patientID,'WaveformLabels_Chan1');

displayWaveformLabels(signalVals(1,1:1000),labelVals.Value(1:1000)) 

Смотрите значения метки вокруг 150-й выборки, где сигнал изменяется быстро. Область отмечает конец комплекса QRS и перехода в выборки N/A.

val = labelVals.Value(145:155)
val = 11×1 categorical array
     QRS 
     QRS 
     QRS 
     QRS 
     QRS 
     QRS 
     QRS 
     QRS 
     n/a 
     n/a 
     n/a 

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

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

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

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

Сеть обучена с 70% данных и протестирована с остающимися 30%. Чтобы предотвратить любое смещение, никакие данные, принадлежащие тому же пациенту, не совместно используются через набор обучающих данных и тестирование набора.

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

rng default
[trainInd,~,testInd] = dividerand(QTData.NumMembers,0.7,0,0.3);

trainQT = subset(QTData,trainInd);
testQT = subset(QTData,testInd);

Чтобы ввести данные timeseries к сети, организуйте данные как массивы ячеек матриц с помощью функции помощника resizeSignals. Эта функция помощника также делит данные на фрагменты с 5000 выборками, чтобы избежать чрезмерного использования памяти.

[signalsTrain,labelsTrain] = resizeSignals(trainQT);
[signalsTest,labelsTest] = resizeSignals(testQT);

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

Во-первых, обучите сеть с помощью необработанных сигналов ECG от обучающего набора данных.

Задайте сетевую архитектуру перед обучением. Задайте 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',...
    'Verbose',0);

Обучение сети

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

Учебные подграфики точности и потери в фигуре отслеживают процесс обучения через все итерации. Используя необработанные данные сигнала, сеть правильно классифицирует приблизительно 70% выборок как принадлежащий волне P, комплексу QRS, волне T или N/A.

net = trainNetwork(signalsTrain,labelsTrain,layers,options);

Классифицируйте данные о тестировании

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

predTest = classify(net,signalsTest,'MiniBatchSize',50);

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

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

Используя необработанный сигнал ECG, как введено к сети, только приблизительно 35% выборок P-волны, 60% QRS-комплексных выборок и 60% выборок T-волны были правильны. Чтобы улучшать производительность, примените некоторое знание характеристик сигнала ECG до входа к нейронной сети для глубокого обучения, например, базовая линия, блуждающая вызванный дыхательным движением пациента.

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

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

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

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

Fs = QTData.SampleRate;
[~,dBP] = bandpass(signalsTrain{1},[0.5 40],Fs);

Задайте анонимную функцию, BPfun, применять полосовой фильтр к каждому сигналу.

BPfun = @(X) filter(dBP,X);

signalsFilteredTrain = cellfun(BPfun,signalsTrain,'UniformOutput',false);
signalsFilteredTest  = cellfun(BPfun,signalsTest,'UniformOutput',false);

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

subplot(2,1,1)
plot(signalsTrain{210}(2001:3000))
title('Raw')
grid

subplot(2,1,2)
plot(signalsFilteredTrain{210}(2001:3000))
title('Filtered')
grid

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

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

filteredNet = trainNetwork(signalsFilteredTrain,labelsTrain,layers,options);

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

Классифицируйте фильтрованные сигналы ECG

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

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

Визуализируйте производительность классификации как матрицу беспорядка.

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

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

Представление частоты времени сигналов ECG

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

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

fsst(signalsTrain{1},Fs,kaiser(128),'yaxis')

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

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

signalsFsstTrain = cell(size(signalsTrain));
meanTrain = cell(1,length(signalsTrain));
stdTrain = cell(1,length(signalsTrain));
for idx = 1:length(signalsTrain)
   [s,f,t] = fsst(signalsTrain{idx},Fs,kaiser(128));
   
   f_indices = (f > 0.5) & (f < 40);
   signalsFsstTrain{idx}= [real(s(f_indices,:)); imag(s(f_indices,:))];
   
   meanTrain{idx} = mean(signalsFsstTrain{idx},2);
   stdTrain{idx} = std(signalsFsstTrain{idx},[],2);
end

standardizeFun = @(x) (x - mean(cell2mat(meanTrain),2))./mean(cell2mat(stdTrain),2);
signalsFsstTrain = cellfun(standardizeFun,signalsFsstTrain,'UniformOutput',false);

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

signalsFsstTest = cell(size(signalsTest));
for idx = 1:length(signalsTest)
   [s,f,t] = fsst(signalsTest{idx},Fs,kaiser(128));
   
   f_indices =  (f > 0.5) & (f < 40);
   signalsFsstTest{idx}= [real(s(f_indices,:)); imag(s(f_indices,:))]; 
end

signalsFsstTest = cellfun(standardizeFun,signalsFsstTest,'UniformOutput',false);

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

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

size(signalsFsstTrain{1})
ans = 1×2

          40        5000

Задайте sequenceInputLayer из 40 входных функций. Сохраните остальную часть сетевых параметров неизменной.

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

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

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

fsstNet = trainNetwork(signalsFsstTrain,labelsTrain,layers,options);

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

Классифицируйте тестовые данные с FSST

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

predFsstTest = classify(fsstNet,signalsFsstTest,'MiniBatchSize',50);

Визуализируйте производительность классификации как матрицу беспорядка.

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

Используя частоту времени представление улучшает классификацию P-волн на 50% (приблизительно с 35% до 85%), QRS-комплексную классификацию на 35% и классификацию T-волн на 25%.

Используйте displayWaveformLabels сравнить сетевой прогноз с основной истиной помечает для одного сигнала ECG.

subplot(2,1,1)
displayWaveformLabels(signalsTest{50}(1400:1900),labelsTest{50}(1400:1900))
title('Ground Truth')

subplot(2,1,2)
displayWaveformLabels(signalsTest{50}(1400:1900),predFsstTest{50}(1400:1900))
title('Predicted')

Заключение

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

Ссылки

[1] Макшарри, Патрик Э., и др. "Динамическая модель для генерации синтетических сигналов электрокардиограммы". IEEE® Transactions на Биоинженерии. Издание 50, № 3, 2003, стр 289–294.

[2] Laguna, Пабло, Рэймон Джейне и Пере Каминаль. "Автоматическое обнаружение контуров волны в мультиведущих сигналах ECG: Валидация с базой данных CSE". Компьютеры и Биомедицинское Исследование. Издание 27, № 1, 1994, стр 45–60.

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

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

[5] Sörnmo, Леиф и Пабло Лагуна. "Электрокардиограмма (ECG) обработка сигналов". Вайли Энкиклопедия Биоинженерии, 2006.

[6] Колер, B-U., Карстен Хенниг и Райнхольд Орглмайстер. "Принципы обнаружения программного обеспечения QRS". Разработка IEEE в Журнале Медицины и Биологии. Издание 21, № 1, 2002, стр 42–57.

[7] Salamon, Джастин и Хуан Пабло Белло. "Глубокие сверточные нейронные сети и увеличение данных для экологической звуковой классификации". Буквы Обработки сигналов IEEE. Издание 24, № 3, 2017, стр 279–283.

Смотрите также

Функции

Похожие темы

Для просмотра документации необходимо авторизоваться на сайте