Main Content

Regresión de secuencia a uno mediante deep learning

En este ejemplo se muestra cómo predecir la frecuencia de una forma de onda mediante una red neuronal de memoria de corto-largo plazo (LSTM).

Puede utilizar una red neuronal LSTM para predecir una respuesta numérica de una secuencia empleando un conjunto de entrenamiento de secuencias y valores objetivo. Una red de LSTM es una red neuronal recurrente (RNN) que procesa datos de entrada formando un lazo con las unidades de tiempo y actualizando el estado de la red. El estado de la red contiene información recordada durante las unidades de tiempo anteriores. Entre los ejemplos de respuestas numéricas de una secuencia encontramos los siguientes:

  • Propiedades de la secuencia, como su frecuencia, valor máximo y media.

  • Valores de unidades de tiempo pasadas o futuras de la secuencia.

En este ejemplo se entrena una red LSTM con regresión de secuencia a uno usando el conjunto de datos de forma de onda, que contiene 1000 formas de onda generadas de forma sintética de diferentes longitudes con tres canales. Para determinar la frecuencia de una forma de onda empleando métodos convencionales, consulte fft.

Cargar datos secuenciales

Cargue los datos de ejemplo de WaveformData.mat. Los datos son un arreglo de celdas de numObservations por 1 de secuencias, donde numObservations es el número de secuencias. Cada secuencia es un arreglo numérico de numTimeSteps por numChannels, donde numTimeSteps es el número de unidades de tiempo de la secuencia y numChannels es el número de canales de la secuencia. Los objetivos correspondientes se encuentran en un arreglo numérico de numObservations por numResponses de las frecuencias de las formas de onda, donde numResponses es el número de canales de los objetivos.

load WaveformData

Visualice el número de observaciones.

numObservations = numel(data)
numObservations = 1000

Visualice los tamaños de las primeras secuencias y las frecuencias correspondientes.

data(1:4)
ans=4×1 cell array
    {103×3 double}
    {136×3 double}
    {140×3 double}
    {124×3 double}

freq(1:4,:)
ans = 4×1

    5.8922
    2.2557
    4.5250
    4.4418

Visualice el número de canales de las secuencias. Para entrenar la red, cada secuencia debe tener el mismo número de canales.

numChannels = size(data{1},2)
numChannels = 3

Visualice el número de respuestas (el número de canales de los objetivos).

numResponses = size(freq,2)
numResponses = 1

Visualice las primeras secuencias en gráficas.

figure
tiledlayout(2,2)
for i = 1:4
    nexttile
    stackedplot(data{i}, DisplayLabels="Channel " + (1:numChannels))

    xlabel("Time Step")
    title("Frequency: " + freq(i))
end

Preparar datos para el entrenamiento

Reserve datos para validación y pruebas. Divida los datos en un conjunto de entrenamiento que contenga el 80% de los datos, un conjunto de validación que contenga el 10% de los datos y un conjunto de prueba que contenga el 10% restante de los datos.

[idxTrain,idxValidation,idxTest] = trainingPartitions(numObservations, [0.8 0.1 0.1]);

XTrain = data(idxTrain);
XValidation = data(idxValidation);
XTest = data(idxTest);

TTrain = freq(idxTrain);
TValidation = freq(idxValidation);
TTest = freq(idxTest);

Definir la arquitectura de red de LSTM

Cree una red de regresión de LSTM.

  • Utilice una capa de entrada de secuencias con un tamaño de entrada que coincida con el número de canales de los datos de entrada.

  • Para un mejor ajuste y para evitar que el entrenamiento diverja, establezca la opción Normalization de la capa de entrada de secuencias en "zscore". Esta operación normaliza los datos secuenciales para que tengan media cero y varianza unitaria.

  • Utilice una capa de LSTM con 100 unidades ocultas. El número de unidades ocultas determina cuánta información aprende la capa. Los valores más grandes pueden producir resultados más precisos, pero son más susceptibles a sobreajustarse a los datos de entrenamiento.

  • Para producir una sola unidad de tiempo para cada secuencia, establezca la opción OutputMode de la capa de LSTM en "last".

  • Para especificar el número de valores que se desea predecir, incluya una capa completamente conectada con un tamaño que coincida con el número de predictores.

numHiddenUnits = 100;

layers = [ ...
    sequenceInputLayer(numChannels, Normalization="zscore")
    lstmLayer(numHiddenUnits, OutputMode="last")
    fullyConnectedLayer(numResponses)]
layers = 
  3×1 Layer array with layers:

     1   ''   Sequence Input    Sequence input with 3 dimensions
     2   ''   LSTM              LSTM with 100 hidden units
     3   ''   Fully Connected   1 fully connected layer

Especificar las opciones de entrenamiento

Especifique las opciones de entrenamiento. Para escoger entre las opciones se requiere un análisis empírico. Para explorar diferentes configuraciones de opciones de entrenamiento mediante la ejecución de experimentos, puede utilizar la app Experiment Manager.

  • Entrenar usando el optimizador Adam.

  • Entrenar durante 250 épocas. Para conjuntos de datos más grandes, puede que no sea necesario entrenar durante tantas épocas para conseguir un buen ajuste.

  • Especificar las secuencias y las respuestas usadas para la validación.

  • Generar la red que dé la mejor pérdida de validación, es decir, la más baja.

  • Establecer la tasa de aprendizaje en 0,005.

  • Truncar las secuencias de cada minilote para que tengan la misma longitud que la secuencia más corta. Truncando las secuencias se garantiza que no se añade relleno, a costa de descartar datos. Para secuencias en las que es probable que todas las unidades de tiempo contengan información importante, el truncamiento puede impedir que la red se ajuste correctamente.

  • Monitorizar el progreso del entrenamiento en una gráfica y monitorizar la métrica RMSE.

  • Deshabilite la salida detallada.

options = trainingOptions("adam", ...
    MaxEpochs=250, ...
    ValidationData={XValidation TValidation}, ...
    InitialLearnRate=0.005, ...
    SequenceLength="shortest", ...
    Metrics="rmse", ...
    Plots="training-progress", ...
    Verbose=false);

Entrenar la red de LSTM

Entrene la red neuronal con la función trainnet. Para la regresión, utilice la pérdida de error cuadrático medio. De forma predeterminada, la función trainnet usa una GPU en caso de que esté disponible. Para utilizar una GPU se requiere una licencia de Parallel Computing Toolbox™ y un dispositivo GPU compatible. Para obtener información sobre los dispositivos compatibles, consulte GPU Computing Requirements (Parallel Computing Toolbox). De lo contrario, la función usa la CPU. Para especificar el entorno de ejecución, utilice la opción de entrenamiento ExecutionEnvironment.

net = trainnet(XTrain,TTrain,layers,"mse",options);

Probar la red de LSTM

Realice predicciones con la función minibatchpredict. De forma predeterminada, la función minibatchpredict usa una GPU en caso de que esté disponible.

YTest = minibatchpredict(net,XTest,SequenceLength="shortest");

Visualice las primeras predicciones en una gráfica.

figure
tiledlayout(2,2)
for i = 1:4
    nexttile
    stackedplot(XTest{i},DisplayLabels="Channel " + (1:numChannels))

    xlabel("Time Step")
    title("Predicted Frequency: " + string(YTest(i)))
end

Visualice los errores cuadráticos medios en un histograma.

figure
histogram(mean((TTest - YTest).^2,2))
xlabel("Error")
ylabel("Frequency")

Calcule el error cuadrático medio raíz global.

rmse = rmse(YTest,TTest)
rmse = single
    0.7605

Represente las frecuencias predichas frente a las frecuencias reales.

figure
scatter(YTest,TTest, "b+");
xlabel("Predicted Frequency")
ylabel("Actual Frequency")
hold on

m = min(freq);
M=max(freq);
xlim([m M])
ylim([m M])
plot([m M], [m M], "r--")

Consulte también

| | | | | | |

Temas relacionados