GAN介绍
生成式对抗网络(GAN, Generative Adversarial Networks )是一种深度学习模型,是近年来复杂分布上无监督学习最具前景的方法之一。GAN网络中最少有两个模块,分别是生成模型和判别模型。而GAN就是让这两个模块相互对抗。举个简单的例子:小明是一个画家,专门画假画的那种,小白是个鉴别师,需要鉴别出假的画作。小明的目的就是能够画出小白无法鉴别出真假的画作,而小白就要保证能够检验出假货。最开始可能小明的技术拙劣,小白一下就看出来了,但是小明在一次又一次的绘画中不断的学习,到某个时间小白发现无法鉴别出画作的真伪,于是小白也跑去学习,那么在这个不断学习,不断鉴别的过程中,小白和小明最终都达到一个动态平衡的时刻,那么这时候,小明的画作已经不能被小白鉴别出来。这就是生成式对抗网络。
那么,我们通过构建一个生成式对抗网络来尝试生成一下mnist数据集叭~~
Generator
# 构建生成模型
def build_generator(self):
model = Sequential()
model.add(Dense(256, input_dim=self.latent_dim))
model.add(LeakyReLU(alpha=0.2))
model.add(BatchNormalization(momentum=0.8))
model.add(Dense(512))
model.add(LeakyReLU(alpha=0.2))
model.add(BatchNormalization(momentum=0.8))
model.add(Dense(1024))
model.add(LeakyReLU(alpha=0.2))
model.add(BatchNormalization(momentum=0.8))
model.add(Dense(np.prod(self.img_shape), activation='tanh'))
model.add(Reshape(self.img_shape))
model.summary()
noise = Input(shape=(self.latent_dim,))
img = model(noise)
return Model(noise, img)
可以看出,这里生成器模块通过一个简单的神经网络,将输入的100维的数据最后输出成28281的图片。首先我们用的是LeakyReLU
而不是RelU
,是因为ReLU在当输入值为负的时候,输出始终为0,其一阶导数也始终为0,这样会导致神经元不能更新参数,也就是神经元不学习了,这种现象叫做“Dead Neuron”。而为了尽量避免这种情况出现,我们使用了LeakyReLU,该函数输出对负值输入有很小的坡度。由于导数总是不为零,这能减少静默神经元的出现,允许基于梯度的学习(虽然会很慢),解决了Relu函数进入负区间后,导致神经元不学习的问题。
Adversarial
def build_discriminator(self):
model = Sequential()
model.add(Flatten(input_shape=self.img_shape))
model.add(Dense(512))
model.add(LeakyReLU(alpha=0.2))
model.add(Dense(256))
model.add(LeakyReLU(alpha=0.2))
model.add(Dense(1, activation='sigmoid'))
model.summary()
img = Input(shape=self.img_shape)
validity = model(img)
return Model(img, validity)
判别模型的目的是根据输入的图片判断出真伪。因此它的输入一个28281维的图片,输出是0到1之间的数,1代表判断这个图片是真的,0代表判断这个图片是假的。所以最后模型输出的是一个1维的数组。
训练思路
在每一轮迭代中,网络要做两件事
训练Generator,保持Adversarial不训练
首先生成一个100维的随机数,之后用Generator生成图片
然后把生成的假图片与真图片混合,真图片 label 为 1, 假图片 label 为 0
然后把组合的图片数据交