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
SimpleRNNamb 128 unitats. - Afegim una capa
Denseamb activaciósoftmaxper predir el següent caràcter.
- Utilitzem una capa
-
Entrenament del model:
- Compilem el model amb la pèrdua
categorical_crossentropyi l'optimitzadoradam. - Entrenem el model durant 20 èpoques.
- Compilem el model amb la pèrdua
-
Generació de text:
- Utilitzem la funció
sampleper 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
