【问题标题】:Tensorflow GAN: "No gradients provided for any variable"Tensorflow GAN:“没有为任何变量提供梯度”
【发布时间】:2019-01-25 04:20:10
【问题描述】:

我正在尝试使用 TF 设置 GAN,但我太愚蠢了。 我搜索了网络,但找不到答案。

当我运行提供的代码时,我得到:

gen_optimize = tf.train.AdamOptimizer(learning_rate, beta1).minimize(gen_loss, var_list=gen_vars)

ValueError: 没有为任何变量提供梯度,请检查您的图表中变量之间不支持梯度的操作

def generator(z, activation=tf.nn.relu, reuse=False):
    shape = z.get_shape().as_list()
    weight_init = tf.random_normal_initializer(stddev=0.1)
    bias_init = tf.constant_initializer(0.0)

    fc1_units = 256
    fc1_weights = tf.get_variable('gen_fc1_weights', (shape[1], fc1_units), dtype=tf.float32, initializer=weight_init)
    fc1_biases = tf.get_variable('gen_fc1_biases', (fc1_units), initializer=bias_init)
    fc1 = activation(tf.matmul(z, fc1_weights) + fc1_biases)

    fc2_units = 784
    fc2_weights = tf.get_variable('gen_fc2_weights', (fc1_units, fc2_units), dtype=tf.float32, initializer=weight_init)
    fc2_biases = tf.get_variable('gen_fc2_biases', (fc2_units), initializer=bias_init)
    fc2 = activation(tf.matmul(fc1, fc2_weights) + fc2_biases)

    output = tf.nn.sigmoid(fc2, name='gen_sigmoid_output')
    return output

def discriminator(X, activation=tf.nn.relu):
    shape = z.get_shape().as_list()
    weight_init = tf.random_normal_initializer(stddev=0.1)
    bias_init = tf.constant_initializer(0.0)

    with tf.variable_scope('discriminator', reuse=tf.AUTO_REUSE):

        fc1_units = 1024
        fc1_weights = tf.get_variable('dis_fc1_weights', (shape[1], fc1_units), dtype=tf.float32, initializer=weight_init)
        fc1_biases = tf.get_variable('dis_fc1_biases', (fc1_units), initializer=bias_init)
        fc1 = activation(tf.matmul(z, fc1_weights) + fc1_biases)

        fc2_units = 1
        fc2_weights = tf.get_variable('dis_fc2_weights', (fc1_units, fc2_units), dtype=tf.float32, initializer=weight_init)
        fc2_biases = tf.get_variable('dis_fc2_biases', (fc2_units), initializer=bias_init)
        fc2 = tf.matmul(fc1, fc2_weights) + fc2_biases

        sigmoid_out = tf.nn.sigmoid(fc2, name='dis_sigmoid_output')
    return sigmoid_out, fc2

X = tf.placeholder(tf.float32, shape=(real_batch_size, 28*28), name='X')
z = tf.placeholder(dtype=tf.float32, shape=(fake_batch_size, 100), name='z')

gen = generator(z)
dis_real, dis_real_logits = discriminator(X)
dis_fake, dis_fake_logits = discriminator(gen)


dis_real_loss = tf.reduce_mean(
                    tf.nn.sigmoid_cross_entropy_with_logits(labels=tf.ones_like(dis_real), logits=dis_real_logits))
dis_fake_loss = tf.reduce_mean(
                    tf.nn.sigmoid_cross_entropy_with_logits(labels=tf.zeros_like(dis_fake), logits=dis_fake_logits))
dis_loss = dis_real_loss + dis_fake_loss
gen_loss = tf.reduce_mean(
                    tf.nn.sigmoid_cross_entropy_with_logits(labels=tf.ones_like(dis_fake), logits=dis_fake_logits))

train_vars = tf.trainable_variables()
dis_vars = [var for var in train_vars if 'dis_' in var.name]
gen_vars = [var for var in train_vars if 'gen_' in var.name]

dis_optimize = tf.train.AdamOptimizer(learning_rate, beta1).minimize(dis_loss, var_list=dis_vars)
gen_optimize = tf.train.AdamOptimizer(learning_rate, beta1).minimize(gen_loss, var_list=gen_vars)

【问题讨论】:

    标签: tensorflow deep-learning generative-adversarial-network


    【解决方案1】:

    您的问题在于如何过滤变量:

    dis_vars = [var for var in train_vars if 'dis_' in var.name]
    gen_vars = [var for var in train_vars if 'gen_' in var.name]
    

    您在discriminator 范围内定义了鉴别器的变量,在/(无前缀)范围内定义了生成器的变量,因此您的过滤器只是过滤掉了每个变量。

    您可以收集正确过滤的变量:

    dis_vars = [var for var in train_vars if 'discriminator' in var.name]
    gen_vars = [var for var in train_vars if 'discriminator' not in var.name]
    

    此外,错误状态“没有为任何变量提供梯度,请检查您的图表中不支持梯度的操作,在变量 [...] 和损失 Tensor("Mean_2:0", shape=(), dtype =float32)"

    其实问题出在损失张量上。

    损失张量是输入为生成器输出时判别器的评估。判别器定义是错误的,实际上,您指的是一个从未定义过的变量 z。 因此,如果您使用 X 而不是 z 更新您的鉴别器代码,它会起作用:

    import tensorflow as tf
    
    
    def generator(z, activation=tf.nn.relu, reuse=False):
        with tf.variable_scope("generator"):
            shape = z.get_shape().as_list()
            weight_init = tf.random_normal_initializer(stddev=0.1)
            bias_init = tf.constant_initializer(0.0)
    
            fc1_units = 256
            fc1_weights = tf.get_variable(
                'gen_fc1_weights', (shape[1], fc1_units),
                dtype=tf.float32,
                initializer=weight_init)
            fc1_biases = tf.get_variable(
                'gen_fc1_biases', (fc1_units), initializer=bias_init)
            fc1 = activation(tf.matmul(z, fc1_weights) + fc1_biases)
    
            fc2_units = 784
            fc2_weights = tf.get_variable(
                'gen_fc2_weights', (fc1_units, fc2_units),
                dtype=tf.float32,
                initializer=weight_init)
            fc2_biases = tf.get_variable(
                'gen_fc2_biases', (fc2_units), initializer=bias_init)
            fc2 = activation(tf.matmul(fc1, fc2_weights) + fc2_biases)
    
            output = tf.nn.sigmoid(fc2, name='gen_sigmoid_output')
            return output
    
    
    def discriminator(X, activation=tf.nn.relu):
        with tf.variable_scope('discriminator', reuse=tf.AUTO_REUSE):
            shape = X.get_shape().as_list()
            weight_init = tf.random_normal_initializer(stddev=0.1)
            bias_init = tf.constant_initializer(0.0)
    
            fc1_units = 1024
            fc1_weights = tf.get_variable(
                'dis_fc1_weights', (shape[1], fc1_units),
                dtype=tf.float32,
                initializer=weight_init)
            fc1_biases = tf.get_variable(
                'dis_fc1_biases', (fc1_units), initializer=bias_init)
            fc1 = activation(tf.matmul(X, fc1_weights) + fc1_biases)
    
            fc2_units = 1
            fc2_weights = tf.get_variable(
                'dis_fc2_weights', (fc1_units, fc2_units),
                dtype=tf.float32,
                initializer=weight_init)
            fc2_biases = tf.get_variable(
                'dis_fc2_biases', (fc2_units), initializer=bias_init)
            fc2 = tf.matmul(fc1, fc2_weights) + fc2_biases
    
            return fc2
    
    
    ### ADDED TO TEST
    real_batch_size, fake_batch_size = 10, 10
    learning_rate = 1e-5
    beta1 = 0.5
    ###
    X = tf.placeholder(tf.float32, shape=(real_batch_size, 28 * 28), name='X')
    z = tf.placeholder(dtype=tf.float32, shape=(fake_batch_size, 100), name='z')
    
    gen = generator(z)
    dis_real_logits = discriminator(X)
    dis_fake_logits = discriminator(gen)
    
    dis_real_loss = tf.reduce_mean(
        tf.nn.sigmoid_cross_entropy_with_logits(
            labels=tf.ones_like(dis_real_logits), logits=dis_real_logits))
    dis_fake_loss = tf.reduce_mean(
        tf.nn.sigmoid_cross_entropy_with_logits(
            labels=tf.zeros_like(dis_fake_logits), logits=dis_fake_logits))
    
    dis_loss = dis_real_loss + dis_fake_loss
    
    gen_loss = tf.reduce_mean(
        tf.nn.sigmoid_cross_entropy_with_logits(
            labels=tf.ones_like(dis_fake_logits), logits=dis_fake_logits))
    
    train_vars = tf.trainable_variables()
    dis_vars = [var for var in train_vars if 'dis_' in var.name]
    gen_vars = [var for var in train_vars if 'gen_' in var.name]
    
    dis_optimize = tf.train.AdamOptimizer(learning_rate, beta1).minimize(
        dis_loss, var_list=dis_vars)
    gen_optimize = tf.train.AdamOptimizer(learning_rate, beta1).minimize(
        gen_loss, var_list=gen_vars)
    

    【讨论】:

    • 感谢您的快速回复。生成器中构造的每个变量都以“gen_”开头,因此过滤器应该可以工作。如果我使用你的,我得到的输出与我自己的完全相同。
    • 对不起,我看错了你的代码。我用解决方案更新我的答案
    • 非常感谢,这太愚蠢了。但我之前有另一个错误,不知何故迷路了。
    猜你喜欢
    • 2018-08-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-10-31
    • 2020-09-30
    • 2021-09-08
    • 2021-04-17
    相关资源
    最近更新 更多