訓練生成對抗網路 (GAN)



我們探討了生成對抗網路的架構及其工作原理。在本章中,我們將透過一個實際示例演示如何實現和訓練一個 GAN 來生成手寫數字,與 MNIST 資料集中的數字相同。我們將使用 Python 以及 TensorFlow 和 Keras 來實現此示例。

訓練生成對抗網路的過程

GAN 的訓練涉及迭代地最佳化生成器模型和判別器模型。讓我們使用以下步驟瞭解生成對抗網路 (GAN) 的訓練過程

初始化

  • 該過程從兩個神經網路開始:生成器網路 (G) 和判別器網路 (D)。
  • 生成器接收一個隨機種子或噪聲向量作為輸入,並生成生成的樣本。
  • 判別器接收真實資料樣本或生成樣本作為輸入,並將它們分類為真實或虛假。

生成虛假資料

  • 隨機噪聲向量被饋送到生成器網路。
  • 生成器處理此噪聲並輸出生成的樣本,這些樣本旨在類似於真實資料。

生成器訓練

  • 首先,它從輸入隨機噪聲生成虛假資料。
  • 然後,它使用判別器的輸出計算生成器的損失。
  • 最後,它更新生成器的權重以最小化損失。

判別器訓練

  • 首先,它獲取一批真實資料和一批虛假資料。
  • 然後,它計算真實資料和虛假資料的判別器損失。
  • 最後,它更新判別器的權重以最小化損失。

迭代訓練

  • 重複步驟 2 到 4。在每次迭代中,生成器和判別器都會交替訓練,並試圖提高彼此的效能。
  • 這種交替最佳化將持續進行,直到生成器生成的資料與真實資料相同,並且判別器無法再可靠地區分真實資料和虛假資料。

訓練和構建 GAN

在這裡,我們將展示使用 Python 和 MNIST 資料集訓練和構建 GAN 的分步過程 -

步驟 1:設定環境

在開始之前,我們需要使用必要的庫設定 Python 環境。確保您的計算機上安裝了 TensorFlow 和 Keras。您可以使用 pip 如下安裝它們 -

pip install tensorflow

步驟 2:匯入必要的庫

我們需要匯入必要的庫 -

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

步驟 3:載入和預處理 MNIST 資料集

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

步驟 4:建立生成器和判別器模型

生成器從隨機噪聲建立虛假影像,而判別器試圖區分真實影像和虛假影像。

生成器模型的實現

生成器模型接收一個隨機噪聲向量作為輸入,並將其透過一系列層進行轉換以生成虛假影像 -

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()

步驟 5:定義損失函式和最佳化器

在此步驟中,我們將對生成器和判別器都使用二元交叉熵損失。生成器的目標是最大化判別器出錯的機率,而判別器的目標是最小化其分類錯誤。

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)

步驟 6:定義訓練迴圈

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')

步驟 7:準備資料集並訓練 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)

步驟 8:生成和顯示影像

現在,在訓練 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

結論

使用 Python 訓練 GAN 涉及幾個關鍵步驟,例如設定環境、建立生成器和判別器模型、定義損失函式和最佳化器以及實現訓練迴圈。透過遵循這些步驟,您可以訓練自己的 GAN 並探索生成對抗網路的迷人世界。

在本章中,我們提供了使用 Python 程式語言構建和訓練 GAN 的詳細指南。我們在示例中使用了 TensorFlow 和 Keras 庫以及 MNIST 資料集。

廣告

© . All rights reserved.