内容简介:在上一篇文章《生成对抗网络中,生成器和判别器是一对冤家。要提高生成器的水平,就要提高判别器的识别能力。在《答案是肯定的,不过和《
在上一篇文章《 实战生成对抗网络[2]:生成手写数字 》中,我们使用了简单的神经网络来生成手写数字,可以看出手写数字字形,但不够完美,生成的手写数字有些毛糙,边缘不够平滑。
生成对抗网络中,生成器和判别器是一对冤家。要提高生成器的水平,就要提高判别器的识别能力。在《 一步步提高手写数字的识别率(3) 》系列文章中,我们探讨了如何提高手写数字的识别率,发现卷积神经网络在图像处理方面优势巨大,最后采用卷积神经网络模型,达到一个不错的识别率。自然的,为了提高生成对抗网络的手写数字生成质量,我们是否也可以采用卷积神经网络呢?
答案是肯定的,不过和《 一步步提高手写数字的识别率(3) 》中随便采用一个卷积神经网络结构是不够的,因为生成对抗网络中,有两个神经网络模型互相对抗,随便选择网络结构,容易在迭代过程中引起振荡,难以收敛。
好在有专家学者进行了这方面的研究,下面就介绍一篇由Alec Radford、Luke Metz和Soumith Chintala合作完成的论文 arXiv: 1511.06434, 《利用深度卷积生成对抗网络进行无监督表征学习(Unsupervised Representation Learning with Deep Convolutional Generative Adversarial Networks)》。
论文给出了生成器的模型结构,如下图所示:
从图中可以看,该网络采用100x1噪声向量(随机输入),表示为z,并将其映射到G(Z)输出,即64x64x3,其变换过程为:
100x1 → 1024x4x4 → 512x8x8 → 256x16x16 → 128x32x32 → 64x64x3
如果采用keras实现上述模型,非常简单。不过需要注意的是,在本文中探讨的手写数字生成,其最终输出是28 x 28 x 1的灰度图片,所以我们沿袭上面的模型架构,但在具体实现上做一些调整:
100x1 → 1024x1 → 128x7x7 → 128x14x14 → 14x14x64 → 28x28x64 → 8x28x1
代码如下:
def generator_model(): model = Sequential() model.add(Dense(input_dim=100, output_dim=1024)) model.add(Activation('tanh')) model.add(Dense(128 * 7 * 7)) model.add(BatchNormalization()) model.add(Activation('tanh')) model.add(Reshape((7, 7, 128), input_shape=(128 * 7 * 7,))) model.add(UpSampling2D(size=(2, 2))) model.add(Conv2D(64, (5, 5), padding='same')) model.add(Activation('tanh')) model.add(UpSampling2D(size=(2, 2))) model.add(Conv2D(1, (5, 5), padding='same')) model.add(Activation('tanh')) return model
代码中引入了批量规则化(BatchNormalization),在实践中被证实可以在许多场合提升训练速度,减少初始化不佳带来的问题并且通常能产生准确的结果。上采样则是用来扩大维度。
判别器的实现差不多是将上述生成器模型倒过来实现,但使用最大池化代替了上采样,代码如下:
def discriminator_model(): model = Sequential() model.add( Conv2D(64, (5, 5), padding='same', input_shape=(28, 28, 1)) ) model.add(Activation('tanh')) model.add(MaxPooling2D(pool_size=(2, 2))) model.add(Conv2D(128, (5, 5))) model.add(Activation('tanh')) model.add(MaxPooling2D(pool_size=(2, 2))) model.add(Flatten()) model.add(Dense(1024)) model.add(Activation('tanh')) model.add(Dense(1)) model.add(Activation('sigmoid')) return model
在论文中,作者建议通过下面一些架构性的约束来固化网络:
-
在判别器中使用跨步卷积取代池化层,在生成器中使用反卷积取代池化层。
-
在生成器和判别器中使用批量规则化。
-
消除架构中较深的全连接层。
-
在生成器的输出层使用Tanh,在其他层均使用ReLU激活。
-
在判别器的所有层中都使用LeakyReLU激活。
上述代码并没有完全遵守作者的建议,可见在面对不同的场景,开发者可以有自己的发挥。事实上,在GANs in Action这本书中,作者也给出了手写数字生成的另外一种DCGAN模型,代码可参考:https://github.com/GANs-in-Action/gans-in-action/blob/master/chapter-3/Chapter_3_GAN.ipynb
经过100个epoch的迭代,我们的代码生成的手写数字如下图所示,虽然有些数字生成得不太准确,不过相对于上一篇文章的输出,边缘还是要平滑一些,效果也有所改进:
本文所演示内容的完整代码,请参考:https://github.com/mogoweb/aiexamples
以上所述就是小编给大家介绍的《实战生成对抗网络(三):DCGAN》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
猜你喜欢:- 实战生成对抗网络(二):生成手写数字
- 实战生成对抗网络[2]:生成手写数字
- Kernel Hack实战:修改并编译手机内核源码对抗反调试
- 对抗攻击之利用水印生成对抗样本
- 基于梯度扰动探索对抗攻击与对抗样本
- WriteUp - 2018中国网络安全技术对抗赛阿里安全攻防对抗赛
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
PERL學習手札.
簡信昌 / 上奇科技 / 20040816 / NT$ 390
1. 關於Perl 當你翻開這本書的時候,你也就進入了一個奇幻的世界。Perl確實是一種非常吸引人的程式語言,而之所以這麼引人入勝的原因不單單在於他的功能,也在於他寫作的方式,或說成為一種程式寫作的藝術。即使你只是每天埋首於程式寫作的程式設計師,也不再讓生活過份單調,至少你可以嘗試在程式碼中多一些變化。而且許多Perl的程式設計師已經這麼作了,這也是Perl的理念-「There is mor......一起来看看 《PERL學習手札.》 这本书的介绍吧!