我在基于DCGAN的GAN上工作。
我听说Generator和Discriminator需要冻结其变量而另一个正在训练。
所以我之前就这样做了。
G = generator(batch_size, z, in_h)
D, D_logits = discriminator(X)
D_, D_logits_ = discriminator(G, reuse=True)
# Variable Grouping
t_vars = tf.trainable_variables()
d_var = [var for var in t_vars if 'discriminator' in var.name]
g_var = [var for var in t_vars if 'generator' in var.name]
op_D = tf.train.AdamOptimizer(learning_rate=learning_rate_D,
beta1=beta1).minimize(D_loss, var_list=d_var)
op_G = tf.train.AdamOptimizer(learning_rate=learning_rate_G,
beta1=beta1).minimize(G_loss, var_list=g_var)
这是我的模特
def generator(batch_size, z, im_size, is_train=True):
with tf.variable_scope('generator', reuse=not is_train):
alpha = 0.2
#half_size, quat_size = im_size//2, im_size//4
x1 = tf.layers.dense(z, 4*4*1024)
x1 = tf.reshape(x1, (-1, 4, 4, 1024))
x1 = tf.layers.batch_normalization(x1, training=is_train)
x1 = tf.maximum(alpha*x1, x1) # leaky relu
# 4*4*256 now
x2 = tf.layers.conv2d_transpose(x1, 512, 5, strides=2, padding='same')
x2 = tf.layers.batch_normalization(x2, training=is_train)
x2 = tf.maximum(alpha*x2, x2)
# 8*8*512 now
x3 = tf.layers.conv2d_transpose(x2, 256, 5, strides=2, padding='same')
x3 = tf.layers.batch_normalization(x3, training=is_train)
x3 = tf.maximum(alpha*x3, x3)
# 16*16*256 now
x4 = tf.layers.conv2d_transpose(x3, 128, 5, strides=2, padding='same')
x4 = tf.layers.batch_normalization(x4, training=is_train)
x4 = tf.maximum(alpha*x4, x4)
# 32*32*128 now
logits = tf.layers.conv2d_transpose(x4, in_ch, 5, strides=2, padding='same')
logits = tf.reshape(logits, (batch_size, im_size, im_size, in_ch))
# 64*64*3 now
out = tf.tanh(logits)
return out
def discriminator(image, reuse=False, is_train=True):
with tf.variable_scope('discriminator', reuse=reuse):
alpha = 0.2
dr_rate = 0.3
#input 64*64*3
x1 = tf.layers.conv2d(image, 64, 5, strides=2, padding='same')
x1 = tf.maximum(alpha*x1, x1)
x1 = tf.layers.dropout(x1, rate=dr_rate, training=is_train)
# now 32*32*64
x2 = tf.layers.conv2d(x1, 128, 5, strides=2, padding='same')
x2 = tf.layers.batch_normalization(x2, training=is_train)
x2 = tf.maximum(alpha*x2, x2)
x2 = tf.layers.dropout(x2, rate=dr_rate, training=is_train)
# now 16*16*128
x3 = tf.layers.conv2d(x2, 256, 5, strides=2, padding='same')
x3 = tf.layers.batch_normalization(x3, training=is_train)
x3 = tf.maximum(alpha*x3, x3)
x3 = tf.layers.dropout(x3, rate=dr_rate, training=is_train)
# now 8*8*256
x4 = tf.layers.conv2d(x3, 512, 5, strides=2, padding='same')
x4 = tf.layers.batch_normalization(x4, training=is_train)
x4 = tf.maximum(alpha*x4, x4)
x4 = tf.layers.dropout(x4, rate=dr_rate, training=is_train)
# now 4*4*512
flat = tf.reshape(x4, (-1, 4*4*512))
logits = tf.layers.dense(flat, 1)
out = tf.sigmoid(logits)
return out, logits
请忽略范围缩进。
如果我制作第二个鉴别器,则is_train = False,结果会发生变化。
D_, D_logits_ = discriminator(G, reuse=True, is_train=False)
像这样。改变is_train = False后,G似乎无法学好。
任何人都知道为什么会这样吗?我认为此代码只会优化' g_var'在op_G期间,
如此改变歧视者' is_train'不应该影响结果。
答案 0 :(得分:1)
让第二版鉴别器可以训练对于GAN正常工作至关重要。如果鉴别器不能根据发生器的输出更新其权重,它将永远不会学会区分真假,因此它永远不会为生成器学习提供有意义的反馈。通过将鉴别器的第二个副本设置为不可训练,您试图通过仅显示其中一个类来训练两类问题的分类器。
作为参考,您可以看到here TensorFlow的TFGAN库如何设置发生器/鉴别器网络。