Introducció

Les seqüències i les sèries temporals són dades que es presenten en un ordre específic, normalment en funció del temps. Aquest tipus de dades són comuns en molts camps, com ara la meteorologia, les finances, el processament del llenguatge natural (PLN) i molts altres. En aquest tema, explorarem com les xarxes neuronals recurrents (RNN) poden ser utilitzades per modelar i predir aquestes dades.

Conceptes Clau

Seqüències

  • Definició: Una seqüència és una col·lecció d'elements ordenats, on l'ordre dels elements és important.
  • Exemples: Text, seqüències de paraules, seqüències d'ADN.

Sèries Temporals

  • Definició: Una sèrie temporal és una seqüència d'observacions ordenades en el temps.
  • Exemples: Preus d'accions, temperatures diàries, senyals d'àudio.

Xarxes Neuronals Recurrentes (RNN)

Les RNN són especialment adequades per treballar amb dades seqüencials i sèries temporals perquè poden mantenir una "memòria" dels estats anteriors a través de les seves connexions recurrents.

Arquitectura Bàsica d'una RNN

Entrada (x_t) -> Capa Recurrent (h_t) -> Sortida (y_t)
  • x_t: Entrada en el temps t.
  • h_t: Estat ocult en el temps t.
  • y_t: Sortida en el temps t.

Propagació cap endavant en una RNN

import numpy as np

# Funció d'activació (tanh)
def tanh(x):
    return np.tanh(x)

# Inicialització de pesos
Wxh = np.random.randn(hidden_size, input_size) * 0.01  # Pesos entrada a estat ocult
Whh = np.random.randn(hidden_size, hidden_size) * 0.01  # Pesos estat ocult a estat ocult
Why = np.random.randn(output_size, hidden_size) * 0.01  # Pesos estat ocult a sortida
bh = np.zeros((hidden_size, 1))  # Bias estat ocult
by = np.zeros((output_size, 1))  # Bias sortida

# Propagació cap endavant
def forward(x, h_prev):
    h_next = tanh(np.dot(Wxh, x) + np.dot(Whh, h_prev) + bh)
    y = np.dot(Why, h_next) + by
    return y, h_next

Long Short-Term Memory (LSTM) i Gated Recurrent Unit (GRU)

Les LSTM i les GRU són variants de les RNN que aborden el problema del gradient que desapareix, permetent a les xarxes aprendre dependències a llarg termini.

LSTM

  • Components: Cèl·lula, porta d'entrada, porta de sortida, porta d'oblit.
  • Avantatges: Capacitat per recordar informació durant períodes de temps més llargs.

GRU

  • Components: Porta de restabliment, porta de posada al dia.
  • Avantatges: Més simple que les LSTM, però igualment efectiva en molts casos.

Aplicacions de RNN en Seqüències i Sèries Temporals

Predicció de Sèries Temporals

  • Objectiu: Predir valors futurs basats en valors històrics.
  • Exemple: Predicció del preu de les accions.

Processament del Llenguatge Natural (PLN)

  • Objectiu: Modelar i generar text.
  • Exemple: Generació automàtica de text, traducció automàtica.

Reconeixement de Veu

  • Objectiu: Convertir senyals d'àudio en text.
  • Exemple: Assistents virtuals com Siri o Google Assistant.

Exercici Pràctic: Predicció de Sèries Temporals amb RNN

Descripció de l'Exercici

En aquest exercici, utilitzarem una RNN per predir una sèrie temporal senzilla, com ara una funció sinusoïdal.

Pas 1: Generació de Dades

import numpy as np
import matplotlib.pyplot as plt

# Generar dades sinusoïdals
def generate_sine_wave(seq_length, num_samples):
    X = []
    y = []
    for _ in range(num_samples):
        start = np.random.rand() * 2 * np.pi
        x = np.array([np.sin(start + i) for i in range(seq_length)])
        X.append(x[:-1])
        y.append(x[1:])
    return np.array(X), np.array(y)

seq_length = 50
num_samples = 1000
X, y = generate_sine_wave(seq_length, num_samples)

# Visualitzar les dades
plt.plot(X[0])
plt.title("Exemple de Seqüència Sinusoïdal")
plt.show()

Pas 2: Construcció de la RNN

import torch
import torch.nn as nn

class SimpleRNN(nn.Module):
    def __init__(self, input_size, hidden_size, output_size):
        super(SimpleRNN, self).__init__()
        self.hidden_size = hidden_size
        self.rnn = nn.RNN(input_size, hidden_size, batch_first=True)
        self.fc = nn.Linear(hidden_size, output_size)
    
    def forward(self, x):
        h0 = torch.zeros(1, x.size(0), self.hidden_size).to(x.device)
        out, _ = self.rnn(x, h0)
        out = self.fc(out)
        return out

input_size = 1
hidden_size = 50
output_size = 1

model = SimpleRNN(input_size, hidden_size, output_size)

Pas 3: Entrenament del Model

import torch.optim as optim

# Convertir dades a tensors
X_tensor = torch.tensor(X, dtype=torch.float32).unsqueeze(-1)
y_tensor = torch.tensor(y, dtype=torch.float32).unsqueeze(-1)

# Definir pèrdua i optimitzador
criterion = nn.MSELoss()
optimizer = optim.Adam(model.parameters(), lr=0.01)

# Entrenament
num_epochs = 100
for epoch in range(num_epochs):
    model.train()
    output = model(X_tensor)
    loss = criterion(output, y_tensor)
    
    optimizer.zero_grad()
    loss.backward()
    optimizer.step()
    
    if (epoch+1) % 10 == 0:
        print(f'Epoch [{epoch+1}/{num_epochs}], Loss: {loss.item():.4f}')

Pas 4: Avaluació del Model

# Predicció
model.eval()
with torch.no_grad():
    predicted = model(X_tensor).squeeze(-1).numpy()

# Visualitzar resultats
plt.plot(y[0], label='Real')
plt.plot(predicted[0], label='Predicció')
plt.title("Predicció de la Sèrie Temporal")
plt.legend()
plt.show()

Conclusió

En aquest tema, hem explorat com les RNN poden ser utilitzades per modelar i predir seqüències i sèries temporals. Hem vist la importància de les RNN en el processament de dades seqüencials i hem implementat un exemple pràctic de predicció de sèries temporals utilitzant PyTorch. Aquest coneixement és fonamental per abordar problemes complexos en camps com el PLN, la predicció financera i el reconeixement de veu.

© Copyright 2024. Tots els drets reservats