Esta página es para la versión anterior. La página correspondiente en inglés ha sido eliminada en la versión actual.

Segmentación de forma de onda mediante aprendizaje profundo

Este ejemplo muestra cómo segmentar señales de electrocardiograma humano (ECG) utilizando 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 basal. Para un único ciclo de latidos cardíacos normal, la señal ECG se puede dividir en las siguientes morfologías de latido [1] :

  • Onda P — Una pequeña desviación ante el complejo QRS que representa la despolarización auricular

  • Complejo QRS — la porción de mayor amplitud de los latidos 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 ECG puede proporcionar la base para mediciones útiles para evaluar la salud general del corazón humano y la presencia de anomalías [2]. Annotar manualmente cada región de la señal ECG puede ser una tarea tediosa y lenta con el potencial de ser automatizado por el procesamiento de la señal y los métodos de aprendizaje automático.

Este ejemplo utiliza las señales ECG de la base de datos QT disponible públicamente [3] [4]. Los datos consisten en aproximadamente 15 minutos de registros de ECG de un total de 105 pacientes. Para obtener cada grabación, los examinadores colocaron dos electrodos en diferentes lugares en el pecho de un paciente, lo que resultó 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 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). Este ejemplo muestra cómo las técnicas de preprocesamiento de señal y el análisis de frecuencia de tiempo se pueden utilizar para mejorar el rendimiento de segmentación LSTM. En particular, el ejemplo utiliza la transformación sincroprimida de Fourier para representar el comportamiento no estacionario de la señal ECG.

Descargar y preparar los datos

El primer paso es descargar los datos del archivo .Repositorio GitHub Todos los navegadores tienen un directorio Descargas que se puede identificar a través de las Preferencias. Busque el archivo en ese directorio y muévalo a una carpeta donde 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 mandato de MATLAB®.tempdir Si tiene los datos en una carpeta diferente de , cambie el nombre del directorio en las instrucciones posteriores.tempdir Comience descomprimiendo el archivo de datos.

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

Descomprimir 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 registro 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 un que mantiene las señales ECG de origen y las etiquetas de forma de onda correspondientes juntas en un solo objeto.QTDatalabeledSignalSet Las 105 señales ECG de dos 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 es tratado de forma independiente, para un total de 210 señales 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 tabla corresponde a un paciente y cada columna de tabla corresponde a un canal. Utilice la función para extraer los datos de la señal del primer paciente.getSignal Utilice la función para extraer etiquetas para el primer canal.getLabelValues Visualice las etiquetas de los primeros 1000 ejemplos mediante 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 150, 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 pruebas.

  2. Entrene la red mediante el conjunto de datos de entrenamiento.

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

La red está entrenada con el 70% de los datos y probada con el 30% restante. Para evitar cualquier sesgo, no se comparten datos que pertenezcan al mismo paciente entre el 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 barajar a 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 series temporales en la red, organice los datos como matrices de celdas de matrices mediante la función auxiliar .resizeSignals Esta función auxiliar también divide los datos en fragmentos de 5000 muestras para evitar el uso excesivo de memoria.

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

Introducir señales ECG sin procesar directamente en una red LSTM

En primer lugar, entrene la red utilizando las señales ECG sin procesar del conjunto de datos de entrenamiento.

Defina la arquitectura de red antes del entrenamiento. Especifique a de tamaño 1 para aceptar series temporales unidimensionales.sequenceInputLayer Especifique una capa LSTM con el modo de salida para proporcionar clasificación para cada muestra de la señal.'sequence' Utilice 200 nodos ocultos para obtener 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 a 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 (Deep Learning Toolbox)

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 de entrenar la red LSTM.trainNetwork Debido al gran tamaño del conjunto de datos, este proceso puede tardar varios minutos. Si el equipo tiene una GPU y Parallel Computing Toolbox™, MATLAB utiliza automáticamente la GPU para el entrenamiento. De lo contrario, utiliza la CPU.

La precisión del entrenamiento y las subtramas de pérdida en la figura realizan un seguimiento del 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 entrenada y el comando.classify Especifique un tamaño de minilote 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 general de la clasificación 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 columna para ver los resultados como porcentajes de muestras para cada clase.

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

Utilizando la señal ECG sin procesar como entrada a la red, sólo alrededor del 35% de las muestras de onda P, el 60% de las muestras complejas de QRS y el 60% de las muestras de onda T eran correctas. Para mejorar el rendimiento, aplique algunos conocimientos de las características de la señal ECG antes de la entrada a la red de aprendizaje profundo, por ejemplo, el vagar basal causado por el movimiento respiratorio de un paciente.

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

Las tres morfologías de ritmo ocupan diferentes bandas de frecuencia. El espectro del complejo QRS típicamente tiene una frecuencia central alrededor de 10–25 Hz, y sus componentes están por debajo de 40 Hz. Las ondas P y T se producen a 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].

El vagar de línea de base 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 ritmo y no proporciona información significativa [6].

Diseñe un filtro de paso de banda con rango de frecuencia de banda de paso de [0.5, 40] Hz para eliminar el vagonado 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);

Trazar las señales crudas y filtradas 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 ECG filtradas

Entrene la red LSTM en las señales 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 más del 80%.

Clasificar señales ECG filtradas

Clasificar 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 ondas P en aproximadamente un 10%, la clasificación compleja de QRS en un 10% y la clasificación de onda T en un 20%.

Representación de frecuencia de tiempo de señales ECG

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

La transformación sincrona (FSST) de Fourier calcula un espectro de frecuenciapara 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 Kaiser de longitud 128 para proporcionar una resolución de frecuencia adecuada.

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

Calcule el FSST de cada señal en el conjunto de datos de entrenamiento. Extraiga los datos en 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 del FSST como características separadas y alimente ambos componentes en la red.

Antes de entrenar la red, estandarice las entidades 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 características 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);

Ajustar la arquitectura de red

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

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

          40        5000

Especifique una de las 40 entidades de entrada.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 FSST de señales ECG

Entrene 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%.

Clasificar datos de prueba con FSST

Utilizando la red LSTM actualizada y las características 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 ondas P en un 50% (de aproximadamente 35% a 85%), la clasificación de QRS en un 35% y la clasificación de onda T en un 25%.

Se utiliza para comparar la predicción de red con las etiquetas de verdad del suelo para una sola señal 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 mostró cómo el preprocesamiento de señal y el análisis de frecuencia de tiempo pueden mejorar el rendimiento de segmentación de la forma de onda LSTM. El filtrado de paso de banda y el sincordancia basado en Fourier dan como resultado una mejora media en todas las clases de salida del 60% a más del 85%.

Referencias

[1] McSharry, Patrick E., et al. "Un modelo dinámico para generar señales sintéticas de electrocardiograma." Vol. 50, No. 3, 2003, págs. 289–294.IEEE® Transacciones en Ingeniería Biomédica.

[2] Laguna, Pablo, Raimon Jané y Pere Caminal. "Detección automática de límites de onda 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. [Páginas Electrónicas de Circulación; ].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] Sornmo, Leif y Pablo Laguna. "Procesamiento de 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 QRS de software." .IEEE Engineering in Medicine and Biology Magazine Vol. 21, No 1, 2002, págs. 42–57.

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

Consulte también

Funciones

Temas relacionados