GANs:生成对抗网络系列及应用

GANs

Goodfellow和Bengio等人发表在NIPS 2014年的文章Generative Adversarial Network是生成对抗网络的开创文章,论文思想启发自博弈论中的二人零和博弈。在二人零和博弈中,两位博弈放的利益之和为零或一个常数,即一方有所得,另一方必有所失。GAN模型中的两位博弈方分别由生成式模型(Generative model)和判别式模型(discriminative model)充当。生成模型G捕捉样本数据的分布,判别模型D是一个二分类器,估计一个样本来自于训练数据(而非生成数据)的概率。G和D一般都是非线性映射函数,例如多层感知机、卷积神经网络等。

GAN的三大指标:

  • 训练“稳定性”
  • 样本的“多样性”
  • “清晰度”

GAN:生成对抗网络(2014)

[paper]Generative Adversarial Networks(2014)
在这里插入图片描述
GAN包括两个模型:一个是生成模型G(Generator),一个是判别模型D(Discriminator)。

  • G负责生成图片,它接收一个随机的噪声z,通过该噪声生成图片,将生成的图片记为G(z)。
  • D负责判别一张图片是不是“真实的”。它的输入是x,x代表一张图片,输出D(x)表示x为真实图片的概率,如果为1,代表是真实图片的概率为100%,而输出为0,代表不可能是真实的图片(真实实例来源与数据集,伪造实例来源与生成模型)

在训练过程中,生成模型G的目标是尽量生成看起来真的和原始数据相似的图片取欺骗判别器D。而判别模型D的目标是近邻把生成模型G生成的图片和真实的图片区分开来。这样,生成器试图欺骗判别器,判别器则努力不被生成器欺骗。两个模型经过交替优化训练,互相提升,G和D构成了一个动态的“博弈”,这是GAN的基本思想。

GAN是让判别器D和生成器G之间进行一种零和博弈,一方面,生成器G要以生成假样本为目的(loss评估),欺骗判别器D误认为是真实样本。
在这里插入图片描述
另一方面,判别器D要以区分真实样本x和假样本G(z)为最终目的(loss评估):
在这里插入图片描述

最后博弈的结果,在理想的状态下,G可以生成足以“以假乱真”的图片G(z)。对于D来说,它难以判定生成的图片究竟是不是真实的,因此D(G(z))=0.5。此时得到了一个生成式的模型G,它可以用来生成图片。

GAN的优势:

  • 根据实际的结果,看上去产生了更好的样本;
  • GAN能训练任何一种生成器网络;
  • GAN不需要设计遵循任何种类的因式分解的模型,任何生成器网络和任何鉴别器都会有用;
  • GAN无需利用马尔科夫链反复采样,无需在学习过程中进行推断,回避了近似计算棘手的概率的难题。

GAN的缺点:

  • 网络难以收敛,目前所有理论都认为GAN应该在纳什均衡上有很好的表现,但梯度下降只有在凸函数的情况下才能保证实现纳什均衡。
  • 有时候很难训练;
  • 有时候(特别是高像素图像),GAN生成图像不清晰;
  • 有时候生成图片多样性太差,只是对真实样本的简单改动。

Generation

生成(generation)就是模型通过学习一些数据,然后生成类似的数据。让机器看一些动物图片,然后自己来产生动物的图片,这就是生成。
以前的技术:

  • auto-encoder(自编码器)
    训练一个很葱的人,把input转换成code,然后训练一个decoder,把code转换成一个image,然后计算得到的image
    在这里插入图片描述

  • VAE

CGAN:条件生成对抗网络(2014)

[paper] Conditional Generative Adversarial Nets(2014)
在这里插入图片描述
CGAN是对条件生成GAN的最先尝试,方法比较简单,直接在网络输入加入条件信息c,用来控制网络的条件输出模式:
在这里插入图片描述
公式也相对简单:
在这里插入图片描述

ACGAN:辅助类别的GAN(2017)

[paper]Conditional Image Synthesis with Auxiliary Classifier GANs(2017)
与CGAN不同的是它在判别器D的真实数据x也加入了类别c的信息,这样就进一步告诉G网络该类的样本结构如何,从而生成更好的类别模型:
在这里插入图片描述
在这里插入图片描述

infoGAN(2016)

[paper] InfoGAN: Interpretable Representation Learning by Information Maximizing Generative Adversarial Nets(2016)
对于生成同类别的样本,InfoGAN另辟蹊径,通过最大化互信息 ( c , c ′ ) (c, c') (c,c)来生成同类别的样本,其中 c c c是隐信息:
在这里插入图片描述
在这里插入图片描述
因为隐信息 c c c可以作为超参数控制生成图像,我们可以得到一些有趣的结果,如下图所示,通过控制隐信息 c c c从-2到2,我们可以控制生成图片的旋转方向或者字体宽度(从左到右的每列)。
在这里插入图片描述

DCGAN:深度卷积生成对抗网络(2016)

[paper] Unsupervised Representation Learnig with Deep Convolutional Generative Adversarial Networks(2016)
在这里插入图片描述
DCGAN是将GAN的概念扩展到卷积神经网络中,可以生成质量较高的图片样本。

曾经一段时间,GANs并不一定使用基于卷积的操作,而是依赖于标准的多层感知器架构。DCGAN改变了这一点,使用了转置卷积运算的方法,转置卷积可以进行向上缩放操作,将低分辨率图像转换为高分辨率图像。

DCGAN 用经验告诉我们什么是比较稳定的GAN网络结构。

CoGAN:耦合生成对抗网络(2016)

[paper] Coupled Generative Adversarial Networks(2016)
在这里插入图片描述
CoGAN能提高图像生成质量,可以在多个图像域上进行训练。因为共享了一些权重,所以与两个单独的GAN相比,CoGAN的参数更少(可以节省更多的内存、计算和存储空间)。

LSGAN:最小二乘GAN(2017)

[paper] Least Squares Generative Adversarial Networks(2017)
传统的GAN中,D网络和G网络都是用简单的交叉熵loss做更新,最小二乘GAN则用最小二乘(least squares)loss做更新:
在这里插入图片描述
选择最小二乘Loss做更新有两个好处:

  • 更严格的惩罚远离数据集的离群fake sample,使得生成图片更接近真实数据(同时图像也更清晰)。
  • 最小二乘保证离群sample惩罚更大,解决了原本GAN训练不充分(不稳定)的问题。

缺点:

  • LSGAN对离群点的过度惩罚,可能导致样本生成的“多样性”降低;
  • 生成样本很可能只是对真实样本的简单“模仿”和细微改动。

WGAN:Wasserstein生成对抗网络(2017)

[paper] Wasserstein GAN (2017)
WGAN告诉我们:不用精巧的网络设计和训练过程,也能训练一个稳定的GAN。

WGAN通过剪裁D网络参数的方式,对D网络进行稳定更新(Facebook采用了一种“Earth-Mover”的距离来度量分布相似度)。
在这里插入图片描述
但是,有时一味地通过裁剪weight参数的方式保证训练稳定性,可能导致生成低质量低清晰度的图片。

WGAN(W代表Wasserstein)提出了一种新的成本函数,这种函数有一些非常好的性质,使得它在数学家和统计学家中非常流行。
旧版的GAN minmax优化公式,它近似一个Jensen-Shannon散度的统计量。
在这里插入图片描述
WGAN使用的新方法,它近似一个1-Wasserstein距离的统计量。
在这里插入图片描述
在这里插入图片描述
原始的GAN论文表明,当判别器为最优时,生成器被更新,以使Jensen-Shannon散度最小化。Jensen-Shannon散度是一种测量两种不同的概率是如何分布的方法。JSD越大,两个分布越不同,反之亦然。
在这里插入图片描述
但是最小化JSD也不是最好的的方法,因为当两个分布完全不重叠时,JSD的值保持为2log2的常量值。当一个函数值为一个常量值时,它的梯度等于零,而梯度为零意味着生成器什么也学不到。

WGAN作者提出的替代距离度量的是1-Wasserstein距离,有时候称为地球移动距离。
在这里插入图片描述

地球移动距离是类比得来的,假设两个分布中的一个是一堆土,另一个是一个坑。地球移动距离是指将土堆运至坑内的成本,其前提是要尽可能高效的运输泥土、沙子、灰尘等。成本即点之间的距离x移动的土方量。
Earth-Mover(EM) distance/Wasserstein Metric
用一个小的实验来解释什么是推土机距离?我们有6个盒子并且我们想将他们从左边的位置移动到右边虚线表示的位置;对于1号box,我们从左边1号盒子所在的位置移动到右边1号盒子所在的位置,移动的距离为6,只看横坐标的差值;
在这里插入图片描述
下面的表格呈现了两种不同的移动方案r1和r2,右边的表格解释了盒子是怎么移动的,比如:第一种方案中我们把2号和3号盒子这两个盒子从位置1移动到位置10,那么在右边的表格中(1,10)的位置填上2(这个数表示从1处移到10处盒子的个数为2);其他位置的数同理
在这里插入图片描述
虽然这两个方案的总移动距离相同但是并不是所有的移动方案的距离是相同的;Wasserstein distance是所有方案中距离最小的一个;用下面这个小例子来表示:
在这里插入图片描述
有两种移动方案:

  • 1号盒子从位置3移动到位置4,2号盒子从7移动到6;
  • 2号盒子从位置3移动到位置6,1号盒子从位置4移动到位置7.

两个分布之间的地球移动距离可写为:
在这里插入图片描述
其中 i n f inf inf是中位数(最小值), x x x y y y是两个分布上的点, γ \gamma γ是最佳的运输方法。但是它的计算非常复杂,难以解决,因此我们计算的是完全不同的东西:
在这里插入图片描述
这两个方程之间的联系一开始似乎并不明显,但通过一个叫做Kantorovich-Rubenstein对偶的奇特数学公式,可以证明这些Wasserstein地球移动距离的公式正试图计算相同的事情。

WGAN-GP

[paper] Improved Training of Wasserstein GANs(2018)
为了解决WGAN有时生成低质量图片的问题,WGAN-GP舍弃裁剪D网络weight参数的方式,而是采用裁剪D网络梯度的方式(依据输入数据裁剪),以下是WGAN-GP的判别器D的Value函数和生成器G的Value函数:
在这里插入图片描述
WGAN-GP在某些情况下是WGAN的改进,但是如果已经用了一些可靠的GAN方法,其实差距并不大。

DRAGAN(2017)

[paper] On Convergence and Stability of GANs(2017)
[code] kodalinaveen3/DRAGAN
DRAGAN本质上也是一种梯度裁剪(虽然文章自称是新颖的正则化方式),其判别器和生成器的价值函数类似WGAN-GP:
在这里插入图片描述
作者的初衷是希望避开局部最优解,获得更稳定的GAN训练。该算法的另一个特点是实现简单。

EBGAN:基于能量函数的GAN(2017)

[paper] Energy-based Generative Adversarial Networks(2017)
基于能量模型的生成对抗网络,训练结果很不错,不像一般的生成网络,生成的图片像素随机性大,字体边界模糊。左边是一般GAN(生成对抗网络)的生成数字,右边就是论文的改进EBGAN(基于能量的生成对抗网络)。可以明显的看出,改进的生成数字比较清晰,连接也比较流畅。传统GAN生成的数字就比较模糊,像素连贯性较差。
在这里插入图片描述
下图是论文EBGAN和DCGAN的比较,EBGAN在边缘的生成效果上更流畅,而且加了特殊的正则项,在生成的类别上,EBGAN更倾向于生成不同的脸型和人种。
在这里插入图片描述

EBGAN的判别器使用了encoder-decoder的结构,如下图所示,这里的D就是判别器,G就是生成器,D不再是一般的神经网络了,而具有深度神经网络的属性:自编码器和自解码器。
在这里插入图片描述
理论基础上是基于能量的模型,判别器D使用基于能量的目标函数,形象的说,物体边缘外部区域具有很强的能量,而内部区域具有弱能量。
在这里插入图片描述
在神经网络中体现在,神经单元v(可视层单元)和h(隐含层单元)的连接上的能量计算,在可视层单元输入一张图片,有一些隐含层单元会激活,这里,有一个能量分布 E n e r g y ( v , h ) Energy(v,h) Energyv,h
在这里插入图片描述
判别器D具有深度网络的表达和总结能力,使得对抗网络的整体表现提高。

判别器的目标函数:
在这里插入图片描述
其实和一般GAN的目标函数是一个形式,只是,判别器变为了 D e c ( E n c ( ⋅ ) ) Dec(Enc( \cdot )) Dec(Enc())。其中,
在这里插入图片描述
判别器的目标很明确,就是当输入样本为真实样本x时,输出的能量 D e c ( E n c ( x ) ) Dec(Enc( x )) Dec(Enc(x))最接近x,即让 ∣ ∣ D e c ( E n c ( x ) ) − x ∣ ∣ ||Dec(Enc(x))-x|| Dec(Enc(x))x的值尽量小;而当输入样本Wie仿造样本z时, ∣ ∣ D e c ( E n c ( G ( z ) ) ) − G ( z ) ∣ ∣ ||Dec(Enc(G(z)))-G(z)|| Dec(Enc(G(z)))G(z)的值尽量大,这样就达到判别器的判别效果。即 ∣ ∣ D e c ( E n c ( x ) ) − x ∣ ∣ + [ m − ∣ ∣ D e c ( E n c ( G ( z ) ) ) − G ( z ) ∣ ∣ ] ||Dec(Enc(x))-x||+[m-||Dec(Enc(G(z)))-G(z)||] Dec(Enc(x))x+[mDec(Enc(G(z)))G(z)]总体值尽量小。

生成器的目标函数也和GAN类似:
在这里插入图片描述
目标很明确,欺骗判别器,使得 ∣ ∣ D e c ( E n c ( G ( z ) ) ) − G ( z ) ∣ ∣ ||Dec(Enc(G(z)))-G(z)|| Dec(Enc(G(z)))G(z)值尽量大。

S = D e c ( E n c ( z ) ) S=Dec(Enc(z)) S=Dec(Enc(z)),S即生成器的输出能量,是图像的能量表达,论文最后,为生成器目标函数引入了一个正则项:
在这里插入图片描述
bs是batch块大小,s是一个生成样本的输出能量 D e c ( E n c ( z ) ) Dec(Enc(z)) Dec(Enc(z)),这个正则项保证了输出生成样本的差异化,能量相似的图像,生成器就可能舍弃,寻求新的有差异能量的样本去生成。两个S之间的正交性越大,越是保留这样的生成样本。

CycleGAN(2018)

[paper] Unpaired Image-to-Image Translation using Cycle-Consistent Adversarial Networks(2018)
在这里插入图片描述
GANs不仅仅用于生成图像,还可以创造外表上同时具有马和斑马特点的生物。为了创建这些图像,CycleGAN致力于解决一个被称为图像翻译的问题。CycleGAN不是一种新的GAN架构,虽然它推动了先进的图像合成技术。相反,它是一种使用GANs的聪明方法,所以可以自由的在任何架构中使用这种技术。

CycleGAN的任务是训练网络G(X),将图像从源域X映射到目标域Y。CycleGAN进行未配对的图像到图像的转换。CycleGAN使用未配对的数据进行训练。
在这里插入图片描述

CycleGAN由两个生成器G和F以及两个判别器Dx和Dy组成。G从X中获取图像,并试图将其映射到Y中的某个图像,判别器Dy判别图像是由G生成的,还是实际上是在Y中生成的。同样的,F是从Y中获取一个图像,并试图将其映射到X中的某个图像,判别器Dx预测图像是由F生成的还是实际存在于X中的。所有四个网络都是以普通的GAN的方式训练的,直到得到强大的生成器G和F,他们可以很好的执行图像到图像的翻译任务,骗过判别器。

为了进一步提高性能,CycleGAN使用另一个度量,即循环一致性损失。CycleGAN强制网络遵守这些限制条件:
F ( G ( x ) ) ≈ x , x ∈ X F(G(x)) \approx x , x \in X F(G(x))x,xX
G ( F ( y ) ) ≈ y , y ∈ Y G(F(y)) \approx y , y \in Y G(F(y))y,yY
从视觉上看,循环一致性如下:
在这里插入图片描述

ProGAN:生成对抗网络的渐进式增长

在训练GANs的时候会有很多问题,其中最重要的是训练的不稳定性。有时GAN的损耗会波动,因为生成器和判别器会相互破坏另一方的学习。其他时候,在网络聚合后损耗可能会爆炸,图像开始变得看起来可怕。

ProGAN代表了生成对抗网络的逐步增长,是一种通过增加生成图像的分辨率来帮助稳定GAN训练的技术。

SAGAN:自注意力生成对抗网络

由于GANs使用转置卷积来扫描特征图,因此它们只能访问附近的信息。单独使用转置卷积就像在绘制图片的时候,只查看画笔小半径范围内的画布区域。即使是可以完美的完成最特殊、最复杂的细节的伟大的艺术家们,也需要后退一步,观察全局。SAGAN使用自注意力机制,由于其转换架构,近年来它已非常流行。自注意力让生成器后退一步,看看大局。

BigGAN:大生成对抗网络

DeepMind团队利用BigGAN完成了很多工作。除了用真实的图像吸引了所有的目光之外,BigGAN向我们展示了非常详细的大规模训练的结果。

BigGAN引入了各种技术,以克服跨多台机器大批量训练GAN的不稳定性。首先,DeepMind使用SAGAN作为基线,并附加了一个称为谱归一化的特征。他们将batch的大小缩放了50%,宽度(通道数)缩放了20%。最初,增加层的数量似乎没有帮助。在尝试了很多其他方法之后,作者使用截断技巧来提高采样图像的质量。在训练过程中,如果潜在向量在生成图像时落在给定范围之外,则对其重新采样。给定范围是一个超参数,用 ψ \psi ψ表示。较小的 ψ \psi ψ缩小了范围,牺牲多样性以增加样品保真度。

BigGAN还表明,大规模的训练会有自己的一系列问题。值得注意的是,通过增加batch大小和宽度等参数,训练似乎可以很好的扩展,但出于某种原因,训练最终会崩溃。

作者还训练了一个BigGAN的新数据集,叫作JFT-300,它是一个类似于ImageNet的数据集,大概有3亿张图片。BigGAN在这个数据集上的表现更好,这表明更大规模的数据集可能是GANs的发展方向。

StyleGAN:基于风格的生成对抗网络

StyleGAN(style Generative Adversarial network)是NVIDIA研究院的成果,它与传统的GAN的研究背道而驰,后者侧重于损失函数、稳定性、体现结构等。StyleGAN没有专注于创建更真实的图像,而是改进了GANs对生成的图像进行精细控制的能力。StyleGAN不专注于架构和损失函数。相反,它是一套技术,可以与任何GAN一起使用,允许你执行各种酷的事情,如混合图像,在多个级别上改进细节以及执行更高级的样式转换。为了实现这一级别的图像样式控制,StyleGAN使用了现有的技术,如自适应实例规范化、潜在的矢量映射网络和持续的学习输入。

应用

DRAGAN:创建动画角色

通过GAN自动生成动画角色并为其上色。
在这里插入图片描述
使用Generative Adversarial Networks创建自动动画人物角色,发生器和鉴别器由多层卷积层、批标准化和具有跳过链接的ReLU组成。
在这里插入图片描述

CGAN:姿势引导人形象生成

通过姿势的附加输入,可以将图像转换为不同的姿势。
在这里插入图片描述
在这里插入图片描述
设计由二级图像发生器和鉴别器组成。生成器使用元数据(姿势)和原始图像重建图像。鉴别器使用原始图像作为CGAN设计标签输入的一部分。
在这里插入图片描述

CycleGAN:跨域名转换

GANs将图像从一个领域(如真实的风景)转换为另一个领域(莫奈绘画或梵高)。
在这里插入图片描述
CycleGAN构建了两个网络G和F来构建从一个域到另一个域以及反向的图像。它使用鉴别器D来批评生成的图像有多好。例如,G将真实图像转换为梵高风格的绘画,并且 D Y D_Y DY用于区分图像是真实的还是生成的。

  • 从域A到域B:
    在这里插入图片描述

  • 从域B到域A:

在这里插入图片描述

PixelDTGAN:从图像中创建服装图像和样式

根据名人图片推荐商品已经成为时尚博客和电子商务的热门话题。PixelDTGAN的作用就是从图像中创建服装图像和样式。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

SRGAN:从低分辨率创建超分辨率

从低分辨率创建超分辨率图像,这是GAN显示出非常令人印象深刻的结果,也是具有直接商业可能性的一个领域。
在这里插入图片描述
和许多GAN的设计类似,它是由多层卷积层、标准化、高级ReLU和跳过连接组成。
在这里插入图片描述

Progressive GAN:展示商业化图像质量的GAN

Progressive GAN是第一个展示商业化图像质量的GAN之一,以下是由GAN创建的1024x1024名人形象。
在这里插入图片描述
它采用分而治之的策略,使训练更加可行。卷积层的一次又一次训练构建出2倍分辨率的图像。
在这里插入图片描述
在9个阶段中,生成1024x1024图像。
在这里插入图片描述

Pix2PixHD: 高分辨率图像合成

高分辨率图像生成并非图像分割,而是从语义上生成图像。由于采集样本非常昂贵,采用生成的数据来补充培训数据集,以降低开发成本。在训练自动驾驶汽车时可以自动生成视频,而不是看到它们在附近巡航,这样就为我们的生活带来了便捷。
pix2pixHD网络结构:
在这里插入图片描述
在这里插入图片描述

StackGAN:文本到图像

文本到图像是域转移GAN的早期应用之一,比如,我们输入一个句子就可以生成多个符合描述的图像。
在这里插入图片描述
在这里插入图片描述

text-condition convolutional GAN:文本到图像合成

在这里插入图片描述

TP-GAN :人脸合成

不同姿态下的合成面:使用单个输入图像,可以在不同的视角下创建面。例如,可以使用它来转换更容易进行人脸识别图像。
在这里插入图片描述
在这里插入图片描述

上下文编码器:图像修复

自编码器在结构上由编码器、解码器以及一个Bottleneck组成。一般的自编码器的目的是通过忽略图像中的噪声来减小图像的尺寸。自编码器不是特定于图像,也可以扩展到其他数据。自编码器有特定的变体来完成特定的任务。

上下文编码器时一种卷积神经网络,经过训练,根据周围环境生成任意图像区域的内容:即上下文编码器接收图像区域周围的数据,并尝试生成适合该图像区域的东西。上下文编码器由一个编码器和一个解码器组成,前者将图像的上下文捕获为一个紧凑的潜在特征表示,后者使用表示来生成缺失的图像内容。由于我们需要一个庞大的数据集来训练一个神经网络,不能只处理修复问题图像。因此,从正常的图像数据集中分割出部分图像,创建一个修复问题,并将图像提供给神经网络,从而在分割的区域创建缺失的图像内容。
在这里插入图片描述

CoGAN:学习联合分配

使用面部字符P(金发、女性、微笑、戴眼镜),P(棕色、男性、微笑、没有眼镜)等不同组合创建GAN是很不现实的。维数的诅咒使得GAN的数量呈现指数增长。但我们可以学习单个数据分布并将他们组合以形成不同的分布,即不同的属性组合。
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

DiscoGAN:提供匹配风格

DiscoGAN提供了匹配的风格;许多潜在的应用程序。DiscoGAN在没有标签或配对的情况下学习跨域关系。例如,它成功的将样式或图案从一个域(手提包)传输到另一个域(鞋子)。

在这里插入图片描述
DiscoGAN和CycleGAN在网络设计中非常相似。
在这里插入图片描述

Pix2Pix:图像到图像的翻译

Pix2Pix是图像到图像的翻译,在跨域的GAN的论文中经常被引用。例如,它可以将卫星图像转换为地图。
在这里插入图片描述

DTN:从图片中创建表情符号

在这里插入图片描述
在这里插入图片描述

MGAN:纹理合成

在这里插入图片描述

ICGAN:图像编辑

重建或编辑具有特定属性的图像。
在这里插入图片描述
在这里插入图片描述

Age-cGAN:人脸老化

在这里插入图片描述
在这里插入图片描述

IAN:神经图像编辑器

用感知图像编辑器(Neural Photo Editor),一个图像编辑界面,可以用IAN(Introspective Adversarial Networks)内省对抗式网络的能力来对图像进行比较大的语义层面的合理修改。可以达到准确重建而不损失特征性质。该网络将GAN和VAE创新的结合在一起。通过使用基于权重分享的扩张卷积(weight-shared dilated convolution)计算块,该模型可以有效的获得远程依赖(龙-range dependencies),并且通过正交正则化(Orthogonal Regularization)这样一个新的权重正则化方法,提升了泛化表现。

基于内省对抗网络IAN的神经图像编辑器Neural Photo Editor界面,中间是原始图像,红色和蓝色的色块是可视化隐空间,可以直接进行操作。
在这里插入图片描述
用户选取一个画刷的大小和颜色(与典型的图像编辑器相同),然后在输出图像上进行绘制。该网络并不是改变独立的像素,而是将局部图像块和要求的颜色之间的差别进行反向传播,然后在隐空间采用梯度下降法来最小化它们之间的差距。这一步产生的全局性连贯变化对于用户要求的色彩变化的情况下有语义意义。

IAN网络示意图
在这里插入图片描述

Perceptual GAN:目标检测

解决小目标检测的方法主要有两种:

  • 一种是通过增加输入图像的尺寸来增加小目标的分辨率,从而可以获取高分辨率的特征图;该方法的缺点是花费时间长。
  • 其他的方法比较关注的是网络结构的变化,是否能够得到小物体的多尺度表示。该方法的缺点是由底层特征所构建的多尺度表示就像是一个黑盒子,无法保证所得到的特征是具有可解释性的。

基于以上分析,提出了一种新型的感知对抗网络。
在这里插入图片描述
Generator通过引入细粒度特征将小目标的特征转化成super-resolved representation。Discriminatory为所产生的精细的特征在质量上提供引导。
Generator Network是由一系列的残差网络构成的,它可以通过引入细粒度的特征,将小物体的特征转化成超分辨率对象。Generator将经过一层卷积层后的feature map作为输入,因为它还保留着低层特征。1x1卷积的目的是增加通道数,保证通道数和conv5输出通道数一致。然后经过B个残差块,这些残差块是一样的布局。经过残差层所学习的特征通过元素相加的操作,以增强小物体特征池化,从而得到最后的结果,即super-resolved representation。
在这里插入图片描述
Discriminatory network不仅仅可以区分小物体所产生的超分辨率对象特征和大物体特征的不同,而且还可以验证检测的准确度。取所产生的超分辨率对象为输入,然后分为两个分支,第一个分支是Adversarial branch,这个分支的输出是输入对象属于一个真实大物体(FI为ground_truth)的可能性。这个分支的误差是Adversarial loss,这个误差的目的是让generator net所产生的的小物体的超分辨率对象特征和大物体特征尽可能相似,所以要最大化;第二个分支是perception branch,这个分支将每一个超分辨对象作为输入(大物体和小物体),输出和类别相关的置信度以及Bbox的回归偏置。
在这里插入图片描述

GP-GAN:图像融合

将图像融合在一起。
在这里插入图片描述

DVD-GAN:视频生成

DeepMind提出的模型Dual Video Discriminator GAN(DVD-GAN),可以利用计算高效的判别器分解,扩展到时间更长,分辨率更高的视频。该研究是迈向逼真视频生成的一次探索。
DVD-GAN生成不同分辨率视频的效果,它们都是在Kinetics-600训练后得到的结果。
在这里插入图片描述
从整体上来说,DVD-GAN能够生成一段连续的视频。但是还有很多问题:

  • 视频中的物体和人不符合几何关系(近大远小等),忽大忽小、物体形变额情况非常多。
  • 有些视频不符合常理,如一个人突然变成别的东西,有些物体突然消失,或者有些物体直接穿过其他物体。
  • 很少有镜头拉近画面或者远离画面的视频,大多数情况下镜头固定,偶尔在画面左右摇晃。
  • 视频生成效果较好的集中在草地、广场、比赛场地等运动行为非常明确的场景,而在室内或人物运动幅度较小的时候生成的效果较差。

DVD-GAN能够生成高分辨率和具备时间一致性的视频。它将大型图像生成模型BigGAN扩展到视频领域,同时使用多项技术加速训练。与之前的研究不同个,该模型的生成器不包含前景、背景或光流的显示先验信息,而是依赖于大容量的神经网络,以数据驱动的方式学习这些信息。DVD-GAN包含自注意力和RNN,但是它在时间或空间中并不具备自回归属性。RNN按顺序为每个视频生成特征,然后ResNet并行的输出所有帧,联合生成每一帧中的所有像素。也就是说,每一帧中的像素并不直接依赖于视频中的其他像素,这与自回归模型并不相同。
DVD-GAN的模型架构如下图所示:
在这里插入图片描述
DVD-GAN使用两个判别器:空间判别器(Spatial Discriminatory:D_S)和时间判别器(Temporal Discriminator:D_T)。

  • D_S对视频随机采样k个全分辨率帧,并对每个帧的内容和结构进行评价。研究人员使用了k=8的参数和TGANv2一样,D_S的最终分数是每个帧的分数之和。
  • D_T则像模型提供生成动作的学习信号(动作是D_S无法评价的)。研究人员对整个视频使用了一种空间降采样函数,并将函数的输出作为D_T的输入,这个降采样函数是一个2x2的平均池化函数。

3DGAN:生成三维对象

使用GAN创建三维对象。
在这里插入图片描述

MidiNet:音乐的产生

GAN可以应用于非图像领域,如作曲。
在这里插入图片描述
在这里插入图片描述

AnoGAN:医疗(异常检测)

GAN可以扩展到其他行业,例如医学中的肿瘤检测。
在这里插入图片描述
在这里插入图片描述

参考资料
深度学习最强资源推荐:一文看尽GAN的前世今生
GAN论文整理
独家 | GAN大盘点,聊聊这些年的生成对抗网络 : LSGAN, WGAN, CGAN, infoGAN, EBGAN, BEGAN, VAE
神经网络结构:生成式对抗网络(GAN)
开发者自述:我是这样学习 GAN 的
GAN的一些很酷的应用
GAN调研:多极扩展
各种GAN结构(笔记)
MakeGirls.moe Official Blog
学界 | 宅男的福音:用GAN自动生成二次元萌妹子
Pytorch实现图像修复:GAN+上下文自编码器
开源|神经照片编辑器:分分钟实现无损风格转换
Perceptual GAN
关于WGAN-GP的理解
用GAN来生成视频,结果很诡异!

  • 2
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
下面是基于PyTorch的Encoder-Decoder GAN模型代码,实现输入128x128x3通道图像,输出128x128x3图像,模型用CUDA训练,并添加随机不规则遮罩函数: ```python import torch import torch.nn as nn import torch.optim as optim from torch.autograd import Variable import torchvision.transforms as transforms from torch.utils.data import DataLoader from torchvision.datasets import ImageFolder import numpy as np import os from PIL import Image cuda = True if torch.cuda.is_available() else False class Generator(nn.Module): def __init__(self): super(Generator, self).__init__() self.encoder = nn.Sequential( nn.Conv2d(3, 64, 3, stride=1, padding=1), nn.BatchNorm2d(64), nn.LeakyReLU(0.2, inplace=True), nn.Conv2d(64, 128, 3, stride=2, padding=1), nn.BatchNorm2d(128), nn.LeakyReLU(0.2, inplace=True), nn.Conv2d(128, 256, 3, stride=2, padding=1), nn.BatchNorm2d(256), nn.LeakyReLU(0.2, inplace=True), nn.Conv2d(256, 512, 3, stride=2, padding=1), nn.BatchNorm2d(512), nn.LeakyReLU(0.2, inplace=True), nn.Conv2d(512, 1024, 3, stride=2, padding=1), nn.BatchNorm2d(1024), nn.LeakyReLU(0.2, inplace=True) ) self.decoder = nn.Sequential( nn.ConvTranspose2d(1024, 512, 5, stride=2, padding=2, output_padding=1), nn.BatchNorm2d(512), nn.ReLU(inplace=True), nn.ConvTranspose2d(512, 256, 5, stride=2, padding=2, output_padding=1), nn.BatchNorm2d(256), nn.ReLU(inplace=True), nn.ConvTranspose2d(256, 128, 5, stride=2, padding=2, output_padding=1), nn.BatchNorm2d(128), nn.ReLU(inplace=True), nn.ConvTranspose2d(128, 64, 5, stride=2, padding=2, output_padding=1), nn.BatchNorm2d(64), nn.ReLU(inplace=True), nn.ConvTranspose2d(64, 3, 5, stride=1, padding=2), nn.Tanh() ) def forward(self, x): x = self.encoder(x) x = self.decoder(x) return x class Discriminator(nn.Module): def __init__(self): super(Discriminator, self).__init__() self.encoder = nn.Sequential( nn.Conv2d(3, 64, 3, stride=1, padding=1), nn.BatchNorm2d(64), nn.LeakyReLU(0.2, inplace=True), nn.Conv2d(64, 128, 3, stride=2, padding=1), nn.BatchNorm2d(128), nn.LeakyReLU(0.2, inplace=True), nn.Conv2d(128, 256, 3, stride=2, padding=1), nn.BatchNorm2d(256), nn.LeakyReLU(0.2, inplace=True), nn.Conv2d(256, 512, 3, stride=2, padding=1), nn.BatchNorm2d(512), nn.LeakyReLU(0.2, inplace=True), nn.Conv2d(512, 1, 3, stride=1, padding=1), nn.Sigmoid() ) def forward(self, x): x = self.encoder(x) return x def random_mask(img, size=30): mask = np.zeros((img.shape[0], img.shape[1], 1), np.uint8) mask = cv2.random_shapes.mask(mask, shape='circle', max_shapes=1, min_size=size, max_size=size)[0] mask = np.tile(mask, (1, 1, 3)) mask = mask.astype(np.float32) mask = mask / 255.0 mask = torch.from_numpy(mask) masked_img = img * (1 - mask) return masked_img, mask def train(generator, discriminator, train_loader, criterion, optimizer_g, optimizer_d): for epoch in range(num_epochs): for i, (input_img, target_img) in enumerate(train_loader): input_img = input_img.cuda() target_img = target_img.cuda() # Train Discriminator optimizer_d.zero_grad() real_output = discriminator(target_img) fake_output = discriminator(generator(input_img)) real_label = torch.ones(real_output.size()).cuda() fake_label = torch.zeros(fake_output.size()).cuda() real_loss = criterion(real_output, real_label) fake_loss = criterion(fake_output, fake_label) d_loss = real_loss + fake_loss d_loss.backward() optimizer_d.step() # Train Generator optimizer_g.zero_grad() fake_output = discriminator(generator(input_img)) g_loss = criterion(fake_output, real_label) g_loss.backward() optimizer_g.step() if (i + 1) % 10 == 0: print('Epoch [{}/{}], Step [{}/{}], Generator Loss: {:.4f}, Discriminator Loss: {:.4f}' .format(epoch + 1, num_epochs, i + 1, len(train_loader), g_loss, d_loss)) def save_model(generator, name="generator"): if not os.path.exists("models/"): os.makedirs("models/") torch.save(generator.state_dict(), "models/{}.pt".format(name)) if __name__ == '__main__': # Hyperparameters num_epochs = 50 learning_rate = 0.0002 batch_size = 32 # Load Data dataset = ImageFolder(root='data/', transform=transforms.Compose([ transforms.Resize(128), transforms.CenterCrop(128), transforms.ToTensor(), transforms.Normalize((0.5, 0.5, 0.5), (0.5, 0.5, 0.5)) ])) train_loader = DataLoader(dataset, batch_size=batch_size, shuffle=True) # Define Generator and Discriminator generator = Generator() discriminator = Discriminator() if cuda: generator.cuda() discriminator.cuda() # Loss function and optimizer criterion = nn.BCELoss() optimizer_g = optim.Adam(generator.parameters(), lr=learning_rate, betas=(0.5, 0.999)) optimizer_d = optim.Adam(discriminator.parameters(), lr=learning_rate, betas=(0.5, 0.999)) # Train model train(generator, discriminator, train_loader, criterion, optimizer_g, optimizer_d) # Save trained model save_model(generator, name="generator") ``` 该代码实现了基于Encoder-Decoder GAN模型的图像生成,同时也添加了随机不规则遮罩函数,并且训练过程中输出生成器、判别器和重建损失,最终保存了训练好的生成器模型。请注意,代码仅为示范,可能还需要根据具体需求进一步修改。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值