Preface
Generative Adversarial Networks (GANs) are a machine learning model used to generate new samples. It consists of two main components: Generator and Discriminator. The generator tries to generate new samples that are similar to the training data, while the discriminator tries to distinguish between the samples generated by the generator and the real training data.
Here is an introductory example of a simple adversarial generative network for generating images of handwritten digits:
Implementation process
1. Import necessary libraries and modules
import numpy as np
import matplotlib.pyplot as plt
from tensorflow.keras.datasets import mnist
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense, Flatten, Reshape
from tensorflow.keras.layers import Conv2D, Conv2DTranspose
from tensorflow.keras.optimizers import Adam
2. Load the MNIST data set
(x_train, _), (_, _) = mnist.load_data()
x_train = x_train / 255.0
x_train = np.expand_dims(x_train, axis=3)
3. Define the generator model
generator = Sequential()
generator.add(Dense(7*7*128, input_shape=(100,), activation='relu'))
generator.add(Reshape((7, 7, 128)))
generator.add(Conv2DTranspose(64, (3, 3), strides=(2, 2), padding='same', activation='relu'))
generator.add(Conv2DTranspose(1, (3, 3), strides=(2, 2), padding='same', activation='sigmoid'))
4. Define the discriminator model
discriminator = Sequential()
discriminator.add(Conv2D(64, (3, 3), strides=(2, 2), padding='same', input_shape=(28, 28, 1), activation='relu'))
discriminator.add(Conv2D(128, (3, 3), strides=(2, 2), padding='same', activation='relu'))
discriminator.add(Flatten())
discriminator.add(Dense(1, activation='sigmoid'))
5. Compile the discriminator model
discriminator.compile(loss='binary_crossentropy', optimizer=Adam(learning_rate=0.0002, beta_1=0.5), metrics=['accuracy'])
6. Freeze the weights of the discriminator model
discriminator.trainable = False
7. Define GAN model
gan = Sequential()
gan.add(generator)
gan.add(discriminator)
8. Compile GAN model
gan.compile(loss='binary_crossentropy', optimizer=Adam(learning_rate=0.0002, beta_1=0.5))
9. Define the training function
def train_gan(epochs, batch_size, sample_interval):
for epoch in range(epochs):
# 生成随机噪声作为输入
noise = np.random.normal(0, 1, (batch_size, 100))
# 生成假样本
generated_images = generator.predict(noise)
# 从真实样本中随机选择一批样本
real_images = x_train[np.random.randint(0, x_train.shape[0], batch_size)]
# 训练判别器
discriminator_loss_real = discriminator.train_on_batch(real_images, np.ones((batch_size, 1)))
discriminator_loss_fake = discriminator.train_on_batch(generated_images, np.zeros((batch_size, 1)))
discriminator_loss = 0.5 * np.add(discriminator_loss_real, discriminator_loss_fake)
# 训练生成器
noise = np.random.normal(0, 1, (batch_size, 100))
generator_loss = gan.train_on_batch(noise, np.ones((batch_size, 1)))
# 打印损失
if epoch % sample_interval == 0:
print(f"Epoch {epoch}/{epochs}, Discriminator Loss: {discriminator_loss[0]}, Generator Loss: {generator_loss}")
# 保存生成的图像
save_images(epoch)
10. Save the generated image
def save_images(epoch):
rows, cols = 5, 5
noise = np.random.normal(0, 1, (rows * cols, 100))
generated_images = generator.predict(noise)
generated_images = 0.5 * generated_images + 0.5
fig, axs = plt.subplots(rows, cols)
idx = 0
for i in range(rows):
for j in range(cols):
axs[i, j].imshow(generated_images[idx, :, :, 0], cmap='gray')
axs[i, j].axis('off')
idx += 1
fig.savefig(f"gan_images/mnist_{epoch}.png")
plt.close()
11. Training GAN model
epochs = 10000
batch_size = 128
sample_interval = 1000
Complete code
import numpy as np
import matplotlib.pyplot as plt
from tensorflow.keras.datasets import mnist
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import Dense, Flatten, Reshape
from tensorflow.keras.layers import Conv2D, Conv2DTranspose
from tensorflow.keras.optimizers import Adam
# 加载MNIST数据集
(x_train, _), (_, _) = mnist.load_data()
x_train = x_train / 255.0
x_train = np.expand_dims(x_train, axis=3)
# 定义生成器模型
generator = Sequential()
generator.add(Dense(7*7*128, input_shape=(100,), activation='relu'))
generator.add(Reshape((7, 7, 128)))
generator.add(Conv2DTranspose(64, (3, 3), strides=(2, 2), padding='same', activation='relu'))
generator.add(Conv2DTranspose(1, (3, 3), strides=(2, 2), padding='same', activation='sigmoid'))
# 定义判别器模型
discriminator = Sequential()
discriminator.add(Conv2D(64, (3, 3), strides=(2, 2), padding='same', input_shape=(28, 28, 1), activation='relu'))
discriminator.add(Conv2D(128, (3, 3), strides=(2, 2), padding='same', activation='relu'))
discriminator.add(Flatten())
discriminator.add(Dense(1, activation='sigmoid'))
# 编译判别器模型
discriminator.compile(loss='binary_crossentropy', optimizer=Adam(learning_rate=0.0002, beta_1=0.5), metrics=['accuracy'])
# 冻结判别器模型的权重
discriminator.trainable = False
# 定义GAN模型
gan = Sequential()
gan.add(generator)
gan.add(discriminator)
# 编译GAN模型
gan.compile(loss='binary_crossentropy', optimizer=Adam(learning_rate=0.0002, beta_1=0.5))
# 定义训练函数
def train_gan(epochs, batch_size, sample_interval):
for epoch in range(epochs):
# 生成随机噪声作为输入
noise = np.random.normal(0, 1, (batch_size, 100))
# 生成假样本
generated_images = generator.predict(noise)
# 从真实样本中随机选择一批样本
real_images = x_train[np.random.randint(0, x_train.shape[0], batch_size)]
# 训练判别器
discriminator_loss_real = discriminator.train_on_batch(real_images, np.ones((batch_size, 1)))
discriminator_loss_fake = discriminator.train_on_batch(generated_images, np.zeros((batch_size, 1)))
discriminator_loss = 0.5 * np.add(discriminator_loss_real, discriminator_loss_fake)
# 训练生成器
noise = np.random.normal(0, 1, (batch_size, 100))
generator_loss = gan.train_on_batch(noise, np.ones((batch_size, 1)))
# 打印损失
if epoch % sample_interval == 0:
print(f"Epoch {epoch}/{epochs}, Discriminator Loss: {discriminator_loss[0]}, Generator Loss: {generator_loss}")
# 保存生成的图像
save_images(epoch)
# 保存生成的图像
def save_images(epoch):
rows, cols = 5, 5
noise = np.random.normal(0, 1, (rows * cols, 100))
generated_images = generator.predict(noise)
generated_images = 0.5 * generated_images + 0.5
fig, axs = plt.subplots(rows, cols)
idx = 0
for i in range(rows):
for j in range(cols):
axs[i, j].imshow(generated_images[idx, :, :, 0], cmap='gray')
axs[i, j].axis('off')
idx += 1
fig.savefig(f"gan_images/mnist_{epoch}.png")
plt.close()
# 训练GAN模型
epochs = 10000
batch_size = 128
sample_interval = 1000
train_gan(epochs, batch_size, sample_interval)
This example uses the MNIST data set to generate images of handwritten digits. The generator and discriminator models use the structure of a convolutional neural network. During training, the generator attempts to generate realistic images of handwritten digits, while the discriminator attempts to differentiate between real and generated images. By repeatedly iteratively training the generator and discriminator, the GAN model can gradually generate more realistic images of handwritten digits. The generated images will be saved in the gan_images folder.