Què són les Xarxes Neuronals Recurrentes (RNN)?

Les Xarxes Neuronals Recurrentes (RNN, per les seves sigles en anglès) són un tipus de xarxa neuronal especialment dissenyada per treballar amb dades seqüencials. A diferència de les xarxes neuronals tradicionals, les RNN tenen connexions recurrents que permeten que la informació es mantingui en la xarxa durant llargues seqüències de temps.

Característiques Clau de les RNN:

  1. Memòria Temporal: Les RNN poden recordar informació de passos anteriors en la seqüència, la qual cosa les fa ideals per a tasques com el processament del llenguatge natural (PLN) i la predicció de sèries temporals.
  2. Pesos Compartits: Els mateixos pesos són utilitzats en cada pas de la seqüència, la qual cosa redueix la complexitat del model.
  3. Capacitat de Processar Seqüències de Longitud Variable: Les RNN poden manejar seqüències de diferents longituds, cosa que les fa molt flexibles.

Arquitectura Bàsica d'una RNN

Una RNN típica consisteix en una capa recurrent que processa una seqüència d'entrades. Cada unitat recurrent pren una entrada de la seqüència i l'estat ocult anterior per produir una sortida i un nou estat ocult.

Fórmules Clau:

  • Estat Ocult: \( h_t = f(W_{hx}x_t + W_{hh}h_{t-1} + b_h) \)
  • Sortida: \( y_t = g(W_{hy}h_t + b_y) \)

On:

  • \( x_t \) és l'entrada en el temps \( t \).
  • \( h_t \) és l'estat ocult en el temps \( t \).
  • \( y_t \) és la sortida en el temps \( t \).
  • \( W_{hx} \), \( W_{hh} \), i \( W_{hy} \) són els pesos de la xarxa.
  • \( b_h \) i \( b_y \) són els biaixos.
  • \( f \) i \( g \) són funcions d'activació (com ReLU o tanh).

Avantatges i Desavantatges de les RNN

Avantatges:

  • Maneig de Dades Seqüencials: Les RNN són excel·lents per a tasques que involucren seqüències, com la traducció automàtica, la generació de text, i la predicció de sèries temporals.
  • Pesos Compartits: La compartició de pesos redueix la quantitat de paràmetres que cal aprendre, fent les RNN més eficients.

Desavantatges:

  • Problemes de Gradient: Les RNN poden patir problemes de gradient desaparegut o explosiu, la qual cosa dificulta l'entrenament de seqüències llargues.
  • Limitacions de Memòria: Tot i que les RNN poden recordar informació de passos anteriors, la seva capacitat de memòria és limitada, especialment per a seqüències molt llargues.

Exemples d'Aplicacions de les RNN

  1. Processament del Llenguatge Natural (PLN): Les RNN són àmpliament utilitzades en tasques de PLN com la traducció automàtica, la generació de text, i l'anàlisi de sentiments.
  2. Predicció de Sèries Temporals: Les RNN són útils per predir valors futurs en sèries temporals, com previsions de vendes o predicció de preus d'accions.
  3. Reconeixement de Parla: Les RNN poden processar seqüències d'àudio per reconèixer paraules i frases.

Exemple Pràctic: Implementació d'una RNN Simple amb PyTorch

A continuació, es mostra un exemple bàsic d'una RNN implementada amb PyTorch per predir la següent paraula en una seqüència de text.

import torch
import torch.nn as nn
import torch.optim as optim

# Definició del model RNN
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[:, -1, :])
        return out

# Paràmetres del model
input_size = 10
hidden_size = 20
output_size = 10

# Creació del model, criteri de pèrdua i optimitzador
model = SimpleRNN(input_size, hidden_size, output_size)
criterion = nn.CrossEntropyLoss()
optimizer = optim.Adam(model.parameters(), lr=0.001)

# Dades d'exemple
inputs = torch.randn(5, 3, input_size)  # Batch de 5 seqüències de longitud 3
targets = torch.randint(0, output_size, (5,))

# Entrenament del model
model.train()
optimizer.zero_grad()
outputs = model(inputs)
loss = criterion(outputs, targets)
loss.backward()
optimizer.step()

print(f'Pèrdua: {loss.item()}')

Explicació del Codi:

  1. Definició del Model: Es defineix una classe SimpleRNN que hereta de nn.Module. Aquesta classe conté una capa RNN i una capa lineal per a la sortida.
  2. Paràmetres del Model: Es defineixen els paràmetres d'entrada, ocults i de sortida.
  3. Entrenament: Es crea un conjunt de dades d'exemple, es calcula la pèrdua i es fa una passada d'optimització.

Exercici Pràctic

Exercici:

Implementa una RNN per predir la següent lletra en una seqüència de caràcters. Utilitza PyTorch i segueix els passos següents:

  1. Prepara un conjunt de dades de seqüències de caràcters.
  2. Defineix una RNN amb una capa recurrent i una capa lineal.
  3. Entrena la RNN amb el conjunt de dades preparat.
  4. Avalua la precisió del model.

Solució:

import torch
import torch.nn as nn
import torch.optim as optim

# Definició del model RNN
class CharRNN(nn.Module):
    def __init__(self, input_size, hidden_size, output_size):
        super(CharRNN, 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[:, -1, :])
        return out

# Paràmetres del model
input_size = 26  # Nombre de lletres en l'alfabet anglès
hidden_size = 50
output_size = 26

# Creació del model, criteri de pèrdua i optimitzador
model = CharRNN(input_size, hidden_size, output_size)
criterion = nn.CrossEntropyLoss()
optimizer = optim.Adam(model.parameters(), lr=0.001)

# Dades d'exemple (seqüències de caràcters codificades com one-hot vectors)
inputs = torch.randn(5, 3, input_size)  # Batch de 5 seqüències de longitud 3
targets = torch.randint(0, output_size, (5,))

# Entrenament del model
model.train()
optimizer.zero_grad()
outputs = model(inputs)
loss = criterion(outputs, targets)
loss.backward()
optimizer.step()

print(f'Pèrdua: {loss.item()}')

Conclusió

En aquesta secció, hem introduït les Xarxes Neuronals Recurrentes (RNN), les seves característiques clau, avantatges i desavantatges, i algunes de les seves aplicacions més comunes. També hem vist un exemple pràctic d'implementació d'una RNN simple amb PyTorch. En la següent secció, explorarem les variants avançades de les RNN, com les LSTM i GRU, que aborden alguns dels problemes inherents de les RNN tradicionals.

© Copyright 2024. Tots els drets reservats