En aquest tema, aprendrem a construir una Xarxa Neuronal Recurrent (RNN) des de zero utilitzant PyTorch. Les RNNs són especialment útils per a dades seqüencials, com ara sèries temporals, text o seqüències d'ADN. A diferència de les xarxes neuronals tradicionals, les RNNs tenen connexions recurrents que permeten mantenir informació de passos anteriors en la seqüència.

Objectius

  • Entendre la estructura bàsica d'una RNN.
  • Implementar una RNN simple amb PyTorch.
  • Entrenar la RNN amb un conjunt de dades seqüencials.
  • Avaluar el rendiment de la RNN.

  1. Estructura Bàsica d'una RNN

Una RNN processa una seqüència d'entrades \( x_1, x_2, \ldots, x_T \) i produeix una seqüència de sortides \( h_1, h_2, \ldots, h_T \). Cada sortida \( h_t \) depèn de l'entrada actual \( x_t \) i de l'estat ocult anterior \( h_{t-1} \).

Fórmules Clau

  • Estat ocult: \( h_t = \tanh(W_{xh} x_t + W_{hh} h_{t-1} + b_h) \)
  • Sortida: \( y_t = W_{hy} h_t + b_y \)

On:

  • \( W_{xh} \) és la matriu de pesos entre l'entrada i l'estat ocult.
  • \( W_{hh} \) és la matriu de pesos entre l'estat ocult anterior i l'estat ocult actual.
  • \( W_{hy} \) és la matriu de pesos entre l'estat ocult i la sortida.
  • \( b_h \) i \( b_y \) són els vectors de biaix.

  1. Implementació d'una RNN Simple amb PyTorch

2.1. Importar Llibreries Necessàries

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

2.2. Definir la Classe de la RNN

class SimpleRNN(nn.Module):
    def __init__(self, input_size, hidden_size, output_size):
        super(SimpleRNN, self).__init__()
        self.hidden_size = hidden_size
        self.i2h = nn.Linear(input_size + hidden_size, hidden_size)
        self.i2o = nn.Linear(hidden_size, output_size)
        self.softmax = nn.LogSoftmax(dim=1)

    def forward(self, input, hidden):
        combined = torch.cat((input, hidden), 1)
        hidden = self.i2h(combined)
        output = self.i2o(hidden)
        output = self.softmax(output)
        return output, hidden

    def initHidden(self):
        return torch.zeros(1, self.hidden_size)

2.3. Inicialitzar la RNN

n_hidden = 128
rnn = SimpleRNN(input_size=10, hidden_size=n_hidden, output_size=2)

  1. Entrenament de la RNN

3.1. Definir la Funció de Pèrdua i l'Optimitzador

criterion = nn.NLLLoss()
optimizer = optim.SGD(rnn.parameters(), lr=0.01)

3.2. Funció d'Entrenament

def train(input_tensor, target_tensor):
    hidden = rnn.initHidden()
    rnn.zero_grad()

    for i in range(input_tensor.size(0)):
        output, hidden = rnn(input_tensor[i], hidden)

    loss = criterion(output, target_tensor)
    loss.backward()
    optimizer.step()

    return output, loss.item()

3.3. Entrenar la RNN amb un Conjunt de Dades Seqüencials

n_iters = 1000
for iter in range(1, n_iters + 1):
    input_tensor = torch.randn(5, 10)  # Exemple de tensor d'entrada
    target_tensor = torch.tensor([1])  # Exemple de tensor objectiu

    output, loss = train(input_tensor, target_tensor)

    if iter % 100 == 0:
        print(f'Iteració {iter} - Pèrdua: {loss:.4f}')

  1. Avaluació del Rendiment de la RNN

4.1. Funció de Predicció

def predict(input_tensor):
    hidden = rnn.initHidden()
    for i in range(input_tensor.size(0)):
        output, hidden = rnn(input_tensor[i], hidden)
    return output

4.2. Avaluar amb un Exemple

input_tensor = torch.randn(5, 10)  # Exemple de tensor d'entrada
output = predict(input_tensor)
print(output)

Resum

En aquest tema, hem après a construir una RNN des de zero utilitzant PyTorch. Hem cobert la definició de la classe de la RNN, la inicialització, l'entrenament i l'avaluació. Les RNNs són eines poderoses per treballar amb dades seqüencials i, amb PyTorch, podem implementar-les de manera eficient i flexible.

En el següent tema, explorarem les Xarxes de Memòria a Llarg i Curt Termini (LSTM), una variant de les RNNs que aborda alguns dels seus problemes més comuns, com el gradient vanishing.

© Copyright 2024. Tots els drets reservats