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

Clasificar las señales de ECG mediante redes de memoria a corto plazo

En este ejemplo se muestra cómo clasificar los datos de electrocardiograma de latidos (ECG) del desafío PhysioNet 2017 mediante el aprendizaje profundo y el procesamiento de señales. En particular, el ejemplo utiliza redes de memoria a corto plazo (LSTM) y análisis de frecuencia de tiempo.

Introducción

Los electrocardiogramas registran la actividad eléctrica del corazón de una persona durante un período de tiempo. Los médicos utilizan ecgs para detectar visualmente si los latidos del corazón de un paciente son normales o irregulares.

La fibrilación auricular (AFib) es un tipo de latido irregular del corazón que ocurre cuando las cavidades superiores del corazón, las aurículas, laten fuera de coordinación con las cavidades inferiores, los ventrículos.

Este ejemplo utiliza datos ECG del desafío PhysioNet 2017 [1], [2], [3], que está disponible en .https://physionet.org/challenge/2017/ Los datos consisten en un conjunto de señales ECG muestreadas a 300 Hz y divididas por un grupo de expertos en cuatro clases diferentes: Normal (N), AFib (A), Otro ritmo (O) y Grabación de noisy ( ) . En este ejemplo se muestra cómo automatizar el proceso de clasificación mediante el aprendizaje profundo. El procedimiento explora un clasificador binario que puede diferenciar las señales ECG normales de las señales que muestran signos de AFib.

Este ejemplo utiliza redes de memoria a corto plazo (LSTM) largas, un tipo de red neuronal recurrente (RNN) adecuada para estudiar datos de secuencia y series temporales. Una red LSTM puede aprender dependencias a largo plazo entre los pasos de tiempo de una secuencia. La capa LSTM ( ) puede mirar la secuencia de tiempo en la dirección de avance, mientras que la capa bidireccional LSTM ( ) puede mirar la secuencia de tiempo en ambas direcciones hacia adelante y hacia atrás.lstmLayerbilstmLayer Este ejemplo utiliza una capa bidireccional LSTM.

Para acelerar el proceso de entrenamiento, ejecute este ejemplo en un equipo con una GPU. 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.

Cargar y examinar los datos

Ejecute el script para descargar los datos del sitio web de PhysioNet y generar un archivo MAT ( ) que contenga las señales ECG en el formato adecuado.ReadPhysionetDataPhysionetData.mat La descarga de los datos puede tardar unos minutos.

ReadPhysionetData load PhysionetData

La operación de carga agrega dos variables al espacio de trabajo: y . es una matriz de células que contiene las señales ECG. es una matriz categórica que contiene las etiquetas de verdad del suelo correspondientes de las señales.SignalsLabelsSignalsLabels

Signals(1:5)
ans = 5×1 cell array
    {1×9000  double}
    {1×9000  double}
    {1×18000 double}
    {1×9000  double}
    {1×18000 double}

Labels(1:5)
ans = 5×1 categorical array
     N 
     N 
     N 
     A 
     A 

Utilice la función para ver que hay 738 señales AFib y 5050 señales normales.summary

summary(Labels)
     A       738       N      5050  

Generar un histograma de longitudes de señal. Observe que la mayoría de las señales son 9000 muestras de largo.

L = cellfun(@length,Signals); h = histogram(L); xticks(0:3000:18000); xticklabels(0:3000:18000); title('Signal Lengths') xlabel('Length') ylabel('Count')

Visualice un segmento de una señal de cada clase. Los latidos del corazón AFib se espacian a intervalos irregulares, mientras que los latidos normales ocurren regularmente. Las señales de latidos aFib también a menudo carecen de una onda P, que pulsa antes del complejo QRS en una señal de latido normal. La gráfica de la señal Normal muestra una onda P y un complejo QRS.

normal = Signals{1}; aFib = Signals{4};  subplot(2,1,1) plot(normal) title('Normal Rhythm') xlim([4000,5200]) ylabel('Amplitude (mV)') text(4330,150,'P','HorizontalAlignment','center') text(4370,850,'QRS','HorizontalAlignment','center')  subplot(2,1,2) plot(aFib) title('Atrial Fibrillation') xlim([4000,5200]) xlabel('Samples') ylabel('Amplitude (mV)')

Preparar los datos para la formación

Durante el entrenamiento, la función divide los datos en mini-batches.trainNetwork A continuación, la función rellena o trunca las señales en el mismo minilote para que todas tengan la misma longitud. Demasiado relleno o truncamiento puede tener un efecto negativo en el rendimiento de la red, porque la red puede interpretar una señal incorrectamente basada en la información agregada o eliminada.

Para evitar el acolchado o el truncamiento excesivos, aplique la función a las señales ECG para que sean todas las 9000 muestras de largo.segmentSignals La función ignora las señales con menos de 9000 muestras. Si una señal tiene más de 9000 muestras, la divide en tantos segmentos de 9000 muestras como sea posible e ignora las muestras restantes.segmentSignals Por ejemplo, una señal con 18500 muestras se convierte en dos señales de 9000 muestras, y se ignoran las 500 muestras restantes.

[Signals,Labels] = segmentSignals(Signals,Labels);

Vea los primeros cinco elementos de la matriz para comprobar que cada entrada tiene ahora 9000 muestras de longitud.Signals

Signals(1:5)
ans = 5×1 cell array
    {1×9000 double}
    {1×9000 double}
    {1×9000 double}
    {1×9000 double}
    {1×9000 double}

Entrene al clasificador usando datos de señal sin procesar

Para diseñar el clasificador, utilice las señales sin procesar generadas en la sección anterior. Divida las señales en un conjunto de entrenamiento para entrenar el clasificador y un conjunto de pruebas para probar la precisión del clasificador en nuevos datos.

Utilice la función para mostrar que hay 718 señales AFib y 4937 señales normales, una relación de 1:7.summary

summary(Labels)
     A       718       N      4937  

Debido a que el 87,3% de las señales son Normales, el clasificador aprendería que puede lograr una alta precisión simplemente clasificando todas las señales como Normales. Para evitar este sesgo, aumente los datos AFib duplicando las señales AFib en el conjunto de datos para que haya el mismo número de señales Normal y AFib. Esta duplicación, comúnmente llamada sobremuestreo, es una forma de aumento de datos utilizada en el aprendizaje profundo.

Divida las señales según su clase.

afibX = Signals(Labels=='A'); afibY = Labels(Labels=='A');  normalX = Signals(Labels=='N'); normalY = Labels(Labels=='N');

A continuación, úselo para dividir los objetivos de cada clase aleatoriamente en conjuntos de entrenamiento y pruebas.dividerand

[trainIndA,~,testIndA] = dividerand(718,0.9,0.0,0.1); [trainIndN,~,testIndN] = dividerand(4937,0.9,0.0,0.1);  XTrainA = afibX(trainIndA); YTrainA = afibY(trainIndA);  XTrainN = normalX(trainIndN); YTrainN = normalY(trainIndN);  XTestA = afibX(testIndA); YTestA = afibY(testIndA);  XTestN = normalX(testIndN); YTestN = normalY(testIndN);

Ahora hay 646 señales AFib y 4443 señales normales para el entrenamiento. Para lograr el mismo número de señales en cada clase, utilice las primeras 4438 señales normales y, a continuación, utilice para repetir las primeras 634 señales AFib siete veces.repmat

Para las pruebas, hay 72 señales AFib y 494 señales normales. Utilice las primeras 490 señales normales y, a continuación, utilice para repetir las primeras 70 señales AFib siete veces.repmat De forma predeterminada, la red neuronal baraja aleatoriamente los datos antes del entrenamiento, lo que garantiza que las señales contiguas no tengan la misma etiqueta.

XTrain = [repmat(XTrainA(1:634),7,1); XTrainN(1:4438)]; YTrain = [repmat(YTrainA(1:634),7,1); YTrainN(1:4438)];  XTest = [repmat(XTestA(1:70),7,1); XTestN(1:490)]; YTest = [repmat(YTestA(1:70),7,1); YTestN(1:490);];

La distribución entre las señales Normal y AFib ahora está equilibrada uniformemente tanto en el conjunto de entrenamiento como en el conjunto de pruebas.

summary(YTrain)
     A      4438       N      4438  
summary(YTest)
     A      490       N      490  

Definir la arquitectura de red LSTM

Las redes LSTM pueden aprender dependencias a largo plazo entre los pasos de tiempo de los datos de secuencia. Este ejemplo utiliza la capa bidireccional LSTM, ya que mira la secuencia en direcciones hacia adelante y hacia atrás.bilstmLayer

Dado que las señales de entrada tienen una dimensión cada una, especifique el tamaño de entrada para que sea secuencias de tamaño 1. Especifique una capa LSTM bidireccional con un tamaño de salida de 100 y genere el último elemento de la secuencia. Este comando indica a la capa bidireccional LSTM que asigne la serie temporal de entrada en 100 entidades y, a continuación, prepara la salida para la capa totalmente conectada. Por último, especifique dos clases incluyendo una capa totalmente conectada de tamaño 2, seguida de una capa softmax y una capa de clasificación.

layers = [ ...     sequenceInputLayer(1)     bilstmLayer(100,'OutputMode','last')     fullyConnectedLayer(2)     softmaxLayer     classificationLayer     ]
layers =    5x1 Layer array with layers:       1   ''   Sequence Input          Sequence input with 1 dimensions      2   ''   BiLSTM                  BiLSTM with 100 hidden units      3   ''   Fully Connected         2 fully connected layer      4   ''   Softmax                 softmax      5   ''   Classification Output   crossentropyex 

A continuación, especifique las opciones de entrenamiento para el clasificador. Establezca el en 10 para permitir que la red realice 10 pasadas a través de los datos de entrenamiento.'MaxEpochs' A de 150 indica a la red que mire 150 señales de entrenamiento a la vez.'MiniBatchSize' Un de 0.01 ayuda a acelerar el proceso de entrenamiento.'InitialLearnRate' Especifique a de 1000 para dividir la señal en partes más pequeñas para que la máquina no se quede sin memoria mirando demasiados datos a la vez.'SequenceLength' Establezca ' ' en 1 para estabilizar el proceso de entrenamiento evitando que los gradientes se agranden demasiado.GradientThreshold Especifique como para generar trazados que muestren un gráfico del progreso del entrenamiento a medida que aumenta el número de iteraciones.'Plots''training-progress' Establézalo para suprimir la salida de tabla que corresponde a los datos mostrados en el trazado.'Verbose'false Si desea ver esta tabla, establezca en .'Verbose'true

Este ejemplo utiliza el solucionador de estimación de momento adaptable (ADAM). ADAM funciona mejor con redes neuronales recurrentes (RNN) como LSMM que el descenso de gradiente estocástico predeterminado con el solucionador de impulso (SGDM).

options = trainingOptions('adam', ...     'MaxEpochs',10, ...     'MiniBatchSize', 150, ...     'InitialLearnRate', 0.01, ...     'SequenceLength', 1000, ...     'GradientThreshold', 1, ...     'ExecutionEnvironment',"auto",...     'plots','training-progress', ...     'Verbose',false);

Capacitar a la red LSTM

Entrene la red LSTM con las opciones de entrenamiento y la arquitectura de capa especificadas mediante .trainNetwork Debido a que el conjunto de entrenamiento es grande, el proceso de entrenamiento puede tardar varios minutos.

net = trainNetwork(XTrain,YTrain,layers,options);

La subtrama superior de la gráfica de progreso de entrenamiento representa la precisión del entrenamiento, que es la precisión de clasificación en cada minilote. Cuando el entrenamiento progresa con éxito, este valor normalmente aumenta hacia el 100%. La subtrama inferior muestra la pérdida de entrenamiento, que es la pérdida de entropía cruzada en cada minilote. Cuando el entrenamiento progresa correctamente, este valor normalmente disminuye hacia cero.

Si el entrenamiento no es convergente, las gráficas pueden oscilar entre valores sin tendencia en una determinada dirección ascendente o descendente. Esta oscilación significa que la precisión del entrenamiento no está mejorando y la pérdida de entrenamiento no está disminuyendo. Esta situación puede ocurrir desde el inicio del entrenamiento, o las parcelas podrían estanca después de alguna mejora preliminar en la precisión del entrenamiento. En muchos casos, cambiar las opciones de formación puede ayudar a la red a lograr la convergencia. Disminuir o disminuir podría dar lugar a un tiempo de entrenamiento más largo, pero puede ayudar a la red a aprender mejor.MiniBatchSizeInitialLearnRate

La precisión de entrenamiento del clasificador oscila entre el 50% y el 60%, y al final de 10 épocas, ya ha tardado varios minutos en entrenarse.

Visualizar la precisión de la formación y las pruebas

Calcular la precisión del entrenamiento, que representa la precisión del clasificador en las señales en las que se entrenó. En primer lugar, clasifique los datos de entrenamiento.

trainPred = classify(net,XTrain,'SequenceLength',1000);

En los problemas de clasificación, las matrices de confusión se utilizan para visualizar el rendimiento de un clasificador en un conjunto de datos para el que se conocen los valores verdaderos. La clase de destino es la etiqueta de la verdad del suelo de la señal, y la clase de salida es la etiqueta asignada a la señal por la red. Las etiquetas de ejes representan las etiquetas de clase, AFib (A) y Normal (N).

Utilice el comando para calcular la precisión general de la clasificación para las predicciones de datos de prueba.confusionchart Especifique como para mostrar las tasas positivas reales y las tasas de falsos positivos en el resumen de filas.'RowSummary''row-normalized' Además, especifique como para mostrar los valores predictivos positivos y las tasas de detección falsas en el resumen de columna.'ColumnSummary''column-normalized'

LSTMAccuracy = sum(trainPred == YTrain)/numel(YTrain)*100
LSTMAccuracy = 61.2100 
 figure ccLSTM = confusionchart(YTrain,trainPred); ccLSTM.Title = 'Confusion Chart for LSTM'; ccLSTM.ColumnSummary = 'column-normalized'; ccLSTM.RowSummary = 'row-normalized';

La matriz de confusión muestra que el 81,7% de las señales AFib de la verdad del suelo se clasifican correctamente como AFib, mientras que el 31,1% de las señales normales de la verdad del suelo se clasifican correctamente como Normales. Además, el 54,2% de las señales clasificadas como AFib son en realidad AFib, y el 63,0% de las señales clasificadas como Normales son realmente Normales. La precisión general del entrenamiento es del 56,4%.

Ahora clasifique los datos de prueba con la misma red.

testPred = classify(net,XTest,'SequenceLength',1000);

Calcule la precisión de las pruebas y visualice el rendimiento de la clasificación como una matriz de confusión.

LSTMAccuracy = sum(testPred == YTest)/numel(YTest)*100
LSTMAccuracy = 61.4286 
 figure ccLSTM = confusionchart(YTest,testPred); ccLSTM.Title = 'Confusion Chart for LSTM'; ccLSTM.ColumnSummary = 'column-normalized'; ccLSTM.RowSummary = 'row-normalized';

Esta matriz de confusión es similar a la matriz de confusión de entrenamiento. La precisión general de las pruebas es del 55,8%.

Mejorar el rendimiento con la extracción de características

La extracción de características de los datos puede ayudar a mejorar la precisión de entrenamiento y pruebas del clasificador. Para decidir qué características extraer, este ejemplo adapta un enfoque que calcula las imágenes de frecuencia de tiempo, como los espectrogramas, y las utiliza para entrenar redes neuronales convolucionales (CNN) [4], [5].

Visualice el espectrograma de cada tipo de señal.

fs = 300;  figure subplot(2,1,1); pspectrum(normal,fs,'spectrogram','TimeResolution',0.5) title('Normal Signal')  subplot(2,1,2); pspectrum(aFib,fs,'spectrogram','TimeResolution',0.5) title('AFib Signal')

Puesto que este ejemplo utiliza un LSTM en lugar de un CNN, es importante traducir el enfoque para que se aplique a las señales unidimensionales. Los momentos de frecuencia de tiempo (TF) extraen información de los espectrogramas. Cada momento se puede utilizar como una característica unidimensional para introducir en el LSTM.

Explora dos momentos de TF en el dominio del tiempo:

  • Frecuencia instantánea ( )instfreq

  • Entropía espectral ( )pentropy

La función estima la frecuencia dependiente del tiempo de una señal como el primer momento del espectrograma de potencia.instfreq La función calcula un espectrograma utilizando transformaciones de Fourier a corto plazo en ventanas de tiempo. En este ejemplo, la función utiliza 255 ventanas de tiempo. Las salidas de tiempo de la función corresponden a los centros de las ventanas de tiempo.

Visualice la frecuencia instantánea para cada tipo de señal.

[instFreqA,tA] = instfreq(aFib,fs); [instFreqN,tN] = instfreq(normal,fs);  figure subplot(2,1,1); plot(tN,instFreqN) title('Normal Signal') xlabel('Time (s)') ylabel('Instantaneous Frequency')  subplot(2,1,2); plot(tA,instFreqA) title('AFib Signal') xlabel('Time (s)') ylabel('Instantaneous Frequency')

Se utiliza para aplicar la función a cada celda de los conjuntos de entrenamiento y pruebas.cellfun instfreq

instfreqTrain = cellfun(@(x)instfreq(x,fs)',XTrain,'UniformOutput',false); instfreqTest = cellfun(@(x)instfreq(x,fs)',XTest,'UniformOutput',false);

La entropía espectral mide cuán plana es el espectro de una señal. Una señal con un espectro puntiagudo, como una suma de sinusoides, tiene baja entropía espectral. Una señal con un espectro plano, como el ruido blanco, tiene una alta entropía espectral. La función estima la entropía espectral basada en un espectrograma de potencia.pentropy Al igual que con el caso de estimación de frecuencia instantánea, utiliza 255 ventanas de tiempo para calcular el espectrograma.pentropy Las salidas de tiempo de la función corresponden al centro de las ventanas de tiempo.

Visualice la entropía espectral para cada tipo de señal.

[pentropyA,tA2] = pentropy(aFib,fs); [pentropyN,tN2] = pentropy(normal,fs);  figure  subplot(2,1,1) plot(tN2,pentropyN) title('Normal Signal') ylabel('Spectral Entropy')  subplot(2,1,2) plot(tA2,pentropyA) title('AFib Signal') xlabel('Time (s)') ylabel('Spectral Entropy')

Se utiliza para aplicar la función a cada celda de los conjuntos de entrenamiento y pruebas.cellfunpentropy

pentropyTrain = cellfun(@(x)pentropy(x,fs)',XTrain,'UniformOutput',false); pentropyTest = cellfun(@(x)pentropy(x,fs)',XTest,'UniformOutput',false);

Concatene las características de modo que cada celda de los nuevos conjuntos de entrenamiento y pruebas tenga dos dimensiones o dos características.

XTrain2 = cellfun(@(x,y)[x;y],instfreqTrain,pentropyTrain,'UniformOutput',false); XTest2 = cellfun(@(x,y)[x;y],instfreqTest,pentropyTest,'UniformOutput',false);

Visualice el formato de las nuevas entradas. Cada célula ya no contiene una señal de 9000 muestras largas; ahora contiene dos características de 255 muestras de largo.

XTrain2(1:5)
ans = 5×1 cell array
    {2×255 double}
    {2×255 double}
    {2×255 double}
    {2×255 double}
    {2×255 double}

Estandarizar los datos

La frecuencia instantánea y la entropía espectral tienen medios que difieren por casi un orden o magnitud. Además, la media de frecuencia instantánea podría ser demasiado alta para que el LSTM aprenda eficazmente. Cuando una red se ajusta a los datos con una media grande y un gran rango de valores, las entradas grandes podrían ralentizar el aprendizaje y la convergencia de la red [6].

mean(instFreqN)
ans = 5.5615 
mean(pentropyN)
ans = 0.6326 

Utilice la media del conjunto de entrenamiento y la desviación estándar para estandarizar los conjuntos de entrenamiento y pruebas. La estandarización, o puntuación z, es una forma popular de mejorar el rendimiento de la red durante el entrenamiento.

XV = [XTrain2{:}]; mu = mean(XV,2); sg = std(XV,[],2);  XTrainSD = XTrain2; XTrainSD = cellfun(@(x)(x-mu)./sg,XTrainSD,'UniformOutput',false);  XTestSD = XTest2; XTestSD = cellfun(@(x)(x-mu)./sg,XTestSD,'UniformOutput',false);

Mostrar los medios de la frecuencia instantánea estandarizada y la entropía espectral.

instFreqNSD = XTrainSD{1}(1,:); pentropyNSD = XTrainSD{1}(2,:);  mean(instFreqNSD)
ans = -0.3210 
mean(pentropyNSD)
ans = -0.2416 

Modificar la arquitectura de red LSTM

Ahora que las señales tienen cada una dos dimensiones, es necesario modificar la arquitectura de red especificando el tamaño de la secuencia de entrada como 2. Especifique una capa LSTM bidireccional con un tamaño de salida de 100 y genere el último elemento de la secuencia. Especifique dos clases incluyendo una capa totalmente conectada de tamaño 2, seguida de una capa softmax y una capa de clasificación.

layers = [ ...     sequenceInputLayer(2)     bilstmLayer(100,'OutputMode','last')     fullyConnectedLayer(2)     softmaxLayer     classificationLayer     ]
layers =    5x1 Layer array with layers:       1   ''   Sequence Input          Sequence input with 2 dimensions      2   ''   BiLSTM                  BiLSTM with 100 hidden units      3   ''   Fully Connected         2 fully connected layer      4   ''   Softmax                 softmax      5   ''   Classification Output   crossentropyex 

Especifique las opciones de entrenamiento. Establezca el número máximo de épocas en 30 para permitir que la red realice 30 pasadas a través de los datos de entrenamiento.

options = trainingOptions('adam', ...     'MaxEpochs',30, ...     'MiniBatchSize', 150, ...     'InitialLearnRate', 0.01, ...     'GradientThreshold', 1, ...     'ExecutionEnvironment',"auto",...     'plots','training-progress', ...     'Verbose',false);

Entrene la red LSTM con funciones de frecuencia de tiempo

Entrene la red LSTM con las opciones de entrenamiento y la arquitectura de capa especificadas mediante .trainNetwork

net2 = trainNetwork(XTrainSD,YTrain,layers,options);

Hay una gran mejora en la precisión del entrenamiento, que ahora es superior al 90%. Las tendencias de pérdida de entropía cruzada hacia 0. Además, el tiempo necesario para el entrenamiento disminuye porque los momentos de TF son más cortos que las secuencias sin procesar.

Visualizar la precisión de la formación y las pruebas

Clasificar los datos de entrenamiento mediante la red LSTM actualizada. Visualice el rendimiento de la clasificación como una matriz de confusión.

trainPred2 = classify(net2,XTrainSD); LSTMAccuracy = sum(trainPred2 == YTrain)/numel(YTrain)*100
LSTMAccuracy = 83.5174 
 figure ccLSTM = confusionchart(YTrain,trainPred2); ccLSTM.Title = 'Confusion Chart for LSTM'; ccLSTM.ColumnSummary = 'column-normalized'; ccLSTM.RowSummary = 'row-normalized';

Clasificar los datos de prueba con la red actualizada. Trazar la matriz de confusión para examinar la precisión de la prueba.

testPred2 = classify(net2,XTestSD);  LSTMAccuracy = sum(testPred2 == YTest)/numel(YTest)*100
LSTMAccuracy = 82.5510 
 figure ccLSTM = confusionchart(YTest,testPred2); ccLSTM.Title = 'Confusion Chart for LSTM'; ccLSTM.ColumnSummary = 'column-normalized'; ccLSTM.RowSummary = 'row-normalized';

Conclusión

Este ejemplo muestra cómo construir un clasificador para detectar la fibrilación auricular en señales ECG mediante una red LSTM. El procedimiento utiliza el sobremuestreo para evitar el sesgo de clasificación que se produce cuando se trata de detectar condiciones anormales en poblaciones compuestas principalmente de pacientes sanos. El entrenamiento de la red LSTM utilizando datos de señal sin procesar da como resultado una precisión de clasificación deficiente. El entrenamiento de la red mediante dos funciones de tiempo-frecuencia-momento para cada señal mejora significativamente el rendimiento de clasificación y también disminuye el tiempo de entrenamiento.

Referencias

[1]AF Classification from a Short Single Lead ECG Recording: the PhysioNet/Computing in Cardiology Challenge, 2017.https://physionet.org/challenge/2017/

[2] Clifford, Gari, Chengyu Liu, Benjamin Moody, Li-wei H. Lehman, Ikaro Silva, Qiao Li, Alistair Johnson y Roger G. Mark. "Clasificación AF a partir de una grabación ECG de un solo cable corto: El PhysioNet Computing in Cardiology Challenge 2017." (Rennes:Computing in Cardiology IEEE). Vol. 44, 2017, págs. 1–4.

[3] Goldberger, A. L., L. A. N. Amaral, L. Glass, J. M. Hausdorff, P. Ch. Ivanov, R. G. Mark, J. E. Mietus, G. B. Moody, C.-K. Peng, y H. E. Stanley. "PhysioBank, PhysioToolkit y PhysioNet: Componentes de un nuevo recurso de investigación para señales fisiológicas complejas". .Circulation Vol. 101, No 23, 13 de junio de 2000, págs. e215–e220.http://circ.ahajournals.org/content/101/23/e215.full

[4] Pons, Jordi, Thomas Lidy y Xavier Serra. "Experimentando con Redes Neuronales Convolucionales Musicalmente Motivadas". .14th International Workshop on Content-Based Multimedia Indexing (CBMI) junio de 2016.

[5] Wang, D. "Deep learning reinventa el audífono", Vol. 54, No. 3, marzo de 2017, págs. 32–37. Doi:IEEE Spectrum 10.1109/MSPEC.2017.7864754.

[6] Brownlee, Jason. .How to Scale Data for Long Short-Term Memory Networks in Python 7 de julio de 2017.https://machinelearningmastery.com/how-to-scale-data-for-long-short-term-memory-networks-in-python/.

Consulte también

Funciones

Temas relacionados