GAN 无法同时与鉴别器和生成器损失收敛到 0

Posted

技术标签:

【中文标题】GAN 无法同时与鉴别器和生成器损失收敛到 0【英文标题】:GAN failure to converge with both discriminator and generator loss go to 0 【发布时间】:2020-05-05 16:42:28 【问题描述】:

我正在 Tensorflow 2.0 中使用 Keras 训练 GAN 网络。在我尝试添加 BatchNormalization 层之前,我可以获得一些合理但不好看的结果。 我知道 GAN 的训练非常敏感,导致发散的原因有很多,但我想知道在这种情况下出了什么问题:判别器/生成器的损失都下降到零。

我的网络就像DCGAN的常见例子:

===== Generator =====  
Input(128)  
Dense(16384) => ReLU  
Reshape(4 x 4 x 1024)  
Conv2DTranspose(8 x 8 x 512, kernel=4, stride=2) => ReLU  
Conv2DTranspose(16 x 16 x 256, kernel=4, stride=2) => ReLU  
Conv2DTranspose(32 x 32 x 128, kernel=4, stride=2) => ReLU  
Conv2DTranspose(64 x 64 x 3, kernel=4, stride=2, activation=sigmoid)  
===== Discriminator =====  
Conv2D(32 x 32 x 64, kernel=3, stride=2) => LeakyReLU(alpha=0.2)  
Conv2D16 x 16 x 128, kernel=3, stride=2) => LeakyReLU(alpha=0.2)  
Conv2D(8 x 8 x 256, kernel=3, stride=2) => LeakyReLU(alpha=0.2)  
Conv2D(4 x 4 x 512, kernel=3, stride=2) => LeakyReLU(alpha=0.2)  
Flatten(8192)  
Dense(1, activation=sigmoid)

我也遵循 DCGAN 的建议训练设置:

Kernel init = RandomNormal, stddev=0.02  
Optimizer = Adam, beta1 = 0.5  
Learning rate = 0.0002  

我的数据集包含 2048 张具有指定类别的图像。 第一次尝试时,我按以下顺序训练网络: 1. 绘制 128 个小空间增强的真实样本。 2.当前生成器生成128个假样本。 3. 堆叠样本,将这256个样本作为一个批次训练判别器 4. 生成 256 个随机潜在数据向量 5. 将这256个向量作为一个batch训练生成器

损失值在每个 epoch 之后进行平均和报告。

我从这些设置中得到了公平的结果。鉴别器损失在0.60-0.70,生成器损失在0.70-1.00,但质量的提升似乎很慢。因此,正如通常建议的那样,我将批量归一化层添加到所有(转置)卷积中,除了生成器输出处的卷积。 添加批量归一化后,训练损失变得非常不稳定,但不会直接发散。判别器损失下降到 0.20-0.40,生成器损失在 1.00-3.00 之间变化。 我尝试过动量 = 0.8 或 0.9,它们给出了类似的行为。

然后我尝试不在单个批次中堆叠真实/虚假样本,而是通过 128 个真实样本和 128 个虚假样本来训练鉴别器,并且仍然使用批量归一化层。 在此设置下,判别器和生成器损失在第一个 epoch 之后都迅速下降并趋于 0。生成的图像在每个像素上看起来都像是强烈的颜色噪声,并且这些噪声图像的预测概率(在 sigmoid 之后)都接近 1.0。 如果我删除所有批归一化层,而只是分别训练真/假样本,则不会发生此问题。

如果生成器可以通过噪声图像欺骗判别器并获得高概率,为什么判别器损失在训练后仍然可以非常接近于零?批量归一化层在这种情况下是否有一些不好的影响?

【问题讨论】:

【参考方案1】:

这个问题也叫饱和问题,意思是判别器训练超出了极限。简单来说,它的发生是因为 GAN 的梯度消失问题。如果您想了解这背后的数学原理,我鼓励您仔细阅读此article。

【讨论】:

以上是关于GAN 无法同时与鉴别器和生成器损失收敛到 0的主要内容,如果未能解决你的问题,请参考以下文章

GAN - 生成器损失减少,但鉴别器假损失在初始下降后增加,为啥?

(MNIST - GAN) 鉴别器和生成器误差在第一次迭代后接近于零

生成对抗网络中的鉴别器损失没有改变

GAN没有收敛。判别者损失不断增加

第一节2:GAN经典案例之MNIST手写数字生成

如何在 Tensorflow 中异步更新 GAN 生成器和判别器?