En aquest tema, explorarem les xarxes neuronals recurrents (RNN) avançades, específicament les unitats de memòria a llarg termini (LSTM) i les unitats recurrents acoblades (GRU). Aquestes arquitectures estan dissenyades per abordar les limitacions de les RNN tradicionals, especialment en la gestió de dependències a llarg termini.
Introducció a les LSTM
Què són les LSTM?
Les LSTM són una variant de les RNN dissenyada per recordar informació durant períodes de temps més llargs. Això es fa mitjançant una estructura de cel·la especial que pot mantenir i actualitzar informació a través de múltiples passos temporals.
Components de les LSTM
Les LSTM tenen tres components principals:
- Porta d'entrada (Input Gate): Controla quanta informació de l'entrada actual ha de ser guardada en l'estat de la cel·la.
- Porta d'oblit (Forget Gate): Decideix quanta informació de l'estat de la cel·la anterior ha de ser oblidada.
- Porta de sortida (Output Gate): Determina quina part de l'estat de la cel·la ha de ser utilitzada per calcular la sortida actual.
Funcionament de les LSTM
-
Porta d'oblit:
f_t = σ(W_f * [h_{t-1}, x_t] + b_f)
On
σ
és la funció sigmoide,W_f
són els pesos associats a la porta d'oblit,h_{t-1}
és l'estat ocult anterior,x_t
és l'entrada actual ib_f
és el biaix. -
Porta d'entrada:
i_t = σ(W_i * [h_{t-1}, x_t] + b_i)
On
W_i
són els pesos associats a la porta d'entrada ib_i
és el biaix. -
Actualització de l'estat de la cel·la:
C_t = f_t * C_{t-1} + i_t * tanh(W_C * [h_{t-1}, x_t] + b_C)
On
C_{t-1}
és l'estat de la cel·la anterior,W_C
són els pesos associats a l'actualització de l'estat de la cel·la ib_C
és el biaix. -
Porta de sortida:
o_t = σ(W_o * [h_{t-1}, x_t] + b_o)
On
W_o
són els pesos associats a la porta de sortida ib_o
és el biaix. -
Sortida de l'estat ocult:
h_t = o_t * tanh(C_t)
Exemple de codi amb LSTM en PyTorch
import torch import torch.nn as nn class LSTMModel(nn.Module): def __init__(self, input_size, hidden_size, num_layers): super(LSTMModel, self).__init__() self.lstm = nn.LSTM(input_size, hidden_size, num_layers, batch_first=True) self.fc = nn.Linear(hidden_size, 1) def forward(self, x): h_0 = torch.zeros(num_layers, x.size(0), hidden_size) c_0 = torch.zeros(num_layers, x.size(0), hidden_size) out, _ = self.lstm(x, (h_0, c_0)) out = self.fc(out[:, -1, :]) return out # Paràmetres input_size = 10 hidden_size = 20 num_layers = 2 # Model model = LSTMModel(input_size, hidden_size, num_layers)
Introducció a les GRU
Què són les GRU?
Les GRU són una altra variant de les RNN que simplifiquen l'estructura de les LSTM combinant les portes d'entrada i d'oblit en una sola porta de "reset" i una porta de "update".
Components de les GRU
- Porta de reset (Reset Gate): Decideix quanta informació de l'estat ocult anterior ha de ser oblidada.
- Porta d'actualització (Update Gate): Controla quanta informació de l'estat ocult anterior ha de ser guardada i quanta de l'estat actual ha de ser actualitzada.
Funcionament de les GRU
-
Porta de reset:
r_t = σ(W_r * [h_{t-1}, x_t] + b_r)
-
Porta d'actualització:
z_t = σ(W_z * [h_{t-1}, x_t] + b_z)
-
Càlcul de l'estat candidat:
n_t = tanh(W_n * [r_t * h_{t-1}, x_t] + b_n)
-
Actualització de l'estat ocult:
h_t = (1 - z_t) * n_t + z_t * h_{t-1}
Exemple de codi amb GRU en PyTorch
import torch import torch.nn as nn class GRUModel(nn.Module): def __init__(self, input_size, hidden_size, num_layers): super(GRUModel, self).__init__() self.gru = nn.GRU(input_size, hidden_size, num_layers, batch_first=True) self.fc = nn.Linear(hidden_size, 1) def forward(self, x): h_0 = torch.zeros(num_layers, x.size(0), hidden_size) out, _ = self.gru(x, h_0) out = self.fc(out[:, -1, :]) return out # Paràmetres input_size = 10 hidden_size = 20 num_layers = 2 # Model model = GRUModel(input_size, hidden_size, num_layers)
Comparació entre LSTM i GRU
Característica | LSTM | GRU |
---|---|---|
Complexitat | Més complexa (3 portes) | Menys complexa (2 portes) |
Capacitat de memòria | Pot recordar informació durant més temps | Pot recordar informació durant menys temps |
Temps d'entrenament | Més llarg | Més curt |
Rendiment | Pot ser millor en tasques amb dependències llargues | Pot ser millor en tasques amb dependències curtes |
Exercici Pràctic
Exercici
Implementa una xarxa LSTM per predir la següent paraula en una seqüència de text utilitzant PyTorch. Utilitza un conjunt de dades de text senzill per entrenar la teva xarxa.
Solució
import torch import torch.nn as nn import torch.optim as optim # Conjunt de dades de text senzill text = "hello world hello pytorch hello deep learning" chars = list(set(text)) char_to_idx = {char: idx for idx, char in enumerate(chars)} idx_to_char = {idx: char for idx, char in enumerate(chars)} # Paràmetres input_size = len(chars) hidden_size = 128 num_layers = 2 seq_length = 5 learning_rate = 0.01 num_epochs = 500 # Preparació de les dades def prepare_data(text, seq_length): X = [] Y = [] for i in range(0, len(text) - seq_length): seq_in = text[i:i + seq_length] seq_out = text[i + seq_length] X.append([char_to_idx[char] for char in seq_in]) Y.append(char_to_idx[seq_out]) return torch.tensor(X), torch.tensor(Y) X, Y = prepare_data(text, seq_length) # Model class LSTMTextModel(nn.Module): def __init__(self, input_size, hidden_size, num_layers): super(LSTMTextModel, self).__init__() self.lstm = nn.LSTM(input_size, hidden_size, num_layers, batch_first=True) self.fc = nn.Linear(hidden_size, input_size) def forward(self, x): h_0 = torch.zeros(num_layers, x.size(0), hidden_size) c_0 = torch.zeros(num_layers, x.size(0), hidden_size) out, _ = self.lstm(x, (h_0, c_0)) out = self.fc(out[:, -1, :]) return out model = LSTMTextModel(input_size, hidden_size, num_layers) criterion = nn.CrossEntropyLoss() optimizer = optim.Adam(model.parameters(), lr=learning_rate) # Entrenament for epoch in range(num_epochs): for i in range(len(X)): inputs = torch.nn.functional.one_hot(X[i], num_classes=input_size).float().unsqueeze(0) targets = Y[i].unsqueeze(0) outputs = model(inputs) loss = criterion(outputs, targets) optimizer.zero_grad() loss.backward() optimizer.step() if (epoch + 1) % 100 == 0: print(f'Epoch [{epoch + 1}/{num_epochs}], Loss: {loss.item():.4f}') # Predicció def predict(model, char, seq_length): input_seq = [char_to_idx[char]] for _ in range(seq_length): input_tensor = torch.nn.functional.one_hot(torch.tensor(input_seq), num_classes=input_size).float().unsqueeze(0) output = model(input_tensor) _, predicted_idx = torch.max(output, 1) input_seq.append(predicted_idx.item()) return ''.join([idx_to_char[idx] for idx in input_seq]) print(predict(model, 'h', 10))
Conclusió
En aquesta secció, hem explorat les arquitectures LSTM i GRU, les seves diferències i com implementar-les utilitzant PyTorch. Les LSTM i les GRU són eines poderoses per treballar amb dades seqüencials i tenen aplicacions en àrees com el processament del llenguatge natural i la predicció de sèries temporals. A la següent secció, veurem com aplicar aquestes tècniques en aplicacions pràctiques.
Curs de Deep Learning
Mòdul 1: Introducció a Deep Learning
- Què és Deep Learning?
- Història i evolució del Deep Learning
- Aplicacions de Deep Learning
- Conceptes bàsics de xarxes neuronals
Mòdul 2: Fonaments de Xarxes Neuronals
- Perceptró i Perceptró Multicapa
- Funció d'activació
- Propagació cap endavant i cap enrere
- Optimització i funció de pèrdua
Mòdul 3: Xarxes Neuronals Convolucionals (CNN)
- Introducció a les CNN
- Capes convolutionals i de pooling
- Arquitectures populars de CNN
- Aplicacions de CNN en reconeixement d'imatges
Mòdul 4: Xarxes Neuronals Recurrentes (RNN)
- Introducció a les RNN
- LSTM i GRU
- Aplicacions de RNN en processament del llenguatge natural
- Seqüències i sèries temporals
Mòdul 5: Tècniques Avançades en Deep Learning
- Xarxes Generatives Adversarials (GAN)
- Autoencoders
- Transfer Learning
- Regularització i tècniques de millora
Mòdul 6: Eines i Frameworks
- Introducció a TensorFlow
- Introducció a PyTorch
- Comparació de frameworks
- Entorns de desenvolupament i recursos addicionals
Mòdul 7: Projectes Pràctics
- Classificació d'imatges amb CNN
- Generació de text amb RNN
- Detecció d'anomalies amb Autoencoders
- Creació d'una GAN per generació d'imatges