DCGAN:鉴别器变得太强太快以至于无法让生成器学习

Mas*_*nya 5 python tensorflow dcgan

我正在尝试将此版本的 DCGAN 代码(在 Tensorflow 中实现)与我的一些数据一起使用。我遇到了鉴别器变得太强大太快以至于生成器无法学习任何东西的问题。

现在,针对 GAN 的问题,通常推荐一些技巧:

  • 批量归一化(DCGAN 代码中已存在)

  • 为发电机提供领先优势。

我做了后者的一些版本,允许每 1 个判别器进行 10 次生成器迭代(不仅在开始时,而是在整个训练过程中),这就是它的样子: 生成器和判别器的损失函数

在这种情况下,添加更多的生成器迭代只会减缓不可避免的情况——判别器变得太强并抑制生成器的学习。

因此我想请教一下是否有另一种方法可以帮助解决鉴别器过强的问题?

小智 7

我认为有几种方法可以减少判别器:

  1. 尝试在判别器函数中使用leaky_relu和dropout:

    def leaky_relu(x, alpha, name="leaky_relu"): return tf.maximum(x, alpha * x , name=name)

这是完整的定义:

def discriminator(images, reuse=False):

# Implement a seperate leaky_relu function
def leaky_relu(x, alpha, name="leaky_relu"):
    return tf.maximum(x, alpha * x , name=name)

# Leaky parameter Alpha 
alpha = 0.2

# Add batch normalization, kernel initializer, the LeakyRelu activation function, ect. to the layers accordingly
with tf.variable_scope('discriminator', reuse=reuse):
    # 1st conv with Xavier weight initialization to break symmetry, and in turn, help converge faster and prevent local minima.
    images = tf.layers.conv2d(images, 64, 5, strides=2, padding="same", kernel_initializer=tf.contrib.layers.xavier_initializer())
    # batch normalization
    bn = tf.layers.batch_normalization(images, training=True)
    # Leaky relu activation function
    relu = leaky_relu(bn, alpha, name="leaky_relu")
    # Dropout "rate=0.1" would drop out 10% of input units, oppsite with keep_prob
    drop = tf.layers.dropout(relu, rate=0.2)

    # 2nd conv with Xavier weight initialization, 128 filters.
    images = tf.layers.conv2d(drop, 128, 5, strides=2, padding="same", kernel_initializer=tf.contrib.layers.xavier_initializer())
    bn = tf.layers.batch_normalization(images, training=True)
    relu = leaky_relu(bn, alpha, name="leaky_relu")
    drop = tf.layers.dropout(relu, rate=0.2)

    # 3rd conv with Xavier weight initialization, 256 filters, strides=1 without reshape
    images = tf.layers.conv2d(drop, 256, 5, strides=1, padding="same", kernel_initializer=tf.contrib.layers.xavier_initializer())
    #print(images)
    bn = tf.layers.batch_normalization(images, training=True)
    relu = leaky_relu(bn, alpha, name="leaky_relu")
    drop = tf.layers.dropout(relu, rate=0.2)


    flatten = tf.reshape(drop, (-1, 7 * 7 * 128))
    logits = tf.layers.dense(flatten, 1)
    ouput = tf.sigmoid(logits)  

    return ouput, logits
Run Code Online (Sandbox Code Playgroud)
  1. 在判别器损失中添加标签平滑,以防止判别器变得过强。根据d_loss性能增加smooth值。

    d_loss_real = tf.reduce_mean( tf.nn.sigmoid_cross_entropy_with_logits(logits=d_logits_real, labels=tf.ones_like(d_model_real)*(1.0 - smooth)))


Mas*_*nya 3

总结这个主题 - 一般建议是:

  • 尝试使用模型参数(例如学习率)
  • 尝试为输入数据添加更多种类
  • 尝试调整生成器和鉴别器网络的架构。

然而,就我而言,问题是数据缩放:我已将输入数据的格式从最初的 .jpg 更改为 .npy,并在途中丢失了重新缩放。请注意,此 DCGAN-tensorflow 代码将输入数据重新缩放到 [-1,1] 范围,并且模型经过调整以适应该范围。