¿Qué es una Red Neuronal Recurrente (RNN)?

Las Redes Neuronales Recurrentes (RNNs) son un tipo de red neuronal diseñada para trabajar con datos secuenciales. A diferencia de las redes neuronales tradicionales, las RNNs tienen conexiones que forman ciclos, lo que les permite mantener un "estado" o "memoria" de las entradas anteriores. Esto las hace especialmente útiles para tareas donde el contexto temporal o secuencial es importante, como el procesamiento de lenguaje natural, la traducción automática, y la predicción de series temporales.

Características Clave de las RNNs

  • Memoria: Las RNNs pueden recordar información de entradas anteriores, lo que les permite capturar dependencias temporales.
  • Ciclos en la Red: Las conexiones recurrentes permiten que la salida de una neurona se retroalimente como entrada en la misma capa.
  • Parámetros Compartidos: Los mismos parámetros (pesos y sesgos) se utilizan en cada paso temporal, lo que reduce la complejidad del modelo.

Arquitectura de una RNN

Una RNN típica consiste en una capa recurrente que procesa una secuencia de entradas. Cada entrada en la secuencia se procesa en un paso temporal, y la salida de cada paso se utiliza junto con la siguiente entrada.

Desglose de la Arquitectura

  1. Entrada: Una secuencia de datos, por ejemplo, una serie de palabras en una oración.
  2. Capa Recurrente: Procesa cada elemento de la secuencia y mantiene un estado oculto que se actualiza en cada paso temporal.
  3. Salida: Puede ser una secuencia de salidas (una por cada entrada) o una única salida después de procesar toda la secuencia.

Ejemplo de una RNN Simple

import tensorflow as tf
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import SimpleRNN, Dense

# Definir la longitud de la secuencia y la dimensión de las características
sequence_length = 10
feature_dim = 1

# Crear un modelo secuencial
model = Sequential()

# Añadir una capa SimpleRNN
model.add(SimpleRNN(units=50, input_shape=(sequence_length, feature_dim)))

# Añadir una capa densa para la salida
model.add(Dense(units=1))

# Compilar el modelo
model.compile(optimizer='adam', loss='mse')

# Resumen del modelo
model.summary()

Explicación del Código

  • Importaciones: Importamos TensorFlow y los módulos necesarios para construir el modelo.
  • Definición de la Secuencia: sequence_length y feature_dim definen la longitud de la secuencia y la dimensión de las características de entrada.
  • Modelo Secuencial: Utilizamos Sequential para crear un modelo secuencial.
  • Capa SimpleRNN: Añadimos una capa SimpleRNN con 50 unidades. input_shape define la forma de la entrada.
  • Capa Densa: Añadimos una capa Dense con una unidad para la salida.
  • Compilación: Compilamos el modelo con el optimizador 'adam' y la función de pérdida 'mse' (error cuadrático medio).
  • Resumen del Modelo: model.summary() muestra un resumen de la arquitectura del modelo.

Ejercicio Práctico

Ejercicio 1: Construir una RNN para Predecir una Serie Temporal

Objetivo: Construir y entrenar una RNN simple para predecir la siguiente valor en una serie temporal.

Datos: Utilizaremos una serie temporal sintética generada con una función sinusoidal.

import numpy as np
import matplotlib.pyplot as plt

# Generar datos sintéticos
t = np.linspace(0, 100, 1000)
data = np.sin(t)

# Preparar los datos para la RNN
sequence_length = 10
X = []
y = []

for i in range(len(data) - sequence_length):
    X.append(data[i:i + sequence_length])
    y.append(data[i + sequence_length])

X = np.array(X)
y = np.array(y)

# Reshape para que sea compatible con la entrada de la RNN
X = X.reshape((X.shape[0], X.shape[1], 1))

# Dividir en conjuntos de entrenamiento y prueba
split = int(0.8 * len(X))
X_train, X_test = X[:split], X[split:]
y_train, y_test = y[:split], y[split:]

# Crear el modelo
model = Sequential()
model.add(SimpleRNN(units=50, input_shape=(sequence_length, 1)))
model.add(Dense(units=1))
model.compile(optimizer='adam', loss='mse')

# Entrenar el modelo
history = model.fit(X_train, y_train, epochs=20, validation_data=(X_test, y_test))

# Evaluar el modelo
loss = model.evaluate(X_test, y_test)
print(f'Loss: {loss}')

# Hacer predicciones
predictions = model.predict(X_test)

# Graficar resultados
plt.plot(y_test, label='True')
plt.plot(predictions, label='Predicted')
plt.legend()
plt.show()

Explicación del Ejercicio

  1. Generación de Datos: Creamos una serie temporal sintética usando una función sinusoidal.
  2. Preparación de Datos: Dividimos la serie en secuencias de longitud sequence_length y sus correspondientes valores de salida.
  3. Reshape: Ajustamos la forma de los datos para que sean compatibles con la entrada de la RNN.
  4. División de Datos: Dividimos los datos en conjuntos de entrenamiento y prueba.
  5. Creación del Modelo: Creamos y compilamos una RNN simple.
  6. Entrenamiento: Entrenamos el modelo con los datos de entrenamiento.
  7. Evaluación: Evaluamos el modelo con los datos de prueba.
  8. Predicciones: Hacemos predicciones y graficamos los resultados.

Solución del Ejercicio

El código proporcionado arriba es la solución al ejercicio. Asegúrate de entender cada paso y cómo se relaciona con la arquitectura y el entrenamiento de una RNN.

Conclusión

En esta lección, hemos introducido las Redes Neuronales Recurrentes (RNNs), explorando su arquitectura y características clave. También hemos construido una RNN simple en TensorFlow y la hemos utilizado para predecir una serie temporal. En la próxima lección, profundizaremos en la construcción de RNNs más complejas y exploraremos variantes como LSTM y GRU.

© Copyright 2024. Todos los derechos reservados