La guía definitiva para redes neuronales recurrentes en Python

Las redes neuronales recurrentes son modelos de aprendizaje profundo que se utilizan normalmente para resolver problemas de series de tiempo. Se utilizan en vehículos autónomos, algoritmos comerciales de alta frecuencia y otras aplicaciones del mundo real.

Este tutorial le enseñará los fundamentos de las redes neuronales recurrentes. También creará su propia red neuronal recurrente que predice el precio de las acciones de mañana para Facebook (FB).

La intuición de las redes neuronales recurrentes

Las redes neuronales recurrentes son un ejemplo del campo más amplio de las redes neuronales. Otros ejemplos incluyen:

  • Redes neuronales artificiales
  • Redes neuronales convolucionales

Este artículo se centrará en las redes neuronales recurrentes.

Este tutorial comenzará nuestra discusión de las redes neuronales recurrentes discutiendo la intuición detrás de las redes neuronales recurrentes.

Los tipos de problemas resueltos por redes neuronales recurrentes

Aunque todavía no lo hemos discutido explícitamente, generalmente hay una amplia gama de problemas que cada tipo de red neuronal está diseñada para resolver:

  • Redes neuronales artificiales: problemas de clasificación y regresión
  • Redes neuronales convolucionales: problemas de visión por computadora

En el caso de las redes neuronales recurrentes, se suelen utilizar para resolver problemas de análisis de series de tiempo.

Cada uno de estos tres tipos de redes neuronales (artificial, convolucional y recurrente) se utiliza para resolver problemas de aprendizaje automático supervisado.

Mapeo de redes neuronales en partes del cerebro humano

Como recordará, las redes neuronales se diseñaron para imitar el cerebro humano. Esto es cierto tanto para su construcción (tanto el cerebro como las redes neuronales están compuestas por neuronas) y su función (ambos se utilizan para tomar decisiones y predicciones).

Las tres partes principales del cerebro son:

  • El cerebro
  • El tronco cerebral
  • El cerebelo

Podría decirse que la parte más importante del cerebro es el cerebro. Contiene cuatro lóbulos:

  • El lóbulo frontal
  • El lóbulo parietal
  • El lóbulo temporal
  • El lóbulo occipital

La principal innovación que contienen las redes neuronales es la idea de pesos.

Dicho de otra manera, la característica más importante del cerebro que las redes neuronales han imitado es la capacidad de aprender de otras neuronas.

La capacidad de una red neuronal para cambiar su peso en cada época de su etapa de entrenamiento es similar a la memoria a largo plazo que se ve en los humanos (y otros animales).

El lóbulo temporal es la parte del cerebro asociada con la memoria a largo plazo. Por separado, la red neuronal artificial fue el primer tipo de red neuronal que tenía esta propiedad de memoria a largo plazo. En este sentido, muchos investigadores han comparado las redes neuronales artificiales con el lóbulo temporal del cerebro humano.

De manera similar, el lóbulo occipital es el componente del cerebro que potencia nuestra visión. Dado que las redes neuronales convolucionales se utilizan normalmente para resolver problemas de visión por computadora, se podría decir que son equivalentes al lóbulo occipital en el cerebro.

Como se mencionó, las redes neuronales recurrentes se utilizan para resolver problemas de series de tiempo. Pueden aprender de eventos que han sucedido en iteraciones anteriores recientes de su etapa de entrenamiento. De esta manera, a menudo se los compara con el lóbulo frontal del cerebro, que alimenta nuestra memoria a corto plazo.

En resumen, los investigadores a menudo emparejan cada una de las tres redes neuronales con las siguientes partes del cerebro:

  • Redes neuronales artificiales: el lóbulo temporal
  • Redes neuronales convolucionales: el lóbulo occipital
  • Redes neuronales recurrentes: el lóbulo frontal

La composición de una red neuronal recurrente

Analicemos ahora la composición de una red neuronal recurrente. Primero, recuerde que la composición de una red neuronal básica tiene la siguiente apariencia:

Una red neuronal básica

La primera modificación que se debe realizar en esta red neuronal es que cada capa de la red debe comprimirse, así:

Una red neuronal aplastada

Luego, se deben realizar tres modificaciones más:

  • Las sinapsis neuronales de la red neuronal deben simplificarse a una sola línea
  • Toda la red neuronal debe rotarse 90 grados
  • Es necesario generar un bucle alrededor de la capa oculta de la red neuronal

La red neuronal ahora tendrá la siguiente apariencia:

Una red neuronal recurrente

Esa línea que rodea la capa oculta de la red neuronal recurrente se llama bucle temporal. Se utiliza para indicar que la capa oculta no solo genera una salida, sino que la salida se retroalimenta como entrada en la misma capa.

Una visualización es útil para comprender esto. Como puede ver en la siguiente imagen, la capa oculta usada en una observación específica de un conjunto de datos no solo se usa para generar una salida para esa observación, sino que también se usa para entrenar la capa oculta de la siguiente observación.

Una red neuronal recurrente de serie temporal

Esta propiedad de una observación que ayuda a entrenar la siguiente observación es por qué las redes neuronales recurrentes son tan útiles para resolver problemas de análisis de series de tiempo.

Resumen: la intuición de las redes neuronales recurrentes

En este tutorial, tuvo su primera introducción a las redes neuronales recurrentes. Más específicamente, discutimos la intuición detrás de las redes neuronales recurrentes.

Aquí hay un breve resumen de lo que discutimos en este tutorial:

  • Los tipos de problemas resueltos por redes neuronales recurrentes.
  • Las relaciones entre las diferentes partes del cerebro y las diferentes redes neuronales que hemos estudiado en este curso.
  • La composición de una red neuronal recurrente y cómo se puede usar cada capa oculta para ayudar a entrenar la capa oculta a partir de la siguiente observación en el conjunto de datos.

El problema de la desaparición del gradiente en redes neuronales recurrentes

El problema del gradiente de desaparición ha sido históricamente una de las mayores barreras para el éxito de las redes neuronales recurrentes.

Debido a esto, es importante comprender el problema del gradiente que desaparece antes de construir su primer RNN.

Esta sección explicará el problema del gradiente que desaparece en un lenguaje sencillo, incluida una discusión de las soluciones más útiles a este interesante problema.

¿Cuál es el problema de la desaparición del gradiente?

Antes de profundizar en los detalles del problema del gradiente que desaparece, es útil comprender cómo se descubrió inicialmente el problema.

El problema del gradiente de desaparición fue descubierto por Sepp Hochreiter, un informático alemán que ha tenido un papel influyente en el desarrollo de redes neuronales recurrentes en el aprendizaje profundo.

Ahora exploremos en detalle el problema del gradiente que desaparece. Como su nombre lo indica, el problema del gradiente de desaparición está relacionado con los algoritmos de descenso de gradientes de aprendizaje profundo. Recuerde que un algoritmo de descenso de gradiente se parece a esto:

Un algoritmo de descenso de gradiente finalizado

Este algoritmo de descenso de gradiente se combina luego con un algoritmo de retropropagación para actualizar los pesos de sinapsis en toda la red neuronal.

Las redes neuronales recurrentes se comportan de manera ligeramente diferente porque la capa oculta de una observación se usa para entrenar la capa oculta de la siguiente observación.

Un algoritmo de descenso de gradiente de red neuronal recurrente

Esto significa que la función de costo de la red neuronal se calcula para cada observación en el conjunto de datos. Estos valores de función de coste se muestran en la parte superior de la siguiente imagen:

Un algoritmo de descenso de gradiente de red neuronal recurrente

El problema del gradiente de desaparición ocurre cuando el algoritmo de retropropagación retrocede a través de todas las neuronas de la red neuronal para actualizar sus pesos. La naturaleza de las redes neuronales recurrentes significa que la función de costo calculada en una capa profunda de la red neuronal se utilizará para cambiar el peso de las neuronas en capas menos profundas.

Las matemáticas que calculan este cambio son multiplicativas, lo que significa que el gradiente calculado en un paso profundo en la red neuronal se volverá a multiplicar a través de los pesos anteriores en la red. Dicho de otra manera, el gradiente calculado en lo profundo de la red se "diluye" a medida que retrocede a través de la red, lo que puede hacer que el gradiente desaparezca, ¡dando el nombre al problema del gradiente que desaparece!

El factor real que se multiplica a través de una red neuronal recurrente en el algoritmo de retropropagación se denomina variable matemática Wrec. Plantea dos problemas:

  • Cuando Wreces pequeño, experimenta un problema de gradiente que desaparece
  • Cuando Wreces grande, experimenta un problema de gradiente explosivo

Tenga en cuenta que ambos problemas se conocen generalmente con el nombre más simple de "problema de gradiente que desaparece".

Para resumir, el problema del gradiente de desaparición es causado por la naturaleza multiplicativa del algoritmo de retropropagación. Significa que los gradientes calculados en una etapa profunda de la red neuronal recurrente tienen un impacto demasiado pequeño (en un problema de gradiente que se desvanece) o un impacto demasiado grande (en un problema de gradiente explosivo) en los pesos de las neuronas que son menos profundas en la red neuronal.

Cómo resolver el problema del gradiente que desaparece

Hay una serie de estrategias que se pueden utilizar para resolver el problema del gradiente de fuga. Exploraremos estrategias para los problemas de gradiente de fuga y explosión por separado. Empecemos por lo último.

Resolver el problema del gradiente explosivo

Para gradientes explosivos, es posible utilizar una versión modificada del algoritmo de retropropagación llamado truncated backpropagation. El algoritmo de retropropagación truncado limita el número de pasos de tiempo en los que se realizará la retropropagación, deteniendo el algoritmo antes de que se produzca el problema del gradiente explosivo.

También puede introducir penalties, que son técnicas codificadas de forma rígida para reducir el impacto de una retropropagación a medida que se mueve a través de capas menos profundas en una red neuronal.

Por último, podría introducir gradient clipping, que introduce un techo artificial que limita qué tan grande puede llegar a ser el gradiente en un algoritmo de retropropagación.

Resolviendo el problema del gradiente que desaparece

La inicialización del peso es una técnica que se puede utilizar para resolver el problema del gradiente de fuga. Implica crear artificialmente un valor inicial para los pesos en una red neuronal para evitar que el algoritmo de retropropagación asigne pesos que son irrealmente pequeños.

También puede usar redes de estado de eco, que es un tipo específico de red neuronal diseñada para evitar el problema del gradiente de desaparición. Las redes de Echo State están fuera del alcance de este curso. Tener conocimiento de su existencia es suficiente por ahora.

La solución más importante al problema del gradiente de desaparición es un tipo específico de red neuronal llamada Redes de memoria a corto plazo (LSTM), que fueron pioneras en Sepp Hochreiter y Jürgen Schmidhuber. Recuerde que el Sr. Hochreiter fue el científico que originalmente descubrió el problema del gradiente de desaparición.

Los LSTM se utilizan en problemas relacionados principalmente con el reconocimiento de voz, y uno de los ejemplos más notables es que Google utilizó un LSTM para el reconocimiento de voz en 2015 y experimentó una disminución del 49% en los errores de transcripción.

Los LSTM se consideran la red neuronal a la que recurren los científicos interesados ​​en implementar redes neuronales recurrentes. Nos centraremos en gran medida en LSTM durante el resto de este curso.

Resumen: el problema del gradiente que desaparece

En esta sección, aprendió sobre el problema del gradiente de desaparición de las redes neuronales recurrentes.

Aquí hay un breve resumen de lo que discutimos:

  • Que Sepp Hochreiter fue el primer científico en descubrir el problema del gradiente que desaparece en las redes neuronales recurrentes
  • Lo que implica el problema del gradiente que desaparece (y su primo, el problema del gradiente explosivo)
  • El papel de Wrecen la desaparición de problemas de gradiente y la explosión de problemas de gradiente
  • Cómo se resuelven los problemas de gradiente que desaparecen y los problemas de gradiente explosivo
  • El papel de los LSTM como la solución más común al problema del gradiente que desaparece

Redes de memoria a corto plazo (LSTM)

Las redes de memoria a largo plazo a corto plazo (LSTM) son un tipo de red neuronal recurrente que se utiliza para resolver el problema del gradiente de fuga.

Se diferencian de las redes neuronales recurrentes "regulares" en aspectos importantes.

Este tutorial le presentará los LSTM. Más adelante en este curso, construiremos y entrenaremos un LSTM desde cero.

Tabla de contenido

Puede saltar a una sección específica de este tutorial de LSTM utilizando la tabla de contenido a continuación:

  • La historia de los LSTM
  • Cómo los LSTM resuelven el problema del gradiente que desaparece
  • Cómo funcionan los LSTM
  • Variaciones de las arquitecturas LSTM
  • La variación de la mirilla
  • La variación de la puerta acoplada
  • Otras variaciones de LSTM
  • Pensamientos finales

La historia de los LSTM

Como mencionamos en el último apartado, las dos figuras más importantes en el campo de los LSTM son Sepp Hochreiter y Jürgen Schmidhuber.

Este último era el supervisor de doctorado del primero en la Universidad Técnica de Munich en Alemania.

La tesis doctoral de Hochreiter introdujo los LSTM en el mundo por primera vez.

Cómo los LSTM resuelven el problema del gradiente que desaparece

En el último tutorial, aprendimos cómo el Wrectérmino en el algoritmo de retropropagación puede conducir a un problema de gradiente que desaparece o un problema de gradiente explosivo.

Exploramos varias posibles soluciones para este problema, incluidas las penalizaciones, el recorte de gradiente e incluso las redes de estado de eco. Los LSTM son la mejor solución.

Entonces, ¿cómo funcionan los LSTM? Simplemente cambian el valor de Wrec.

En nuestra explicación del problema del gradiente de desaparición, aprendió que:

  • Cuando Wreces pequeño, experimenta un problema de gradiente que desaparece
  • Cuando Wreces grande, experimenta un problema de gradiente explosivo

De hecho, podemos ser mucho más específicos:

  • Cuando Wrec < 1experimentas un problema de gradiente que desaparece
  • Cuando Wrec > 1experimente un problema de gradiente explosivo

Esto tiene sentido si piensa en la naturaleza multiplicativa del algoritmo de retropropagación.

Si tienes un número que es menor que 1y lo multiplicas contra sí mismo una y otra vez, terminarás con un número que se desvanece. De manera similar, multiplicar un número mayor que 1contra sí mismo muchas veces da como resultado un número muy grande.

Para resolver este problema, se establecen LSTM Wrec = 1. Ciertamente, hay más en LSTMS que configuración Wrec = 1, pero este es definitivamente el cambio más importante que hace esta especificación de redes neuronales recurrentes.

Cómo funcionan los LSTM

Esta sección explicará cómo funcionan los LSTM. Antes de continuar, vale la pena mencionar que usaré imágenes de la publicación del blog de Christopher Olah Understanding LSTMs, que se publicó en agosto de 2015 y tiene algunas de las mejores visualizaciones de LSTM que he visto.

Para empezar, consideremos la versión básica de una red neuronal recurrente:

Una red neuronal recurrente básica

Esta red neuronal tiene neuronas y sinapsis que transmiten las sumas ponderadas de las salidas de una capa como entradas de la siguiente. Un algoritmo de retropropagación se moverá hacia atrás a través de este algoritmo y actualizará los pesos de cada neurona en respuesta a la función de costo calculada en cada época de su etapa de entrenamiento.

Por el contrario, así es como se ve un LSTM:

Un LSTM

Como puede ver, un LSTM tiene mucha más complejidad incorporada que una red neuronal recurrente regular. Mi objetivo es permitirle comprender completamente esta imagen cuando haya terminado este tutorial.

Primero, pongámonos cómodos con la notación utilizada en la imagen de arriba:

La notación que usaremos en nuestro tutorial de LSTM

Ahora que tiene una idea de la notación que usaremos en este tutorial de LSTM, podemos comenzar a examinar la funcionalidad de una capa dentro de una red neuronal de LSTM. Cada capa tiene la siguiente apariencia:

Un nodo de una red neuronal LSTM

Antes de profundizar en la funcionalidad de los nodos dentro de una red neuronal LSTM, vale la pena señalar que cada entrada y salida de estos modelos de aprendizaje profundo es un vector. En Python, esto generalmente se representa mediante una matriz NumPy u otra estructura de datos unidimensional.

Lo primero que sucede dentro de un LSTM es la función de activación del forget gate layer. Examina las entradas de la capa (etiquetadas xtpara la observación y htla salida de la capa anterior de la red neuronal) y las salidas 1o 0para cada número en el estado de celda de la capa anterior (etiquetada Ct-1).

Aquí hay una visualización de la activación de forget gate layer:

Un nodo de una red neuronal LSTM

Aún no hemos hablado del estado de la celda, así que hagámoslo ahora. El estado de la celda está representado en nuestro diagrama por la línea horizontal larga que atraviesa la parte superior del diagrama. Como ejemplo, aquí está el estado de la celda en nuestras visualizaciones:

Estado de la celda dentro de las redes LSTM

El propósito del estado de la celda es decidir qué información llevar adelante de las diferentes observaciones sobre las que se entrena una red neuronal recurrente. La decisión de trasladar o no la información la toma gates, de lo cual forget gatees un buen ejemplo. Cada puerta dentro de un LSTM tendrá la siguiente apariencia:

Estado de la celda dentro de las redes LSTM

El σcarácter dentro de estas puertas se refiere a la función Sigmoide, que probablemente haya visto utilizada en modelos de aprendizaje automático de regresión logística. La función sigmoidea se utiliza como un tipo de función de activación en los LSTM que determina qué información se pasa a través de una puerta para afectar el estado de la celda de la red.

Por definición, la función Sigmoide solo puede generar números entre 0y 1. A menudo se usa para calcular probabilidades debido a esto. En el caso de los modelos LSTM, especifica qué proporción de cada salida debe permitirse influir en el estado de venta.

Los siguientes dos pasos de un modelo LSTM están estrechamente relacionados: el input gate layery el tanh layer. Estas capas trabajan juntas para determinar cómo actualizar el estado de la celda. Al mismo tiempo, se completa el último paso, que le permite a la celda determinar qué olvidarse de la última observación en el conjunto de datos.

Aquí hay una visualización de este proceso:

Un nodo de una red neuronal LSTM

El último paso de un LSTM determina el resultado de esta observación (indicado ht). Este paso pasa por una función sigmoidea y una función tangente hiperbólica. Se puede visualizar de la siguiente manera:

Un nodo de una red neuronal LSTM

Eso concluye el proceso de entrenamiento de una sola capa de un modelo LSTM. Como puede imaginar, hay muchas matemáticas debajo de la superficie que hemos pasado por alto. El objetivo de esta sección es explicar ampliamente cómo funcionan los LSTM, no que usted comprenda en profundidad cada operación del proceso.

Variaciones de las arquitecturas LSTM

Quería concluir este tutorial discutiendo algunas variaciones diferentes de la arquitectura LSTM que son ligeramente diferentes de la LSTM básica que hemos discutido hasta ahora.

Como resumen rápido, así es como se ve un nodo generalizado de un LSTM:

Un nodo de una red neuronal LSTM

La variación de la mirilla

Quizás la variación más importante de la arquitectura LSTM es la peepholevariante, que permite a las capas de puerta leer datos del estado de la celda.

Aquí hay una visualización de cómo se vería la variante de mirilla:

Un nodo de una red neuronal mirilla LSTM

Tenga en cuenta que si bien este diagrama agrega una mirilla a cada puerta en la red neuronal recurrente, también puede agregar mirillas a algunas puertas y no a otras puertas.

La variación de la puerta acoplada

Existe otra variación de la arquitectura LSTM en la que el modelo toma la decisión de qué olvidar y a qué agregar nueva información. En el modelo LSTM original, estas decisiones se tomaron por separado.

Aquí hay una visualización de cómo se ve esta arquitectura:

Un nodo de una red neuronal LSTM de puerta acoplada

Otras variaciones de LSTM

Estos son solo dos ejemplos de variantes de la arquitectura LSTM. Hay muchos más. Unos pocos se enumeran a continuación:

  • Unidades recurrentes cerradas (GRU)
  • RNN con puerta de profundidad
  • RNN mecánicos

Resumen: redes de memoria a corto plazo

En este tutorial, tuvo su primera exposición a las redes de memoria a corto plazo (LSTM).

Aquí hay un breve resumen de lo que aprendió:

  • Una (muy) breve historia de los LSTM y el papel que jugaron Sepp Hochreiter y Jürgen Schmidhuber en su desarrollo
  • Cómo resuelven los LSTM el problema del gradiente de fuga
  • Cómo funcionan los LSTM
  • El papel de las puertas, las funciones sigmoideas y la función tangente hiperbólica en los LSTM
  • Algunas de las variaciones más populares de la arquitectura LSTM

Cómo construir y entrenar una red neuronal recurrente

Hasta ahora, en nuestra discusión sobre redes neuronales recurrentes, ha aprendido:

  • La intuición básica detrás de las redes neuronales recurrentes
  • El problema del gradiente que desaparece que históricamente impidió el progreso de las redes neuronales recurrentes
  • Cómo ayudan las redes de memoria a corto plazo (LSTM) a resolver el problema del gradiente de desaparición

¡Ha llegado el momento de crear su primera red neuronal recurrente! Más específicamente, este tutorial le enseñará cómo construir y entrenar un LSTM para predecir el precio de las acciones de Facebook (FB).

Tabla de contenido

Puede saltar a una sección específica de este tutorial de redes neuronales recurrentes de Python utilizando la tabla de contenido a continuación:

  • Descarga del conjunto de datos para este tutorial
  • Importación de las bibliotecas que necesitará para este tutorial
  • Importación de nuestro conjunto de entrenamiento al script de Python
  • Aplicar escalamiento de características a nuestro conjunto de datos
  • Especificar el número de pasos de tiempo para nuestra red neuronal recurrente
  • Finalización de nuestros conjuntos de datos transformándolos en matrices NumPy
  • Importación de nuestras bibliotecas de TensorFlow
  • Construyendo nuestra red neuronal recurrente
  • Añadiendo nuestra primera capa LSTM
  • Agregar algo de regularización de abandonos
  • Agregar tres capas LSTM más con regularización de abandonos
  • Agregar la capa de salida a nuestra red neuronal recurrente
  • Compilando nuestra red neuronal recurrente
  • Adaptación de la red neuronal recurrente en el equipo de entrenamiento
  • Hacer predicciones con nuestra red neuronal recurrente
  • Importar nuestros datos de prueba
  • Construyendo el conjunto de datos de prueba que necesitamos para hacer predicciones
  • Escalar nuestros datos de prueba
  • Agrupación de nuestros datos de prueba
  • Realmente haciendo predicciones
  • El código completo para este tutorial
  • Pensamientos finales

Descarga del conjunto de datos para este tutorial

Para continuar con este tutorial, necesitará descargar dos conjuntos de datos:

  • Un conjunto de datos de formación que contiene información sobre el precio de las acciones de Facebook desde principios de 2015 hasta finales de 2019.
  • Un conjunto de datos de prueba que contiene información sobre el precio de las acciones de Facebook durante el primer mes de 2020

Nuestra red neuronal recurrente se entrenará con los datos de 2015-2019 y se utilizará para predecir los datos de enero de 2020.

Puede descargar los datos de entrenamiento y los datos de prueba utilizando los enlaces a continuación:

  • Datos de entrenamiento
  • Datos de prueba

Cada uno de estos conjuntos de datos son simplemente exportaciones de Yahoo! Finanzas. Se ven así (cuando se abren en Microsoft Excel):

Un conjunto de datos de ejemplo que usaremos para entrenar nuestra red neuronal recurrente

Una vez descargados los archivos, muévalos al directorio en el que le gustaría trabajar y abra un Jupyter Notebook.

Importación de las bibliotecas que necesitará para este tutorial

Este tutorial dependerá de una serie de bibliotecas Python de código abierto, incluidas NumPy, pandas y matplotlib.

Comencemos nuestro script de Python importando algunas de estas bibliotecas:

 import numpy as np import pandas as pd import matplotlib.pyplot as plt 

Importación de nuestro conjunto de entrenamiento al script de Python

La siguiente tarea que debe completarse es importar nuestro conjunto de datos en la secuencia de comandos de Python.

Inicialmente importaremos el conjunto de datos como un DataFrame de pandas usando el read_csvmétodo. Sin embargo, dado que el kerasmódulo de TensorFlowsolo acepta matrices NumPy como parámetros, la estructura de datos deberá transformarse después de la importación.

Comencemos importando todo el .csvarchivo como un DataFrame:

 training_data = pd.read_csv('FB_training_data.csv') 

Al mirar el DataFrame, notará que contiene numerosas formas diferentes de medir el precio de las acciones de Facebook, incluido el precio de apertura, el precio de cierre, los precios altos y bajos e información de volumen:

Un conjunto de datos de ejemplo que usaremos para entrenar nuestra red neuronal recurrente

Tendremos que seleccionar un tipo específico de precio de acciones antes de continuar. Usemos Close, que indica el precio de cierre no ajustado de las acciones de Facebook.

Ahora tenemos que seleccionar esa columna del DataFrame y almacenarla en una matriz NumPy. Aquí está el comando para hacer esto:

 training_data = training_data.iloc[:, 1].values 

Tenga en cuenta que este comando sobrescribe la training_datavariable existente que habíamos creado anteriormente.

Ahora puede verificar que nuestra training_datavariable es de hecho una matriz NumPy ejecutando type(training_data), que debería devolver:

 numpy.ndarray 

Aplicar escalamiento de características a nuestro conjunto de datos

Tomemos ahora un tiempo para aplicar algunas características de escala a nuestro conjunto de datos.

Como repaso rápido, hay dos formas principales en las que puede aplicar la escala de características a su conjunto de datos:

  • Estandarización
  • Normalización

Usaremos la normalización para construir nuestra red neuronal recurrente, lo que implica restar el valor mínimo del conjunto de datos y luego dividir por el rango del conjunto de datos.

Aquí está la función de normalización definida matemáticamente:

Ecuación de normalización de escala de características

Afortunadamente, scikit-learnhace que sea muy fácil aplicar la normalización a un conjunto de datos utilizando su MinMaxScalerclase.

Comencemos por importar esta clase a nuestro script de Python. La MinMaxScalerclase vive dentro del preprocessingmódulo de scikit-learn, por lo que el comando para importar la clase es:

 from sklearn.preprocessing import MinMaxScaler 

A continuación, necesitamos crear una instancia de esta clase. Asignaremos el objeto recién creado a una variable llamada scaler. Usaremos los parámetros predeterminados para esta clase, por lo que no necesitamos pasar nada en:

 scaler = MinMaxScaler() 

Dado que no hemos especificado ningún parámetro no predeterminado, esto escalará nuestro conjunto de datos para que cada observación esté entre 0y 1.

Hemos creado nuestro scalerobjeto, pero nuestro training_dataconjunto de datos aún no se ha escalado. Necesitamos usar el fit_transformmétodo para modificar el conjunto de datos original. Aquí está la declaración para hacer esto:

 training_data = scaler.fit_transform(training_data.reshape(-1, 1)) 

Especificar el número de pasos de tiempo para nuestra red neuronal recurrente

Lo siguiente que debemos hacer es especificar nuestro número de timesteps. Los pasos de tiempo especifican cuántas observaciones anteriores se deben considerar cuando la red neuronal recurrente hace una predicción sobre la observación actual.

Usaremos 40intervalos de tiempo en este tutorial. Esto significa que por cada día que predice la red neuronal, considerará los precios de las acciones de los últimos 40 días para determinar su producción. Tenga en cuenta que, dado que solo hay ~ 20 días de negociación en un mes determinado, usar 40 pasos de tiempo significa que confiamos en los datos del precio de las acciones de los 2 meses anteriores.

Entonces, ¿cómo especificamos realmente el número de pasos de tiempo dentro de nuestro script de Python?

Se hace mediante la creación de dos estructuras de datos especiales:

  • Una estructura de datos que llamaremos x_training_dataque contiene las últimas 40 observaciones del precio de las acciones en el conjunto de datos. Estos son los datos que utilizará la red neuronal recurrente para hacer predicciones.
  • Una estructura de datos que llamaremos y_training_dataque contiene el precio de las acciones para el siguiente día de negociación. Este es el punto de datos que la red neuronal recurrente está tratando de predecir.

Para empezar, inicialicemos cada una de estas estructuras de datos como una lista de Python vacía:

 x_training_data = [] y_training_data =[] 

Ahora usaremos un bucle for para completar los datos reales en cada una de estas listas de Python. Aquí está el código (con una explicación más detallada del código después del bloque de código):

 for i in range(40, len(training_data)): x_training_data.append(training_data[i-40:i, 0]) y_training_data.append(training_data[i, 0]) 

Desempaquetamos los componentes de este bloque de código:

  • La range(40, len(training_data))función hace que el ciclo for repita desde 40el último índice de los datos de entrenamiento.
  • La x_training_data.append(training_data[i-40:i, 0])línea hace que el ciclo agregue los 40 precios de las acciones anteriores x_training_datacon cada iteración del ciclo.
  • De manera similar, y_training_data.append(training_data[i, 0])hace que el ciclo agregue el precio de las acciones del día siguiente y_training_datacon cada iteración del ciclo.

Finalización de nuestros conjuntos de datos transformándolos en matrices NumPy

TensorFlow está diseñado para funcionar principalmente con matrices NumPy. Debido a esto, lo último que debemos hacer es transformar las dos listas de Python que acabamos de crear en matrices NumPy.

Afortunadamente, esto es sencillo. Simplemente necesita envolver las listas de Python en la np.arrayfunción. Aquí está el código:

 x_training_data = np.array(x_training_data) y_training_data = np.array(y_training_data) 

Una forma importante de asegurarse de que su script se esté ejecutando según lo previsto es verificar la forma de ambas matrices NumPy.

La x_training_datamatriz debe ser una matriz NumPy bidireccional con una dimensión 40(el número de pasos de tiempo) y la segunda dimensión len(training_data) - 40, que se evalúa 1218en nuestro caso.

De manera similar, el y_training_dataobjeto debe ser una matriz NumPy unidimensional de longitud 1218(que, nuevamente, es len(training_data) - 40).

Puede verificar la forma de las matrices imprimiendo su shapeatributo, así:

 print(x_training_data.shape) print(y_training_data.shape) 

Esto imprime:

 (1218, 40) (1218,) 

Ambas matrices tienen las dimensiones esperadas. Sin embargo, necesitamos remodelar nuestro x_training_dataobjeto una vez más antes de proceder a construir nuestra red neuronal recurrente.

La razón de esto es que la capa de red neuronal recurrente disponible en TensorFlow solo acepta datos en un formato muy específico. Puedes leer la documentación de TensorFlow sobre este tema aquí.

Para remodelar el x_training_dataobjeto, usaré el método np.reshape. Aquí está el código para hacer esto:

 x_training_data = np.reshape(x_training_data, (x_training_data.shape[0], x_training_data.shape[1], 1)) 

Ahora imprimamos la forma de x_training_datauna vez más:

 print(x_training_data.shape) 

Esto produce:

 (1218, 40, 1) 

Nuestras matrices tienen la forma deseada, por lo que podemos proceder a construir nuestra red neuronal recurrente.

Importación de nuestras bibliotecas de TensorFlow

Antes de que podamos comenzar a construir nuestra red neuronal recurrente, necesitaremos importar varias clases de TensorFlow. Estas son las declaraciones que debe ejecutar antes de continuar:

 from tensorflow.keras.models import Sequential from tensorflow.keras.layers import Dense from tensorflow.keras.layers import LSTM from tensorflow.keras.layers import Dropout 

Construyendo nuestra red neuronal recurrente

Ahora es el momento de construir nuestra red neuronal recurrente.

Lo primero que debe hacerse es inicializar un objeto de la Sequentialclase de TensorFlow . Como su nombre lo indica, la Sequentialclase está diseñada para construir redes neuronales agregando secuencias de capas a lo largo del tiempo.

Aquí está el código para inicializar nuestra red neuronal recurrente:

 rnn = Sequential() 

Al igual que con nuestras redes neuronales artificiales y redes neuronales convolucionales, podemos agregar más capas a esta red neuronal recurrente utilizando el addmétodo.

Añadiendo nuestra primera capa LSTM

La primera capa que agregaremos es una capa LSTM. Para hacer esto, pase una invocación de la LSTMclase (que acabamos de importar) al addmétodo.

La LSTMclase acepta varios parámetros. Más precisamente, especificaremos tres argumentos:

  • La cantidad de neuronas LSTM que le gustaría incluir en esta capa. Aumentar la cantidad de neuronas es un método para aumentar la dimensionalidad de su red neuronal recurrente. En nuestro caso, especificaremos units = 45.
  • return_sequences = True- esto siempre debe especificarse si planea incluir otra capa LSTM después de la que está agregando. Debe especificar return_sequences = Falsela última capa LSTM en su red neuronal recurrente.
  • input_shape: el número de pasos de tiempo y el número de predictores en nuestros datos de entrenamiento. En nuestro caso, estamos usando 40pasos de tiempo y solo 1predictor (precio de las acciones), por lo que agregaremos

Aquí está el addmétodo completo :

 rnn.add(LSTM(units = 45, return_sequences = True, input_shape = (x_training_data.shape[1], 1))) 

Tenga en cuenta que utilicé en x_training_data.shape[1]lugar del valor codificado en caso de que decidiéramos entrenar la red neuronal recurrente en un modelo más grande en una fecha posterior.

Agregar algo de regularización de abandonos

La regularización de abandonos es una técnica que se utiliza para evitar el sobreajuste al entrenar redes neuronales.

Implica la exclusión aleatoria, o el "abandono", de determinadas salidas de capa durante la etapa de formación.

TensorFlow facilita la implementación de la regularización de abandonos mediante la Dropoutclase que importamos anteriormente en nuestro script de Python. La Dropoutclase acepta un solo parámetro: la tasa de deserción.

La tasa de abandono indica cuántas neuronas deben eliminarse en una capa específica de la red neuronal. Es común utilizar una tasa de abandono del 20%. Seguiremos esta convención en nuestra red neuronal recurrente.

A continuación, le mostramos cómo puede indicar a TensorFlow que suelte el 20% de la neurona de la capa LSTM durante cada iteración de la etapa de entrenamiento:

 rnn.add(Dropout(0.2)) 

Agregar tres capas LSTM más con regularización de abandonos

Ahora agregaremos tres capas LSTM más (con regularización de abandono) a nuestra red neuronal recurrente. Verá que después de especificar la primera capa LSTM, agregar más es trivial.

Para agregar más capas, todo lo que debe hacerse es copiar los dos primeros addmétodos con un pequeño cambio. Es decir, deberíamos eliminar el input_shapeargumento de la LSTMclase.

Mantendremos unitsigual el número de neuronas (o ) y la tasa de abandono en cada una de las LSTMinvocaciones de clase. Dado que la tercera LSTMcapa que agregamos en esta sección será nuestra última capa de LSTM, podemos eliminar el return_sequences = Trueparámetro como se mencionó anteriormente. Eliminando los conjuntos de parámetros return_sequencesa su valor predeterminado de False.

Aquí está el código completo para agregar nuestras próximas tres capas LSTM:

 rnn.add(LSTM(units = 45, return_sequences = True)) rnn.add(Dropout(0.2)) rnn.add(LSTM(units = 45, return_sequences = True)) rnn.add(Dropout(0.2)) rnn.add(LSTM(units = 45)) rnn.add(Dropout(0.2)) 

Este código es muy repetitivo y viola el principio DRY (No se repita) del desarrollo de software. En su lugar, anidaremos en un bucle:

 for i in [True, True, False]: rnn.add(LSTM(units = 45, return_sequences = i)) rnn.add(Dropout(0.2)) 

Agregar la capa de salida a nuestra red neuronal recurrente

Terminemos de diseñar nuestra red neuronal recurrente agregando nuestra capa de salida.

La capa de salida será una instancia de la Denseclase, que es la misma clase que usamos para crear la capa de conexión completa de nuestra red neuronal convolucional anteriormente en este curso.

El único parámetro que debemos especificar es units cuál es el número deseado de dimensiones que debe generar la capa de salida. Dado que queremos generar el precio de las acciones del día siguiente (un valor único), especificaremos units = 1.

Aquí está el código para crear nuestra capa de salida:

 rnn.add(Dense(units = 1)) 

Compilando nuestra red neuronal recurrente

Como recordará de los tutoriales sobre redes neuronales artificiales y redes neuronales convolucionales, el paso de compilación para construir una red neuronal es donde especificamos el optimizador y la función de pérdida de la red neuronal.

TensorFlow nos permite compilar una red neuronal utilizando el compilemétodo con el nombre adecuado. Acepta dos argumentos: optimizery loss. Comencemos creando una compilefunción vacía :

 rnn.compile(optimizer = '', loss = '') 

Ahora necesitamos especificar los parámetros optimizery loss.

Comencemos discutiendo el optimizerparámetro. Las redes neuronales recurrentes suelen utilizar el optimizador RMSProp en su etapa de compilación. Dicho esto, usaremos el optimizador de Adam (como antes). El optimizador de Adam es un optimizador de caballo de batalla que es útil en una amplia variedad de arquitecturas de redes neuronales.

El lossparámetro es bastante simple. Dado que estamos prediciendo una variable continua, podemos usar el error cuadrático medio, tal como lo haría al medir el rendimiento de un modelo de aprendizaje automático de regresión lineal. Esto significa que podemos especificar loss = mean_squared_error.

Aquí está el compilemétodo final :

 rnn.compile(optimizer = 'adam', loss = 'mean_squared_error') 

Adaptación de la red neuronal recurrente en el equipo de entrenamiento

Ahora es el momento de entrenar nuestra red recurrente en nuestros datos de entrenamiento.

Para hacer esto, usamos el fitmétodo. El fitmétodo acepta cuatro argumentos en este caso:

  • Los datos de entrenamiento : en nuestro caso, seráx_training_datayy_training_data
  • Épocas : la cantidad de iteraciones en las que le gustaría que se entrenara la red neuronal recurrente. Especificaremosepochs = 100en este caso.
  • El tamaño del lote : el tamaño de los lotes en los que se entrenará la red en cada época.

Aquí está el código para entrenar esta red neuronal recurrente según nuestras especificaciones:

 rnn.fit(x_training_data, y_training_data, epochs = 100, batch_size = 32) 

Su Jupyter Notebook ahora generará una serie de salidas impresas para cada época en el algoritmo de entrenamiento. Se ven así:

Resultados de la formación de aprendizaje automático

Como puede ver, cada resultado muestra cuánto tiempo tardó la época en calcularse, así como la función de pérdida calculada en esa época.

Debería ver que el valor de la función de pérdida disminuye lentamente a medida que la red neuronal recurrente se ajusta a los datos de entrenamiento a lo largo del tiempo. En mi caso, el valor de la función de pérdida disminuyó desde 0.0504la primera iteración hasta 0.0017la última iteración.

Hacer predicciones con nuestra red neuronal recurrente

Hemos construido nuestra red neuronal recurrente y la hemos entrenado con datos del precio de las acciones de Facebook durante los últimos 5 años. ¡Ahora es el momento de hacer algunas predicciones!

Importar nuestros datos de prueba

Para empezar, importemos los datos reales del precio de las acciones del primer mes de 2020. Esto nos dará algo con lo que comparar nuestros valores predichos.

Aquí está el código para hacer esto. Tenga en cuenta que es muy similar al código que usamos para importar nuestros datos de entrenamiento al comienzo de nuestro script de Python:

 test_data = pd.read_csv('FB_test_data.csv') test_data = test_data.iloc[:, 1].values 

Si ejecuta la declaración print(test_data.shape), volverá (21,). Esto muestra que nuestros datos de prueba son una matriz NumPy unidimensional con 21 entradas, lo que significa que hubo 21 días de negociación en el mercado de valores en enero de 2020.

También puede generar un gráfico rápido de los datos utilizando plt.plot(test_data). Esto debería generar la siguiente visualización de Python:

Una visualización de nuestros datos de prueba

Con suerte, nuestros valores predichos deberían seguir la misma distribución.

Construyendo el conjunto de datos de prueba que necesitamos para hacer predicciones

Antes de que podamos hacer predicciones sobre el precio de las acciones de Facebook en enero de 2020, primero debemos realizar algunos cambios en nuestro conjunto de datos.

La razón de esto es que para predecir cada una de las 21observaciones en enero, necesitaremos los 40días de negociación anteriores. Algunos de estos días de negociación vendrán del conjunto de prueba, mientras que el resto vendrá del conjunto de entrenamiento. Debido a esto, es necesaria cierta concatenación.

Desafortunadamente, puede concatenar las matrices NumPy inmediatamente. Esto se debe a que ya aplicamos la escala de funciones a los datos de entrenamiento, pero no aplicamos ninguna escala de funciones a los datos de prueba.

Para solucionar esto, necesitamos volver a importar el x_training_dataobjeto original con un nuevo nombre de variable llamado unscaled_x_training_data. Para mantener la coherencia, también volveremos a importar los datos de prueba como un DataFrame llamado unscaled_test_data:

 unscaled_training_data = pd.read_csv('FB_training_data.csv') unscaled_test_data = pd.read_csv('FB_test_data.csv') 

Ahora podemos concatenar la Opencolumna de cada DataFrame con la siguiente declaración:

 all_data = pd.concat((unscaled_x_training_data['Open'], unscaled_test_data['Open']), axis = 0) 

Este all_dataobjeto es una serie de pandas de 1279 de longitud.

Ahora necesitamos crear una matriz de todos los precios de las acciones de enero de 2020 y los 40 días de negociación anteriores a enero. Llamaremos a este objeto x_test_dataya que contiene los xvalores que usaremos para hacer predicciones del precio de las acciones para enero de 2020.

Lo primero que debe hacer es encontrar el índice del primer día de negociación de enero dentro de nuestro all_dataobjeto. La declaración len(all_data) - len(test_data)identifica este índice para nosotros.

Esto representa el límite superior del primer elemento de la matriz. Para obtener el límite inferior, simplemente reste 40de este número. Dicho de otra manera, el límite inferior es len(all_data) - len(test_data) - 40.

El límite superior de toda la x_test_datamatriz será el último elemento del conjunto de datos. En consecuencia, podemos crear esta matriz NumPy con la siguiente declaración:

 x_test_data = all_data[len(all_data) - len(test_data) - 40:].values 

Puede comprobar si este objeto se ha creado según lo deseado imprimiendo len(x_test_data), que tiene un valor de 61. Esto tiene sentido: debe contener los 21valores de enero de 2020, así como los 40valores anteriores.

El último paso de esta sección es remodelar rápidamente nuestra matriz NumPy para que sea adecuada para el predictmétodo:

 x_test_data = np.reshape(x_test_data, (-1, 1)) 

Tenga en cuenta que si no realizó este paso, TensorFlow imprimiría un mensaje útil que explicaría exactamente cómo necesitaría transformar sus datos.

Escalar nuestros datos de prueba

Nuestra red neuronal recurrente se entrenó con datos escalados. Debido a esto, necesitamos escalar nuestra x_test_datavariable antes de que podamos usar el modelo para hacer predicciones.

 x_test_data = scaler.transform(x_test_data) 

Tenga en cuenta que usamos el transformmétodo aquí en lugar del fit_transformmétodo (como antes). Esto se debe a que queremos transformar los datos de prueba de acuerdo con el ajuste generado a partir de todo el conjunto de datos de entrenamiento.

Esto significa que la transformación que se aplica a los datos de prueba será la misma que se aplica a los datos de entrenamiento, lo cual es necesario para que nuestra red neuronal recurrente haga predicciones precisas.

Agrupación de nuestros datos de prueba

Lo último que debemos hacer es agrupar nuestros datos de prueba en 21matrices de tamaño 40. Dicho de otra manera, ahora crearemos una matriz donde cada entrada corresponde a una fecha en enero y contiene los precios de las acciones de los 40días de negociación anteriores.

El código para hacer esto es similar a algo que usamos anteriormente:

 final_x_test_data = [] for i in range(40, len(x_test_data)): final_x_test_data.append(x_test_data[i-40:i, 0]) final_x_test_data = np.array(final_x_test_data) 

Por último, debemos remodelar la final_x_test_datavariable para que cumpla con los estándares de TensorFlow.

Vimos esto anteriormente, por lo que el código no debería necesitar explicación:

 final_x_test_data = np.reshape(final_x_test_data, (final_x_test_data.shape[0], final_x_test_data.shape[1], 1)) 

Realmente haciendo predicciones

Después de una cantidad absurda de reprocesamiento de datos, ¡ahora estamos listos para hacer predicciones utilizando nuestros datos de prueba!

Este paso es sencillo. Simplemente pase nuestro final_x_test_dataobjeto al predictmétodo llamado en el rnnobjeto. A modo de ejemplo, a continuación se muestra cómo puede generar estas predicciones y almacenarlas en una variable con un nombre adecuado llamada predictions:

 predictions = rnn.predict(final_x_test_data) 

Tracemos estas predicciones ejecutando plt.plot(predictions)(tenga en cuenta que plt.clf()primero deberá ejecutar para borrar su lienzo):

Las predicciones originales de nuestra red neuronal recurrente

Como puede ver, los valores predichos en este gráfico están entre 0y 1. ¡Esto se debe a que nuestro conjunto de datos todavía está escalado! Necesitamos desescalarlo para que las predicciones tengan algún significado práctico.

La MinMaxScalerclase que usamos para escalar originalmente nuestro conjunto de datos viene con un inverse_transformmétodo útil para desescalar los datos. A continuación, le mostramos cómo puede reducir la escala de los datos y generar una nueva gráfica:

 unscaled_predictions = scaler.inverse_transform(predictions) plt.clf() #This clears the first prediction plot from our canvas plt.plot(unscaled_predictions) 
Las predicciones sin escala de nuestra red neuronal recurrente

¡Esto se ve mucho mejor! Cualquiera que haya seguido el precio de las acciones de Facebook durante un período de tiempo puede ver que esto parece bastante cerca de donde Facebook realmente ha cotizado.

Generemos un gráfico que compare nuestros precios de acciones previstos con el precio real de las acciones de Facebook:

 plt.plot(unscaled_predictions, color = '#135485', label = "Predictions") plt.plot(test_data, color = 'black', label = "Real Data") plt.title('Facebook Stock Price Predictions') 

El código completo para este tutorial

Puede ver el código completo para este tutorial en este repositorio de GitHub. También se pega a continuación para su referencia:

 #Import the necessary data science libraries import numpy as np import pandas as pd import matplotlib.pyplot as plt #Import the data set as a pandas DataFrame training_data = pd.read_csv('FB_training_data.csv') #Transform the data set into a NumPy array training_data = training_data.iloc[:, 1].values #Apply feature scaling to the data set from sklearn.preprocessing import MinMaxScaler scaler = MinMaxScaler() training_data = scaler.fit_transform(training_data.reshape(-1, 1)) #Initialize our x_training_data and y_training_data variables #as empty Python lists x_training_data = [] y_training_data =[] #Populate the Python lists using 40 timesteps for i in range(40, len(training_data)): x_training_data.append(training_data[i-40:i, 0]) y_training_data.append(training_data[i, 0]) #Transforming our lists into NumPy arrays x_training_data = np.array(x_training_data) y_training_data = np.array(y_training_data) #Verifying the shape of the NumPy arrays print(x_training_data.shape) print(y_training_data.shape) #Reshaping the NumPy array to meet TensorFlow standards x_training_data = np.reshape(x_training_data, (x_training_data.shape[0], x_training_data.shape[1], 1)) #Printing the new shape of x_training_data print(x_training_data.shape) #Importing our TensorFlow libraries from tensorflow.keras.models import Sequential from tensorflow.keras.layers import Dense from tensorflow.keras.layers import LSTM from tensorflow.keras.layers import Dropout #Initializing our recurrent neural network rnn = Sequential() #Adding our first LSTM layer rnn.add(LSTM(units = 45, return_sequences = True, input_shape = (x_training_data.shape[1], 1))) #Perform some dropout regularization rnn.add(Dropout(0.2)) #Adding three more LSTM layers with dropout regularization for i in [True, True, False]: rnn.add(LSTM(units = 45, return_sequences = i)) rnn.add(Dropout(0.2)) #(Original code for the three additional LSTM layers) # rnn.add(LSTM(units = 45, return_sequences = True)) # rnn.add(Dropout(0.2)) # rnn.add(LSTM(units = 45, return_sequences = True)) # rnn.add(Dropout(0.2)) # rnn.add(LSTM(units = 45)) # rnn.add(Dropout(0.2)) #Adding our output layer rnn.add(Dense(units = 1)) #Compiling the recurrent neural network rnn.compile(optimizer = 'adam', loss = 'mean_squared_error') #Training the recurrent neural network rnn.fit(x_training_data, y_training_data, epochs = 100, batch_size = 32) #Import the test data set and transform it into a NumPy array test_data = pd.read_csv('FB_test_data.csv') test_data = test_data.iloc[:, 1].values #Make sure the test data's shape makes sense print(test_data.shape) #Plot the test data plt.plot(test_data) #Create unscaled training data and test data objects unscaled_training_data = pd.read_csv('FB_training_data.csv') unscaled_test_data = pd.read_csv('FB_test_data.csv') #Concatenate the unscaled data all_data = pd.concat((unscaled_x_training_data['Open'], unscaled_test_data['Open']), axis = 0) #Create our x_test_data object, which has each January day + the 40 prior days x_test_data = all_data[len(all_data) - len(test_data) - 40:].values x_test_data = np.reshape(x_test_data, (-1, 1)) #Scale the test data x_test_data = scaler.transform(x_test_data) #Grouping our test data final_x_test_data = [] for i in range(40, len(x_test_data)): final_x_test_data.append(x_test_data[i-40:i, 0]) final_x_test_data = np.array(final_x_test_data) #Reshaping the NumPy array to meet TensorFlow standards final_x_test_data = np.reshape(final_x_test_data, (final_x_test_data.shape[0], final_x_test_data.shape[1], 1)) #Generating our predicted values predictions = rnn.predict(final_x_test_data) #Plotting our predicted values plt.clf() #This clears the old plot from our canvas plt.plot(predictions) #Unscaling the predicted values and re-plotting the data unscaled_predictions = scaler.inverse_transform(predictions) plt.clf() #This clears the first prediction plot from our canvas plt.plot(unscaled_predictions) #Plotting the predicted values against Facebook's actual stock price plt.plot(unscaled_predictions, color = '#135485', label = "Predictions") plt.plot(test_data, color = 'black', label = "Real Data") plt.title('Facebook Stock Price Predictions') 

Resumen: la intuición detrás de las redes neuronales recurrentes

En este tutorial, aprendió a construir y entrenar una red neuronal recurrente.

Aquí hay un breve resumen de lo que aprendió:

  • Cómo aplicar el escalado de características a un conjunto de datos en el que se entrenará una red neuronal recurrente
  • El papel de timestepsen el entrenamiento de una red neuronal recurrente
  • Que TensorFlow usa principalmente arreglos NumPy como estructura de datos para entrenar modelos con
  • Cómo agregar capas LSTMy Dropouta una red neuronal recurrente
  • Por qué la regularización de abandonos se usa comúnmente para evitar el sobreajuste al entrenar redes neuronales
  • Que la Densecapa de TensorFlow se usa comúnmente como la capa de salida de una red neuronal recurrente
  • Que el compilationpaso de construir una red neuronal implica especificar su optimizador y su función de pérdida
  • Cómo hacer predicciones usando una red neuronal recurrente
  • Las predicciones que hacen el uso de una red neuronal entrenada con datos escalados deben ser sin escalar para que los humanos puedan interpretarlas.

Si esta publicación le resultó útil, consulte mi libro Aprendizaje automático pragmático para obtener una guía basada en proyectos sobre modelos de aprendizaje profundo cubiertos aquí y en mis otros artículos.

Aprendizaje automático pragmático El aprendizaje automático está cambiando el mundo. Pero siempre ha sido difícil aprender el aprendizaje automático ... hasta ahora. Aprendizaje automático pragmático es una guía paso a paso que le enseñará los fundamentos del aprendizaje automático mediante la construcción de 9 proyectos del mundo real. Aprenderá: Regresión lineal Regresión logística… Nick McCullum Gumroad