在TensorFlow中使用多个图形

时间:2016-03-12 07:50:30

标签: tensorflow

有人可以向我解释一下name_scope在TensorFlow中的运作方式吗?

假设我有以下代码:

import tensorflow as tf

g1 = tf.Graph()
with g1.as_default() as g:
    with g.name_scope( "g1" ) as scope:
        matrix1 = tf.constant([[3., 3.]])
        matrix2 = tf.constant([[2.],[2.]])
        product = tf.matmul(matrix1, matrix2)

tf.reset_default_graph()

g2 = tf.Graph()
with g2.as_default() as g:
    with g.name_scope( "g2" ) as scope:
        matrix1 = tf.constant([[4., 4.]])
        matrix2 = tf.constant([[5.],[5.]])
        product = tf.matmul(matrix1, matrix2)

tf.reset_default_graph()

with tf.Session( graph = g1 ) as sess:
    result = sess.run( product )
    print( result )

当我运行此代码时,我收到以下错误消息:

Tensor Tensor("g2/MatMul:0", shape=(1, 1), dtype=float32) is not an element of this graph.

我同意" g2 / MatMul"不是图g1的元素,但为什么选择" g2 / MatMul"会话图设置为g1时?为什么不选择" g1 / MatMul"?

修改

以下代码似乎有效:

import tensorflow as tf

g1 = tf.Graph()
with g1.as_default() as g:
    with g.name_scope( "g1" ) as g1_scope:
        matrix1 = tf.constant([[3., 3.]])
        matrix2 = tf.constant([[2.],[2.]])
        product = tf.matmul( matrix1, matrix2, name = "product")

tf.reset_default_graph()

g2 = tf.Graph()
with g2.as_default() as g:
    with g.name_scope( "g2" ) as g2_scope:
        matrix1 = tf.constant([[4., 4.]])
        matrix2 = tf.constant([[5.],[5.]])
        product = tf.matmul( matrix1, matrix2, name = "product" )

tf.reset_default_graph()

use_g1 = False

if ( use_g1 ):
    g = g1
    scope = g1_scope
else:
    g = g2
    scope = g2_scope

with tf.Session( graph = g ) as sess:
    tf.initialize_all_variables()
    result = sess.run( sess.graph.get_tensor_by_name( scope + "product:0" ) )
    print( result )

通过翻转开关use_g1,图表g1g2将在会话中运行。这是名称范围界定的方式吗?

6 个答案:

答案 0 :(得分:16)

您的product是一个全局变量,并且您已将其设置为指向" g2 / MatMul"。

特别是

尝试

print product

你会看到

Tensor("g2/MatMul:0", shape=(1, 1), dtype=float32)

因此系统会使用"g2/MatMul:0",因为这是Tensor的名称,并尝试在图g1中找到它,因为那是您为其设置的图表会议。顺便提一下,您可以在图print [n.name for n in g1.as_graph_def().node]

中查看所有节点

通常,使用多个图表很少有用。您无法合并它们,也无法在它们之间传递张量。我建议只做

tf.reset_default_graph()
a = tf.Constant(2)
sess = tf.InteractiveSession()
....

通过这种方式,您将拥有一个默认图表和一个默认会话,并且在大多数情况下您可以省略指定图表或会话。如果您需要明确地引用它们,可以从tf.get_default_graph()tf.get_default_session()

获取它们

答案 1 :(得分:6)

这是一个非常糟糕的问题,但它仍然是与此相关的问题的最佳搜索结果,我认为可能有助于明确说明先前的答案(正确的)顺便说明:< / p>

Q的变量product python 变量。因此,它指向一个对象:当定义时,它指向name_scope&#39; g1&#39;中定义的matmul tf.Tensor的{​​{1}}输出。稍后将其重新定义为指向另一个对象,即&#39; g2&#39;的tf.Operation输出。这个python变量从未听说过tf.Tensor s并且不关心。

是你需要通过tensorflow对象的名称属性进行查找的原因......通过使用name_scopes,这些是唯一且可访问的。或者生成不同的python变量 - 根据python作用域规则是唯一且可访问的 - 指向要引用的每个tf.name_scope对象。

Dunno如果这对其他人有帮助,但如果我忘记了,我会感谢我过去的自我。

答案 2 :(得分:2)

我在处理IPython笔记本上的多个图表时遇到了类似的困难。对我来说有用的是将每个图及其会话封装在一个函数中。我知道这更像是一个黑客,我猜,我对命名空间一无所知,而且我知道OP需要这些内容。也许它会帮助我不知道的人,你也可以在计算之间传递结果。

import tensorflow as tf

def Graph1():
    g1 = tf.Graph()
    with g1.as_default() as g:
        matrix1 = tf.constant([[3., 3.]])
        matrix2 = tf.constant([[2.],[2.]])
        product = tf.matmul( matrix1, matrix2, name = "product")

    with tf.Session( graph = g ) as sess:
        tf.initialize_all_variables().run()
        return product


def Graph2(incoming):
    i = incoming
    g2 = tf.Graph()
    with g2.as_default() as g:
        matrix1 = tf.constant([[4., 4.]])
        matrix2 = tf.constant([[5.],[5.]])
        product = tf.matmul( matrix1, matrix2, name = "product" )

    with tf.Session( graph = g ) as sess:
        tf.initialize_all_variables().run()
        print product
        print i

print Graph1()

Graph2(Graph1())

答案 3 :(得分:2)

你的问题是你正在调用最新变量product,它指向在g2上创建的张量 - 你在第二个范围内覆盖了它。只需重新标记所有变量,你就应该好好去。工作代码如下。

import tensorflow as tf

g1 = tf.Graph() with g1.as_default() as g:
    with g.name_scope( "g1" ) as scope:
        matrix11 = tf.constant([[3., 3.]])
        matrix21 = tf.constant([[2.],[2.]])
        product1 = tf.matmul(matrix11, matrix21)

tf.reset_default_graph()

g2 = tf.Graph() with g2.as_default() as g:
    with g.name_scope( "g2" ) as scope:
        matrix12 = tf.constant([[4., 4.]])
        matrix22 = tf.constant([[5.],[5.]])
        product2 = tf.matmul(matrix12, matrix22)

tf.reset_default_graph()

with tf.Session( graph = g1 ) as sess:
    result = sess.run( product1 )
    print( result )

答案 4 :(得分:0)

你有3张图,而不是2张图(g1或g2)。

您可以通过id()

查看3个图表
...

print 'g1           ', id(g1)
print 'g2           ', id(g2)
print 'current graph', id ( tf.get_default_graph() )

with tf.Session( graph = g1 ) as sess:
    result = sess.run( product )
    print( result )

使用“with g1.as_default():”犯同样的错误

...

with g1.as_default() :
    with tf.Session( graph = g1 ) as sess:
        result = sess.run( product )
        print( result )

因为,你有两个'产品',而不是一个。

g1 = tf.Graph()
with g1.as_default() as g:
    ...
    print 'g1 product', id ( product )

...

g2 = tf.Graph()
with g2.as_default() as g:
    ...
    print 'g2 product', id ( product )

with tf.Session( graph = g1 ) as sess:
    print 'last product', id(product)
    ...

上一个产品== g2产品

...
    product = tf.matmul(matrix1, matrix2, name='g1_product')
...
with g1.as_default() as g:
    with tf.Session() as sess:
        product = g.get_tensor_by_name(  "g1_product:0" )
        result = sess.run( product )
        print( result )

以上代码工作。

但是,两个具有相同名称的变量(产品)

封装类很好吗?

答案 5 :(得分:0)

我写了两个片段来做你想做的事。

第一个在图形之间切换,不使用name_scope。第二个使用default_graph用于两个操作并使用name_scope在它们之间切换......

import tensorflow as tf

g1 = tf.Graph()
with g1.as_default() as g:
  matrix1 = tf.constant([[3., 3.]])
  matrix2 = tf.constant([[2.],[2.]])
  tf.matmul(matrix1, matrix2, name="productX")

g2 = tf.Graph()
with g2.as_default() as g:
  matrix1 = tf.constant([[4., 4.]])
  matrix2 = tf.constant([[5.],[5.]])
  tf.matmul(matrix1, matrix2, name="productX")

product_op = g1.get_tensor_by_name(  "productX:0" )
with tf.Session( graph = g1 ) as sess:
    result = sess.run( product_op )
    print( result )

product_op = g2.get_tensor_by_name(  "productX:0" )
with tf.Session( graph = g2 ) as sess:
  result = sess.run( product_op )
  print( result )

注意A)我已经取消了默认图表的重置(从不使用默认图表)和B)我已经摆脱了&#39;产品&#39;变量并给操作命名,而不是

重要的切换代码是......

product_op = g2.get_tensor_by_name(  "productX:0" )

我们使用两个图的变量名来区分两个产品操作。

注意烦人的&#39;:0&#39;你必须把它放在变量名的末尾。

现在使用name_scope ...

import tensorflow as tf

g = tf.get_default_graph()

matrix1 = tf.constant([[3., 3.]])
matrix2 = tf.constant([[2.],[2.]])
with g.name_scope("prodA"):
  tf.matmul(matrix1, matrix2, name="productX")

matrix1 = tf.constant([[4., 4.]])
matrix2 = tf.constant([[5.],[5.]])
with g.name_scope("prodB"):
  tf.matmul(matrix1, matrix2, name="productX")

with tf.Session() as sess:

  product_op = g.get_tensor_by_name(  "prodA/productX:0" )
  result = sess.run( product_op )
  print( result )

  product_op = g.get_tensor_by_name(  "prodB/productX:0" )
  result = sess.run( product_op )
  print( result )

现在代码的切换线就是这个......

product_op = g.get_tensor_by_name(  "prodB/productX:0" )

注意A)图表或会话之间没有切换。 B)name_scope为您提供了一种名称层次结构的目录结构。

graph vs name_scope切换的优点和缺点是什么?如果有人写了博客,我会读它!

然而,我并不认为图表和会话之间的切换速度非常快。