Gen-ai 简明教程

Training a Generative Adversarial Network (GANs)

我们探索了生成对抗网络的结构及其工作原理。在本章中,我们将选取一个实际示例来说明如何实现和训练 GAN 生成手写数字,这些数字与 MNIST 数据集中的一样。我们将在此示例中使用 Python 以及 TensorFlow 和 Keras。

Process of Training a Generative Adversarial Network

GAN 的培训涉及迭代优化生成器模型和判别器模型。让我们通过以下步骤了解生成对抗网络 (GAN) 的训练流程:

Initialization

  1. 该流程从两个神经网络开始:生成器网络 (G) 和判别器网络 (D)。

  2. 生成器采用随机种子或噪声向量作为输入并生成生成的样本。

  3. 判别器采用真实数据样本或生成的样本作为输入并将其分类为真或假。

Generating Fake Data

  1. 将随机噪声向量送入生成器网络。

  2. 生成器处理此噪声并输出旨在类似真实数据的生成数据样本。

Generator Training

  1. 首先,它根据输入随机噪声生成虚假数据。

  2. 然后,它使用判别器的输出计算生成器的损失。

  3. 最后,它更新生成器的权重以最小化损失。

Discriminator Training

  1. 首先,它采用一批真实数据和一批虚假数据。

  2. 然后,它计算真实和虚假数据的判别器损失。

  3. 最后,它更新判别器的权重以最小化损失。

Iterative Training

  1. 重复步骤 2 到 4。在每次迭代中,生成器和判别器交替进行训练,并尝试提高彼此的性能。

  2. 交替优化持续到生成器生成与真实数据相同的数据,而判别器不再能够可靠地区分真实和伪造数据。

Training and Building a GAN

在这里,我们将展示使用 Python 和 MNIST 数据集训练和构建 GAN 的逐步过程 -

Step 1: Setting Up the Environment

在开始之前,我们需要使用必要的库来设置 Python 环境。确保您的计算机上已安装 TensorFlow 和 Keras。您可以使用 pip 如下安装它们 -

pip install tensorflow

Step 2: Import Necessary Libraries

我们需要导入必要的库 -

import numpy as np
import tensorflow as tf
from tensorflow.keras import layers, models
from tensorflow.keras.datasets import mnist
import matplotlib.pyplot as plt

Step 3: Load and Preprocess the MNIST Dataset

MNIST 数据集包含 60,000 张手写数字训练图像和 10,000 张测试图像,每张图像大小为 28x28 像素。我们将像素值归一化到范围 [-1, 1] 以提高训练效率 -

# Load the dataset
(x_train, _), (_, _) = mnist.load_data()

# Normalize the images to [-1, 1]
x_train = (x_train - 127.5) / 127.5
x_train = np.expand_dims(x_train, axis=-1)

# Set batch size and buffer size
BUFFER_SIZE = 60000
BATCH_SIZE = 256

Step 4: Create the Generator and Discriminator Models

生成器从随机噪声创建伪造图像,判别器尝试区分真实和伪造图像。

生成器模型将随机噪声向量作为输入,并通过一系列层对其进行转换,生成伪造图像 -

def build_generator():
   model = models.Sequential()
   model.add(layers.Dense(256, use_bias=False, input_shape=(100,)))
   model.add(layers.BatchNormalization())
   model.add(layers.LeakyReLU())

   model.add(layers.Dense(512, use_bias=False))
   model.add(layers.BatchNormalization())
   model.add(layers.LeakyReLU())

   model.add(layers.Dense(28 * 28 * 1, use_bias=False, activation='tanh'))
   model.add(layers.Reshape((28, 28, 1)))

   return model

generator = build_generator()

判别器模型将图像作为输入(真实或生成的),并输出一个概率值,表示图像真实还是伪造 -

def build_discriminator():
   model = models.Sequential()
   model.add(layers.Flatten(input_shape=(28, 28, 1)))
   model.add(layers.Dense(512))
   model.add(layers.LeakyReLU())
   model.add(layers.Dropout(0.3))

   model.add(layers.Dense(256))
   model.add(layers.LeakyReLU())
   model.add(layers.Dropout(0.3))

   model.add(layers.Dense(1, activation='sigmoid'))

   return model

discriminator = build_discriminator()

Step 5: Define Loss Functions and Optimizers

在此步骤中,我们将对生成器和判别器都使用二元交叉熵损失。生成器的目的是最大化判别器犯错的概率,而判别器的目的是最小化其分类错误。

cross_entropy = tf.keras.losses.BinaryCrossentropy(from_logits=True)

def generator_loss(fake_output):
   return cross_entropy(tf.ones_like(fake_output), fake_output)

def discriminator_loss(real_output, fake_output):
   real_loss = cross_entropy(tf.ones_like(real_output), real_output)
   fake_loss = cross_entropy(tf.zeros_like(fake_output), fake_output)
   total_loss = real_loss + fake_loss
   return total_loss

generator_optimizer = tf.keras.optimizers.Adam(1e-4)
discriminator_optimizer = tf.keras.optimizers.Adam(1e-4)

Step 6: Define the Training Loop

GAN 的训练过程涉及迭代训练生成器和判别器。在这里,我们将定义一个训练步骤,包括生成伪造图像、计算损失以及使用反向传播更新模型权重。

@tf.function
def train_step(images):
   noise = tf.random.normal([BATCH_SIZE, 100])

   with tf.GradientTape() as gen_tape, tf.GradientTape() as disc_tape:
      generated_images = generator(noise, training=True)

      real_output = discriminator(images, training=True)
      fake_output = discriminator(generated_images, training=True)

      gen_loss = generator_loss(fake_output)
      disc_loss = discriminator_loss(real_output, fake_output)

   gradients_of_generator = gen_tape.gradient(gen_loss, generator.trainable_variables)
   gradients_of_discriminator = disc_tape.gradient(disc_loss, discriminator.trainable_variables)

   generator_optimizer.apply_gradients(zip(gradients_of_generator, generator.trainable_variables))
   discriminator_optimizer.apply_gradients(zip(gradients_of_discriminator, discriminator.trainable_variables))

def train(dataset, epochs):
   for epoch in range(epochs):
      for image_batch in dataset:
         train_step(image_batch)
      print(f'Epoch {epoch+1} completed')

Step 7: Prepare the Dataset and Train the GAN

接下来,我们将通过对 MNIST 图像进行洗牌和批处理来准备数据集,然后开始训练过程。

# Prepare the dataset for training
train_dataset = tf.data.Dataset.from_tensor_slices(x_train).shuffle(BUFFER_SIZE).batch(BATCH_SIZE)

# Train the GAN
EPOCHS = 50
train(train_dataset, EPOCHS)

Step 8: Generate and Display Images

现在,在训练 GAN 之后,我们可以生成并显示生成器创建的新图像。它包括创建随机噪声、将它输入生成器,并显示生成图像。

def generate_and_save_images(model, epoch, test_input):
   predictions = model(test_input, training=False)

   fig = plt.figure(figsize=(7.50, 3.50))

   for i in range(predictions.shape[0]):
      plt.subplot(4, 4, i + 1)
      plt.imshow(predictions[i, :, :, 0] * 127.5 + 127.5, cmap='gray')
      plt.axis('off')

   plt.savefig('image_at_epoch_{:04d}.png'.format(epoch))
   plt.show()

seed = tf.random.normal([16, 100])
generate_and_save_images(generator, EPOCHS, seed)

实现后,运行此代码时,您将获得以下输出 -

training and building a gan

Conclusion

使用 Python 训练 GAN 涉及几个关键步骤,例如设置环境、创建生成器和判别器模型、定义损失函数和优化器以及实现训练循环。通过遵循这些步骤,您可以训练自己的 GAN,并探索生成对抗网络的迷人世界。

在本章中,我们提供了使用 Python 编程语言构建和训练 GAN 的详细指南。在我们的示例中,我们使用了 TensorFlow 和 Keras 库以及 MNIST 数据集。