Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/337.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python GAN无法收敛,鉴别器和发电机损耗均为0_Python_Tensorflow_Keras_Deep Learning_Generative Adversarial Network - Fatal编程技术网

Python GAN无法收敛,鉴别器和发电机损耗均为0

Python GAN无法收敛,鉴别器和发电机损耗均为0,python,tensorflow,keras,deep-learning,generative-adversarial-network,Python,Tensorflow,Keras,Deep Learning,Generative Adversarial Network,我在Tensorflow 2.0中训练Keras的GAN网络。在尝试添加BatchNormalization层之前,我可以得到一些合理但外观不好的结果。 我知道GAN的训练非常敏感,有很多原因会导致发散,但我想知道在这种情况下出现了什么问题:鉴别器/发生器的损耗都降到了零 我的网络类似于DCGAN的常见示例: ===== Generator ===== Input(128) Dense(16384) => ReLU Reshape(4 x 4 x 1024) Conv2DT

我在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)
Kernel init = RandomNormal, stddev=0.02  
Optimizer = Adam, beta1 = 0.5  
Learning rate = 0.0002  
我还遵循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)
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个向量作为一批对生成器进行训练

损失值在每个历元后平均并报告

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

然后,我尝试不在单个批次中堆叠真实/虚假样本,而是通过128个真实样本,然后是128个虚假样本来训练鉴别器,并且仍然使用批次标准化层。
在此设置下,鉴别器和发电机损耗在第一个历元之后迅速下降,并朝着0。生成的图像在每个像素处看起来都像强彩色噪声,并且这些噪声图像的预测概率(在sigmoid之后)都接近1.0。
如果我删除了所有批处理规范化层,但只单独训练真实/虚假样本,那么这个问题就不会发生


如果发生器可以通过噪声图像愚弄鉴别器并获得高概率,那么为什么鉴别器在训练后的损耗仍然非常接近于零?在这种情况下,批处理规范化层是否会产生一些不良影响?

此问题也称为饱和问题,它意味着鉴别器训练超出了限制。简单地说,这是因为GANs的消失梯度问题。如果你想理解这背后的数学,我鼓励你仔细阅读