BatchNormalization结果差

时间:2019-10-14 11:53:44

标签: deep-learning conv-neural-network batch-normalization dcgan

我一直在尝试实施面书的DCGan,并且在将近两个星期内受到以下两个问题的阻挠。任何建议,将不胜感激。谢谢。

问题1:

DCGAN论文建议生成器和鉴别器都使用BN(批量归一化)。但是,使用BN不能获得比没有BN更好的结果。

我复制了我使用的DCGAN模型,该模型与DCGAN纸完全相同。我不认为这是由于过度拟合。因为(1)它始终显示与初始噪声图像相同的噪声,并且似乎从未受到过训练。 (2)损耗值非常稳定,gan和判别器都没有真正改变。 (它保持在0.6〜0.7左右,并且从未像两个模型都崩溃时一样感觉到跌落或颠簸。)如果我仅检查损失函数,则似乎训练得很好。

问题2:

当我使用float16时,它总是为Nan提供以下模型。 我将epsilon都更改为1e-4 1e-3,但是都失败了。 这是另一个问题。 如果我不使用BatchNormalization,则可以是Nan。它足够有意义,我可以理解。但是,如果我使用BatchNormalization,它将在每一层中进行标准化。即使结果变得非常大或非常小,它也会在每一层中进行批量标准化,以使结果几乎居中,并且不应发生淡出。是不是这实际上是我的想法,但我不知道我在想什么错。 请有人帮帮我。

=====生成器=====

输入#(无,128)<=潜伏

密集#(无,16384)
BatchNormalization
LeakyReLU

重塑#(无,4,4,1024)

Conv2DTranspose#(无,4,4,4,512)

BatchNormalization
LeakyReLU

Conv2DTranspose#(无,8、8、256)

BatchNormalization
LeakyReLU

Conv2DTranspose#(无,16、16、128)

BatchNormalization
LeakyReLU

Conv2DTranspose#(无,32、32、64)

BatchNormalization
LeakyReLU

Conv2DTranspose#(无,64、64、32)

BatchNormalization
LeakyReLU

Conv2DTranspose#(无,128、128、16)

BatchNormalization
LeakyReLU

Conv2D#(无,128、128、3)

=====判别器=====

Conv2D#(无,128、128、3) LeakyReLU

Conv2D#(无,64、64、16) BatchNormalization
辍学
LeakyReLU

Conv2D#(无,32、32、32)
BatchNormalization
辍学
LeakyReLU

Conv2D#(无,16、16、64)
BatchNormalization
辍学
LeakyReLU

Conv2D#(无,8、8、128)
BatchNormalization
辍学
LeakyReLU

Conv2D#(无,4,4,4,256)
BatchNormalization
辍学
LeakyReLU

Conv2D#(无,2、2、512)
BatchNormalization
辍学
LeakyReLU

平板
辍学
密集

我尝试的最后一个超参数如下,我没有忘记在训练图像中添加高斯噪声。

image_shape => (128, 128, 3)
latent_dim => 128
channels => 3
iterations => 10000
batch_size => 128
epsilon => 0.005
weight_init_stddev => 0.02
beta_1 => 0.5
discriminator_lr => 0.0002
gan_lr => 0.0002

3 个答案:

答案 0 :(得分:0)

我不知道DCGAN thesis的详细信息,但是如果我仔细研究,我可以找到以下指导原则来制作稳定的DCGAN。为什么在Generator中使用LeakyReLU而不是ReLU

  

稳定的深度卷积GAN的体系结构指南

     
      
  • 用跨步卷积(鉴别器)和分数跨步卷积(生成器)替换所有池化层。
  •   
  • 在生成器和鉴别器中都使用batchnorm。
  •   
  • 删除完全连接的隐藏层以获得更深的体系结构。
  •   对于所有图层,
  • 在生成器中使用ReLU激活,除了使用Tanh的输出之外。
  •   
  • 在所有层的鉴别器中使用LeakyReLU激活
  •   

答案 1 :(得分:0)

我们知道批量归一化的学习伪代码是

moving_mean = None;
moving_variance = None;

if not moving_mean:
  moving_mean = current_batch_mean
else:
  moving_mean = moving_mean * momentum + current_batch_mean * (1-momentum)

if not moving_variance:
  moving_variance = current_batch_variance
else:
  moving_variance = moving_variance * momentum + current_batch_variance * (1-momentum)

这就是重点。

tensorflow和keras的默认动量为0.99,如果您不经修改使用它,则以下更新值不会影响新的更新值。 对于火炬,默认动量为0.1,与tensorflow或keras中的0.9相同。

使用修改后的动量值,我得到了改善的结果。

如果有人像我一样遭受症状,请尝试降低动量值。

谢谢。

答案 2 :(得分:0)

在鉴别符中使用SpectralNorm,在生成器中使用SelfModulationBatchNorm。或者,如果您有标签,请使用ConditionalBatchNorm

代码,其他方法的帮助以及GAN培训here