前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >生成对抗网络(GAN)的直观介绍

生成对抗网络(GAN)的直观介绍

作者头像
刀刀老高
发布2018-04-10 17:59:39
1.1K0
发布2018-04-10 17:59:39
举报
文章被收录于专栏:奇点大数据奇点大数据

原文来源:freeCodeCamp

作者:Thalles Silva

让我们假设这样一种情景:你的邻居正在举办一场非常酷的聚会,你非常想去参加。但有要参加聚会的话,你需要一张特价票,而这个票早就已经卖完了。

而对于这次聚会的组织者来说,为了让聚会能够成功举办,他们雇佣了一个合格的安全机构。主要目标就是不允许任何人破坏这次的聚会。为了做到这一点,他们在会场入口处安置了很多警卫,检查每个人所持门票的真实性。

考虑到你没有任何武术上的天赋,而你又特别想去参加聚会,那么唯一的办法就是用一张非常有说服力的假票来骗他们。

但是这个计划存在一个很大的bug——你从来没有真正看到过这张门票到底是什么样的。所以,在这种情况下,如果你仅是根据自己的创造力设计了一张门票,那么在第一次尝试期间就想要骗过警卫几乎是不可能的。除此之外,除非你有一个很好的关于此次聚会的门票的复印件,否则你最好不要把你的脸展露出来。

为了帮助解决问题,你决定打电话给你的朋友Bob为你做这个工作。

Bob的任务非常简单。他会试图用你的假通行证进入聚会。如果他被拒绝了,他将返回,然后告诉你一些有关真正的门票应该是什么样的建议。

基于这个反馈,你可以制作一张全新版本的门票,然后将其交给Bob,再去检票处尝试一下。这个过程不断重复,直到你能够设计一个完美的门票“复制品”。

对于上面这个小故事,抛开里面的假想成分,这几乎就是生成对抗网络(GAN)的工作方式。

目前,GAN的大部分应用都是在计算机视觉领域。其中一些应用包括训练半监督分类器,以及从低分辨率对应产生高分辨率图像。

本篇文章对GAN进行了一些介绍,并对图像生成问题进行了实际实践。你可以在你的笔记本电脑上进行演示。

生成对抗网络

生成敌对网络框架

GAN是由Goodfellow等人设计的生成模型。在GAN设置中,以神经网络为代表的两个可微函数被锁定在游戏中。这两个参与者(生成器和鉴别器)在这个框架中有不同的角色。

生成器试图生成来自某种概率分布的数据。即你想重新生成一张聚会的门票。

鉴别器就像一个法官。它可以决定输入是来自生成器还是来自真正的训练集。这就像是聚会中的安保设置,比将你的假票和这正的门票进行比较,以找到你的设计中存在的缺陷。

我们将一个4层卷积网络用于生成器和鉴别器,进行批量正则化。训练该模型以生成SVHN和MNIST图像。以上是训练期间SVHN(上)和MNIST(下)发生器样本。

总而言之,游戏如下:

生成器试图使鉴别器错误地将输入错误的概率最大化。

鉴别器引导生成器产生更逼真的图像。

在完美的平衡中,发电机将捕获一般的训练数据分布。结果,鉴别器总是不确定其输入是否真实。

摘自DCGAN论文。生成器网络在这里实现。注意:完全连接层和池化层的不存在

在DCGAN论文中,作者描述了一些深度学习技术的组合作为训练GAN的关键。这些技术包括:(i)全卷积网和(ii)批量标准化(BN)。

第一个重点是增加和减少特征的空间维度的叠加卷积(而不是汇集层)。第二个规格化特征向量在所有图层中具有零均值和单位方差。这有助于稳定学习和处理重量不佳的初始化问题。

不用多说,让我们深入实施细节,并在我们走的时候多谈谈GAN。我们提出了深度卷积生成对抗网络(DCGAN)的实现。我们的实现使用Tensorflow并遵循DCGAN论文中描述的一些实践。

生成器

该网络有4个卷积层,所有的BN(除了输出层)和校正线性单元(ReLU)激活。

它将随机向量z(从正态分布中抽取)作为输入。将z重塑为4D形状之后,将其馈送到启动一系列上采样层的发生器。

每个上采样层都代表一个跨步旋转运算。转置卷积与常规卷积类似。

一般来说,规则的卷积从宽层和浅层到更窄更深的层次。转移卷积走另一条路。他们从深而窄的层次走向更宽更浅。

转置卷积操作的步幅定义了输出层的大小。在“相同”的填充和步幅为2时,输出特征将具有输入层大小的两倍。

发生这种情况的原因是,每次我们移动输入层中的一个像素时,我们都会将输出层上的卷积内核移动两个像素。换句话说,输入图像中的每个像素都用于在输出图像中绘制一个正方形。

将跨3x3内核在2x2输入上进行卷积的步骤2相当于将3x3内核在步长2的5x5输入上进行卷积运算。对于二者,均不使用填充“有效”。

最后一层通过双曲正切(tanh)函数输出一个32x32x3的张量 - 压扁在-1和1之间。

这个最终的输出形状是由训练图像的大小来定义的。在这种情况下,如果SVHN训练,发生器产生32x32x3的图像。但是,如果对MNIST进行培训,则会生成28x28的灰度图像。

最后,请注意,在将输入向量z馈送到发生器之前,我们需要将其缩放到-1到1的区间。这是遵循使用tanh函数的选择。

鉴别器

鉴别器也是一个有BN的4层CNN(输入层除外)和泄露的ReLU激活。这个基本的GAN体系结构可以使许多激活功能正常工作。但是,泄漏的ReLU非常受欢迎,因为它们可以帮助渐变在架构中更容易地流动。

常规的ReLU函数通过将负值截断为0来工作。这具有阻止梯度流过网络的效果。泄漏的ReLU不是函数为零,而是允许一个小的负值通过。也就是说,函数计算出特征与小因素之间的最大值。

泄漏的ReLU代表了一个试图解决垂死的ReLU问题。这种情况发生在神经元处于ReLU单元总是输出0 的状态下。对于这些情况,梯度完全关闭以通过网络回流。

这对于GAN来说尤其重要,因为发生器必须学习的唯一方法是接收鉴别器的梯度。

(左)ReLU,(右)泄漏ReLU激活功能。请注意,当x为负值时,泄漏的ReLU允许有一个小的斜率。

鉴别器开始收到一个32x32x3图像张量。与发生器相反,鉴别器执行一系列跨步的2次卷积。每种方法通过将特征矢量的空间尺寸减小一半来工作,也使学习滤波器的数量加倍。

最后,鉴别器需要输出概率。为此,我们在最后的logits上使用Logistic Sigmoid激活函数。

请注意,在此框架中,鉴别器充当正则二进制分类器。一半时间从训练集接收图像,另一半从发生器接收图像。

回到我们的冒险之旅,重现派对的票价,唯一的信息来源是我们朋友Bob的反馈。换句话说,Bob在每次试用期间向您提供的反馈质量对于完成工作至关重要。

以同样的方式,每当鉴别器注意到真实图像和假图像之间的差异时,它就向发生器发送一个信号。该信号是从鉴别器向发生器反向流动的梯度。通过接收它,发生器能够调整其参数以接近真实的数据分布。

这就是鉴别器的重要性所在。实际上,生成器将要尽可能好地产生数据,因为鉴别器正在不断地缩小真实和虚假数据的差距。

损失

现在,让我们来描述这个架构中最棘手的部分 - 损失。首先,我们知道鉴别器从训练组和发生器接收图像。

我们希望鉴别器能够区分真实的和假的图像。每次我们通过鉴别器运行一个小批量的时候,我们都会得到logits。这些是来自模型的未缩放的值。

但是,我们可以将鉴别器接收的小批量分成两种类型。第一个是仅由来自训练集的真实图像组成,第二个仅由假发图像组成,即由生成器创建的图像。

代码语言:javascript
复制
def model_loss(input_real, input_z, output_dim, alpha=0.2, smooth=0.1):
    """
    Get the loss for the discriminator and generator
    :param input_real: Images from the real dataset
    :param input_z: random vector z
    :param out_channel_dim: The number of channels in the output image
    :param smooth: label smothing scalar
    :return: A tuple of (discriminator loss, generator loss)
    """
    g_model = generator(input_z, output_dim, alpha=alpha)
    d_model_real, d_logits_real = discriminator(input_real, alpha=alpha)
    d_model_fake, d_logits_fake = discriminator(g_model, reuse=True, alpha=alpha)
    # for the real images, we want them to be classified as positives,  
    # so we want their labels to be all ones.
    # notice here we use label smoothing for helping the discriminator to generalize better.
    # Label smoothing works by avoiding the classifier to make extreme predictions when extrapolating.
    d_loss_real = tf.reduce_mean(
        tf.nn.sigmoid_cross_entropy_with_logits(logits=d_logits_real, labels=tf.ones_like(d_logits_real) * (1 - smooth)))
    # for the fake images produced by the generator, we want the discriminator to clissify them as false images,
    # so we set their labels to be all zeros.
    d_loss_fake = tf.reduce_mean(
        tf.nn.sigmoid_cross_entropy_with_logits(logits=d_logits_fake, labels=tf.zeros_like(d_model_fake)))
    # since the generator wants the discriminator to output 1s for its images, it uses the discriminator logits for the
    # fake images and assign labels of 1s to them.
    g_loss = tf.reduce_mean(
        tf.nn.sigmoid_cross_entropy_with_logits(logits=d_logits_fake, labels=tf.ones_like(d_model_fake)))
    d_loss = d_loss_real + d_loss_fake
    return d_loss, g_loss

由于两个网络同时训练,GAN也需要两个优化器。每一个分别用于最小化鉴别器和发生器的损失函数。

我们希望鉴别器输出对于真实图像接近1的概率和对假图像接近0的概率。要做到这一点,鉴别器需要两个损失。因此,鉴别器的总损失是这两个部分损失的总和。一个用于最大化真实图像的概率,另一个用于最小化假图像的概率。

比较实际(左)和生成(右)的SVHN样本图像。虽然有些图像看起来模糊,有些图像很难辨认,但数据分布是由模型捕捉的。

在训练开始时,会出现两个有趣的情况。首先,生成器不知道如何创建类似于训练集中的图像。其次,鉴别器不知道如何将其接收的图像分类为真实的或假的。

结果,鉴别器接收两种非常不同类型的批次。一个由训练集的真实图像组成,另一个包含非常嘈杂的信号。随着训练的进行,发生器开始输出更接近训练集图像的图像。发生这种情况是因为生成器训练学习组成训练集图像的数据分布。

与此同时,鉴别器开始真正把样品分类为真假。结果,这两种小批量开始在结构上彼此相似。因此,鉴别器无法将图像识别为真实或假的。

对于亏损,我们使用亚当的香草交叉熵作为优化者的不错选择。

比较实际(左)和生成(右)的MNIST样本图像。因为MNIST图像具有更简单的数据结构,所以与SVHN相比,该模型能够产生更逼真的样本。

结论

GAN是目前机器学习中最热门的课程之一。这些模型有可能解开无监督的学习方法,将ML扩展到新的视野。

自创建以来,研究人员已经开发出许多用于培训GAN的技术。在用于训练GAN的改进技术中,作者描述了用于图像生成和半监督学习的最新技术。


本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2018-01-17,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 奇点 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 鉴别器
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档