代码
https://github.com/carpedm20/DCGAN-tensorflow
fGAN:JS Div 出现问题的原因是:只要𝑃𝐺与𝑃𝑑𝑎𝑡𝑎完全没有重合,判别器就 能 100%地鉴别出𝑃𝐺(𝑥)与𝑃𝑑𝑎𝑡𝑎(𝑥)的差异,因此二者的 JS Div 就是一样的。那现在的一个解
决思路就是,让判别器始终都不能 100%地鉴别出𝑃𝐺(𝑥)与𝑃𝑑𝑎𝑡𝑎(𝑥)的差异,这样即便𝑃𝐺与 𝑃𝑑𝑎𝑡𝑎完全没有重合,二者的 JS Div 也会不一样,而只要 Div 存在差异,就能反映出𝑃𝐺的优劣度来。基于这样的思路,LSGAN(最小二乘 GAN)被提出了。
第一张图是判别器训练得太好的例子,它能够 100%地鉴别出𝑃𝐺(𝑥)与𝑃𝑑𝑎𝑡𝑎(𝑥)的差异。
蓝色样本点,是生成样本𝑃𝐺,它们的得分为 0;绿色样本点,是真实样本𝑃𝑑𝑎𝑡𝑎,它们的得分为 1;𝑃𝐺与𝑃𝑑𝑎𝑡𝑎之间完全没有交集。这样会出现什么问题呢?当轮到生成器训练的时候,它希望蓝色的点能够向右移,但是因为对于所有蓝色点,判别器计算出的 JS Div 都是一样的,这意味着所有点的梯度都是 0,于是基于 gradient descent 所有的生成样本的点都无法移动了。这种情况其实是很有意思的,因为在之前的理论中,我们希望判别器尽可能训练到最好,但是当𝑃𝐺与𝑃𝑑𝑎𝑡𝑎之间完全没有交集时,判别器就不能训练得太好,因为那意味着梯度消失至 0,生成器无法更新。
解决
想办法去限制判别器不要训练得太好。只需要将判别器的最后的 sigmoid 激活层改成 linear 激活层,这样训练出的 D 就会是一个线性的直线,如下图所示。
D 只有在一种情况下才会梯度为 0,就是𝑃𝐺与𝑃𝑑𝑎𝑡𝑎完全重合时,D 变为一条 y=1/2 处的
水平直线;其他情况下𝑃𝐺都会顺着直线的梯度向𝑃𝑑𝑎𝑡𝑎靠拢。
方法:最小二乘得到上述直线
将判别器视为分类器,采用sigmoid交叉熵损失函数,当更新生成器时,该损失函数将导致位于决策边界正确一侧但仍远离实际数据的样本的梯度消失问题。为了解决这个问题,提出了最小二乘生成对抗网络。假设使用a-b编码方案作为鉴别器,其中a和b分别是伪数据和真实数据的标签。
- 方案一:设置a = −1, b = 1, and c = 0, 即
- 方案二:设置c=b使G生成的样本尽可能真实,例如,使用0-1二进制编码方案,我们得到以下目标函数:b=c=1,a=0。
网络结构
(a): Thegenerator. (b): The discriminator.带有BN的层表示该层后面是批处理规范化层。“fc,N”表示具有N个输出节点的完全连接层。激活层被省略。
实验
数据集
设定场景和汉字的学习率分别为0.001和0.0002。在DCGANs之后,Adam优化器的β1设置为0.5。