如何使用TensorFlow创建生成式对抗网络GAN
更新时间:2023-07-23
前言
生成式对抗网络(Generative Adversarial Networks,GAN)是一种用于生成新颖数据的深度学习模型。GAN由两个互相对抗的网络组成:生成器(Generator)和判别器(Discriminator)。生成器负责生成与真实数据相似的新样本,而判别器则负责判断输入的样本是真实的还是由生成器生成的。通过不断的对抗训练,生成器逐渐提高生成样本的质量,而判别器逐渐提高对生成样本的鉴别能力。
步骤一:导入依赖库
首先,我们需要导入TensorFlow库和一些其他必要的库来帮助我们创建和训练GAN模型。
```python
import tensorflow as tf
from tensorflow.keras import layers
import numpy as np
import matplotlib.pyplot as plt
```
步骤二:定义生成器和判别器
接下来,我们需要定义生成器和判别器的架构。生成器是一个负责生成样本的神经网络,判别器是一个判断输入样本真实性的神经网络。
```python
# 定义生成器
def make_generator_model():
model = tf.keras.Sequential()
model.add(layers.Dense(7*7*256, use_bias=False, input_shape=(100,)))
model.add(layers.BatchNormalization())
model.add(layers.LeakyReLU())
model.add(layers.Reshape((7, 7, 256)))
assert model.output_shape == (None, 7, 7, 256)
model.add(layers.Conv2DTranspose(128, (5, 5), strides=(1, 1), padding='same', use_bias=False))
assert model.output_shape == (None, 7, 7, 128)
model.add(layers.BatchNormalization())
model.add(layers.LeakyReLU())
model.add(layers.Conv2DTranspose(64, (5, 5), strides=(2, 2), padding='same', use_bias=False))
assert model.output_shape == (None, 14, 14, 64)
model.add(layers.BatchNormalization())
model.add(layers.LeakyReLU())
model.add(layers.Conv2DTranspose(1, (5, 5), strides=(2, 2), padding='same', use_bias=False, activation='tanh'))
assert model.output_shape == (None, 28, 28, 1)
return model
# 定义判别器
def make_discriminator_model():
model = tf.keras.Sequential()
model.add(layers.Conv2D(64, (5, 5), strides=(2, 2), padding='same',
input_shape=[28, 28, 1]))
model.add(layers.LeakyReLU())
model.add(layers.Dropout(0.3))
model.add(layers.Conv2D(128, (5, 5), strides=(2, 2), padding='same'))
model.add(layers.LeakyReLU())
model.add(layers.Dropout(0.3))
model.add(layers.Flatten())
model.add(layers.Dense(1))
return model
```
步骤三:定义损失函数和优化器
在GAN模型中,生成器和判别器的目标是相互对抗的。因此,我们需要为每个网络定义自己的损失函数和优化器。生成器的目标是欺骗判别器,而判别器的目标是尽可能准确地区分真实样本和生成样本。
```python
cross_entropy = tf.keras.losses.BinaryCrossentropy(from_logits=True)
# 判别器损失
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
# 生成器损失
def generator_loss(fake_output):
return cross_entropy(tf.ones_like(fake_output), fake_output)
# 定义优化器
generator_optimizer = tf.keras.optimizers.Adam(1e-4)
discriminator_optimizer = tf.keras.optimizers.Adam(1e-4)
```
步骤四:训练GAN模型
接下来,我们将使用前面定义的生成器、判别器、损失函数和优化器来训练GAN模型。训练过程中,首先生成器接收一个随机噪声作为输入,生成一个样本。然后,判别器接收真实样本和生成器生成的样本,判断它们的真实性。根据判别器的输出,计算生成器和判别器的损失,并根据损失来更新两个网络的参数。
```python
EPOCHS = 50
noise_dim = 100
num_examples_to_generate = 16
# 定义生成器生成样本的函数
def generate_and_save_images(model, epoch, test_input):
predictions = model(test_input, training=False)
fig = plt.figure(figsize=(4, 4))
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()
# 定义训练步骤
@tf.function
def train_step(images):
noise = tf.random.normal([BATCH_SIZE, noise_dim])
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)
if epoch % 10 == 0:
generate_and_save_images(generator, epoch + 1, test_input)
print('Epoch {} completed.'.format(epoch + 1))
generate_and_save_images(generator, epochs, test_input)
```
总结
通过以上步骤,我们可以使用TensorFlow创建并训练生成式对抗网络(GAN)。首先,我们定义了生成器和判别器的架构;然后,我们定义了损失函数和优化器;最后,我们训练了GAN模型。训练过程中,生成器逐渐提高生成样本的质量,判别器逐渐提高对生成样本的鉴别能力。GAN模型可以用于生成各种类型的数据,如图像、音频等,具有广泛的应用前景。