talk is cheap, show me the code——dcgan,wgan,wgan-gp的tensorflow实现

时间:2023-03-09 20:54:25
talk is cheap, show me the code——dcgan,wgan,wgan-gp的tensorflow实现

最近学习了生成对抗网络(GAN),基于几个经典GAN网络结构做了些小实验,包括dcgan,wgan,wgan-gp。坦率的说,wgan,wgan-gp论文的原理还是有点小复杂,我也没有完全看明白,因此在此就不详细介绍了,如果感兴趣可以阅读参考部分的论文,本篇博客主要着重于记录如何利用tensorflow实现这几种网络的训练、预测。下面先简单介绍下GAN的原理和个人理解,以及dcgan,wgan,wgan-gp的改进,最后给出代码。

1.GAN原理和个人理解

Generative Adversarial Nets(GAN),生成对抗网络,是2014年由Goodfellow等人提出的一个深度学习框架,这个框架的目的是生成和真实图片概率分布一致的输出,也就是所谓的生成模型。该框架包含两部分:生成网络(Generator,简称G)、判别网络(Discriminator,简称D)。假设G的输入是z,输出是x’,真实数据是x,则G要尽量将输入映射到输出数据的分布上,即利用z尽量生成和x接近的x’。而D要尽量将x’和x区分开。具体公式如下:talk is cheap, show me the code——dcgan,wgan,wgan-gp的tensorflow实现

上面公式中,G(z)是G的输出即x’。D要最大化这个公式,其实就是区分生成数据和真实数据之间的真假,是个二分类问题,也就是尽量将x分为1类、x’分为0类。另一方面,G又想尽量生成和真实数据近似的x’,这个就体现在欺骗D上,如果D无法分辨x’和x,就说明D成功生成了符合x分布的x’,因此G的目的是要让x'都被D分为1类(而不是0类)。又因第一部分logD(x)和G没关系,所以G的目标是最小化下面这个式子,

talk is cheap, show me the code——dcgan,wgan,wgan-gp的tensorflow实现

根据论文的说法,上面这个式子容易saturates,导致G训练出现困难,所以转化成最大化log(D(G(z)))。因为一般做优化都是求目标函数的最小值(当然tf也支持最大值),因此实际编程中是这么写的:

1. min[-log(D(x))-log(1-D(G(z)))]

2. min[-log(1-D(G(z)))]

实际上就是加了个负号。另外,在做前向后向的时候,一般是分别对D、G进行更新,也就是说在后向误差传播更新梯度的时候,会先固定G的参数(权重、偏置等),然后前向计算式1并做后向误差传播,更新G的参数。接着再固定G的参数,前向计算式2并做后向误差传播,更新D的参数。

最后再说下输入z,在没有label的经典gan中,z是一个符合正态分布的随机高维向量,至于在其他经典gan的变体中,z可以是正态分布的随机高维向量加上label,或者是纯label。

2.dcgan、wgan、wgan-gp

Dcgan于2015年提出,相比于最早的GAN相比,主要做了网络结构方面的改进,例如:引入bm层,去掉pooling以strided conv层代之,去掉fc层,引入relu和leakyRelu等等。这些改进效果带来了更好的生成图片效果,不过和早期GAN相比,依然很难训练,所以这个阶段也引入了训练时的一些小窍门,比如每个stepG迭代两次,D迭代一次。在一开始的时候D不能训练的太好,防止G难以收敛等等。

wgan在2017年横空出世,通过理论分析,wgan指出了传统gan的为什么训练时难以收敛,并进行了改进,使其训练难度大幅降低、收敛速度加快。主要有两点改进:一是把目标函数中的log去掉,二是每次迭代更新权重后做weight clipping,把权重限制到一个范围内(例如限定范围[-0.1,+0.1],则超出这个范围的权重都会被修剪到-0.1或+0.1)。

同年,wgan-gp又基于wgan提出了改进方案,因为wgan虽然降低了gan的训练难度,但在一些设定下仍然难以收敛,并且生成图片效果相比dcgan还要差,wgan-gp将weight clipping改为penalize the norm of the gradient of the critic with respect to its input(根据D的输入后向计算出权重梯度,并针对梯度的范数进行惩罚),解决了上述问题。

3.基于tf的代码实现

https://github.com/handspeaker/gan_practice

每种结构的代码都比较简洁,属于实验性质,没有加太多东西,看起来比一些github上很大的工程容易懂些。

4.参考

Generative Adversarial Nets

Wasserstein GAN

Improved Training of Wasserstein GANs

https://github.com/shekkizh/WassersteinGAN.tensorflow

https://github.com/igul222/improved_wgan_training