Introducció
En aquest tema, explorarem com utilitzar Xarxes Neuronals Recurrentes (RNN) per a la generació de text. Les RNN són especialment útils per a tasques seqüencials com el processament del llenguatge natural (PLN), ja que poden mantenir informació sobre contextos anteriors en una seqüència. Aprendrem els conceptes bàsics, veurem exemples pràctics i realitzarem exercicis per consolidar els nostres coneixements.
Conceptes Clau
-
Xarxes Neuronals Recurrentes (RNN):
- Les RNN són un tipus de xarxa neuronal dissenyada per treballar amb dades seqüencials.
- Cada unitat de la xarxa té una connexió recurrent que permet mantenir informació sobre els estats anteriors.
-
LSTM (Long Short-Term Memory):
- Una variant de les RNN que aborda el problema del gradient que desapareix.
- Utilitza cel·les de memòria per mantenir informació durant períodes de temps més llargs.
-
GRU (Gated Recurrent Unit):
- Una altra variant de les RNN que simplifica les cel·les de memòria de les LSTM.
- Té menys paràmetres que les LSTM, cosa que pot fer-les més eficients.
-
Embedding:
- Una representació vectorial d'elements de text (paraules, caràcters) en un espai de dimensions més baixes.
- Facilita l'aprenentatge de relacions semàntiques entre paraules.
Exemples Pràctics
Exemple 1: Generació de text amb una RNN bàsica
import numpy as np import tensorflow as tf from tensorflow.keras.models import Sequential from tensorflow.keras.layers import Embedding, SimpleRNN, Dense # Dades d'exemple text = "Hola, benvingut al curs de Deep Learning. Aprendrem moltes coses interessants." # Preprocessament del text chars = sorted(list(set(text))) char_to_index = {c: i for i, c in enumerate(chars)} index_to_char = {i: c for i, c in enumerate(chars)} # Paràmetres maxlen = 40 step = 3 # Preparar les seqüències d'entrada i sortida sentences = [] next_chars = [] for i in range(0, len(text) - maxlen, step): sentences.append(text[i: i + maxlen]) next_chars.append(text[i + maxlen]) X = np.zeros((len(sentences), maxlen, len(chars)), dtype=np.bool) y = np.zeros((len(sentences), len(chars)), dtype=np.bool) for i, sentence in enumerate(sentences): for t, char in enumerate(sentence): X[i, t, char_to_index[char]] = 1 y[i, char_to_index[next_chars[i]]] = 1 # Construir el model model = Sequential() model.add(SimpleRNN(128, input_shape=(maxlen, len(chars)))) model.add(Dense(len(chars), activation='softmax')) model.compile(loss='categorical_crossentropy', optimizer='adam') # Entrenar el model model.fit(X, y, batch_size=128, epochs=20) # Generar text def sample(preds, temperature=1.0): preds = np.asarray(preds).astype('float64') preds = np.log(preds) / temperature exp_preds = np.exp(preds) preds = exp_preds / np.sum(exp_preds) probas = np.random.multinomial(1, preds, 1) return np.argmax(probas) generated_text = text[:maxlen] print('--- Generating with seed: "' + generated_text + '"') for i in range(400): sampled = np.zeros((1, maxlen, len(chars))) for t, char in enumerate(generated_text): sampled[0, t, char_to_index[char]] = 1 preds = model.predict(sampled, verbose=0)[0] next_index = sample(preds, 0.5) next_char = index_to_char[next_index] generated_text += next_char generated_text = generated_text[1:] print(next_char, end='') print()
Explicació del Codi
-
Preprocessament del text:
- Convertim el text en una seqüència de caràcters únics.
- Creem diccionaris per mapar caràcters a índexs i viceversa.
-
Preparació de les seqüències d'entrada i sortida:
- Dividim el text en seqüències de longitud fixa (
maxlen
). - Preparem les dades d'entrada (
X
) i les etiquetes (y
).
- Dividim el text en seqüències de longitud fixa (
-
Construcció del model:
- Utilitzem una capa
SimpleRNN
amb 128 unitats. - Afegim una capa
Dense
amb activaciósoftmax
per predir el següent caràcter.
- Utilitzem una capa
-
Entrenament del model:
- Compilem el model amb la pèrdua
categorical_crossentropy
i l'optimitzadoradam
. - Entrenem el model durant 20 èpoques.
- Compilem el model amb la pèrdua
-
Generació de text:
- Utilitzem la funció
sample
per generar el següent caràcter basat en les prediccions del model. - Generem text de manera iterativa, afegint el nou caràcter a la seqüència generada.
- Utilitzem la funció
Exercicis Pràctics
Exercici 1: Millorar la Generació de Text amb LSTM
Modifica l'exemple anterior per utilitzar una capa LSTM
en lloc de SimpleRNN
. Compara els resultats obtinguts.
Solució
from tensorflow.keras.layers import LSTM # Construir el model amb LSTM model = Sequential() model.add(LSTM(128, input_shape=(maxlen, len(chars)))) model.add(Dense(len(chars), activation='softmax')) model.compile(loss='categorical_crossentropy', optimizer='adam') # Entrenar el model model.fit(X, y, batch_size=128, epochs=20) # Generar text generated_text = text[:maxlen] print('--- Generating with seed: "' + generated_text + '"') for i in range(400): sampled = np.zeros((1, maxlen, len(chars))) for t, char in enumerate(generated_text): sampled[0, t, char_to_index[char]] = 1 preds = model.predict(sampled, verbose=0)[0] next_index = sample(preds, 0.5) next_char = index_to_char[next_index] generated_text += next_char generated_text = generated_text[1:] print(next_char, end='') print()
Exercici 2: Ajustar la Temperatura de la Funció de Mostreig
Experimenta amb diferents valors de temperatura en la funció sample
. Observa com afecta la diversitat del text generat.
Solució
# Funció de mostreig amb diferents temperatures def sample(preds, temperature=1.0): preds = np.asarray(preds).astype('float64') preds = np.log(preds) / temperature exp_preds = np.exp(preds) preds = exp_preds / np.sum(exp_preds) probas = np.random.multinomial(1, preds, 1) return np.argmax(probas) # Generar text amb diferents temperatures for temp in [0.2, 0.5, 1.0, 1.2]: print('--- Temperature:', temp) generated_text = text[:maxlen] print('--- Generating with seed: "' + generated_text + '"') for i in range(400): sampled = np.zeros((1, maxlen, len(chars))) for t, char in enumerate(generated_text): sampled[0, t, char_to_index[char]] = 1 preds = model.predict(sampled, verbose=0)[0] next_index = sample(preds, temp) next_char = index_to_char[next_index] generated_text += next_char generated_text = generated_text[1:] print(next_char, end='') print()
Resum
En aquest tema, hem après com utilitzar RNN per a la generació de text. Hem vist com construir i entrenar un model bàsic de RNN i com millorar-lo utilitzant LSTM. També hem explorat com ajustar la temperatura de la funció de mostreig per controlar la diversitat del text generat. Aquests coneixements són fonamentals per a tasques avançades de processament del llenguatge natural i obren la porta a aplicacions més complexes com la traducció automàtica i la síntesi de text.
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