Capítulo 2: Comprendiendo los Modelos Generativos
Ejercicios Prácticos
Ejercicio 1: Implementar una GAN Simple
Tarea: Implementa una GAN simple para generar nuevas muestras del conjunto de datos MNIST. Utiliza el ejemplo proporcionado en la sección 2.2.1 y modifícalo para incluir una capa adicional tanto en el generador como en el discriminador.
Solución:
import tensorflow as tf
from tensorflow.keras.layers import Dense, LeakyReLU, Reshape, Flatten, Dropout
from tensorflow.keras.models import Sequential
import numpy as np
import matplotlib.pyplot as plt
# Generator model
def build_generator():
model = Sequential([
Dense(256, input_dim=100),
LeakyReLU(alpha=0.2),
Dense(512),
LeakyReLU(alpha=0.2),
Dense(1024),
LeakyReLU(alpha=0.2),
Dense(28 * 28, activation='tanh'),
Reshape((28, 28, 1))
])
return model
# Discriminator model
def build_discriminator():
model = Sequential([
Flatten(input_shape=(28, 28, 1)),
Dense(1024),
LeakyReLU(alpha=0.2),
Dropout(0.3),
Dense(512),
LeakyReLU(alpha=0.2),
Dropout(0.3),
Dense(256),
LeakyReLU(alpha=0.2),
Dropout(0.3),
Dense(1, activation='sigmoid')
])
return model
# Build and compile the GAN
generator = build_generator()
discriminator = build_discriminator()
discriminator.compile(optimizer='adam', loss='binary_crossentropy', metrics=['accuracy'])
# GAN model
discriminator.trainable = False
gan_input = tf.keras.Input(shape=(100,))
gan_output = discriminator(generator(gan_input))
gan = tf.keras.Model(gan_input, gan_output)
gan.compile(optimizer='adam', loss='binary_crossentropy')
# Training the GAN
(x_train, _), (_, _) = tf.keras.datasets.mnist.load_data()
x_train = (x_train.astype(np.float32) - 127.5) / 127.5 # Normalize to [-1, 1]
x_train = np.expand_dims(x_train, axis=-1)
batch_size = 64
epochs = 10000
for epoch in range(epochs):
# Train discriminator
idx = np.random.randint(0, x_train.shape[0], batch_size)
real_images = x_train[idx]
noise = np.random.normal(0, 1, (batch_size, 100))
fake_images = generator.predict(noise)
d_loss_real = discriminator.train_on_batch(real_images, np.ones((batch_size, 1)))
d_loss_fake = discriminator.train_on_batch(fake_images, np.zeros((batch_size, 1)))
d_loss = 0.5 * np.add(d_loss_real, d_loss_fake)
# Train generator
noise = np.random.normal(0, 1, (batch_size, 100))
g_loss = gan.train_on_batch(noise, np.ones((batch_size, 1)))
# Print progress
if epoch % 1000 == 0:
print(f"{epoch} [D loss: {d_loss[0]}, acc.: {d_loss[1] * 100}%] [G loss: {g_loss}]")
# Generate new samples
noise = np.random.normal(0, 1, (10, 100))
generated_images = generator.predict(noise)
# Plot generated images
fig, axs = plt.subplots(1, 10, figsize=(20, 2))
for i, img in enumerate(generated_images):
axs[i].imshow(img.squeeze(), cmap='gray')
axs[i].axis('off')
plt.show()
Ejercicio 2: Ajustar Fino un Modelo GPT-4 Preentrenado
Tarea: Ajustar fino un modelo GPT-4 preentrenado para una tarea específica de generación de texto utilizando la API de OpenAI. Usa un prompt personalizado y genera texto basado en ese prompt.
Solución:
import openai
# Set your OpenAI API key
openai.api_key = 'your-api-key-here'
# Define the prompt for GPT-4
prompt = "In a futuristic city, the AI robots started to develop their own consciousness. One day,"
# Generate text using GPT-4
response = openai.Completion.create(
engine="gpt-4",
prompt=prompt,
max_tokens=100,
n=1,
stop=None,
temperature=0.7
)
# Extract the generated text
generated_text = response.choices[0].text.strip()
print(generated_text)
Ejercicio 3: Implementar un VAE Simple
Tarea: Implementa un VAE simple para generar nuevas muestras del conjunto de datos MNIST. Utiliza el ejemplo proporcionado en la sección 2.2.2 y modifícalo para incluir capas adicionales tanto en el codificador como en el decodificador.
Solución:
import tensorflow as tf
from tensorflow.keras.layers import Dense, Flatten, Reshape, Lambda, Input, Conv2D, Conv2DTranspose
from tensorflow.keras.models import Model
from tensorflow.keras.losses import binary_crossentropy
from tensorflow.keras import backend as K
import numpy as np
import matplotlib.pyplot as plt
# Sampling function
def sampling(args):
z_mean, z_log_var = args
batch = tf.shape(z_mean)[0]
dim = tf.shape(z_mean)[1]
epsilon = tf.keras.backend.random_normal(shape=(batch, dim))
return z_mean + K.exp(0.5 * z_log_var) * epsilon
# Encoder model
input_img = Input(shape=(28, 28, 1))
x = Conv2D(32, 3, activation='relu', padding='same')(input_img)
x = Conv2D(64, 3, activation='relu', padding='same', strides=2)(x)
x = Conv2D(128, 3, activation='relu', padding='same', strides=2)(x)
x = Flatten()(x)
x = Dense(256, activation='relu')(x)
z_mean = Dense(2)(x)
z_log_var = Dense(2)(x)
z = Lambda(sampling, output_shape=(2,))([z_mean, z_log_var])
encoder = Model(input_img, z)
# Decoder model
decoder_input = Input(shape=(2,))
x = Dense(7*7*128, activation='relu')(decoder_input)
x = Reshape((7, 7, 128))(x)
x = Conv2DTranspose(128, 3, activation='relu', padding='same', strides=2)(x)
x = Conv2DTranspose(64, 3, activation='relu', padding='same', strides=2)(x)
x = Conv2DTranspose(32, 3, activation='relu', padding='same')(x)
output_img = Conv2DTranspose(1, 3, activation='sigmoid', padding='same')(x)
decoder = Model(decoder_input, output_img)
# VAE model
output_img = decoder(encoder(input_img))
vae = Model(input_img, output_img)
# VAE loss function
reconstruction_loss = binary_crossentropy(K.flatten(input_img), K.flatten(output_img))
reconstruction_loss *= 28 * 28
kl_loss = 1 + z_log_var - K.square(z_mean) - K.exp(z_log_var)
kl_loss = K.sum(kl_loss, axis=-1)
kl_loss *= -0.5
vae_loss = K.mean(reconstruction_loss + kl_loss)
vae.add_loss(vae_loss)
vae.compile(optimizer='adam')
# Training the VAE
(x_train, _), (_, _) = tf.keras.datasets.mnist.load_data()
x_train = (x_train.astype(np.float32) / 255.0) - 0.5
x_train = np.expand_dims(x_train, axis=-1)
vae.fit(x_train, epochs=50, batch_size=128, verbose=1)
# Generate new samples
z_sample = np.array([[0.0, 0.0]])
generated_image = decoder.predict(z_sample)
# Plot generated image
plt.imshow(generated_image[0].squeeze(), cmap='gray')
plt.axis('off')
plt.show()
Ejercicio 4: Aplicar Normalización Espectral a un Discriminador
Tarea: Implementa la normalización espectral en un modelo de discriminador simple. Utiliza el ejemplo proporcionado en la sección 2.3.2 y asegúrate de que el discriminador se aplique al conjunto de datos MNIST.
Solución:
import torch
import torch.nn as nn
import torch.optim as optim
from torchvision import datasets, transforms
from torch.utils.data import DataLoader
import matplotlib.pyplot as plt
# Define a simple discriminator with spectral normalization
class Discriminator(nn.Module):
def __init__(self):
super(Discriminator, self).__init__()
self.model = nn.Sequential(
nn.utils.spectral_norm(nn.Conv2d(1, 64, 4, stride=2, padding=1)),
nn.LeakyReLU(0.2, inplace=True),
nn.utils.spectral_norm(nn.Conv2d(64, 128, 4, stride=2, padding=1)),
nn.LeakyReLU(0.2, inplace=True),
nn.Flatten(),
nn.utils.spectral_norm(nn.Linear(128 * 7 * 7, 1))
)
def forward(self, x):
return self.model(x)
# Load MNIST dataset
transform = transforms.Compose([
transforms.ToTensor(),
transforms.Normalize((0.5,),
(0.5,))
])
dataset = datasets.MNIST(root='./data', train=True, download=True, transform=transform)
dataloader = DataLoader(dataset, batch_size=64, shuffle=True)
# Instantiate the discriminator
discriminator = Discriminator()
optimizer = optim.Adam(discriminator.parameters(), lr=0.0002)
criterion = nn.BCELoss()
# Training loop
num_epochs = 5
for epoch in range(num_epochs):
for images, _ in dataloader:
optimizer.zero_grad()
labels = torch.ones(images.size(0), 1)
outputs = discriminator(images)
loss = criterion(outputs, labels)
loss.backward()
optimizer.step()
print(f'Epoch [{epoch+1}/{num_epochs}], Loss: {loss.item():.4f}')
# Generate fake data (for demonstration purposes)
noise = torch.randn(64, 1, 28, 28)
fake_images = noise
# Evaluate discriminator on fake data
with torch.no_grad():
fake_outputs = discriminator(fake_images)
print("Discriminator output on fake images:", fake_outputs[:5])
Ejercicio 5: Implementar una GAN 3D para la Generación de Objetos Basados en Vóxeles
Tarea: Implementa una GAN 3D simple para generar objetos basados en vóxeles. Utiliza el ejemplo proporcionado en la sección 2.3.3 y visualiza los objetos 3D generados.
Solución:
import torch
import torch.nn as nn
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
# Define a simple 3D GAN for voxel-based object generation
class VoxelGenerator(nn.Module):
def __init__(self):
super(VoxelGenerator, self).__init__()
self.model = nn.Sequential(
nn.Linear(100, 128),
nn.ReLU(inplace=True),
nn.Linear(128, 256),
nn.ReLU(inplace=True),
nn.Linear(256, 512),
nn.ReLU(inplace=True),
nn.Linear(512, 32*32*32),
nn.Tanh()
)
def forward(self, z):
return self.model(z).view(-1, 32, 32, 32)
# Instantiate the generator
voxel_generator = VoxelGenerator()
# Generate random latent vectors
num_voxels = 5
latent_vectors = torch.randn(num_voxels, 100)
# Generate 3D voxel objects
generated_voxels = voxel_generator(latent_vectors)
# Visualize the generated 3D objects
fig = plt.figure(figsize=(15, 15))
for i in range(num_voxels):
ax = fig.add_subplot(1, num_voxels, i+1, projection='3d')
ax.voxels(generated_voxels[i].detach().numpy() > 0, edgecolor='k')
ax.axis('off')
plt.show()
Estos ejercicios prácticos deberían ayudar a reforzar tu comprensión de los conceptos cubiertos en este capítulo. Al implementar estos modelos y experimentar con diferentes configuraciones, obtendrás experiencia práctica con los modelos generativos y sus aplicaciones prácticas. ¡Sigue practicando y no dudes en explorar más por tu cuenta!
Ejercicios Prácticos
Ejercicio 1: Implementar una GAN Simple
Tarea: Implementa una GAN simple para generar nuevas muestras del conjunto de datos MNIST. Utiliza el ejemplo proporcionado en la sección 2.2.1 y modifícalo para incluir una capa adicional tanto en el generador como en el discriminador.
Solución:
import tensorflow as tf
from tensorflow.keras.layers import Dense, LeakyReLU, Reshape, Flatten, Dropout
from tensorflow.keras.models import Sequential
import numpy as np
import matplotlib.pyplot as plt
# Generator model
def build_generator():
model = Sequential([
Dense(256, input_dim=100),
LeakyReLU(alpha=0.2),
Dense(512),
LeakyReLU(alpha=0.2),
Dense(1024),
LeakyReLU(alpha=0.2),
Dense(28 * 28, activation='tanh'),
Reshape((28, 28, 1))
])
return model
# Discriminator model
def build_discriminator():
model = Sequential([
Flatten(input_shape=(28, 28, 1)),
Dense(1024),
LeakyReLU(alpha=0.2),
Dropout(0.3),
Dense(512),
LeakyReLU(alpha=0.2),
Dropout(0.3),
Dense(256),
LeakyReLU(alpha=0.2),
Dropout(0.3),
Dense(1, activation='sigmoid')
])
return model
# Build and compile the GAN
generator = build_generator()
discriminator = build_discriminator()
discriminator.compile(optimizer='adam', loss='binary_crossentropy', metrics=['accuracy'])
# GAN model
discriminator.trainable = False
gan_input = tf.keras.Input(shape=(100,))
gan_output = discriminator(generator(gan_input))
gan = tf.keras.Model(gan_input, gan_output)
gan.compile(optimizer='adam', loss='binary_crossentropy')
# Training the GAN
(x_train, _), (_, _) = tf.keras.datasets.mnist.load_data()
x_train = (x_train.astype(np.float32) - 127.5) / 127.5 # Normalize to [-1, 1]
x_train = np.expand_dims(x_train, axis=-1)
batch_size = 64
epochs = 10000
for epoch in range(epochs):
# Train discriminator
idx = np.random.randint(0, x_train.shape[0], batch_size)
real_images = x_train[idx]
noise = np.random.normal(0, 1, (batch_size, 100))
fake_images = generator.predict(noise)
d_loss_real = discriminator.train_on_batch(real_images, np.ones((batch_size, 1)))
d_loss_fake = discriminator.train_on_batch(fake_images, np.zeros((batch_size, 1)))
d_loss = 0.5 * np.add(d_loss_real, d_loss_fake)
# Train generator
noise = np.random.normal(0, 1, (batch_size, 100))
g_loss = gan.train_on_batch(noise, np.ones((batch_size, 1)))
# Print progress
if epoch % 1000 == 0:
print(f"{epoch} [D loss: {d_loss[0]}, acc.: {d_loss[1] * 100}%] [G loss: {g_loss}]")
# Generate new samples
noise = np.random.normal(0, 1, (10, 100))
generated_images = generator.predict(noise)
# Plot generated images
fig, axs = plt.subplots(1, 10, figsize=(20, 2))
for i, img in enumerate(generated_images):
axs[i].imshow(img.squeeze(), cmap='gray')
axs[i].axis('off')
plt.show()
Ejercicio 2: Ajustar Fino un Modelo GPT-4 Preentrenado
Tarea: Ajustar fino un modelo GPT-4 preentrenado para una tarea específica de generación de texto utilizando la API de OpenAI. Usa un prompt personalizado y genera texto basado en ese prompt.
Solución:
import openai
# Set your OpenAI API key
openai.api_key = 'your-api-key-here'
# Define the prompt for GPT-4
prompt = "In a futuristic city, the AI robots started to develop their own consciousness. One day,"
# Generate text using GPT-4
response = openai.Completion.create(
engine="gpt-4",
prompt=prompt,
max_tokens=100,
n=1,
stop=None,
temperature=0.7
)
# Extract the generated text
generated_text = response.choices[0].text.strip()
print(generated_text)
Ejercicio 3: Implementar un VAE Simple
Tarea: Implementa un VAE simple para generar nuevas muestras del conjunto de datos MNIST. Utiliza el ejemplo proporcionado en la sección 2.2.2 y modifícalo para incluir capas adicionales tanto en el codificador como en el decodificador.
Solución:
import tensorflow as tf
from tensorflow.keras.layers import Dense, Flatten, Reshape, Lambda, Input, Conv2D, Conv2DTranspose
from tensorflow.keras.models import Model
from tensorflow.keras.losses import binary_crossentropy
from tensorflow.keras import backend as K
import numpy as np
import matplotlib.pyplot as plt
# Sampling function
def sampling(args):
z_mean, z_log_var = args
batch = tf.shape(z_mean)[0]
dim = tf.shape(z_mean)[1]
epsilon = tf.keras.backend.random_normal(shape=(batch, dim))
return z_mean + K.exp(0.5 * z_log_var) * epsilon
# Encoder model
input_img = Input(shape=(28, 28, 1))
x = Conv2D(32, 3, activation='relu', padding='same')(input_img)
x = Conv2D(64, 3, activation='relu', padding='same', strides=2)(x)
x = Conv2D(128, 3, activation='relu', padding='same', strides=2)(x)
x = Flatten()(x)
x = Dense(256, activation='relu')(x)
z_mean = Dense(2)(x)
z_log_var = Dense(2)(x)
z = Lambda(sampling, output_shape=(2,))([z_mean, z_log_var])
encoder = Model(input_img, z)
# Decoder model
decoder_input = Input(shape=(2,))
x = Dense(7*7*128, activation='relu')(decoder_input)
x = Reshape((7, 7, 128))(x)
x = Conv2DTranspose(128, 3, activation='relu', padding='same', strides=2)(x)
x = Conv2DTranspose(64, 3, activation='relu', padding='same', strides=2)(x)
x = Conv2DTranspose(32, 3, activation='relu', padding='same')(x)
output_img = Conv2DTranspose(1, 3, activation='sigmoid', padding='same')(x)
decoder = Model(decoder_input, output_img)
# VAE model
output_img = decoder(encoder(input_img))
vae = Model(input_img, output_img)
# VAE loss function
reconstruction_loss = binary_crossentropy(K.flatten(input_img), K.flatten(output_img))
reconstruction_loss *= 28 * 28
kl_loss = 1 + z_log_var - K.square(z_mean) - K.exp(z_log_var)
kl_loss = K.sum(kl_loss, axis=-1)
kl_loss *= -0.5
vae_loss = K.mean(reconstruction_loss + kl_loss)
vae.add_loss(vae_loss)
vae.compile(optimizer='adam')
# Training the VAE
(x_train, _), (_, _) = tf.keras.datasets.mnist.load_data()
x_train = (x_train.astype(np.float32) / 255.0) - 0.5
x_train = np.expand_dims(x_train, axis=-1)
vae.fit(x_train, epochs=50, batch_size=128, verbose=1)
# Generate new samples
z_sample = np.array([[0.0, 0.0]])
generated_image = decoder.predict(z_sample)
# Plot generated image
plt.imshow(generated_image[0].squeeze(), cmap='gray')
plt.axis('off')
plt.show()
Ejercicio 4: Aplicar Normalización Espectral a un Discriminador
Tarea: Implementa la normalización espectral en un modelo de discriminador simple. Utiliza el ejemplo proporcionado en la sección 2.3.2 y asegúrate de que el discriminador se aplique al conjunto de datos MNIST.
Solución:
import torch
import torch.nn as nn
import torch.optim as optim
from torchvision import datasets, transforms
from torch.utils.data import DataLoader
import matplotlib.pyplot as plt
# Define a simple discriminator with spectral normalization
class Discriminator(nn.Module):
def __init__(self):
super(Discriminator, self).__init__()
self.model = nn.Sequential(
nn.utils.spectral_norm(nn.Conv2d(1, 64, 4, stride=2, padding=1)),
nn.LeakyReLU(0.2, inplace=True),
nn.utils.spectral_norm(nn.Conv2d(64, 128, 4, stride=2, padding=1)),
nn.LeakyReLU(0.2, inplace=True),
nn.Flatten(),
nn.utils.spectral_norm(nn.Linear(128 * 7 * 7, 1))
)
def forward(self, x):
return self.model(x)
# Load MNIST dataset
transform = transforms.Compose([
transforms.ToTensor(),
transforms.Normalize((0.5,),
(0.5,))
])
dataset = datasets.MNIST(root='./data', train=True, download=True, transform=transform)
dataloader = DataLoader(dataset, batch_size=64, shuffle=True)
# Instantiate the discriminator
discriminator = Discriminator()
optimizer = optim.Adam(discriminator.parameters(), lr=0.0002)
criterion = nn.BCELoss()
# Training loop
num_epochs = 5
for epoch in range(num_epochs):
for images, _ in dataloader:
optimizer.zero_grad()
labels = torch.ones(images.size(0), 1)
outputs = discriminator(images)
loss = criterion(outputs, labels)
loss.backward()
optimizer.step()
print(f'Epoch [{epoch+1}/{num_epochs}], Loss: {loss.item():.4f}')
# Generate fake data (for demonstration purposes)
noise = torch.randn(64, 1, 28, 28)
fake_images = noise
# Evaluate discriminator on fake data
with torch.no_grad():
fake_outputs = discriminator(fake_images)
print("Discriminator output on fake images:", fake_outputs[:5])
Ejercicio 5: Implementar una GAN 3D para la Generación de Objetos Basados en Vóxeles
Tarea: Implementa una GAN 3D simple para generar objetos basados en vóxeles. Utiliza el ejemplo proporcionado en la sección 2.3.3 y visualiza los objetos 3D generados.
Solución:
import torch
import torch.nn as nn
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
# Define a simple 3D GAN for voxel-based object generation
class VoxelGenerator(nn.Module):
def __init__(self):
super(VoxelGenerator, self).__init__()
self.model = nn.Sequential(
nn.Linear(100, 128),
nn.ReLU(inplace=True),
nn.Linear(128, 256),
nn.ReLU(inplace=True),
nn.Linear(256, 512),
nn.ReLU(inplace=True),
nn.Linear(512, 32*32*32),
nn.Tanh()
)
def forward(self, z):
return self.model(z).view(-1, 32, 32, 32)
# Instantiate the generator
voxel_generator = VoxelGenerator()
# Generate random latent vectors
num_voxels = 5
latent_vectors = torch.randn(num_voxels, 100)
# Generate 3D voxel objects
generated_voxels = voxel_generator(latent_vectors)
# Visualize the generated 3D objects
fig = plt.figure(figsize=(15, 15))
for i in range(num_voxels):
ax = fig.add_subplot(1, num_voxels, i+1, projection='3d')
ax.voxels(generated_voxels[i].detach().numpy() > 0, edgecolor='k')
ax.axis('off')
plt.show()
Estos ejercicios prácticos deberían ayudar a reforzar tu comprensión de los conceptos cubiertos en este capítulo. Al implementar estos modelos y experimentar con diferentes configuraciones, obtendrás experiencia práctica con los modelos generativos y sus aplicaciones prácticas. ¡Sigue practicando y no dudes en explorar más por tu cuenta!
Ejercicios Prácticos
Ejercicio 1: Implementar una GAN Simple
Tarea: Implementa una GAN simple para generar nuevas muestras del conjunto de datos MNIST. Utiliza el ejemplo proporcionado en la sección 2.2.1 y modifícalo para incluir una capa adicional tanto en el generador como en el discriminador.
Solución:
import tensorflow as tf
from tensorflow.keras.layers import Dense, LeakyReLU, Reshape, Flatten, Dropout
from tensorflow.keras.models import Sequential
import numpy as np
import matplotlib.pyplot as plt
# Generator model
def build_generator():
model = Sequential([
Dense(256, input_dim=100),
LeakyReLU(alpha=0.2),
Dense(512),
LeakyReLU(alpha=0.2),
Dense(1024),
LeakyReLU(alpha=0.2),
Dense(28 * 28, activation='tanh'),
Reshape((28, 28, 1))
])
return model
# Discriminator model
def build_discriminator():
model = Sequential([
Flatten(input_shape=(28, 28, 1)),
Dense(1024),
LeakyReLU(alpha=0.2),
Dropout(0.3),
Dense(512),
LeakyReLU(alpha=0.2),
Dropout(0.3),
Dense(256),
LeakyReLU(alpha=0.2),
Dropout(0.3),
Dense(1, activation='sigmoid')
])
return model
# Build and compile the GAN
generator = build_generator()
discriminator = build_discriminator()
discriminator.compile(optimizer='adam', loss='binary_crossentropy', metrics=['accuracy'])
# GAN model
discriminator.trainable = False
gan_input = tf.keras.Input(shape=(100,))
gan_output = discriminator(generator(gan_input))
gan = tf.keras.Model(gan_input, gan_output)
gan.compile(optimizer='adam', loss='binary_crossentropy')
# Training the GAN
(x_train, _), (_, _) = tf.keras.datasets.mnist.load_data()
x_train = (x_train.astype(np.float32) - 127.5) / 127.5 # Normalize to [-1, 1]
x_train = np.expand_dims(x_train, axis=-1)
batch_size = 64
epochs = 10000
for epoch in range(epochs):
# Train discriminator
idx = np.random.randint(0, x_train.shape[0], batch_size)
real_images = x_train[idx]
noise = np.random.normal(0, 1, (batch_size, 100))
fake_images = generator.predict(noise)
d_loss_real = discriminator.train_on_batch(real_images, np.ones((batch_size, 1)))
d_loss_fake = discriminator.train_on_batch(fake_images, np.zeros((batch_size, 1)))
d_loss = 0.5 * np.add(d_loss_real, d_loss_fake)
# Train generator
noise = np.random.normal(0, 1, (batch_size, 100))
g_loss = gan.train_on_batch(noise, np.ones((batch_size, 1)))
# Print progress
if epoch % 1000 == 0:
print(f"{epoch} [D loss: {d_loss[0]}, acc.: {d_loss[1] * 100}%] [G loss: {g_loss}]")
# Generate new samples
noise = np.random.normal(0, 1, (10, 100))
generated_images = generator.predict(noise)
# Plot generated images
fig, axs = plt.subplots(1, 10, figsize=(20, 2))
for i, img in enumerate(generated_images):
axs[i].imshow(img.squeeze(), cmap='gray')
axs[i].axis('off')
plt.show()
Ejercicio 2: Ajustar Fino un Modelo GPT-4 Preentrenado
Tarea: Ajustar fino un modelo GPT-4 preentrenado para una tarea específica de generación de texto utilizando la API de OpenAI. Usa un prompt personalizado y genera texto basado en ese prompt.
Solución:
import openai
# Set your OpenAI API key
openai.api_key = 'your-api-key-here'
# Define the prompt for GPT-4
prompt = "In a futuristic city, the AI robots started to develop their own consciousness. One day,"
# Generate text using GPT-4
response = openai.Completion.create(
engine="gpt-4",
prompt=prompt,
max_tokens=100,
n=1,
stop=None,
temperature=0.7
)
# Extract the generated text
generated_text = response.choices[0].text.strip()
print(generated_text)
Ejercicio 3: Implementar un VAE Simple
Tarea: Implementa un VAE simple para generar nuevas muestras del conjunto de datos MNIST. Utiliza el ejemplo proporcionado en la sección 2.2.2 y modifícalo para incluir capas adicionales tanto en el codificador como en el decodificador.
Solución:
import tensorflow as tf
from tensorflow.keras.layers import Dense, Flatten, Reshape, Lambda, Input, Conv2D, Conv2DTranspose
from tensorflow.keras.models import Model
from tensorflow.keras.losses import binary_crossentropy
from tensorflow.keras import backend as K
import numpy as np
import matplotlib.pyplot as plt
# Sampling function
def sampling(args):
z_mean, z_log_var = args
batch = tf.shape(z_mean)[0]
dim = tf.shape(z_mean)[1]
epsilon = tf.keras.backend.random_normal(shape=(batch, dim))
return z_mean + K.exp(0.5 * z_log_var) * epsilon
# Encoder model
input_img = Input(shape=(28, 28, 1))
x = Conv2D(32, 3, activation='relu', padding='same')(input_img)
x = Conv2D(64, 3, activation='relu', padding='same', strides=2)(x)
x = Conv2D(128, 3, activation='relu', padding='same', strides=2)(x)
x = Flatten()(x)
x = Dense(256, activation='relu')(x)
z_mean = Dense(2)(x)
z_log_var = Dense(2)(x)
z = Lambda(sampling, output_shape=(2,))([z_mean, z_log_var])
encoder = Model(input_img, z)
# Decoder model
decoder_input = Input(shape=(2,))
x = Dense(7*7*128, activation='relu')(decoder_input)
x = Reshape((7, 7, 128))(x)
x = Conv2DTranspose(128, 3, activation='relu', padding='same', strides=2)(x)
x = Conv2DTranspose(64, 3, activation='relu', padding='same', strides=2)(x)
x = Conv2DTranspose(32, 3, activation='relu', padding='same')(x)
output_img = Conv2DTranspose(1, 3, activation='sigmoid', padding='same')(x)
decoder = Model(decoder_input, output_img)
# VAE model
output_img = decoder(encoder(input_img))
vae = Model(input_img, output_img)
# VAE loss function
reconstruction_loss = binary_crossentropy(K.flatten(input_img), K.flatten(output_img))
reconstruction_loss *= 28 * 28
kl_loss = 1 + z_log_var - K.square(z_mean) - K.exp(z_log_var)
kl_loss = K.sum(kl_loss, axis=-1)
kl_loss *= -0.5
vae_loss = K.mean(reconstruction_loss + kl_loss)
vae.add_loss(vae_loss)
vae.compile(optimizer='adam')
# Training the VAE
(x_train, _), (_, _) = tf.keras.datasets.mnist.load_data()
x_train = (x_train.astype(np.float32) / 255.0) - 0.5
x_train = np.expand_dims(x_train, axis=-1)
vae.fit(x_train, epochs=50, batch_size=128, verbose=1)
# Generate new samples
z_sample = np.array([[0.0, 0.0]])
generated_image = decoder.predict(z_sample)
# Plot generated image
plt.imshow(generated_image[0].squeeze(), cmap='gray')
plt.axis('off')
plt.show()
Ejercicio 4: Aplicar Normalización Espectral a un Discriminador
Tarea: Implementa la normalización espectral en un modelo de discriminador simple. Utiliza el ejemplo proporcionado en la sección 2.3.2 y asegúrate de que el discriminador se aplique al conjunto de datos MNIST.
Solución:
import torch
import torch.nn as nn
import torch.optim as optim
from torchvision import datasets, transforms
from torch.utils.data import DataLoader
import matplotlib.pyplot as plt
# Define a simple discriminator with spectral normalization
class Discriminator(nn.Module):
def __init__(self):
super(Discriminator, self).__init__()
self.model = nn.Sequential(
nn.utils.spectral_norm(nn.Conv2d(1, 64, 4, stride=2, padding=1)),
nn.LeakyReLU(0.2, inplace=True),
nn.utils.spectral_norm(nn.Conv2d(64, 128, 4, stride=2, padding=1)),
nn.LeakyReLU(0.2, inplace=True),
nn.Flatten(),
nn.utils.spectral_norm(nn.Linear(128 * 7 * 7, 1))
)
def forward(self, x):
return self.model(x)
# Load MNIST dataset
transform = transforms.Compose([
transforms.ToTensor(),
transforms.Normalize((0.5,),
(0.5,))
])
dataset = datasets.MNIST(root='./data', train=True, download=True, transform=transform)
dataloader = DataLoader(dataset, batch_size=64, shuffle=True)
# Instantiate the discriminator
discriminator = Discriminator()
optimizer = optim.Adam(discriminator.parameters(), lr=0.0002)
criterion = nn.BCELoss()
# Training loop
num_epochs = 5
for epoch in range(num_epochs):
for images, _ in dataloader:
optimizer.zero_grad()
labels = torch.ones(images.size(0), 1)
outputs = discriminator(images)
loss = criterion(outputs, labels)
loss.backward()
optimizer.step()
print(f'Epoch [{epoch+1}/{num_epochs}], Loss: {loss.item():.4f}')
# Generate fake data (for demonstration purposes)
noise = torch.randn(64, 1, 28, 28)
fake_images = noise
# Evaluate discriminator on fake data
with torch.no_grad():
fake_outputs = discriminator(fake_images)
print("Discriminator output on fake images:", fake_outputs[:5])
Ejercicio 5: Implementar una GAN 3D para la Generación de Objetos Basados en Vóxeles
Tarea: Implementa una GAN 3D simple para generar objetos basados en vóxeles. Utiliza el ejemplo proporcionado en la sección 2.3.3 y visualiza los objetos 3D generados.
Solución:
import torch
import torch.nn as nn
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
# Define a simple 3D GAN for voxel-based object generation
class VoxelGenerator(nn.Module):
def __init__(self):
super(VoxelGenerator, self).__init__()
self.model = nn.Sequential(
nn.Linear(100, 128),
nn.ReLU(inplace=True),
nn.Linear(128, 256),
nn.ReLU(inplace=True),
nn.Linear(256, 512),
nn.ReLU(inplace=True),
nn.Linear(512, 32*32*32),
nn.Tanh()
)
def forward(self, z):
return self.model(z).view(-1, 32, 32, 32)
# Instantiate the generator
voxel_generator = VoxelGenerator()
# Generate random latent vectors
num_voxels = 5
latent_vectors = torch.randn(num_voxels, 100)
# Generate 3D voxel objects
generated_voxels = voxel_generator(latent_vectors)
# Visualize the generated 3D objects
fig = plt.figure(figsize=(15, 15))
for i in range(num_voxels):
ax = fig.add_subplot(1, num_voxels, i+1, projection='3d')
ax.voxels(generated_voxels[i].detach().numpy() > 0, edgecolor='k')
ax.axis('off')
plt.show()
Estos ejercicios prácticos deberían ayudar a reforzar tu comprensión de los conceptos cubiertos en este capítulo. Al implementar estos modelos y experimentar con diferentes configuraciones, obtendrás experiencia práctica con los modelos generativos y sus aplicaciones prácticas. ¡Sigue practicando y no dudes en explorar más por tu cuenta!
Ejercicios Prácticos
Ejercicio 1: Implementar una GAN Simple
Tarea: Implementa una GAN simple para generar nuevas muestras del conjunto de datos MNIST. Utiliza el ejemplo proporcionado en la sección 2.2.1 y modifícalo para incluir una capa adicional tanto en el generador como en el discriminador.
Solución:
import tensorflow as tf
from tensorflow.keras.layers import Dense, LeakyReLU, Reshape, Flatten, Dropout
from tensorflow.keras.models import Sequential
import numpy as np
import matplotlib.pyplot as plt
# Generator model
def build_generator():
model = Sequential([
Dense(256, input_dim=100),
LeakyReLU(alpha=0.2),
Dense(512),
LeakyReLU(alpha=0.2),
Dense(1024),
LeakyReLU(alpha=0.2),
Dense(28 * 28, activation='tanh'),
Reshape((28, 28, 1))
])
return model
# Discriminator model
def build_discriminator():
model = Sequential([
Flatten(input_shape=(28, 28, 1)),
Dense(1024),
LeakyReLU(alpha=0.2),
Dropout(0.3),
Dense(512),
LeakyReLU(alpha=0.2),
Dropout(0.3),
Dense(256),
LeakyReLU(alpha=0.2),
Dropout(0.3),
Dense(1, activation='sigmoid')
])
return model
# Build and compile the GAN
generator = build_generator()
discriminator = build_discriminator()
discriminator.compile(optimizer='adam', loss='binary_crossentropy', metrics=['accuracy'])
# GAN model
discriminator.trainable = False
gan_input = tf.keras.Input(shape=(100,))
gan_output = discriminator(generator(gan_input))
gan = tf.keras.Model(gan_input, gan_output)
gan.compile(optimizer='adam', loss='binary_crossentropy')
# Training the GAN
(x_train, _), (_, _) = tf.keras.datasets.mnist.load_data()
x_train = (x_train.astype(np.float32) - 127.5) / 127.5 # Normalize to [-1, 1]
x_train = np.expand_dims(x_train, axis=-1)
batch_size = 64
epochs = 10000
for epoch in range(epochs):
# Train discriminator
idx = np.random.randint(0, x_train.shape[0], batch_size)
real_images = x_train[idx]
noise = np.random.normal(0, 1, (batch_size, 100))
fake_images = generator.predict(noise)
d_loss_real = discriminator.train_on_batch(real_images, np.ones((batch_size, 1)))
d_loss_fake = discriminator.train_on_batch(fake_images, np.zeros((batch_size, 1)))
d_loss = 0.5 * np.add(d_loss_real, d_loss_fake)
# Train generator
noise = np.random.normal(0, 1, (batch_size, 100))
g_loss = gan.train_on_batch(noise, np.ones((batch_size, 1)))
# Print progress
if epoch % 1000 == 0:
print(f"{epoch} [D loss: {d_loss[0]}, acc.: {d_loss[1] * 100}%] [G loss: {g_loss}]")
# Generate new samples
noise = np.random.normal(0, 1, (10, 100))
generated_images = generator.predict(noise)
# Plot generated images
fig, axs = plt.subplots(1, 10, figsize=(20, 2))
for i, img in enumerate(generated_images):
axs[i].imshow(img.squeeze(), cmap='gray')
axs[i].axis('off')
plt.show()
Ejercicio 2: Ajustar Fino un Modelo GPT-4 Preentrenado
Tarea: Ajustar fino un modelo GPT-4 preentrenado para una tarea específica de generación de texto utilizando la API de OpenAI. Usa un prompt personalizado y genera texto basado en ese prompt.
Solución:
import openai
# Set your OpenAI API key
openai.api_key = 'your-api-key-here'
# Define the prompt for GPT-4
prompt = "In a futuristic city, the AI robots started to develop their own consciousness. One day,"
# Generate text using GPT-4
response = openai.Completion.create(
engine="gpt-4",
prompt=prompt,
max_tokens=100,
n=1,
stop=None,
temperature=0.7
)
# Extract the generated text
generated_text = response.choices[0].text.strip()
print(generated_text)
Ejercicio 3: Implementar un VAE Simple
Tarea: Implementa un VAE simple para generar nuevas muestras del conjunto de datos MNIST. Utiliza el ejemplo proporcionado en la sección 2.2.2 y modifícalo para incluir capas adicionales tanto en el codificador como en el decodificador.
Solución:
import tensorflow as tf
from tensorflow.keras.layers import Dense, Flatten, Reshape, Lambda, Input, Conv2D, Conv2DTranspose
from tensorflow.keras.models import Model
from tensorflow.keras.losses import binary_crossentropy
from tensorflow.keras import backend as K
import numpy as np
import matplotlib.pyplot as plt
# Sampling function
def sampling(args):
z_mean, z_log_var = args
batch = tf.shape(z_mean)[0]
dim = tf.shape(z_mean)[1]
epsilon = tf.keras.backend.random_normal(shape=(batch, dim))
return z_mean + K.exp(0.5 * z_log_var) * epsilon
# Encoder model
input_img = Input(shape=(28, 28, 1))
x = Conv2D(32, 3, activation='relu', padding='same')(input_img)
x = Conv2D(64, 3, activation='relu', padding='same', strides=2)(x)
x = Conv2D(128, 3, activation='relu', padding='same', strides=2)(x)
x = Flatten()(x)
x = Dense(256, activation='relu')(x)
z_mean = Dense(2)(x)
z_log_var = Dense(2)(x)
z = Lambda(sampling, output_shape=(2,))([z_mean, z_log_var])
encoder = Model(input_img, z)
# Decoder model
decoder_input = Input(shape=(2,))
x = Dense(7*7*128, activation='relu')(decoder_input)
x = Reshape((7, 7, 128))(x)
x = Conv2DTranspose(128, 3, activation='relu', padding='same', strides=2)(x)
x = Conv2DTranspose(64, 3, activation='relu', padding='same', strides=2)(x)
x = Conv2DTranspose(32, 3, activation='relu', padding='same')(x)
output_img = Conv2DTranspose(1, 3, activation='sigmoid', padding='same')(x)
decoder = Model(decoder_input, output_img)
# VAE model
output_img = decoder(encoder(input_img))
vae = Model(input_img, output_img)
# VAE loss function
reconstruction_loss = binary_crossentropy(K.flatten(input_img), K.flatten(output_img))
reconstruction_loss *= 28 * 28
kl_loss = 1 + z_log_var - K.square(z_mean) - K.exp(z_log_var)
kl_loss = K.sum(kl_loss, axis=-1)
kl_loss *= -0.5
vae_loss = K.mean(reconstruction_loss + kl_loss)
vae.add_loss(vae_loss)
vae.compile(optimizer='adam')
# Training the VAE
(x_train, _), (_, _) = tf.keras.datasets.mnist.load_data()
x_train = (x_train.astype(np.float32) / 255.0) - 0.5
x_train = np.expand_dims(x_train, axis=-1)
vae.fit(x_train, epochs=50, batch_size=128, verbose=1)
# Generate new samples
z_sample = np.array([[0.0, 0.0]])
generated_image = decoder.predict(z_sample)
# Plot generated image
plt.imshow(generated_image[0].squeeze(), cmap='gray')
plt.axis('off')
plt.show()
Ejercicio 4: Aplicar Normalización Espectral a un Discriminador
Tarea: Implementa la normalización espectral en un modelo de discriminador simple. Utiliza el ejemplo proporcionado en la sección 2.3.2 y asegúrate de que el discriminador se aplique al conjunto de datos MNIST.
Solución:
import torch
import torch.nn as nn
import torch.optim as optim
from torchvision import datasets, transforms
from torch.utils.data import DataLoader
import matplotlib.pyplot as plt
# Define a simple discriminator with spectral normalization
class Discriminator(nn.Module):
def __init__(self):
super(Discriminator, self).__init__()
self.model = nn.Sequential(
nn.utils.spectral_norm(nn.Conv2d(1, 64, 4, stride=2, padding=1)),
nn.LeakyReLU(0.2, inplace=True),
nn.utils.spectral_norm(nn.Conv2d(64, 128, 4, stride=2, padding=1)),
nn.LeakyReLU(0.2, inplace=True),
nn.Flatten(),
nn.utils.spectral_norm(nn.Linear(128 * 7 * 7, 1))
)
def forward(self, x):
return self.model(x)
# Load MNIST dataset
transform = transforms.Compose([
transforms.ToTensor(),
transforms.Normalize((0.5,),
(0.5,))
])
dataset = datasets.MNIST(root='./data', train=True, download=True, transform=transform)
dataloader = DataLoader(dataset, batch_size=64, shuffle=True)
# Instantiate the discriminator
discriminator = Discriminator()
optimizer = optim.Adam(discriminator.parameters(), lr=0.0002)
criterion = nn.BCELoss()
# Training loop
num_epochs = 5
for epoch in range(num_epochs):
for images, _ in dataloader:
optimizer.zero_grad()
labels = torch.ones(images.size(0), 1)
outputs = discriminator(images)
loss = criterion(outputs, labels)
loss.backward()
optimizer.step()
print(f'Epoch [{epoch+1}/{num_epochs}], Loss: {loss.item():.4f}')
# Generate fake data (for demonstration purposes)
noise = torch.randn(64, 1, 28, 28)
fake_images = noise
# Evaluate discriminator on fake data
with torch.no_grad():
fake_outputs = discriminator(fake_images)
print("Discriminator output on fake images:", fake_outputs[:5])
Ejercicio 5: Implementar una GAN 3D para la Generación de Objetos Basados en Vóxeles
Tarea: Implementa una GAN 3D simple para generar objetos basados en vóxeles. Utiliza el ejemplo proporcionado en la sección 2.3.3 y visualiza los objetos 3D generados.
Solución:
import torch
import torch.nn as nn
import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
# Define a simple 3D GAN for voxel-based object generation
class VoxelGenerator(nn.Module):
def __init__(self):
super(VoxelGenerator, self).__init__()
self.model = nn.Sequential(
nn.Linear(100, 128),
nn.ReLU(inplace=True),
nn.Linear(128, 256),
nn.ReLU(inplace=True),
nn.Linear(256, 512),
nn.ReLU(inplace=True),
nn.Linear(512, 32*32*32),
nn.Tanh()
)
def forward(self, z):
return self.model(z).view(-1, 32, 32, 32)
# Instantiate the generator
voxel_generator = VoxelGenerator()
# Generate random latent vectors
num_voxels = 5
latent_vectors = torch.randn(num_voxels, 100)
# Generate 3D voxel objects
generated_voxels = voxel_generator(latent_vectors)
# Visualize the generated 3D objects
fig = plt.figure(figsize=(15, 15))
for i in range(num_voxels):
ax = fig.add_subplot(1, num_voxels, i+1, projection='3d')
ax.voxels(generated_voxels[i].detach().numpy() > 0, edgecolor='k')
ax.axis('off')
plt.show()
Estos ejercicios prácticos deberían ayudar a reforzar tu comprensión de los conceptos cubiertos en este capítulo. Al implementar estos modelos y experimentar con diferentes configuraciones, obtendrás experiencia práctica con los modelos generativos y sus aplicaciones prácticas. ¡Sigue practicando y no dudes en explorar más por tu cuenta!