Esta página aún no se ha traducido para esta versión. Puede ver la versión más reciente de esta página en inglés.

Segmentación de forma de onda mediante Deep Learning

Este ejemplo muestra cómo segmentar señales de electrocardiograma humano (ECG) mediante redes de aprendizaje profundo recurrentes y análisis de frecuencia de tiempo.

Introducción

La actividad eléctrica en el corazón se puede medir como una secuencia de amplitudes lejos de una señal de línea de base. Para un único ciclo de latido cardíaco normal, la señal de ECG se puede dividir en las siguientes morfologías de latido [1]:

  • Onda P — una pequeña desviación antes del complejo QRS que representa la despolarización auricular

  • Complejo QRS — la porción de mayor amplitud del latido del corazón

  • Onda T — una pequeña desviación después del complejo QRS que representa la repolarización ventricular

La segmentación de estas regiones de formas de onda de ECG puede proporcionar la base para las mediciones útiles para evaluar la salud general del corazón humano y la presencia de anomalías [2]. Anotar manualmente cada región de la señal de ECG puede ser una tarea tediosa y que consume mucho tiempo con el potencial de ser automatizado por el procesamiento de señales y métodos de aprendizaje automático.

Este ejemplo utiliza señales de ECG de la base de datos QT disponible públicamente [3] [4]. Los datos consisten en aproximadamente 15 minutos de grabaciones de ECG de un total de 105 pacientes. Para obtener cada grabación, los examinadores colocaron dos electrodos en diferentes lugares en el pecho del paciente, resultando en una señal de dos canales. La base de datos proporciona etiquetas de región de señal generadas por un sistema experto automatizado [2]. Este ejemplo tiene como objetivo utilizar una solución de aprendizaje profundo para proporcionar una etiqueta para cada muestra según la región donde se encuentra la muestra. Este proceso de etiquetado de las regiones de interés a través de una señal se conoce a menudo como segmentación de forma de onda.

Para entrenar una red neuronal profunda para clasificar las regiones de señal, puede utilizar una red de memoria a corto plazo (LSTM) larga. Este ejemplo muestra cómo se pueden utilizar las técnicas de preprocesamiento de señal y el análisis de frecuencia de tiempo para mejorar el rendimiento de segmentación de LSTM. En particular, el ejemplo utiliza la transformada de Fourier synchrosqueezed para representar el comportamiento no estacionario de la señal de ECG.

Descargue y prepare los datos

El primer paso es descargar los datos de la.Repositorio de GitHub Todos los navegadores tienen un directorio de descargas que se puede identificar a través de las preferencias. Localice el archivo en ese directorio y muévase a una carpeta en la que tenga permiso de escritura.QT_Database-master.zip En este ejemplo se supone que ha colocado el archivo en el directorio temporal, cuya ubicación se especifica mediante el comando de MATLAB®.tempdir Si tiene los datos en una carpeta diferente de, cambie el nombre del directorio en las instrucciones subsiguientes.tempdir Empiece por descomprimir el DataFile.

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

La descompresión crea la carpeta en el directorio temporal.QT_Database-master Esta carpeta contiene el archivo de texto y los siguientes archivos:README.md

  • QTData.mat

  • Modified_physionet_data.txt

  • License.txt

contiene los datos utilizados en este ejemplo.QTData.mat El archivo proporciona las atribuciones de origen para los datos y una descripción de las operaciones aplicadas a cada grabación de ECG sin procesar.Modified_physionet_data.txt

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.  

es una que contiene las señales de ECG de origen y las etiquetas de forma de onda correspondientes juntas en un solo objeto.QTDatalabeledSignalSet Las señales de ECG de 105 2 canales están contenidas en la propiedad.Source La propiedad contiene una tabla de etiquetas de forma de onda.Labels Cada canal fue etiquetado de forma independiente por el sistema experto automatizado y se trata de forma independiente, para un total de 210 señales de ECG. Las etiquetas de forma de onda especifican cada muestra de la señal como perteneciente a una de las siguientes clases: P, QRS, T y N/A. Un valor de N/a corresponde a muestras fuera de una onda P, un complejo QRS o una onda T.

Utilice el comando para inspeccionar las primeras filas de la tabla contenida en la propiedad de.headLabelsQTData

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]  

Cada fila de la tabla corresponde a un paciente y cada columna de la tabla corresponde a un canal. Utilice la función para extraer los datos de la señal para el primer paciente.getSignal Utilice la función para extraer etiquetas para el primer canal.getLabelValues Visualice las etiquetas de las primeras 1000 muestras utilizando la función auxiliar.displayWaveformLabels

patientID = 1; signalVals = getSignal(QTData,patientID); labelVals = getLabelValues(QTData,patientID,'WaveformLabels_Chan1');  displayWaveformLabels(signalVals(1,1:1000),labelVals.Value(1:1000)) 

Inspeccione los valores de la etiqueta alrededor de la muestra 150th, donde la señal cambia rápidamente. La región marca el final del complejo QRS y la transición A muestras 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 

El procedimiento habitual de clasificación de aprendizaje automático es el siguiente:

  1. Divida la base de datos en conjuntos de datos de entrenamiento y prueba.

  2. Entrenar la red utilizando el DataSet de entrenamiento.

  3. Utilice la red entrenada para realizar predicciones en el DataSet de prueba.

La red se entrena con el 70% de los datos y se prueba con el 30% restante. Para evitar cualquier sesgo, no se comparte ningún dato perteneciente al mismo paciente a través del conjunto de entrenamiento y el conjunto de pruebas.

Para obtener resultados reproducibles, restablezca el generador de números aleatorios. Utilice la propiedad de la para extraer el número de pacientes.NumMemberslabeledSignalSet Utilice la función para mezclar los pacientes y utilizar la función para dividir los datos en entrenamiento y pruebas s.dividerandsubsetlabeledSignalSet

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

Para introducir datos de serie temporal en la red, organice los datos como matrices de celdas de matrices utilizando la función auxiliar.resizeSignals Esta función auxiliar también divide los datos en fragmentos de 5000-sample para evitar el uso excesivo de memoria.

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

Entrada de señales de ECG RAW directamente en una red LSTM

En primer lugar, entrenar la red utilizando las señales de ECG sin procesar del DataSet de entrenamiento.

Defina la arquitectura de red antes del entrenamiento. Especifique un tamaño de 1 para aceptar series de tiempo unidimensionales.sequenceInputLayer Especifique una capa LSTM con el modo de salida para proporcionar la clasificación de cada muestra en la señal.'sequence' Utilice 200 nodos ocultos para un rendimiento óptimo. Especifique a con un tamaño de salida de 4, uno para cada una de las clases de forma de onda.fullyConnectedLayer Agregue un y a para generar las etiquetas estimadas.softmaxLayerclassificationLayer

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

Elija Opciones para el proceso de formación que garanticen un buen rendimiento de la red. Consulte la documentación para obtener una descripción de cada parámetro.trainingOptions

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

Red de trenes

Utilice el comando para entrenar la red LSTM.trainNetwork Debido al gran tamaño del conjunto de datos, este proceso puede tardar varios minutos. Si su máquina tiene una GPU y una caja de herramientas de computación paralela™, MATLAB utiliza automáticamente la GPU para el entrenamiento. De lo contrario, utiliza la CPU.

Los subtrazados de precisión y pérdida de entrenamiento en la figura rastrean el progreso del entrenamiento en todas las iteraciones. Utilizando los datos de señal sin procesar, la red clasifica correctamente alrededor del 70% de las muestras como pertenecientes a una onda P, un complejo QRS, una onda T o N/A.

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

Clasificar datos de prueba

Clasifique los datos de prueba utilizando la red LSTM capacitada y el comando.classify Especifique un tamaño de mini lote de 50 para que coincida con las opciones de entrenamiento.

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

Una matriz de confusión proporciona un medio intuitivo e informativo para visualizar el rendimiento de la clasificación. Utilice el comando para calcular la precisión de clasificación general para las predicciones de datos de prueba.confusionchart Para cada entrada, convierta la matriz de celdas de etiquetas categóricas en un vector de fila. Especifique una visualización normalizada por columnas para ver los resultados como porcentajes de muestras para cada clase.

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

Utilizando la señal de ECG sin procesar como entrada a la red, sólo alrededor del 35% de las muestras de onda P, el 60% de las muestras del complejo QRS y el 60% de las muestras de ondas T eran correctas. Para mejorar el rendimiento, aplicar un poco de conocimiento de las características de la señal de ECG antes de la entrada a la red de aprendizaje profundo, por ejemplo, la línea de fondo errante causada por el movimiento respiratorio de un paciente.

Aplicar métodos de filtrado para eliminar el paseo de línea base y el ruido de alta frecuencia

Las tres morfologías de ritmo ocupan diferentes bandas de frecuencias. El espectro del complejo QRS tiene típicamente una frecuencia central alrededor de 10 – 25 Hz, y sus componentes están por debajo de 40 Hz. Las ondas P y T ocurren en frecuencias aún más bajas: Los componentes de onda P están por debajo de 20 Hz, y los componentes de onda T están por debajo de 10 Hz [5].

La vagación basal es una oscilación de baja frecuencia (< 0,5 Hz) causada por el movimiento respiratorio del paciente. Esta oscilación es independiente de las morfologías de Beat y no proporciona información significativa [6].

Diseñe un filtro de paso de banda con rango de frecuencias de bandas de paso de [0,5, 40] Hz para eliminar el vagar y cualquier ruido de alta frecuencia. La eliminación de estos componentes mejora el entrenamiento LSTM porque la red no aprende características irrelevantes.

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

Especifique una función anónima, para aplicar el filtro de paso de banda a cada señal.BPfun

BPfun = @(X) filter(dBP,X);  signalsFilteredTrain = cellfun(BPfun,signalsTrain,'UniformOutput',false); signalsFilteredTest  = cellfun(BPfun,signalsTest,'UniformOutput',false);

Trace las señales RAW y filtrada para un caso típico.

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

Red de trenes con señales de ECG filtradas

Entrenar la red LSTM en las señales de ECG filtradas utilizando la misma arquitectura de red.

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

El preprocesamiento de las señales mejora la precisión del entrenamiento a mejor que el 80%.

Clasificar las señales de ECG filtradas

Clasifique los datos de prueba preprocesados con la red LSTM actualizada.

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

Visualice el rendimiento de la clasificación como una matriz de confusión.

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

El preprocesamiento simple mejora la clasificación de la onda P en aproximadamente el 10%, la clasificación del complejo QRS en un 10% y la clasificación de ondas T en un 20%.

Representación de frecuencia horaria de las señales de ECG

Un enfoque común para la clasificación exitosa de los datos de series temporales es extraer las características de frecuencia de tiempo y alimentarlas con la red en lugar de con los datos originales. La red entonces aprende patrones a través del tiempo y la frecuencia simultáneamente [7].

La transformada de Fourier synchrosqueezed (FSST) computa un espectro de frecuencias para cada muestra de señal. Utilice la función para inspeccionar la transformación de una de las señales de entrenamiento.fsst Especifique una ventana de longitud 128 de Kaiser para proporcionar una resolución de frecuencia adecuada.

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

Calcule la FSST de cada señal en el DataSet de entrenamiento. Extraiga los datos sobre el rango de frecuencia de interés, [0,5, 40] Hz, indexando el contenido relevante de las salidas de transformación. Trate las partes reales e imaginarias de la FSST como entidades separadas y alimente ambos componentes en la red.

Antes de entrenar la red, estandarice las características de entrenamiento restando la media y dividiendo por la desviación estándar.

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);

Repita este procedimiento para los datos de prueba. Estandarice las funciones de prueba utilizando la media y la desviación estándar de los datos de entrenamiento.

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);

Ajuste la arquitectura de red

Modifique la arquitectura LSTM para que la red acepte un espectro de frecuencias para cada muestra en lugar de un único valor. Inspeccione el tamaño de la FSST para ver el número de frecuencias.

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

          40        5000

Especifique una de las entidades de entrada 40.sequenceInputLayer Mantenga el resto de los parámetros de red sin cambios.

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

Red de trenes con señales de la FSST de ECG

Entrenar la red LSTM actualizada con el conjunto de datos transformado.

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

El uso de funciones de frecuencia de tiempo mejora la precisión del entrenamiento, que ahora supera el 90%.

Clasifique los datos de prueba con FSST

Utilizando la red LSTM actualizada y las funciones FSST extraídas, clasifique los datos de prueba.

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

Visualice el rendimiento de la clasificación como una matriz de confusión.

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

El uso de una representación de frecuencia de tiempo mejora la clasificación de las ondas P en un 50% (de aproximadamente 35% a 85%), la clasificación de QRS-Complex en un 35% y la clasificación de ondas T en un 25%.

Se utiliza para comparar la predicción de la red con las etiquetas de la verdad del terreno para una sola señal de ECG.displayWaveformLabels

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')

Conclusión

Este ejemplo mostraba cómo el preprocesamiento de señal y el análisis de frecuencia de tiempo pueden mejorar el rendimiento de segmentación de forma de onda LSTM. El filtrado de paso de banda y la sincocompresión basada en Fourier resultan en una mejora promedio en todas las clases de salida del 60% a más del 85%.

Referencias

[1] McSharry, Patrick E., et al. "Un modelo dinamico para generar señales de electrocardiograma sintético." Vol. 50, no. 3, 2003, págs. 289 – 294.IEEE® Transactions on Biomedical Engineering.

[2] Laguna, Pablo, Raimon Jané, y Pere Caminal. "Detección automática de límites de ondas en señales ECG multilead: Validación con la base de datos CSE. " Vol. 27, no. 1, 1994, págs. 45 – 60.Computers and Biomedical Research.

[3] Goldberger, Ary L., Luis A. N. Amaral, Leon Glass, Jeffery M. Hausdorff, Plamen ch. Ivanov, Roger G. Mark, Joseph E. Mietus, George B. Moody, Chung-Kang Peng y H. Eugene Stanley. "PhysioBank, PhysioToolkit y PhysioNet: Componentes de un nuevo recurso de investigación para señales fisiológicas complejas. " Vol. 101, no. 23, 2000, PP. e215 – E220. [Circulación de páginas electrónicas; ].Circulation. http://circ.ahajournals.org/content/101/23/e215.full

[4] Laguna, Pablo, Roger G. Mark, Ary L. Goldberger, y George B. Moody. "A Database for Evaluation of Algorithms for Measurement of QT and Other Waveform Intervals in the ECG.Vol. 24, 1997, págs. 673 – 676."Computers in Cardiology.

[5] sörnmo, Leif, y Pablo Laguna. "Procesamiento de la señal de Electrocardiograma (ECG)." 2006.Wiley Encyclopedia of Biomedical Engineering,

[6] Kohler, B-U., Carsten Hennig y Reinhold Orglmeister. "Los principios de la detección de software QRS." .IEEE Engineering in Medicine and Biology Magazine Vol. 21, no. 1, 2002, págs. 42 – 57.

[7] Salamon, Justin, y Juan Pablo bello. "Profundas redes neuronales convolucionales y aumento de datos para la clasificación del sonido ambiental." Vol. 24, no. 3, 2017, págs. 279 – 283.IEEE Signal Processing Letters.

Consulte también

Funciones

Temas relacionados