Capítulo 4: La arquitectura del transformador
Ejercicios Prácticos del Capítulo 4
Estos ejercicios prácticos están diseñados para reforzar tu comprensión de los conceptos fundamentales discutidos en el Capítulo 4, incluyendo los principios básicos de la arquitectura Transformer, sus componentes y comparaciones con arquitecturas tradicionales. Cada ejercicio incluye soluciones y ejemplos de código para una experiencia práctica.
Ejercicio 1: Comprendiendo la Codificación Posicional
Tarea: Escribir una función en Python para generar codificaciones posicionales para una secuencia de longitud n y dimensión de incrustación dmodel. Visualizar los valores de codificación posicional para una longitud de secuencia de 10 y dimensión de incrustación de 16.
Solución:
import numpy as np
import matplotlib.pyplot as plt
def positional_encoding(sequence_length, d_model):
"""
Generate positional encoding for a sequence.
sequence_length: Length of the sequence
d_model: Dimensionality of embeddings
"""
pos = np.arange(sequence_length)[:, np.newaxis] # Positions
i = np.arange(d_model)[np.newaxis, :] # Embedding dimensions
angle_rates = 1 / np.power(10000, (2 * (i // 2)) / d_model)
angle_rads = pos * angle_rates
# Apply sine to even indices, cosine to odd indices
pos_encoding = np.zeros_like(angle_rads)
pos_encoding[:, 0::2] = np.sin(angle_rads[:, 0::2])
pos_encoding[:, 1::2] = np.cos(angle_rads[:, 1::2])
return pos_encoding
# Generate positional encoding
sequence_length = 10
d_model = 16
pos_encoding = positional_encoding(sequence_length, d_model)
# Visualize the positional encoding
plt.figure(figsize=(10, 6))
plt.imshow(pos_encoding, cmap='viridis')
plt.colorbar(label='Encoding Value')
plt.title('Positional Encoding Visualization')
plt.xlabel('Embedding Dimension')
plt.ylabel('Token Position')
plt.show()
Ejercicio 2: Atención de Producto Punto Escalado
Tarea: Implementar una función para la atención de producto punto escalado y aplicarla a un conjunto de datos pequeño. Imprimir los pesos de atención y la salida.
Solución:
import numpy as np
def scaled_dot_product_attention(Q, K, V):
"""
Compute scaled dot-product attention.
Q: Queries
K: Keys
V: Values
"""
d_k = Q.shape[-1] # Dimension of keys
scores = np.dot(Q, K.T) / np.sqrt(d_k) # Scaled dot product
weights = np.exp(scores) / np.sum(np.exp(scores), axis=-1, keepdims=True) # Softmax
output = np.dot(weights, V) # Weighted sum of values
return output, weights
# Example inputs
Q = np.array([[1, 0, 1]])
K = np.array([[1, 0, 1], [0, 1, 0], [1, 1, 0]])
V = np.array([[0.5, 1.0], [0.2, 0.8], [0.9, 0.3]])
output, weights = scaled_dot_product_attention(Q, K, V)
print("Attention Weights:\n", weights)
print("Attention Output:\n", output)
Salida Esperada:
Attention Weights:
[[0.57611688 0.21194156 0.21194156]]
Attention Output:
[[0.67394156 0.55611688]]
Ejercicio 3: Comparación de Salidas de RNN y Transformer
Tarea: Crear un modelo RNN simple y un modelo Transformer. Usar ambos modelos para procesar la misma secuencia de entrada y comparar sus salidas. Por simplicidad, usar PyTorch.
Solución:
import torch
import torch.nn as nn
from transformers import BertModel, BertTokenizer
# Define a simple RNN
class SimpleRNN(nn.Module):
def __init__(self, input_size, hidden_size, output_size):
super(SimpleRNN, self).__init__()
self.rnn = nn.RNN(input_size, hidden_size, batch_first=True)
self.fc = nn.Linear(hidden_size, output_size)
def forward(self, x):
out, _ = self.rnn(x)
return self.fc(out[:, -1, :])
# RNN parameters
input_size = 10
hidden_size = 20
output_size = 10
sequence_length = 5
batch_size = 1
# Initialize and process input with RNN
rnn_model = SimpleRNN(input_size, hidden_size, output_size)
rnn_input = torch.randn(batch_size, sequence_length, input_size)
rnn_output = rnn_model(rnn_input)
print("RNN Output Shape:", rnn_output.shape)
# Transformer: Use pre-trained BERT
tokenizer = BertTokenizer.from_pretrained("bert-base-uncased")
bert_model = BertModel.from_pretrained("bert-base-uncased")
# Input for Transformer
text = "The cat sat on the mat."
inputs = tokenizer(text, return_tensors="pt")
bert_output = bert_model(**inputs)
print("Transformer Output Shape:", bert_output.last_hidden_state.shape)
Ejercicio 4: Interacción Codificador-Decodificador
Tarea: Simular una interacción codificador-decodificador implementando componentes simples de codificador y decodificador. Pasar datos a través de ambos e imprimir la salida final.
Solución:
class Encoder(nn.Module):
def __init__(self, input_dim, hidden_dim):
super(Encoder, self).__init__()
self.fc = nn.Linear(input_dim, hidden_dim)
def forward(self, x):
return torch.relu(self.fc(x))
class Decoder(nn.Module):
def __init__(self, hidden_dim, output_dim):
super(Decoder, self).__init__()
self.fc = nn.Linear(hidden_dim, output_dim)
def forward(self, x, encoder_output):
combined = x + encoder_output # Simple interaction
return torch.sigmoid(self.fc(combined))
# Encoder-Decoder parameters
input_dim = 10
hidden_dim = 20
output_dim = 5
sequence_length = 6
# Initialize models
encoder = Encoder(input_dim, hidden_dim)
decoder = Decoder(hidden_dim, output_dim)
# Dummy input
x = torch.randn(sequence_length, input_dim)
encoder_output = encoder(x)
decoder_output = decoder(x, encoder_output)
print("Encoder Output Shape:", encoder_output.shape)
print("Decoder Output Shape:", decoder_output.shape)
Estos ejercicios proporcionan una experiencia práctica integral con los conceptos cubiertos en el Capítulo 4, como la codificación posicional, los mecanismos de atención y las interacciones codificador-decodificador. Al completar estas tareas, obtendrás una comprensión más profunda de la arquitectura Transformer y sus ventajas sobre los modelos tradicionales.
Ejercicios Prácticos del Capítulo 4
Estos ejercicios prácticos están diseñados para reforzar tu comprensión de los conceptos fundamentales discutidos en el Capítulo 4, incluyendo los principios básicos de la arquitectura Transformer, sus componentes y comparaciones con arquitecturas tradicionales. Cada ejercicio incluye soluciones y ejemplos de código para una experiencia práctica.
Ejercicio 1: Comprendiendo la Codificación Posicional
Tarea: Escribir una función en Python para generar codificaciones posicionales para una secuencia de longitud n y dimensión de incrustación dmodel. Visualizar los valores de codificación posicional para una longitud de secuencia de 10 y dimensión de incrustación de 16.
Solución:
import numpy as np
import matplotlib.pyplot as plt
def positional_encoding(sequence_length, d_model):
"""
Generate positional encoding for a sequence.
sequence_length: Length of the sequence
d_model: Dimensionality of embeddings
"""
pos = np.arange(sequence_length)[:, np.newaxis] # Positions
i = np.arange(d_model)[np.newaxis, :] # Embedding dimensions
angle_rates = 1 / np.power(10000, (2 * (i // 2)) / d_model)
angle_rads = pos * angle_rates
# Apply sine to even indices, cosine to odd indices
pos_encoding = np.zeros_like(angle_rads)
pos_encoding[:, 0::2] = np.sin(angle_rads[:, 0::2])
pos_encoding[:, 1::2] = np.cos(angle_rads[:, 1::2])
return pos_encoding
# Generate positional encoding
sequence_length = 10
d_model = 16
pos_encoding = positional_encoding(sequence_length, d_model)
# Visualize the positional encoding
plt.figure(figsize=(10, 6))
plt.imshow(pos_encoding, cmap='viridis')
plt.colorbar(label='Encoding Value')
plt.title('Positional Encoding Visualization')
plt.xlabel('Embedding Dimension')
plt.ylabel('Token Position')
plt.show()
Ejercicio 2: Atención de Producto Punto Escalado
Tarea: Implementar una función para la atención de producto punto escalado y aplicarla a un conjunto de datos pequeño. Imprimir los pesos de atención y la salida.
Solución:
import numpy as np
def scaled_dot_product_attention(Q, K, V):
"""
Compute scaled dot-product attention.
Q: Queries
K: Keys
V: Values
"""
d_k = Q.shape[-1] # Dimension of keys
scores = np.dot(Q, K.T) / np.sqrt(d_k) # Scaled dot product
weights = np.exp(scores) / np.sum(np.exp(scores), axis=-1, keepdims=True) # Softmax
output = np.dot(weights, V) # Weighted sum of values
return output, weights
# Example inputs
Q = np.array([[1, 0, 1]])
K = np.array([[1, 0, 1], [0, 1, 0], [1, 1, 0]])
V = np.array([[0.5, 1.0], [0.2, 0.8], [0.9, 0.3]])
output, weights = scaled_dot_product_attention(Q, K, V)
print("Attention Weights:\n", weights)
print("Attention Output:\n", output)
Salida Esperada:
Attention Weights:
[[0.57611688 0.21194156 0.21194156]]
Attention Output:
[[0.67394156 0.55611688]]
Ejercicio 3: Comparación de Salidas de RNN y Transformer
Tarea: Crear un modelo RNN simple y un modelo Transformer. Usar ambos modelos para procesar la misma secuencia de entrada y comparar sus salidas. Por simplicidad, usar PyTorch.
Solución:
import torch
import torch.nn as nn
from transformers import BertModel, BertTokenizer
# Define a simple RNN
class SimpleRNN(nn.Module):
def __init__(self, input_size, hidden_size, output_size):
super(SimpleRNN, self).__init__()
self.rnn = nn.RNN(input_size, hidden_size, batch_first=True)
self.fc = nn.Linear(hidden_size, output_size)
def forward(self, x):
out, _ = self.rnn(x)
return self.fc(out[:, -1, :])
# RNN parameters
input_size = 10
hidden_size = 20
output_size = 10
sequence_length = 5
batch_size = 1
# Initialize and process input with RNN
rnn_model = SimpleRNN(input_size, hidden_size, output_size)
rnn_input = torch.randn(batch_size, sequence_length, input_size)
rnn_output = rnn_model(rnn_input)
print("RNN Output Shape:", rnn_output.shape)
# Transformer: Use pre-trained BERT
tokenizer = BertTokenizer.from_pretrained("bert-base-uncased")
bert_model = BertModel.from_pretrained("bert-base-uncased")
# Input for Transformer
text = "The cat sat on the mat."
inputs = tokenizer(text, return_tensors="pt")
bert_output = bert_model(**inputs)
print("Transformer Output Shape:", bert_output.last_hidden_state.shape)
Ejercicio 4: Interacción Codificador-Decodificador
Tarea: Simular una interacción codificador-decodificador implementando componentes simples de codificador y decodificador. Pasar datos a través de ambos e imprimir la salida final.
Solución:
class Encoder(nn.Module):
def __init__(self, input_dim, hidden_dim):
super(Encoder, self).__init__()
self.fc = nn.Linear(input_dim, hidden_dim)
def forward(self, x):
return torch.relu(self.fc(x))
class Decoder(nn.Module):
def __init__(self, hidden_dim, output_dim):
super(Decoder, self).__init__()
self.fc = nn.Linear(hidden_dim, output_dim)
def forward(self, x, encoder_output):
combined = x + encoder_output # Simple interaction
return torch.sigmoid(self.fc(combined))
# Encoder-Decoder parameters
input_dim = 10
hidden_dim = 20
output_dim = 5
sequence_length = 6
# Initialize models
encoder = Encoder(input_dim, hidden_dim)
decoder = Decoder(hidden_dim, output_dim)
# Dummy input
x = torch.randn(sequence_length, input_dim)
encoder_output = encoder(x)
decoder_output = decoder(x, encoder_output)
print("Encoder Output Shape:", encoder_output.shape)
print("Decoder Output Shape:", decoder_output.shape)
Estos ejercicios proporcionan una experiencia práctica integral con los conceptos cubiertos en el Capítulo 4, como la codificación posicional, los mecanismos de atención y las interacciones codificador-decodificador. Al completar estas tareas, obtendrás una comprensión más profunda de la arquitectura Transformer y sus ventajas sobre los modelos tradicionales.
Ejercicios Prácticos del Capítulo 4
Estos ejercicios prácticos están diseñados para reforzar tu comprensión de los conceptos fundamentales discutidos en el Capítulo 4, incluyendo los principios básicos de la arquitectura Transformer, sus componentes y comparaciones con arquitecturas tradicionales. Cada ejercicio incluye soluciones y ejemplos de código para una experiencia práctica.
Ejercicio 1: Comprendiendo la Codificación Posicional
Tarea: Escribir una función en Python para generar codificaciones posicionales para una secuencia de longitud n y dimensión de incrustación dmodel. Visualizar los valores de codificación posicional para una longitud de secuencia de 10 y dimensión de incrustación de 16.
Solución:
import numpy as np
import matplotlib.pyplot as plt
def positional_encoding(sequence_length, d_model):
"""
Generate positional encoding for a sequence.
sequence_length: Length of the sequence
d_model: Dimensionality of embeddings
"""
pos = np.arange(sequence_length)[:, np.newaxis] # Positions
i = np.arange(d_model)[np.newaxis, :] # Embedding dimensions
angle_rates = 1 / np.power(10000, (2 * (i // 2)) / d_model)
angle_rads = pos * angle_rates
# Apply sine to even indices, cosine to odd indices
pos_encoding = np.zeros_like(angle_rads)
pos_encoding[:, 0::2] = np.sin(angle_rads[:, 0::2])
pos_encoding[:, 1::2] = np.cos(angle_rads[:, 1::2])
return pos_encoding
# Generate positional encoding
sequence_length = 10
d_model = 16
pos_encoding = positional_encoding(sequence_length, d_model)
# Visualize the positional encoding
plt.figure(figsize=(10, 6))
plt.imshow(pos_encoding, cmap='viridis')
plt.colorbar(label='Encoding Value')
plt.title('Positional Encoding Visualization')
plt.xlabel('Embedding Dimension')
plt.ylabel('Token Position')
plt.show()
Ejercicio 2: Atención de Producto Punto Escalado
Tarea: Implementar una función para la atención de producto punto escalado y aplicarla a un conjunto de datos pequeño. Imprimir los pesos de atención y la salida.
Solución:
import numpy as np
def scaled_dot_product_attention(Q, K, V):
"""
Compute scaled dot-product attention.
Q: Queries
K: Keys
V: Values
"""
d_k = Q.shape[-1] # Dimension of keys
scores = np.dot(Q, K.T) / np.sqrt(d_k) # Scaled dot product
weights = np.exp(scores) / np.sum(np.exp(scores), axis=-1, keepdims=True) # Softmax
output = np.dot(weights, V) # Weighted sum of values
return output, weights
# Example inputs
Q = np.array([[1, 0, 1]])
K = np.array([[1, 0, 1], [0, 1, 0], [1, 1, 0]])
V = np.array([[0.5, 1.0], [0.2, 0.8], [0.9, 0.3]])
output, weights = scaled_dot_product_attention(Q, K, V)
print("Attention Weights:\n", weights)
print("Attention Output:\n", output)
Salida Esperada:
Attention Weights:
[[0.57611688 0.21194156 0.21194156]]
Attention Output:
[[0.67394156 0.55611688]]
Ejercicio 3: Comparación de Salidas de RNN y Transformer
Tarea: Crear un modelo RNN simple y un modelo Transformer. Usar ambos modelos para procesar la misma secuencia de entrada y comparar sus salidas. Por simplicidad, usar PyTorch.
Solución:
import torch
import torch.nn as nn
from transformers import BertModel, BertTokenizer
# Define a simple RNN
class SimpleRNN(nn.Module):
def __init__(self, input_size, hidden_size, output_size):
super(SimpleRNN, self).__init__()
self.rnn = nn.RNN(input_size, hidden_size, batch_first=True)
self.fc = nn.Linear(hidden_size, output_size)
def forward(self, x):
out, _ = self.rnn(x)
return self.fc(out[:, -1, :])
# RNN parameters
input_size = 10
hidden_size = 20
output_size = 10
sequence_length = 5
batch_size = 1
# Initialize and process input with RNN
rnn_model = SimpleRNN(input_size, hidden_size, output_size)
rnn_input = torch.randn(batch_size, sequence_length, input_size)
rnn_output = rnn_model(rnn_input)
print("RNN Output Shape:", rnn_output.shape)
# Transformer: Use pre-trained BERT
tokenizer = BertTokenizer.from_pretrained("bert-base-uncased")
bert_model = BertModel.from_pretrained("bert-base-uncased")
# Input for Transformer
text = "The cat sat on the mat."
inputs = tokenizer(text, return_tensors="pt")
bert_output = bert_model(**inputs)
print("Transformer Output Shape:", bert_output.last_hidden_state.shape)
Ejercicio 4: Interacción Codificador-Decodificador
Tarea: Simular una interacción codificador-decodificador implementando componentes simples de codificador y decodificador. Pasar datos a través de ambos e imprimir la salida final.
Solución:
class Encoder(nn.Module):
def __init__(self, input_dim, hidden_dim):
super(Encoder, self).__init__()
self.fc = nn.Linear(input_dim, hidden_dim)
def forward(self, x):
return torch.relu(self.fc(x))
class Decoder(nn.Module):
def __init__(self, hidden_dim, output_dim):
super(Decoder, self).__init__()
self.fc = nn.Linear(hidden_dim, output_dim)
def forward(self, x, encoder_output):
combined = x + encoder_output # Simple interaction
return torch.sigmoid(self.fc(combined))
# Encoder-Decoder parameters
input_dim = 10
hidden_dim = 20
output_dim = 5
sequence_length = 6
# Initialize models
encoder = Encoder(input_dim, hidden_dim)
decoder = Decoder(hidden_dim, output_dim)
# Dummy input
x = torch.randn(sequence_length, input_dim)
encoder_output = encoder(x)
decoder_output = decoder(x, encoder_output)
print("Encoder Output Shape:", encoder_output.shape)
print("Decoder Output Shape:", decoder_output.shape)
Estos ejercicios proporcionan una experiencia práctica integral con los conceptos cubiertos en el Capítulo 4, como la codificación posicional, los mecanismos de atención y las interacciones codificador-decodificador. Al completar estas tareas, obtendrás una comprensión más profunda de la arquitectura Transformer y sus ventajas sobre los modelos tradicionales.
Ejercicios Prácticos del Capítulo 4
Estos ejercicios prácticos están diseñados para reforzar tu comprensión de los conceptos fundamentales discutidos en el Capítulo 4, incluyendo los principios básicos de la arquitectura Transformer, sus componentes y comparaciones con arquitecturas tradicionales. Cada ejercicio incluye soluciones y ejemplos de código para una experiencia práctica.
Ejercicio 1: Comprendiendo la Codificación Posicional
Tarea: Escribir una función en Python para generar codificaciones posicionales para una secuencia de longitud n y dimensión de incrustación dmodel. Visualizar los valores de codificación posicional para una longitud de secuencia de 10 y dimensión de incrustación de 16.
Solución:
import numpy as np
import matplotlib.pyplot as plt
def positional_encoding(sequence_length, d_model):
"""
Generate positional encoding for a sequence.
sequence_length: Length of the sequence
d_model: Dimensionality of embeddings
"""
pos = np.arange(sequence_length)[:, np.newaxis] # Positions
i = np.arange(d_model)[np.newaxis, :] # Embedding dimensions
angle_rates = 1 / np.power(10000, (2 * (i // 2)) / d_model)
angle_rads = pos * angle_rates
# Apply sine to even indices, cosine to odd indices
pos_encoding = np.zeros_like(angle_rads)
pos_encoding[:, 0::2] = np.sin(angle_rads[:, 0::2])
pos_encoding[:, 1::2] = np.cos(angle_rads[:, 1::2])
return pos_encoding
# Generate positional encoding
sequence_length = 10
d_model = 16
pos_encoding = positional_encoding(sequence_length, d_model)
# Visualize the positional encoding
plt.figure(figsize=(10, 6))
plt.imshow(pos_encoding, cmap='viridis')
plt.colorbar(label='Encoding Value')
plt.title('Positional Encoding Visualization')
plt.xlabel('Embedding Dimension')
plt.ylabel('Token Position')
plt.show()
Ejercicio 2: Atención de Producto Punto Escalado
Tarea: Implementar una función para la atención de producto punto escalado y aplicarla a un conjunto de datos pequeño. Imprimir los pesos de atención y la salida.
Solución:
import numpy as np
def scaled_dot_product_attention(Q, K, V):
"""
Compute scaled dot-product attention.
Q: Queries
K: Keys
V: Values
"""
d_k = Q.shape[-1] # Dimension of keys
scores = np.dot(Q, K.T) / np.sqrt(d_k) # Scaled dot product
weights = np.exp(scores) / np.sum(np.exp(scores), axis=-1, keepdims=True) # Softmax
output = np.dot(weights, V) # Weighted sum of values
return output, weights
# Example inputs
Q = np.array([[1, 0, 1]])
K = np.array([[1, 0, 1], [0, 1, 0], [1, 1, 0]])
V = np.array([[0.5, 1.0], [0.2, 0.8], [0.9, 0.3]])
output, weights = scaled_dot_product_attention(Q, K, V)
print("Attention Weights:\n", weights)
print("Attention Output:\n", output)
Salida Esperada:
Attention Weights:
[[0.57611688 0.21194156 0.21194156]]
Attention Output:
[[0.67394156 0.55611688]]
Ejercicio 3: Comparación de Salidas de RNN y Transformer
Tarea: Crear un modelo RNN simple y un modelo Transformer. Usar ambos modelos para procesar la misma secuencia de entrada y comparar sus salidas. Por simplicidad, usar PyTorch.
Solución:
import torch
import torch.nn as nn
from transformers import BertModel, BertTokenizer
# Define a simple RNN
class SimpleRNN(nn.Module):
def __init__(self, input_size, hidden_size, output_size):
super(SimpleRNN, self).__init__()
self.rnn = nn.RNN(input_size, hidden_size, batch_first=True)
self.fc = nn.Linear(hidden_size, output_size)
def forward(self, x):
out, _ = self.rnn(x)
return self.fc(out[:, -1, :])
# RNN parameters
input_size = 10
hidden_size = 20
output_size = 10
sequence_length = 5
batch_size = 1
# Initialize and process input with RNN
rnn_model = SimpleRNN(input_size, hidden_size, output_size)
rnn_input = torch.randn(batch_size, sequence_length, input_size)
rnn_output = rnn_model(rnn_input)
print("RNN Output Shape:", rnn_output.shape)
# Transformer: Use pre-trained BERT
tokenizer = BertTokenizer.from_pretrained("bert-base-uncased")
bert_model = BertModel.from_pretrained("bert-base-uncased")
# Input for Transformer
text = "The cat sat on the mat."
inputs = tokenizer(text, return_tensors="pt")
bert_output = bert_model(**inputs)
print("Transformer Output Shape:", bert_output.last_hidden_state.shape)
Ejercicio 4: Interacción Codificador-Decodificador
Tarea: Simular una interacción codificador-decodificador implementando componentes simples de codificador y decodificador. Pasar datos a través de ambos e imprimir la salida final.
Solución:
class Encoder(nn.Module):
def __init__(self, input_dim, hidden_dim):
super(Encoder, self).__init__()
self.fc = nn.Linear(input_dim, hidden_dim)
def forward(self, x):
return torch.relu(self.fc(x))
class Decoder(nn.Module):
def __init__(self, hidden_dim, output_dim):
super(Decoder, self).__init__()
self.fc = nn.Linear(hidden_dim, output_dim)
def forward(self, x, encoder_output):
combined = x + encoder_output # Simple interaction
return torch.sigmoid(self.fc(combined))
# Encoder-Decoder parameters
input_dim = 10
hidden_dim = 20
output_dim = 5
sequence_length = 6
# Initialize models
encoder = Encoder(input_dim, hidden_dim)
decoder = Decoder(hidden_dim, output_dim)
# Dummy input
x = torch.randn(sequence_length, input_dim)
encoder_output = encoder(x)
decoder_output = decoder(x, encoder_output)
print("Encoder Output Shape:", encoder_output.shape)
print("Decoder Output Shape:", decoder_output.shape)
Estos ejercicios proporcionan una experiencia práctica integral con los conceptos cubiertos en el Capítulo 4, como la codificación posicional, los mecanismos de atención y las interacciones codificador-decodificador. Al completar estas tareas, obtendrás una comprensión más profunda de la arquitectura Transformer y sus ventajas sobre los modelos tradicionales.