Python实操案例:使用温度为0.6的GAN生成手写数字图像
1. 简介
生成对抗网络(GAN)是一种强大的深度学习模型,能够生成逼真的图像。在本案例中,我们将使用GAN生成手写数字图像。通过调整温度参数,我们可以控制生成图像的多样性。
2. 数据集
我们将使用MNIST数据集,其中包含了大量的手写数字图像。每个图像都是28x28像素的灰度图像,像素的值范围从0到255。我们将使用TensorFlow库加载并预处理数据集。
2.1 数据预处理
首先,我们将导入所需的库并加载MNIST数据集:
import tensorflow as tf
from tensorflow import keras
(train_images, train_labels), (_, _) = keras.datasets.mnist.load_data()
图像像素值的范围是0到255,我们将归一化这些值到-1到1之间:
train_images = (train_images - 127.5) / 127.5
2.2 GAN模型架构
我们使用的GAN模型由两部分组成: 生成器(Generator)和判别器(Discriminator)。
生成器接收一个随机向量作为输入,并输出一个28x28的图像。判别器接收一张图像作为输入,并输出一个0到1之间的概率,表示图像是真实的还是生成的。两个模型将相互竞争,使得生成器越来越能够生成逼真的图像。
def make_generator_model():
model = keras.Sequential([
keras.layers.Dense(7*7*256, use_bias=False, input_shape=(100,)),
keras.layers.BatchNormalization(),
keras.layers.LeakyReLU(),
keras.layers.Reshape((7, 7, 256)),
keras.layers.Conv2DTranspose(128, (5, 5), strides=(1, 1), padding='same', use_bias=False),
keras.layers.BatchNormalization(),
keras.layers.LeakyReLU(),
keras.layers.Conv2DTranspose(64, (5, 5), strides=(2, 2), padding='same', use_bias=False),
keras.layers.BatchNormalization(),
keras.layers.LeakyReLU(),
keras.layers.Conv2DTranspose(1, (5, 5), strides=(2, 2), padding='same', use_bias=False, activation='tanh')
])
return model
def make_discriminator_model():
model = keras.Sequential([
keras.layers.Conv2D(64, (5, 5), strides=(2, 2), padding='same', input_shape=[28, 28, 1]),
keras.layers.LeakyReLU(),
keras.layers.Dropout(0.3),
keras.layers.Conv2D(128, (5, 5), strides=(2, 2), padding='same'),
keras.layers.LeakyReLU(),
keras.layers.Dropout(0.3),
keras.layers.Flatten(),
keras.layers.Dense(1)
])
return model
3. 训练GAN模型
3.1 定义损失函数和优化器
我们将使用二元交叉熵作为损失函数:
cross_entropy = 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 = keras.optimizers.Adam(0.0002, beta_1=0.5)
discriminator_optimizer = keras.optimizers.Adam(0.0002, beta_1=0.5)
3.2 定义训练函数
我们将定义一个训练函数,该函数将在每个训练步骤中更新生成器和判别器的参数:
@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_model(noise, training=True)
real_output = discriminator_model(images, training=True)
fake_output = discriminator_model(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_model.trainable_variables)
gradients_of_discriminator = disc_tape.gradient(disc_loss, discriminator_model.trainable_variables)
generator_optimizer.apply_gradients(zip(gradients_of_generator, generator_model.trainable_variables))
discriminator_optimizer.apply_gradients(zip(gradients_of_discriminator, discriminator_model.trainable_variables))
3.3 开始训练
在进行训练之前,我们需要创建一个生成器和一个判别器实例:
generator_model = make_generator_model()
discriminator_model = make_discriminator_model()
然后,我们可以开始训练GAN模型:
EPOCHS = 100
BATCH_SIZE = 256
for epoch in range(EPOCHS):
for i in range(len(train_images) // BATCH_SIZE):
images = train_images[i * BATCH_SIZE : (i + 1) * BATCH_SIZE]
train_step(images)
4. 生成手写数字图像
训练完成后,我们可以使用训练好的生成器生成新的手写数字图像:
num_examples_to_generate = 16
noise = tf.random.normal([num_examples_to_generate, 100])
generated_images = generator_model(noise, training=False)
generated_images = 0.5 * generated_images + 0.5
fig = plt.figure(figsize=(4, 4))
for i in range(generated_images.shape[0]):
plt.subplot(4, 4, i+1)
plt.imshow(generated_images[i, :, :, 0], cmap='gray')
plt.axis('off')
plt.show()
5. 结论
通过本实操案例,我们了解了如何使用GAN生成手写数字图像。通过调整温度参数,我们可以控制生成图像的多样性。
GAN是一个非常强大的模型,可以应用于各种图像生成任务。通过深入研究和实践,我们可以进一步探索和提升GAN的能力。