Tensorflow:如何在图表中共享操作?

时间:2017-12-22 10:46:51

标签: tensorflow tensorboard

关于创建尽可能简单的图表,以及稍后能够检查它的图表。代码的相关部分是这个,我认为这是创建生成性对抗性训练的典型代码块(接下来是一个在实践中不起作用的简化网络):

def generator(x):
    w_init = tf.truncated_normal_initializer(0., 0.02)
    b_init = tf.constant_initializer(0.)
    l1 = tf.layers.dense(x, 256, kernel_initializer=w_init, bias_initializer=b_init, activation=tf.nn.relu, name='layer_1')
    l2 = tf.layers.dense(l1, 512, kernel_initializer=w_init, bias_initializer=b_init, activation=tf.nn.relu, name='layer_2')
    o = tf.layers.dense(l2, 784, kernel_initializer=w_init, bias_initializer=b_init, activation=tf.nn.tanh, name='layer_out')
    return o

def discriminator(x, reuse=False):
    w_init = tf.truncated_normal_initializer(0., 0.02)
    b_init = tf.constant_initializer(0.)
    x = tf.reshape(x, [-1, 784])
    l1 = tf.layers.dense(x, 1024, kernel_initializer=w_init, bias_initializer=b_init, activation=tf.nn.relu, name='layer_1')
    l2 = tf.layers.dense(l1, 512, kernel_initializer=w_init, bias_initializer=b_init, activation=tf.nn.relu, name='layer_2')
    o = tf.layers.dense(l2, 1, kernel_initializer=w_init, bias_initializer=b_init, activation=tf.nn.sigmoid, name='layer_out')
    return o

with tf.variable_scope('input_variables'):
    x = tf.placeholder(tf.float32, shape=(None, 28, 28, 1), name='real_images')
    z = tf.placeholder(tf.float32, shape=(None, noise_size), name='noise_vector')

with tf.variable_scope('generator'):
    G_z = generator(z)

with tf.variable_scope('discriminator', reuse=tf.AUTO_REUSE):
    D_real = discriminator(x)
    D_fake = discriminator(G_z, reuse=True)

我的整个代码的Tensorflow图如下所示: enter image description here

现在我用' tf.name_scope'尝试了一切。和' tf.variable_scope'但有一件事我不能做,那就是合并操作。 Tensorflow会自动为网络再次创建相同的操作。这意味着,例如在此设置和图表中,它将始终创建' layer_1'和layer_1_2'。我想我明白这一切都在做什么。但我不明白为什么不可能将这个范围扩展到一个层,只有一个操作块和一个生成变量的块。因此,在图表中,内部只有一个网络“鉴别器”。并且选择仅在输入处进行。我认为基本上归结为为什么不可能制作一个图表,在重塑后,网络将其视为一个较大的批次,因为现在操作是相同的?

1 个答案:

答案 0 :(得分:1)

你永远不会在tensorflow中分享操作。假设op有一个固定的输入(在运行期间),再次运行相同的op是没有意义的,因为它会给你相同的输出。

然而,共享权重/变量是有意义的。假设您有一个密集的完全连接的图层,您可以将其应用于两个不同的张量(在您的情况下为假数据和真实数据)。请注意,输入是不同的,因此这些将是不同的操作。使用tf.variable_scope(..., reuse=tf.AUTO_REUSE)重用变量。

如果你真的想在你的图中有一个操作,一个选项是将输入连接成一个看起来像当前批量大小两倍的批量并在连接张量上运行op。通过这种方式,您可以确保对两个输入应用相同的操作,并且可能会获得一些小的速度提升(类似于从较大批次获得的操作)。