Generative models
Generative models are a type of machine learning models that learn to generate new data samples that are similar to the original training data. They are widely used in applications such as image and text generation, data augmentation, and anomaly detection. Two popular types of generative models are variational autoencoders (VAEs) and generative adversarial networks (GANs).
Variational Autoencoders (VAEs) Variational Autoencoders (VAEs) are generative models that learn to encode input data into a lower-dimensional representation and then decode the encoded representation back into the original input. The encoder network learns to approximate the posterior distribution of the latent variables, while the decoder network learns to generate new samples from the latent variables. Here is an example code for VAE implementation using the Keras library:
import keras
from keras import layers
# Define the encoder network
latent_dim = 2
input_shape = (28, 28, 1)
encoder_inputs = keras.Input(shape=input_shape)
x = layers.Conv2D(32, 3, activation="relu", strides=2, padding="same")(encoder_inputs)
x = layers.Conv2D(64, 3, activation="relu", strides=2, padding="same")(x)
x = layers.Flatten()(x)
x = layers.Dense(16, activation="relu")(x)
z_mean = layers.Dense(latent_dim, name="z_mean")(x)
z_log_var = layers.Dense(latent_dim, name="z_log_var")(x)
# Define the sampling layer
def sampling(args):
z_mean, z_log_var = args
epsilon = keras.backend.random_normal(shape=(keras.backend.shape(z_mean)[0], latent_dim), mean=0., stddev=1.)
return z_mean + keras.backend.exp(z_log_var / 2) * epsilon
z = layers.Lambda(sampling)([z_mean, z_log_var])
# Define the decoder network
decoder_inputs = keras.Input(shape=(latent_dim,))
x = layers.Dense(7 * 7 * 64, activation="relu")(decoder_inputs)
x = layers.Reshape((7, 7, 64))(x)
x = layers.Conv2DTranspose(64, 3, activation="relu", strides=2, padding="same")(x)
x = layers.Conv2DTranspose(32, 3, activation="relu", strides=2, padding="same")(x)
decoder_outputs = layers.Conv2DTranspose(1, 3, activation="sigmoid", padding="same")(x)
# Define the VAE model
vae = keras.Model(encoder_inputs, decoder_outputs)
# Define the loss function
reconstruction_loss = keras.losses.binary_crossentropy(encoder_inputs, decoder_outputs)
reconstruction_loss *= input_shape[0] * input_shape[1]
kl_loss = 1 + z_log_var - keras.backend.square(z_mean) - keras.backend.exp(z_log_var)
kl_loss = keras.backend.sum(kl_loss, axis=-1)
kl_loss *= -0.5
vae_loss = keras.backend.mean(reconstruction_loss + kl_loss)
vae.add_loss(vae_loss)
# Compile the VAE model
vae.compile(optimizer=keras.optimizers.Adam())
Generative Adversarial Networks (GANs) Generative Adversarial Networks (GANs) are generative models that consist of two neural networks: a generator network and a discriminator network. The generator network learns to generate new data samples that are similar to the original data, while the discriminator network learns to distinguish between the generated data and the original data. The two networks are trained simultaneously in a minimax game. Here is an example code for GAN implementation using the PyTorch library:
import torch
import torch.nn as nn
# Define the generator network
class Generator(nn.Module):
def __init__(self, latent_dim, img_shape):
super(Generator, self).__init__()
self.latent_dim = latent_dim
self.img_shape = img_shape
self.model = nn.Sequential(
nn.Linear(latent_dim, 128),
nn.BatchNorm1d(128, 0.8),
nn.LeakyReLU(0.2, inplace=True),
nn.Linear(128, 256),
nn.BatchNorm1d(256, 0.8),
nn.LeakyReLU(0.2, inplace=True),
nn.Linear(256, 512),
nn.BatchNorm1d(512, 0.8),
nn.LeakyReLU(0.2, inplace=True),
nn.Linear(512, 1024),
nn.BatchNorm1d(1024, 0.8),
nn.LeakyReLU(0.2, inplace=True),
nn.Linear(1024, int(torch.prod(torch.tensor(img_shape)))))
self.out_activation = nn.Tanh()
def forward(self, z):
img = self.model(z)
img = img.view(img.size(0), *self.img_shape)
img = self.out_activation(img)
return img
# Define the discriminator network
class Discriminator(nn.Module):
def __init__(self, img_shape):
super(Discriminator, self).__init__()
self.img_shape = img_shape
self.model = nn.Sequential(
nn.Linear(int(torch.prod(torch.tensor(img_shape))), 512),
nn.LeakyReLU(0.2, inplace=True),
nn.Linear(512, 256),
nn.LeakyReLU(0.2, inplace=True),
nn.Linear(256, 1),
nn.Sigmoid(),
)
def forward(self, img):
img_flat = img.view(img.size(0), -1)
validity = self.model(img_flat)
return validity
# Define the GAN model
class GAN(nn.Module):
def __init__(self, latent_dim, img_shape):
super(GAN, self).__init__()
self.latent_dim = latent_dim
self.img_shape = img_shape
self.generator = Generator(latent_dim, img_shape)
self.discriminator = Discriminator(img_shape)
def forward(self, z):
img = self.generator(z)
validity = self.discriminator(img)
return validity
# Initialize the GAN model
latent_dim = 100
img_shape = (1, 28, 28)
gan = GAN(latent_dim, img_shape)
# Define the loss functions and optimizers
adversarial_loss = nn.BCELoss()
generator_optimizer = torch.optim.Adam(gan.generator.parameters(), lr=0.0002, betas=(0.5, 0.999))
discriminator_optimizer = torch.optim.Adam(gan.discriminator.parameters(), lr=0.0002, betas=(0.5, 0.999))
# Train the GAN model
num_epochs = 200
batch_size = 64
for epoch in range(num_epochs):
for i, (imgs, _) in enumerate(dataloader):
# Train the discriminator network
discriminator_optimizer.zero_grad()
real_imgs = imgs.to(device)
real_validity = gan.discriminator(real_imgs)
real_labels = torch.ones((batch_size, 1)).to(device)
real_loss = adversarial_loss(real_validity, real_labels)
z = torch.randn((batch_size, latent_dim)).to(device)
fake_imgs = gan.generator(z)
fake_validity = gan.discriminator(fake_imgs.detach())
fake_labels = torch.zeros((batch_size, 1)).to(device)
fake_loss = adversarial_loss(fake_validity, fake_labels)
discriminator_loss = (real_loss + fake_loss) / 2
discriminator_loss.backward()
discriminator_optimizer.step()
# Train the generator network
generator_optimizer.zero_grad()
z = torch.randn((batch_size, latent_dim)).to(device)
fake_imgs = gan.generator(z)
fake_validity = gan.discriminator(fake_imgs)
real_labels = torch.ones((batch_size, 1)).to(device)
generator_loss = adversarial_loss(fake_validity, real_labels)
generator_loss.backward()
generator_optimizer.step()
# Print the training progress
if i == len(dataloader)-1:
print(f"[Epoch {epoch}/{num_epochs}] [D loss: {discriminator_loss.item():.6f}] [G loss: {generator_loss.item():.6f}]")
In this example, we defined the generator and discriminator networks using PyTorch's nn.Module
class. The generator network takes a random noise vector z
as input and outputs an image. The discriminator network takes an image as input and outputs a probability indicating whether the image is real or fake.
We then defined the GAN model, which consists of the generator and discriminator networks. We also defined the loss functions and optimizers for the generator and discriminator networks.
During training, we first train the discriminator network on a batch of real images and a batch of fake images generated by the generator network. We then train the generator network by optimizing the adversarial loss between the fake images generated by the generator network and the real labels. This process is repeated for a number of epochs until the generator network is able to generate realistic images.
Leave a Comment