Generative Adversarial Networks (GANs, 生成对抗网络) 是一种由两个网络构成的通过对抗学习训练的生成模型，由 Ian Goodfellow 等人（包括 Yoshua Bengio）在 2014 年提出，并得到了 Yann LeCun 的盛赞 ，称其为『机器学习界10年来最有趣的点子』。

生成算法 vs. 分类算法

GAN 作为一种生成算法，其目标是能够『模仿』给定数据集中的数据，生成新的符合数据集特征的数据。

GAN 的结构

GAN 是由两个神经网络，即生成器（Generator）和鉴别器（Discriminator）构成的。

# Disctiminator
D = Sequential([
Flatten(input_shape=img_shape, name='flatten'),
Dense(512, activation='relu', name='fully_connected1'),
Dense(256, activation='relu', name='fully_connected2'),
Dense(1, activation='sigmoid', name='classifier')
])

# Generator
G = Sequential([
Dense(256, activation='relu', input_dim=latent_dim, name='fully_connected1'),
Dense(512, activation='relu', name='fully_connected2'),
Dense(1024, activation='relu', name='fully_connected3'),
Dense(np.prod(img_shape), activation='tanh', name='output_generated'),
Reshape(img_shape)
])

对抗训练

GAN 训练的过程如下：

# 编译D
D.compile(loss='binary_crossentropy', optimizer=d_optimizer, metrics=['accuracy'])
# 将D和G"串联"，得到模型C
z = Input(shape=(latent_dim,))
generated_img = G(z)
D.trainable = False       # 模型C中D的参数锁定
validity = D(generated_img)
# Combined model
C = Model(z, validity)
C.compile(loss='binary_crossentropy', optimizer=g_optimizer)
C.summary()

# load data
(x_train, _), (_, _) = mnist.load_data()
x_train = x_train / 127.5 - 1
# (60000, 28, 28) -> (60000, 28, 28, 1)
x_train = np.expand_dims(x_train, axis=3)
valid = np.ones((batch_size, 1))
fake = np.zeros((batch_size, 1))
for epoch in range(epochs):
for _ in range(x_train.shape[0] // batch_size):
# train D
idx = np.random.randint(low=0, high=x_train.shape[0], size=batch_size)
imgs = x_train[idx]
noise = np.random.normal(0, 1, (batch_size, latent_dim))
gen_imgs = G.predict(noise)
D.train_on_batch(imgs, valid)
D.train_on_batch(gen_imgs, fake)
# train G
noise = np.random.normal(0, 1, (batch_size, latent_dim))
C.train_on_batch(noise, valid)