在尝试训练GAN生成图像时,我遇到了一个无法解释的问题。

训练生成器时,train_on_batch仅经过2或3次迭代后返回的损耗就直接降至零。经过调查,我意识到train_on_batch方法的一些奇怪行为:

当我检查以下内容时:

noise = np.random.uniform(-1.0, 1.0, size=[batch_size, gen_noise_length])
predictions = GAN.stackedModel.predict(noise)


正如我所期望的那样,这将返回所有接近于零的值,因为尚未对生成器进行训练。

然而:

y = np.ones([batch_size, 1])
noise = np.random.uniform(-1.0, 1.0, size=[batch_size, gen_noise_length])
loss = GAN.stackedModel.train_on_batch(noise, y)


尽管我的预期目标很明显,但损失几乎为零。
当我跑步时:

y = np.ones([batch_size, 1])
noise = np.random.uniform(-1.0, 1.0, size=[batch_size, gen_noise_length])
loss = GAN.stackedModel.test_on_batch(noise, y)


如我所料,退货损失很高。

train_on_batch方法是怎么回事?我真的很笨

编辑

我的损失是二进制交叉熵,我建立了如下模型:

def createStackedModel(self):
    # Build stacked GAN model
    gan_in = Input([self.noise_length])
    H = self.genModel(gan_in)
    gan_V = self.disModel(H)
    GAN = Model(gan_in, gan_V)
    opt = RMSprop(lr=0.0001, decay=3e-8)
    GAN.compile(loss='binary_crossentropy', optimizer=opt, metrics=['accuracy'])
    return GAN


编辑2

生成器是通过堆叠其中每个包含BatchNormalization的某些块来构造的:

    self.G.add(UpSampling2D())
    self.G.add(Conv2DTranspose(int(depth/8), 5, padding='same'))
    self.G.add(BatchNormalization(momentum=0.5))
    self.G.add(Activation('relu'))


编辑3

我已将代码加载到https://gitlab.com/benjamingraf24/DCGAN/
显然,问题出在我构建GAN网络的方式上。因此,在GANBuilder.py中一定有问题。但是,我找不到它...

最佳答案

BatchNormalization层在训练和测试阶段的行为有所不同。

在训练阶段,他们将使用当前批次平均值和激活方差进行归一化。

但是,在测试阶段,他们使用在训练期间收集的移动平均值和移动方差。如果没有足够的事先培训,这些收集的值可能与实际批次统计数据相差甚远,从而导致明显的损失值差异。

请参考Keras documentation for BatchNormalizationmomentum参数用于定义运动平均值和运动平均值在训练过程中适应新收集的批次值的速度。

09-06 13:57