DCGAN:鉴别器变得太强太快以至于无法让生成器学习
DCGANs: discriminator getting too strong too quickly to allow generator to learn
我正在尝试对我的一些数据使用 this version of the DCGAN code(在 Tensorflow 中实现)。我 运行 进入鉴别器变得太快以至于生成器无法学习任何东西的问题。
现在有一些通常推荐用于 GAN 问题的技巧:
批量归一化(已经在 DCGAN 代码中)
让发电机领先。
我做了后者的某个版本,允许每 1 个鉴别器迭代 10 次生成器(不仅在开始时,而且在整个训练过程中),这就是它的样子:
在这种情况下添加更多生成器迭代只会有助于减缓不可避免的鉴别器变得过于强大并抑制生成器学习。
因此,我想请教一下是否有另一种方法可以帮助解决鉴别器太强的问题?
总结这个主题 - 一般建议是:
- 尝试使用模型参数(例如学习率)
- 尝试为输入数据添加更多种类
- 尝试调整生成器和判别器的架构
网络。
但是,在我的例子中,问题是数据缩放:我已经将输入数据的格式从最初的 .jpg 更改为 .npy,并且在途中丢失了重新缩放。请注意,this DCGAN-tensorflow code 将输入数据重新缩放到 [-1,1] 范围,并且模型已调整为在此范围内工作。
我认为有几种方法可以减少鉴别器:
尝试 leaky_relu 并在判别器函数中退出:
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
在判别器损失中添加标签平滑,以防止判别器变强。根据 d_loss 性能增加平滑值。
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)))
我正在尝试对我的一些数据使用 this version of the DCGAN code(在 Tensorflow 中实现)。我 运行 进入鉴别器变得太快以至于生成器无法学习任何东西的问题。
现在有一些通常推荐用于 GAN 问题的技巧:
批量归一化(已经在 DCGAN 代码中)
让发电机领先。
我做了后者的某个版本,允许每 1 个鉴别器迭代 10 次生成器(不仅在开始时,而且在整个训练过程中),这就是它的样子:
在这种情况下添加更多生成器迭代只会有助于减缓不可避免的鉴别器变得过于强大并抑制生成器学习。
因此,我想请教一下是否有另一种方法可以帮助解决鉴别器太强的问题?
总结这个主题 - 一般建议是:
- 尝试使用模型参数(例如学习率)
- 尝试为输入数据添加更多种类
- 尝试调整生成器和判别器的架构 网络。
但是,在我的例子中,问题是数据缩放:我已经将输入数据的格式从最初的 .jpg 更改为 .npy,并且在途中丢失了重新缩放。请注意,this DCGAN-tensorflow code 将输入数据重新缩放到 [-1,1] 范围,并且模型已调整为在此范围内工作。
我认为有几种方法可以减少鉴别器:
尝试 leaky_relu 并在判别器函数中退出:
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
在判别器损失中添加标签平滑,以防止判别器变强。根据 d_loss 性能增加平滑值。
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)))