DCGAN 训练+代码总结

自从两年前蒙特利尔大学的Ian Goodfellow等人提出生成式对抗网络(Generative Adversarial Networks,GAN)的概念以来,GAN呈现出井喷式发展。

这篇发布在O’Reilly上的文章中,作者向初学者进行了GAN基础知识答疑,并手把手教给大家如何用GAN创建可以生成手写数字的程序。

本教程由两人完成:Jon Bruner是O’Reilly编辑组的一员,负责管理硬件、互联网、制造和电子学等方面的出版物;Adit Deshpande是加州大学洛杉矶分校计算机科学专业的大二学生。

判别网络


判别器就是一个典型的CNN,它能将二维或三维的像素值矩阵(matrix of pixel values)转化成一个概率。然而作为一个生成器,需要d-维度向量 d-dimensional vector ,并需要将其变为28*28的图像。ReLU和批量标准化(batch normalization)也经常用于稳定每一层的输出。

判别器的结构与TensorFlow的样例CNN分类模型密切相关。它有两层特征为5×5像素特征的卷积层,还有两个全连接层按图像中每个像素计算增加权重的层。

创建了神经网络后,通常需要将权重和偏差初始化,这项任务可以在tf.get_variable中完成。权重在截断正态分布中被初始化,偏差在0处被初始化。

tf.nn.conv2d()是TensorFlow中的标准卷积函数,它包含四个参数:首个参数就是输入图像(input volume),也就是本示例中的28×28像素的图片;第二个参数是滤波器/权矩阵,最终你也可以改变卷积的“步幅”和“填充”。这两个参数控制着输出图像的尺寸大小。

其实上面这些就是一个普通简单的二进制分类器,如果你不是初次接触CNN,应该对此并不陌生。


定义了判别器之后,我们需要回头看看生成模型。我们将以Tim O’Shea编写的简单生成器代码为基础构建模型的整体结构。


其实你可以把生成器想象成反向卷积神经网络的一种。判别器就是一个典型的CNN,它能将二维或三维的像素值矩阵(matrix of pixel values)转化成一个概率。然而作为一个生成器,需要d-维度向量 d-dimensional vector ,并需要将其变为28*28的图像。ReLU和批量标准化(batch normalization)也经常用于稳定每一层的输出。

在这个神经网络中,我们用了三个卷积层和插值,直到形成28*28像素的图像。

我们在输出层添加了一个tf.sigmoid() 激活函数,它将挤压灰色呈现白色或黑色相,从而产生一个更清晰的图像。

看起来像噪音对吧。现在我们需要训练生成网络中的权重和偏差,将随机数转变为可识别的数字。我们再看看损失函数和优化。

训练GAN

构建和调试GAN就复杂在它有两个损失函数:一个鼓励生成器创造出更好的图像,另一个鼓励判别器区分哪个是真图像,哪个是生成器生成的。

我们同时训练生成器和判别器,当判别器能够很好区分图像来自哪里时,生成器也能更好地调整它的权重和偏差来生成更以假乱真的图像。

所以,让我们首先考虑一下我们需要在网络中得到什么。判别器的目标是正确地将MNIST图像标记为真,而判别器生成的标记为假。我们将计算判别器的两种损失:Dx和1(代表MNIST中的真实图像)的损失,以及Dg与0(代表生成图像)的损失。我们将这个函数在TensorFlow中的tf.nn.sigmoid_cross_entropy_with_logits()函数上运行,计算Dx和0与Dg和1之间的交叉熵损失。

下一步,你需要制定两个优化器,我们一般选择Adam优化算法,它利用了自适应学习速率和动量。我们调用Adam最小函数并且指定我们想更新的变量——也就是我们训练生成器时的生成器权重和偏差,和我们训练判别器时的判别器权重和偏差。

我们为判别器设置了两套不同的训练方案:一种是用真实图像训练判别器,另一种是用生成的“假图像”训练它。有时使用不同的学习速率很有必要,或者单独使用它们来规范学习的其他方面。

收敛GAN是一件棘手的事情,经常需要训练很长时间。可以用TensorBoard追踪训练过程:它可以用图表描绘标量属性(如损失),展示训练中的样本图像,并展示神经网络中的拓扑结构。

现在先给判别器几个简单的原始训练进行迭代,这种方法有助于形成对生成器有用的梯度。

之后我们继续进行主要的训练循环。当训练生成器的时候,我们需要将随机的z向量输入到生成器中,并将其输出传递给判别器(这就是我们早先定义的Dg变量)。生成器的权重和偏差将被改变,主要是为了生成能骗过判别器的图像。

为了训练判别器,我们将给它提供一组来自MNIST数据集中的正面例子,并且再次用生成的图像训练判别器,用它们作为反面例子。

因为训练GAN通常需要很长时间,所以我们建议如果您是第一次使用这个教程,建议先不要运行这个代码块。但你可以先执行下面的代码块,让它生成出一个预先训练模型。

如果你想自己运行这个代码块,请做好长时间等待的准备:在速度相对较快的GPU上运行大概需要3小时,在台式机的CPU上可能耗费10倍时间。

所以,建议你跳过上面直接执行下面的cell。它加载了一个我们在高速GPU机器上训练了10小时的模型,你可以试验下训练过的GAN。

训练不易

众所周知训练GAN很艰难。在没有正确的超参数、网络体系结构和培训流程的情况下,判别器会压制生成器。

一个常见的故障模式是,判别器压制了生成器,肯定地把生成图像定义为假的。当判别器以绝对肯定时,会使生成器无梯度可降。这就是为什么我们建立判别器来产生未缩放的输出,而不是通过一个sigmoid函数将其输出推到0或1。

在另一种常见的故障模式(模式崩溃)中,生成器发现并利用了判别器中的一些弱点,如果它不顾生成器输入z.变量,生成了很多相似图像,你是可以识别出这种模式崩溃的。模式崩溃有时可以通过“强化”鉴别器来修正,例如通过调整其训练速率或重新配置它的层。

先看main.py:

with tf.Session(config=run_config) as sess:
  if FLAGS.dataset == 'mnist':
    dcgan = DCGAN(
        sess,
        input_width=FLAGS.input_width,
        input_height=FLAGS.inp
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值