生成对抗模型
D、G
用D指导G去学习。D固定之后去训练G,G训练到一定程度之后去骗D;然后G固定,去训练D;循环反复。
生成模型:Generator Network
GAN 没看 Understanding and optimizing GANs (Going back to first principles)
GANs的训练过程
零和博弈的过程,找一个纳什均衡。
训练过程:梯度下降,生成器和判别器交替优化的方式。 在训练判别器时,先固定生成器G(.);然后利用生成器随机模拟产生样本G(z)作为负样本(z是一个随机向量),并从真实数据集中采样获得正样本X;将这些正负样本输入到判别器D(.)中,根据判别器的输出(即D(X)或D(G(z))和样本标签采计算误差,最后利用误差反向传播算法来更新判别器D(.)的参数。 在训练生成器时,先固定判别器D(.);然后利用当前生成器G(.)随机模拟产生样本G(z),并输入到判别器D(.)中(只有负样本);根据判别器的输出D(G(z))和样本标签来计算误差,最后利用误差反向传播算法来更新生成器G(.)的参数。
一些训练trick:先让警多跑几次;然后接着警和匪一起训练的时候,让匪跑几次警跑一次(因为匪的模型从乱码生成目标还挺不容易,所以要多跑几次)
GANs的值函数
判别器D试图识别实际数据为真实样本,识别生成器生成的数据为模拟样本,所以这是一个二分类问题,损失函数写成Negative Log-Likelihood,也称Categorical Cross-Entropy Loss。
第一种生成器loss是一个MinMax函数。发现判别器最优的情况下,优化生成器G是在最小化生成样本分布与真实样本分布的JS距离。而JS距离在两个分布没有重叠或者重叠可忽略的情况下,JS固定是常数log,使得梯度为0。
第二种生成器loss是-log D trick,不涉及真实样本分布的loss。存在两个问题,梯度不稳定、collapse mode即多样性不足。因为这个loss化简后发现:第一,它要最小化生成分布与真实分布的KL散度,却又要最大化两者的JS散度,一个要拉近,一个却要推远!在数值上则会导致梯度不稳定,这是后面那个JS散度项的毛病。第二,即便是前面那个正常的KL散度项也有毛病。因为KL散度不是一个对称的衡量。
存在的问题:
- 判别器训练的太好,生成器梯度消失,生成器loss降不下去。判别器训练的不好,生成器梯度不准,四处乱跑。只有判别器训练得不好不坏才行,这个火候很难把握。
- 生成图片多样性不足,或者生成的图片和实际有差距;这是由于距离计算有问题(KL距离的问题)。
CGAN
给GAN加上条件,让生成的样本符合我们的预期,这个条件可以是类别标签(例如MNIST手写数据集的类别标签),也可以是其他的多模态信息(例如对图像的描述语言)等。
设计生成和判别网络,多加一个标签信息。
DCGAN
DCGAN:deep convolutional gan。把正常的cnn倒过来(去掉最后一层的预测,把flatten layer作为第一层,这是一个一维数据;Deconv(放大过程)(Deconv是shared batch normalized的,展开的过程会造成数据的离散))。(噪音应该符合一定的分布,这个分布由你决定,例如一个高斯分布,高斯分布数值可以变化,可以导致生成的东西符合一定的特性)。
优化了网络结构,加入了conv、batch_norm等层,使得网络更容易训练。
源码分析
https://github.com/carpedm20/DCGAN-tensorflow/blob/85edbcdc9a9183419b2d2654fe37d4281177bfb5/ops.py
自己定义了batch_norm,因为模型中batch_norm参数都是一样的。
https://github.com/carpedm20/DCGAN-tensorflow/blob/85edbcdc9a9183419b2d2654fe37d4281177bfb5/model.py
定义了generator和sampler这两个G网络,一个用于训练阶段,一个用于测试阶段,因为涉及batch_norm,需要有train参数,训练阶段train=True,测试阶段train=False。
WGAN
WGAN之前的过渡解决方案:原始GAN问题的根源可以归结为两点,一是等价优化的距离衡量(KL散度、JS散度)不合理,二是生成器随机初始化后的生成分布很难与真实分布有不可忽略的重叠。WGAN前作其实已经针对第二点提出了一个解决方案,就是对生成样本和真实样本加噪声,直观上说,使得原本的两个低维流形“弥散”到整个高维空间,强行让它们产生不可忽略的重叠。而一旦存在重叠,JS散度就能真正发挥作用,此时如果两个分布越靠近,它们“弥散”出来的部分重叠得越多,JS散度也会越小而不会一直是一个常数,于是(在第一种原始GAN形式下)梯度消失的问题就解决了。但因为加噪JS散度的具体数值受到噪声的方差影响,随着噪声的退火,前后的数值就没法比较了,所以它不能成为Pr和Pg距离的本质性衡量。
最后提出了WGAN。
- 解决了GAN训练不稳定的问题,不需要小心平衡生成器和判别器的训练程度。
- 基本解决了collapse mode的问题,确保了生成样本的多样性。
- 训练过程中有一个像交叉熵、准确率这样的数值来指示训练的进程,这个值越小代表GAN训练得越好,代表生成器产生的图片质量越高。
- 上述好处不需要精心涉及的网络结构,最简单的多层全连接网络就可以做到。
Wasserstein距离(Earth-Mover距离)。Wasserstein距离相比KL散度、JS散度的优越性在于,即便两个分布没有重叠,Wasserstein距离仍然能够反映它们的远近。但这个距离没办法直接求解,通过KR Duality,用一个公式来近似一下。
WGAN与原始GAN第一种形式相比,只改了四点:
- 判别器最后一层去掉sigmoid。
- 生成器和判别器的loss不取log。
- 每次更新判别器的参数之后把它们的绝对值截断到不超过一个固定常数c。
- 不要用基于动量的优化算法(包括momentum和Adam),推荐RMSProp,SGD也行。
WGAN既解决了训练不稳定的问题,也提供了一个可靠的训练进程指标,而且该指标确实与生成样本的质量高度相关。
前三点都是从理论分析中得到的,已经介绍完毕;第四点却是作者从实验中发现的,属于trick,相对比较“玄”。作者发现如果使用Adam,判别器的loss有时候会崩掉,当它崩掉时,Adam给出的更新方向与梯度方向夹角的cos值就变成负数,更新方向与梯度方向南辕北辙,这意味着判别器的loss梯度是不稳定的,所以不适合用Adam这类基于动量的优化算法。作者改用RMSProp之后,问题就解决了,因为RMSProp适合梯度不稳定的情况。
做实验验证,第一,判别器所近似的Wasserstein距离与生成器的生成图片质量高度相关。第二,WGAN如果用类似DCGAN架构,生成图片的效果与DCGAN差不多。第三,在所有WGAN的实验中未观察到collapse mode,作者也只说应该是解决了。
https://github.com/martinarjovsky/WassersteinGAN
https://github.com/Zardinality/WGAN-tensorflow
多种多样的GAN
CycleGAN
两个G、两个D。
loss:Discriminator Loss、GeneratorLoss、Cycle Loss
Generator Loss = Generator Loss + Cycle Loss
https://junyanz.github.io/CycleGAN/
DiscoGAN
https://github.com/SKTBrain/DiscoGAN
其他GAN
InfoGAN
f-GANs
BiGAN
IRGAN
基于能量的GAN
视频地址:
http://www.julyedu.com/video/play/90/752
EBGAN energy-based 基于能量的GAN
energy based。
判别器变了。
L = D(x) + max(0, m - D(G(z)))
margin m是动态变化的,随着生成器生成的图片越来越好,margin越来越小。
- 真实图片物体边缘外部的东西会有很强的能量;内部区域有弱的能量,比较稳定。能量的概念就是重构误差。
- 修改了D网络,改造成了有自编码器和自解码器的神经网络,不是输出概率。
- 判别起D训练的时候用的是带margin的loss function。(带margin的原因是避免loss仅仅优化-D(G(z)),而不优化D(x))
BEGAN boundary equilibrium 基于能量的GAN
修正判别器,做一些自适应。
判别器用Auto-Encoder而不是分类网络。
GAN是通过匹配真假图片的分布,而BEGAN是通过匹配真假图片在Auto-Encoder上的分布,判别器的作用是“好好重构”真实图片和“不好好重构”生成的假图片。即本文是让生成图像的重构误差分布逼近真实图片的重构误差分布,而传统GAN的做法是让生成图像的分布逼近真实图像的分布。
LSGAN loss-sensitive 基于能量的GAN
LSGAN让generator更“专注于”提高和真实图片差距更远的生成图片。
D(x) + max(0, delta(x, G(z)) + D(x) - D(G(z)))
delta(x, G(z))相当于EBGAN的m,使得D(x) - D(G(z))比delta(.)小的话(delta是原图和生成图的能量差距a,这个意思是既然原图有差距,那么对原图和生成图进行判断也应该有差距,且差距至少为a,这样loss才为0,要不然就有loss),加一个损失;否则这部分损失为0。这个delta()可以衡量生成和真实图片能量的差距,而且越学越好,delta也会变化,delta是自变化的;而刚才会强制m变化。
GAN实战
视频资源:
http://www.julyedu.com/video/play/90/757
关于GAN的思考
在原版GAN中仅有一种损失函数–判别器网络D,其自身就是另一种神经网络。
通过传统损失函数与神经网络的集成,GAN使将神经网络作为损失函数来训练另一神经网络成为可能。两个神经网络间的巧妙交互使得深度神经网络能够解决一些先前无法完成的任务(如生成逼真图像)。
我们可以将GAN本质上视为一种学得的损失函数。
参考
生成式模型 & 生成对抗网络——资料梳理(专访资料 + 论文分类)