Herramientas de usuario

Herramientas del sitio


clase:iabd:pia:2eval:tema10

10. Redes Neuronales Recurrentes

Las redes neuronales recurrentes son redes neuronales que dependen de los datos anteriores, es decir que tienen "memoria".

Por ejemplo, al predecir si una foto es un tipo de flor, no depende de lo que se haya predecido antes pero en una red neuronal si. Son redes que predicen secuencias de datos como por ejemplo series de temperatura, o cotizaciones de bolsa, etc:

  • Procesamiento de lenguaje natural (NLP):
    • Traducción automática: Las RNN se emplean para traducir texto de un idioma a otro, dado que las traducciones requieren una comprensión contextual de las secuencias de palabras.
    • Generación de texto: Pueden generar texto, completando frases o creando contenido basado en ejemplos previos, como en los modelos de lenguaje.
    • Análisis de sentimiento: Se utilizan para determinar si un texto tiene un sentimiento positivo, negativo o neutral.
  • Reconocimiento de voz:
    • Las RNN son comunes en los sistemas de reconocimiento automático de voz (ASR), donde deben entender las secuencias temporales de las ondas sonoras para convertirlas en texto.
  • Generación de música:
    • Se usan para generar música en formato MIDI, ya que las composiciones musicales tienen una estructura secuencial y temporal, similar al lenguaje.
  • Análisis de series temporales:
    • Predicción de la bolsa de valores: Se pueden emplear para predecir precios de acciones basados en datos históricos.
    • Pronóstico meteorológico: Utilizan series temporales de datos climáticos para prever el clima futuro.
    • Detección de anomalías: En sistemas de monitoreo de sensores, las RNN pueden identificar patrones inusuales en las series temporales.
  • Modelado de secuencias de video:
    • En aplicaciones de visión por computadora, las RNN pueden analizar secuencias de fotogramas para realizar tareas como la reconocimiento de acciones o segmentación de video.
  • Robótica:
    • Se usan para controlar robots en tareas que requieren la interpretación de secuencias temporales, como la navegación o el seguimiento de trayectorias en tiempo real.
  • Diagnóstico médico:
    • Análisis de secuencias de ECG o datos de sensores para detectar patrones relacionados con enfermedades o eventos de salud.
  • Sistemas de recomendación:
    • Pueden analizar el comportamiento pasado de un usuario (como en la navegación web o la compra de productos) para predecir lo que podría interesarle en el futuro.
  • Redes sociales:
    • En plataformas de redes sociales, las RNN se utilizan para analizar la evolución de los comentarios o publicaciones, predecir tendencias y generar recomendaciones personalizadas.

Para hacer este tipo de redes se usan nuevas capas que son:

  • RNN estándar: Son las redes recurrentes clásicas, pero tienen problemas en secuencias largas.
  • LSTM (Long Short-Term Memory): Son una mejora de las RNN estándar por lo que recuerdan lo que ocurre a largo plazo.
  • GRU (Gated Recurrent Unit): Parecidas a las LSTM pero más sencillas. Tienen la ventaja de que se entrenan con muchas menos épocas pero son peores si la relación a "obtener" es muy compleja.

En Keras las 3 capas se definen así:

from tensorflow.keras.layers import RNN
from tensorflow.keras.layers import LSTM
from tensorflow.keras.layers import GRU

Por ahora no vamos a contar como son estas neuronas pero su esquema es este:

Las fórmulas matemáticas de cada tipo de neurona se puede ver en RNN, LSTM & GRU

Más información:

Ejemplo

Vamos a hacer una red neuronal que dado 24 temperatura (una por cada hora) obtener la temperatura que hará 12 horas despues.

  • Vamos a generar una serie de datos temporales de temperaturas a lo largo del día y que cada día van aumentando.

def get_serie_tiempo(datetime_start,num_dias=30,pendiente=0.005,amplitud=5,ruido_amplitud=1):
    np.random.seed(7)

    num_datos = num_dias*24
    


    x = np.linspace(0, num_dias * 2 * np.pi, num_datos)  # Eje x (progresión del tiempo)
    fechas = pd.date_range(start=datetime_start, periods=num_datos, freq="h")
    tendencia = np.linspace(0, pendiente * num_datos, num_datos)  # Tendencia ascendente
    onda = amplitud * np.sin(x)  # Onda sinusoidal
    ruido = np.random.normal(0, ruido_amplitud, num_datos)  # Ruido aleatorio

    datos = tendencia + onda + ruido

    return fechas,datos

fechas,temperaturas=get_serie_tiempo(datetime(2025, 1, 1, 10, 0, 0),num_dias=200,ruido_amplitud=0.5)

figure=plt.figure(figsize=(20,10))

axes = figure.add_subplot(2,1,1)
axes.plot(fechas,temperaturas)
axes_configure_labels(axes,"Datos originales","Tiempo","Temperatura")

  • Ahora los transformamos en la estructura que quiere Keras que es una matriz para cada dato. Fijarse que la y también es una matriz.



def get_datos(serie_datos,tamanyo_ventana=24,adelanto_prediccion=12):
    size=len(serie_datos)



    x=[]
    y=[]
    for i in range(size-tamanyo_ventana-adelanto_prediccion):
        x.append(serie_datos[i:i+tamanyo_ventana])
        y.append(serie_datos[i+tamanyo_ventana+adelanto_prediccion])

    

    x=np.array(x)
    y=np.array(y)



    size_entrenamiento=math.floor(x.shape[0]*0.8)

    x_entrenamiento=x[0:size_entrenamiento]
    x_validacion=x[size_entrenamiento:]
    y_entrenamiento=y[0:size_entrenamiento]
    y_validacion=y[size_entrenamiento:]


    return x_entrenamiento.reshape(-1,tamanyo_ventana,1), y_entrenamiento.reshape(-1,1), x_validacion.reshape(-1,tamanyo_ventana,1), y_validacion.reshape(-1,1)


scaler = MinMaxScaler()
temperaturas_scaled = scaler.fit_transform(temperaturas.reshape(-1,1)).reshape(temperaturas.shape)
x_entrenamiento, y_entrenamiento, x_validacion, y_validacion=get_datos(temperaturas_scaled,tamanyo_ventana=24,adelanto_prediccion=12)

En nuestro ejemplo lo que hemos hecho es que para cada 24 temperaturas (tamanyo_ventana=24) , obtener la temperatura que habrá 12 horas después (adelanto_prediccion=12). Tambien hemos escalado los datos, lo cual es importante para que la red funcione mejor. Por último fíjate que tanto la x como la y son matrices x_entrenamiento.reshape(-1,tamanyo_ventana,1) y y_entrenamiento.reshape(-1,1)

  • Ahora vamos a crear la red y entrenarla

def get_model(shape):
    model=Sequential()
    model.add(Input(shape=shape))
    model.add(GRU(24, activation='swish', return_sequences=True))
    model.add(Dropout(0.1))       
    model.add(GRU(50, activation='swish', return_sequences=True ))
    model.add(Dropout(0.1))  
    model.add(GRU(24, activation='swish', return_sequences=False))
    model.add(Dropout(0.1))    
    model.add(Dense(1, activation='linear'))
    model.compile(loss='mean_squared_error',optimizer="adam")

    return model

def fit(model,x_entrenamiento, y_entrenamiento, x_validacion, y_validacion,epochs):
    history=model.fit(x_entrenamiento,y_entrenamiento,validation_data=(x_validacion,y_validacion),epochs=epochs,verbose=False)

    return history  

model=get_model(shape=x_entrenamiento.shape[1:])
history=fit(model,x_entrenamiento, y_entrenamiento, x_validacion, y_validacion,30)
Fijarse que en las capas GRU hay que indicar return_sequences=True excepto en la última que debe ser return_sequences=False

  • Vamos a mostrar la gráfica de la pérdida en cada época

figure=plt.figure(figsize=(6,4))
axes = figure.add_subplot(1,1,1)
axes.plot(history.history['loss'],label=f"Loss:{history.history['loss'][-1]:.3f}")
axes.plot(history.history['val_loss'],label=f"Val Loss:{history.history['val_loss'][-1]:.3f}")
axes_configure_labels(axes,"Loss por época","Épocas","MSE")

  • Para acabar vamos a mostrar 4 gráficos en la que se va a sobreponer los datos verdaderos y los predichos, tanto en entrenamiento como en validación.



y_pred_entrenamiento=model.predict(x_entrenamiento)
y_entrenamiento_inverse_transform=scaler.inverse_transform(y_entrenamiento)
y_pred_entrenamiento_inverse_transform=scaler.inverse_transform(y_pred_entrenamiento)



y_pred_validacion=model.predict(x_validacion)
y_validacion_inverse_transform=scaler.inverse_transform(y_validacion)
y_pred_validacion_inverse_transform=scaler.inverse_transform(y_pred_validacion)


figure=plt.figure(figsize=(20,25))


axes = figure.add_subplot(4,1,1)
axes.plot(y_entrenamiento_inverse_transform,label="Real")
axes.plot(y_pred_entrenamiento_inverse_transform,label="Predicha")
axes_configure_labels(axes,"Todos Entrenamiento","Tiempo","Temperatura")
axes.set_xlim(xmin=0,xmax=y_entrenamiento_inverse_transform.shape[0])
axes.set_ylim(ymin=-6,ymax=16)

axes = figure.add_subplot(4,1,2)
axes.plot(y_validacion_inverse_transform,label="Real")
axes.plot(y_pred_validacion_inverse_transform,label="Predicha")
axes_configure_labels(axes,"Todos Validacion","Tiempo","Temperatura")
axes.set_xlim(xmin=0,xmax=y_entrenamiento_inverse_transform.shape[0])
axes.set_ylim(ymin=-6,ymax=16)


axes = figure.add_subplot(4,1,3)
axes.plot(y_entrenamiento_inverse_transform,label="Real")
axes.plot(y_pred_entrenamiento_inverse_transform,label="Predicha")
axes_configure_labels(axes,"Últimos Entrenamiento","Tiempo","Temperatura")
axes.set_xlim(xmin=y_entrenamiento_inverse_transform.shape[0]-500,xmax=y_entrenamiento_inverse_transform.shape[0])
axes.set_ylim(ymin=-6,ymax=16)

axes = figure.add_subplot(4,1,4)
axes.plot(y_validacion_inverse_transform,label="Real")
axes.plot(y_pred_validacion_inverse_transform,label="Predicha")
axes_configure_labels(axes,"Últimos Validacion","Tiempo","Temperatura")
axes.set_xlim(xmin=y_validacion_inverse_transform.shape[0]-500,xmax=y_validacion_inverse_transform.shape[0])
axes.set_ylim(ymin=-6,ymax=16)

clase/iabd/pia/2eval/tema10.txt · Última modificación: 2025/01/06 11:22 por admin