Tutorial de RNN (red neuronal recurrente): ejemplo de TensorFlow

โšก Resumen inteligente

Las redes neuronales recurrentes aรฑaden un estado de memoria a las neuronas convencionales, realimentando cada salida como la siguiente entrada para que el modelo pueda aprender del orden. Este tutorial muestra cรณmo construir una en TensorFlow y pronosticar una serie temporal.

  • ๐Ÿ”˜ Estado de la memoria: Cada neurona recurrente recibe la salida anterior junto con la nueva entrada, lo que le da a la red su percepciรณn temporal.
  • โ˜‘๏ธ Forma de salida: Una ejecuciรณn de la red de juguete devuelve un tensor (3, 2, 6): lotes, pasos de tiempo y neuronas en ese orden.
  • โœ… Regla de agrupaciรณn: Las series temporales de entrada se transforman a tres dimensiones y la matriz de etiquetas es la misma serie desplazada un perรญodo hacia adelante.
  • ๐Ÿงช Esqueleto del modelo: Marcadores de posiciรณn, una BasicRNNCell envuelta en dynamic_rnn, una proyecciรณn densa y luego el error cuadrรกtico medio con un optimizador Adam.
  • ๐Ÿ› ๏ธ Carrera de entrenamiento: Tras 1,500 รฉpocas en 120 neuronas recurrentes, la pรฉrdida se reduce de 502,893 a aproximadamente 1,385.
  • ๐Ÿ“‰ Lรญmite conocido: Las secuencias largas desencadenan el problema del gradiente evanescente, que las variantes LSTM y con compuertas fueron diseรฑadas para resolver.

Red neuronal recurrente (RNN)

ยฟPor quรฉ necesitamos una red neuronal recurrente (RNN)?

La red neuronal recurrente (RNN) le permite modelar unidades de memoria para conservar datos y modelar dependencias a corto plazo. Tambiรฉn se utiliza en pronรณsticos de series de tiempo para la identificaciรณn de correlaciones y patrones de datos. Tambiรฉn ayuda a producir resultados predictivos para datos secuenciales al ofrecer un comportamiento similar al del cerebro humano.

La estructura de un Red neuronal artificial Es relativamente sencillo y se basa principalmente en la multiplicaciรณn de matrices. En el primer paso, las entradas se multiplican por pesos y sesgos inicialmente aleatorios, se transforman mediante una funciรณn de activaciรณn y los valores de salida se utilizan para realizar una predicciรณn. Este paso permite hacerse una idea de cuรกn alejada estรก la red de la realidad.

La mรฉtrica aplicada es la pรฉrdida. Cuanto mayor sea la funciรณn de pรฉrdida, mรกs tonto serรก el modelo. Para mejorar el conocimiento de la red, se requiere cierta optimizaciรณn mediante el ajuste de los pesos de la red. El descenso de gradiente estocรกstico es el mรฉtodo empleado para cambiar los valores de los pesos en la direcciรณn correcta. Una vez realizado el ajuste, la red puede utilizar otro lote de datos para probar su nuevo conocimiento.

Afortunadamente, el error es menor que antes, aunque no lo suficientemente pequeรฑo. El paso de optimizaciรณn se realiza de forma iterativa hasta que el error se minimiza, es decir, hasta que no se puede extraer mรกs informaciรณn.tracted

El problema de este tipo de modelo es que no tiene memoria. Significa que la entrada y la salida son independientes. En otras palabras, al modelo no le importa lo que vino antes. Plantea algunas dudas cuando es necesario predecir series de tiempo o oraciones porque la red necesita tener informaciรณn sobre datos histรณricos o palabras pasadas.

Para superar este problema, se ha desarrollado un nuevo tipo de arquitectura: Red neuronal recurrente (RNN en adelante).

ยฟQuรฉ es una red neuronal recurrente (RNN)?

Una red neuronal recurrente (RNN) es un tipo de red neuronal artificial en la que la conexiรณn entre diferentes nodos forma un grafo dirigido que proporciona un comportamiento dinรกmico temporal. Ayuda a modelar datos secuenciales derivados de redes de propagaciรณn directa. Funciona de forma similar al cerebro humano para ofrecer resultados predictivos.

Una red neuronal recurrente se parece bastante a una red neuronal tradicional, excepto que se agrega un estado de memoria a las neuronas. El cรกlculo para incluir una memoria es sencillo.

Imagina un modelo simple con una sola neurona alimentada por un lote de datos. En una red neuronal tradicional, el modelo produce la salida multiplicando la entrada por el peso y la funciรณn de activaciรณn. Con una RNN, esta salida se envรญa de vuelta a sรญ misma varias veces. La llamamos hora de caminar la cantidad de veces que la salida se convierte en la entrada de la siguiente multiplicaciรณn de matrices.

Por ejemplo, en la imagen siguiente, puede ver que la red estรก compuesta por una neurona. La red calcula la multiplicaciรณn de matrices entre la entrada y el peso y agrega no linealidad con la funciรณn de activaciรณn. Se convierte en la salida en t-1. Esta salida es la entrada de la segunda multiplicaciรณn de matrices.

Una sola neurona recurrente envรญa su salida en t-1 de vuelta como entrada de la siguiente multiplicaciรณn.

Red neuronal recurrente (RNN)

A continuaciรณn, codificamos un RNN simple en TensorFlow para comprender el paso y tambiรฉn la forma de la salida.

La red estรก compuesta por:

  • Cuatro entradas
  • Seis neuronas
  • pasos de 2 veces

La red procederรก como se muestra en la siguiente imagen.

Red neuronal recurrente desplegada con cuatro entradas, seis neuronas y dos pasos de tiempo.

La red se denomina "recurrente" porque realiza la misma operaciรณn en cada casilla de activaciรณn. La red calcula los pesos de las entradas y la salida anterior antes de utilizar una funciรณn de activaciรณn.

Nota de versiรณn: El cรณdigo de este tutorial estรก dirigido a la API de grรกficos de TensorFlow 1.x. En TensorFlow 2.x, el mismo script sigue ejecutรกndose despuรฉs import tensorflow.compat.v1 as tf mรกs tf.disable_v2_behavior(), porque los marcadores de posiciรณn, las sesiones y el mรณdulo rnn_cell ahora viven bajo tf.compat.v1. El equivalente idiomรกtico 2.x es tf.keras.layers.SimpleRNN.

import numpy as np
import tensorflow as tf
n_inputs = 4
n_neurons = 6
n_timesteps = 2
The data is a sequence of a number from 0 to 9 and divided into three batches of data.
## Data 
X_batch = np.array([
        [[0, 1, 2, 5], [9, 8, 7, 4]], # Batch 1
        [[3, 4, 5, 2], [0, 0, 0, 0]], # Batch 2
        [[6, 7, 8, 5], [6, 5, 4, 2]], # Batch 3
    ])

Podemos construir la red con un marcador de posiciรณn para los datos, la etapa recurrente y la salida.

Definir el marcador de posiciรณn para los datos.

X = tf.placeholder(tf.float32, [None, n_timesteps, n_inputs])

Aquรญ:

  • Ninguno: Desconocido y tomarรก el tamaรฑo del lote.
  • n_timesteps: nรบmero de veces que la red enviarรก la salida a la neurona
  • n_inputs: nรบmero de entradas por lote

Definir la red recurrente

Como se menciona en la imagen de arriba, la red estรก compuesta por 6 neuronas. La red calcularรก dos productos escalares:

  • Ingrese datos con el primer conjunto de pesos (es decir, 6: igual al nรบmero de neuronas)
  • Salida anterior con un segundo conjunto de pesos (es decir, 6: correspondiente al nรบmero de salida)

Tenga en cuenta que, durante el primer avance, los valores de la salida anterior son iguales a ceros porque no tenemos ningรบn valor disponible.

El objeto para construir un RNN es tf.contrib.rnn.BasicRNNCell con el argumento num_units para definir el nรบmero de entradas

basic_cell = tf.contrib.rnn.BasicRNNCell(num_units=n_neurons)

Ahora que la red estรก definida, puede calcular las salidas y los estados.

outputs, states = tf.nn.dynamic_rnn(basic_cell, X, dtype=tf.float32)

Este objeto utiliza un bucle interno para multiplicar las matrices el nรบmero apropiado de veces.

Cabe destacar que la neurona recurrente es una funciรณn de todas las entradas de los pasos de tiempo anteriores. Asรญ es como la red construye su propia memoria. La informaciรณn del tiempo anterior puede propagarse al tiempo futuro. Esta es la magia de las redes neuronales recurrentes.

## Define the shape of the tensor
X = tf.placeholder(tf.float32, [None, n_timesteps, n_inputs])
## Define the network
basic_cell = tf.contrib.rnn.BasicRNNCell(num_units=n_neurons)
outputs, states = tf.nn.dynamic_rnn(basic_cell, X, dtype=tf.float32)
init = tf.global_variables_initializer()
init = tf.global_variables_initializer()
with tf.Session() as sess:
    init.run()
    outputs_val = outputs.eval(feed_dict={X: X_batch})
print(states.eval(feed_dict={X: X_batch}))
[[ 0.38941205 -0.9980438   0.99750966  0.7892596   0.9978241   0.9999997 ]
 [ 0.61096436  0.7255889   0.82977575 -0.88226104  0.29261455 -0.15597084]
 [ 0.62091285 -0.87023467  0.99729395 -0.58261937  0.9811445   0.99969864]]

Para fines explicativos, se imprimen los valores del estado anterior. La salida mostrada arriba corresponde al รบltimo estado. Ahora, al imprimir toda la salida, se puede observar que los estados son la salida anterior de cada lote. Es decir, la salida anterior contiene la informaciรณn de toda la secuencia.

print(outputs_val)    
print(outputs_val.shape)    
[[[-0.75934666 -0.99537754  0.9735819  -0.9722234  -0.14234993
   -0.9984044 ]
  [ 0.99975264 -0.9983206   0.9999993  -1.         -0.9997506
   -1.        ]]

 [[ 0.97486496 -0.98773265  0.9969686  -0.99950117 -0.7092863
   -0.99998885]
  [ 0.9326837   0.2673438   0.2808514  -0.7535883  -0.43337247
    0.5700631 ]]

 [[ 0.99628735 -0.9998728   0.99999213 -0.99999976 -0.9884324
   -1.        ]
  [ 0.99962527 -0.9467421   0.9997403  -0.99999714 -0.99929446
   -0.9999795 ]]]
(3, 2, 6)

La vista anotada que se muestra a continuaciรณn desglosa el mismo tensor impreso lote por lote.

Tensor de salida RNN anotado que etiqueta los tres lotes, las seis salidas de neuronas y la forma (3, 2, 6)

La salida tiene la forma de (3, 2, 6):

  • 3: Nรบmero de lotes
  • 2: Nรบmero del paso de tiempo
  • 6: Nรบmero de neuronas

La optimizaciรณn de una red neuronal recurrente es idรฉntica a la de una red neuronal tradicional. Verรก con mรกs detalle cรณmo optimizar el cรณdigo en la siguiente parte de este tutorial de Red neuronal recurrente.

Aplicaciones de RNN

RNN tiene mรบltiples usos, especialmente cuando se trata de predecir el futuro. En la industria financiera, RNN puede resultar รบtil para predecir los precios de las acciones o el signo de la direcciรณn del mercado de valores (es decir, positivo o negativo).

RNN es รบtil para un coche autรณnomo ya que puede evitar un accidente automovilรญstico anticipando la trayectoria del vehรญculo.

RNN se utiliza ampliamente en anรกlisis de texto, subtรญtulos de imรกgenes, anรกlisis de sentimientos y traducciรณn automรกtica. Por ejemplo, se puede utilizar una reseรฑa de una pelรญcula para comprender el sentimiento que percibiรณ el espectador despuรฉs de ver la pelรญcula. Automatizar esta tarea es muy รบtil cuando la productora cinematogrรกfica no tiene tiempo suficiente para revisar, etiquetar, consolidar y analizar las reseรฑas. La mรกquina puede hacer el trabajo con un mayor nivel de precisiรณn.

Limitaciones de RNN

En teorรญa, se supone que RNN transporta la informaciรณn varias veces. Sin embargo, es bastante difรญcil propagar toda esta informaciรณn cuando el paso de tiempo es demasiado largo. Cuando una red tiene demasiadas capas profundas, se vuelve imposible de entrenar. Este problema se llama: problema de gradiente de fuga. Si recuerdas, la red neuronal actualiza el peso mediante el algoritmo de descenso de gradiente. Los gradientes se hacen mรกs pequeรฑos a medida que la red avanza hacia capas inferiores.

En conclusiรณn, los gradientes permanecen constantes, lo que significa que no hay margen de mejora. El modelo aprende de los cambios en el gradiente, los cuales afectan la salida de la red. Sin embargo, si la diferencia en el gradiente es demasiado pequeรฑa (es decir, los pesos cambian ligeramente), la red no puede aprender nada y, por lo tanto, la salida tampoco. En consecuencia, una red que se enfrenta al problema del gradiente evanescente no puede converger hacia una buena soluciรณn.

Mejora LSTM

Para superar el problema potencial del desvanecimiento del gradiente que enfrentan las redes neuronales recurrentes (RNN), tres investigadores, Hochreiter, Schmidhuber y Bengio, mejoraron las RNN con una arquitectura llamada Memoria a Largo y Corto Plazo (LSTM). En resumen, LSTM proporciona a la red informaciรณn relevante del pasado para momentos mรกs recientes. La mรกquina utiliza una arquitectura mejorada para seleccionar y transportar informaciรณn hacia tiempos posteriores.

La arquitectura LSTM estรก disponible en TensorFlow, tf.contrib.rnn.LSTMCell. LSTM estรก fuera del alcance de este tutorial. Puede consultar la documentaciรณn oficial. documentaciรณn para mayor informaciรณn

En TensorFlow 2.x se llega a esa celda como tf.compat.v1.nn.rnn_cell.LSTMCell, mientras que el cรณdigo nuevo normalmente utiliza tf.keras.layers.LSTM o el encendedor tf.keras.layers.GRU, que alcanza una precisiรณn comparable con menos parรกmetros.

RNN en series de tiempo

En este tutorial de RNN de TensorFlow, utilizarรกs una RNN con datos de series temporales. Las series temporales dependen de datos anteriores, lo que significa que los valores pasados โ€‹โ€‹contienen informaciรณn relevante de la que la red puede aprender. La idea detrรกs de la predicciรณn de series temporales es estimar el valor futuro de una serie, por ejemplo, el precio de las acciones, la temperatura, el PIB, etc.

La preparaciรณn de datos para Keras RNN y series temporales puede ser un poco complicada. En primer lugar, el objetivo es predecir el siguiente valor de la serie, es decir, utilizarรก la informaciรณn pasada para estimar el valor en t + 1. La etiqueta es igual a la secuencia de entrada y se adelantรณ un perรญodo. En segundo lugar, el nรบmero de entradas se establece en 1, es decir, una observaciรณn por vez. Por รบltimo, el paso de tiempo es igual a la secuencia del valor numรฉrico. Por ejemplo, si establece el paso de tiempo en 10, la secuencia de entrada regresarรก diez veces consecutivas.

Mire el grรกfico a continuaciรณn, hemos representado los datos de la serie temporal a la izquierda y una secuencia de entrada ficticia a la derecha. Crea una funciรณn para devolver un conjunto de datos con valor aleatorio para cada dรญa desde enero de 2001 hasta diciembre de 2016.

# To plot pretty figures
%matplotlib inline
import matplotlib
import matplotlib.pyplot as plt
import pandas as pd
def create_ts(start = '2001', n = 201, freq = 'M'):
    rng = pd.date_range(start=start, periods=n, freq=freq)
    ts = pd.Series(np.random.uniform(-18, 18, size=len(rng)), rng).cumsum()
    return ts
ts= create_ts(start = '2001', n = 192, freq = 'M')
ts.tail(5)

Resultado

2016-08-31    -93.459631
2016-09-30    -95.264791
2016-10-31    -95.551935
2016-11-30   -105.879611
2016-12-31   -123.729319
Freq: M, dtype: float64
ts = create_ts(start = '2001', n = 222)

# Left
plt.figure(figsize=(11,4))
plt.subplot(121)
plt.plot(ts.index, ts)
plt.plot(ts.index[90:100], ts[90:100], "b-", linewidth=3, label="A training instance")
plt.title("A time series (generated)", fontsize=14)

# Right
plt.subplot(122)
plt.title("A training instance", fontsize=14)
plt.plot(ts.index[90:100], ts[90:100], "b-", markersize=8, label="instance")
plt.plot(ts.index[91:101], ts[91:101], "bo", markersize=10, label="target", markerfacecolor='red')
plt.legend(loc="upper left")
plt.xlabel("Time")

plt.show()

Series temporales generadas a la izquierda y una instancia de entrenamiento de diez pasos con objetivos desplazados a la derecha.

La parte derecha del grรกfico muestra todas las series. Comienza en 2001 y termina en 2019. No tiene sentido introducir todos los datos en la red; en su lugar, es necesario crear un lote de datos con una longitud igual al intervalo de tiempo. Este lote serรก la variable X. La variable Y es igual que X, pero desplazada un perรญodo (es decir, se desea pronosticar t+1).

Ambos vectores tienen la misma longitud. Puedes verlo en la parte derecha del grรกfico anterior. La lรญnea representa los diez valores de la entrada X, mientras que los puntos rojos son los diez valores de la etiqueta, Y. Tenga en cuenta que la etiqueta comienza un perรญodo antes de X y termina un perรญodo despuรฉs.

Cree un RNN para predecir series temporales en TensorFlow

Ahora, en este entrenamiento de RNN, es el momento de crear su primer RNN para predecir la serie anterior. Debe especificar algunos hiperparรกmetros (los parรกmetros del modelo, es decir, el nรบmero de neuronas, etc.) para el modelo:

  • Nรบmero de entrada: 1
  • Paso de tiempo (ventanas en series de tiempo): 10
  • Nรบmero de neuronas: 120
  • Nรบmero de salida: 1

Tu red aprenderรก de una secuencia de 10 dรญas y contendrรก 120 neuronas recurrentes. Alimentas el modelo con una sola entrada, es decir, un dรญa. Puedes modificar los valores para comprobar si el modelo mejora.

Antes de construir el modelo, debes dividir el conjunto de datos en un conjunto de entrenamiento y un conjunto de prueba. El conjunto de datos completo tiene 222 puntos; usarรกs los primeros 201 puntos para entrenar el modelo y los รบltimos 21 para probarlo.

Tras definir los conjuntos de entrenamiento y prueba, es necesario crear un objeto que contenga los lotes. Estos lotes contienen valores X e Y. Recuerde que los valores X tienen un desfase de un periodo. Por lo tanto, se utilizan las primeras 200 observaciones y el paso de tiempo es de 10. El objeto `X_batches` debe contener 20 lotes de tamaรฑo 10*1. El objeto `Y_batches` tiene la misma estructura que el objeto `X_batches`, pero con un desfase de un periodo.

Paso 1) Crea el tren y prueba.

En primer lugar, conviertes la serie en una NumPy matriz; luego, define las ventanas (es decir, la cantidad de veces que la red aprenderรก), la cantidad de entradas, salidas y el tamaรฑo del conjunto de entrenamiento como se muestra en el ejemplo de TensorFlow RNN a continuaciรณn.

series = np.array(ts)
n_windows = 20   
n_input =  1
n_output = 1
size_train = 201

Despuรฉs de eso, simplemente divide la matriz en dos conjuntos de datos.

## Split data
train = series[:size_train]
test = series[size_train:]
print(train.shape, test.shape)
(201,) (21,)

Paso 2) Cree la funciรณn para devolver X_batches e y_batches

Para hacerlo mรกs fรกcil, puede crear una funciรณn que devuelva dos matrices diferentes, una para X_batches y otra para y_batches.

Escribamos una funciรณn RNN TensorFlow para construir los lotes.

Nรณtese que los lotes X estรกn retrasados โ€‹โ€‹por un perรญodo (tomamos el valor t-1). La salida de la funciรณn debe tener tres dimensiones. La primera dimensiรณn equivale al nรบmero de lotes, la segunda al tamaรฑo de las ventanas y la รบltima al nรบmero de entradas.

La parte complicada es seleccionar los puntos de datos correctamente. Para los puntos de datos X, elige las observaciones de t = 1 a t =200, mientras que para el punto de datos Y, devuelve las observaciones de t = 2 a 201. Una vez que tenga los puntos de datos correctos, es sencillo remodelar las series.

Para construir el objeto con los lotes, debe dividir el conjunto de datos en diez lotes de igual longitud (es decir, 20). Puede utilizar el mรฉtodo de remodelaciรณn y pasar -1 para que la serie sea similar al tamaรฑo del lote. El valor 20 es el nรบmero de observaciones por lote y 1 es el nรบmero de entradas.

Debes hacer el mismo paso pero para la etiqueta.

Ten en cuenta que debes desplazar los datos segรบn el nรบmero de veces que quieras realizar la predicciรณn. Por ejemplo, si quieres predecir con un dรญa de antelaciรณn, desplaza la serie en 1. Si quieres predecir con dos dรญas de antelaciรณn, desplaza los datos en 2.

x_data = train[:size_train-1]: Select all the training instance minus one day
X_batches = x_data.reshape(-1, windows, input): create the right shape for the batch e.g (10, 20, 1)
def create_batches(df, windows, input, output):
    ## Create X         
        x_data = train[:size_train-1] # Select the data
        X_batches = x_data.reshape(-1, windows, input)  # Reshape the data 
    ## Create y
        y_data = train[n_output:size_train]
        y_batches = y_data.reshape(-1, windows, output)
        return X_batches, y_batches

Ahora que la funciรณn estรก definida, puede llamarla para crear los lotes como se muestra en el siguiente ejemplo de RNN.

X_batches, y_batches = create_batches(df = train,
                                      windows = n_windows,
                                      input = n_input,
                                      output = n_output)

Puede imprimir la forma para asegurarse de que las dimensiones sean correctas.

print(X_batches.shape, y_batches.shape)
(10, 20, 1) (10, 20, 1)

Debe crear el conjunto de prueba con solo un lote de datos y 20 observaciones.

Tenga en cuenta que, si pronostica dรญas tras dรญas, significa que el segundo valor previsto se basarรก en el valor real del primer dรญa (t+1) del conjunto de datos de prueba. De hecho, se conocerรก el verdadero valor.

Si desea pronosticar t+2 (es decir, con dos dรญas de antelaciรณn), debe utilizar el valor previsto t+1; Si va a predecir t+3 (con tres dรญas de anticipaciรณn), debe usar el valor predicho t+1 y t+2. Tiene sentido que sea difรญcil predecir con precisiรณn t+n dรญas de antelaciรณn.

X_test, y_test = create_batches(df = test, windows = 20,input = 1, output = 1)
print(X_test.shape, y_test.shape)
(10, 20, 1) (10, 20, 1)

Muy bien, el tamaรฑo del lote estรก listo, puedes construir la arquitectura de la red neuronal recurrente. Recuerda que tienes 120 neuronas recurrentes.

Paso 3) Construye el modelo

Para crear el modelo, es necesario definir tres partes:

  1. La variable con los tensores.
  2. el RNN
  3. La pรฉrdida y la optimizaciรณn.

Paso 3.1) Variables

Debe especificar las variables X e y con la forma adecuada. Este paso es trivial. El tensor tiene la misma dimensiรณn que los objetos X_batches e y_batches.

Por ejemplo, el tensor X es un marcador de posiciรณn (Consulta el tutorial en Introducciรณn a TensorFlow para refrescar su mente sobre la declaraciรณn de variables) tiene tres dimensiones:

  • Nota: tamaรฑo del lote
  • n_windows: Longitud de las ventanas. Es decir, el nรบmero de veces que el modelo mira hacia atrรกs.
  • n_input: nรบmero de entrada

El resultado es:

tf.placeholder(tf.float32, [None, n_windows, n_input])
## 1. Construct the tensors
X = tf.placeholder(tf.float32, [None, n_windows, n_input])   
y = tf.placeholder(tf.float32, [None, n_windows, n_output])

Paso 3.2) Crear el RNN

En la segunda parte de este ejemplo de RNN de TensorFlow, debe definir la arquitectura de la red. Como antes, utilice el objeto BasicRNNCell y dynamic_rnn del estimador de TensorFlow.

## 2. create the model
basic_cell = tf.contrib.rnn.BasicRNNCell(num_units=r_neuron, activation=tf.nn.relu)   
rnn_output, states = tf.nn.dynamic_rnn(basic_cell, X, dtype=tf.float32)   

La siguiente parte es un poco mรกs complicada pero permite un cรกlculo mรกs rรกpido. Debe transformar la salida de la ejecuciรณn en una capa densa y luego convertirla nuevamente para que tenga la misma dimensiรณn que la entrada.

stacked_rnn_output = tf.reshape(rnn_output, [-1, r_neuron])          
stacked_outputs = tf.layers.dense(stacked_rnn_output, n_output)       
outputs = tf.reshape(stacked_outputs, [-1, n_windows, n_output])  

Paso 3.3) Crear la pรฉrdida y optimizaciรณn.

La optimizaciรณn del modelo depende de la tarea que estรฉ realizando. En el tutorial anterior sobre CNNTu objetivo era clasificar imรกgenes; en este tutorial de RNN, el objetivo es ligeramente diferente. Se te pide que hagas una predicciรณn sobre una variable continua en comparaciรณn con una clase.

Esta diferencia es importante porque cambiarรก el problema de optimizaciรณn. El problema de optimizaciรณn para una variable continua es minimizar el error cuadrรกtico medio. Para construir estas mรฉtricas en TF, puede utilizar:

tf.reduce_sum(tf.square(salidas โ€“ y))

El resto del cรณdigo RNN es el mismo que antes; utiliza un optimizador Adam para reducir la pรฉrdida (es decir, MSE):

tf.train.AdamOptimizer(tasa_de_aprendizaje=tasa_de_aprendizaje)

optimizador.minimizar (pรฉrdida)

Eso es todo, puedes empacar todo junto y tu modelo estarรก listo para entrenar.

tf.reset_default_graph()
r_neuron = 120    

## 1. Construct the tensors
X = tf.placeholder(tf.float32, [None, n_windows, n_input])   
y = tf.placeholder(tf.float32, [None, n_windows, n_output])

## 2. create the model
basic_cell = tf.contrib.rnn.BasicRNNCell(num_units=r_neuron, activation=tf.nn.relu)   
rnn_output, states = tf.nn.dynamic_rnn(basic_cell, X, dtype=tf.float32)              

stacked_rnn_output = tf.reshape(rnn_output, [-1, r_neuron])          
stacked_outputs = tf.layers.dense(stacked_rnn_output, n_output)       
outputs = tf.reshape(stacked_outputs, [-1, n_windows, n_output])   

## 3. Loss + optimization
learning_rate = 0.001  
 
loss = tf.reduce_sum(tf.square(outputs - y))    
optimizer = tf.train.AdamOptimizer(learning_rate=learning_rate)         
training_op = optimizer.minimize(loss)                                          

init = tf.global_variables_initializer() 

Entrenarรก el modelo utilizando 1500 รฉpocas e imprimirรก la pรฉrdida cada 150 iteraciones. Una vez que se entrena el modelo, se evalรบa el modelo en el conjunto de prueba y se crea un objeto que contiene las predicciones como se muestra en el siguiente ejemplo de Red neuronal recurrente.

iteration = 1500 

with tf.Session() as sess:
    init.run()
    for iters in range(iteration):
        sess.run(training_op, feed_dict={X: X_batches, y: y_batches})
        if iters % 150 == 0:
            mse = loss.eval(feed_dict={X: X_batches, y: y_batches})
            print(iters, "\tMSE:", mse)
    
    y_pred = sess.run(outputs, feed_dict={X: X_test})
0 	MSE: 502893.34
150 	MSE: 13839.129
300 	MSE: 3964.835
450 	MSE: 2619.885
600 	MSE: 2418.772
750 	MSE: 2110.5923
900 	MSE: 1887.9644
1050 	MSE: 1747.1377
1200 	MSE: 1556.3398
1350 	MSE: 1384.6113

Por fin, en este tutorial de aprendizaje profundo de RNN, puede trazar el valor real de la serie con el valor previsto. Si su modelo estรก corregido, los valores predichos deben colocarse encima de los valores reales.

Como puedes ver, el modelo tiene margen de mejora. Depende de ti modificar los hiperparรกmetros, como las ventanas, el tamaรฑo del lote o el nรบmero de neuronas recurrentes.

plt.title("Forecast vs Actual", fontsize=14)
plt.plot(pd.Series(np.ravel(y_test)), "bo", markersize=8, label="Actual", color='green')
plt.plot(pd.Series(np.ravel(y_pred)), "r.", markersize=8, label="Forecast", color='red')
plt.legend(loc="lower left")
plt.xlabel("Time")

plt.show()

Grรกfico de pronรณstico versus valor real con puntos reales en verde y puntos predichos en rojo.

Pronรณstico versus real

Preguntas Frecuentes

Empiece con una ventana que cubra un ciclo completo del patrรณn y luego ajรบstela. Las ventanas mรกs largas capturan mรกs contexto, pero ralentizan el entrenamiento y empeoran la degradaciรณn del gradiente. Diez pasos funcionan bien para la serie diaria en este caso; la estacionalidad semanal generalmente requiere mรกs.

Sรญ, con un shim. Reemplace la importaciรณn con tensorflow.compat.v1 y llame a disable_v2_behavior(), porque placeholders, sessions y rnn_cell se movieron bajo el espacio de nombres compat. Nuevo TensorFlow Los proyectos deberรญan usar tf.keras.layers.SimpleRNN en su lugar.

Los asistentes de IA sugieren tamaรฑos de ventana, detectan discrepancias en la forma antes de la ejecuciรณn y elaboran cรณdigo de carga de datos a partir de un esquema. Reducen el proceso de prueba y error que predomina en el desarrollo de modelos recurrentes, aunque la selecciรณn final de hiperparรกmetros aรบn requiere validaciรณn con datos de prueba.

Copilot maneja bien la estructuraciรณn repetitiva: bloques de sesiรณn, diccionarios de alimentaciรณn e impresiรณn periรณdica de pรฉrdidas. Las formas de los tensores y el cambio de etiquetas siguen siendo la parte arriesgada, asรญ que siempre verifique usted mismo las dimensiones del lote antes de confiar en un bucle generado.

Las capas recurrentes esperan (lote, paso de tiempo, caracterรญstica). El redimensionamiento a (-1, ventanas, entrada) le indica al marco cuรกntas secuencias existen, quรฉ tan atrรกs abarca cada una y cuรกntos valores llegan por paso. Una dimensiรณn faltante genera un error de clasificaciรณn.

LSTM utiliza tres compuertas mรกs un estado de celda independiente; GRU combina las compuertas de olvido y entrada y descarta el estado de celda. GRU se entrena mรกs rรกpido con menos parรกmetros, mientras que LSTM suele superarlo en dependencias muy largas.

Las predicciones continuas minimizan el error cuadrรกtico medio, como lo hace este recorrido con reduce_sum of squared residuales. La clasificaciรณn de secuencias, como las etiquetas de sentimiento o las tareas de imรกgenes cubiertas en el CNN tutorial, utiliza entropรญa cruzada en su lugar.

Los transformadores dominan el procesamiento del lenguaje porque la atenciรณn se paraleliza a lo largo de una secuencia. Los modelos recurrentes siguen siendo competitivos para seรฑales en tiempo real, predicciones univariadas cortas y dispositivos con poca memoria, donde procesar un paso a la vez es una ventaja en lugar de un cuello de botella.

Resumir este post con: