在TensorFlow中处理多个图

在TensorFlow中处理多个图,tensorflow,Tensorflow,有人能给我解释一下在TensorFlow中,name\u scope是如何工作的吗 假设我有以下代码: 将tensorflow导入为tf g1=tf.Graph() 将g1.as_default()作为g: 以g.name_范围(“g1”)作为范围: matrix1=tf.常数([[3,3.]] matrix2=tf.常数([[2.],[2.]] product=tf.matmul(matrix1,matrix2) tf.reset_default_graph() g2=tf.Graph() 将

有人能给我解释一下在TensorFlow中,
name\u scope
是如何工作的吗

假设我有以下代码:

将tensorflow导入为tf
g1=tf.Graph()
将g1.as_default()作为g:
以g.name_范围(“g1”)作为范围:
matrix1=tf.常数([[3,3.]]
matrix2=tf.常数([[2.],[2.]]
product=tf.matmul(matrix1,matrix2)
tf.reset_default_graph()
g2=tf.Graph()
将g2.as_default()作为g:
以g.name_范围(“g2”)作为范围:
matrix1=tf.常数([[4,4.]]
matrix2=tf.常数([[5.],[5.]]
product=tf.matmul(matrix1,matrix2)
tf.reset_default_graph()
将tf.Session(graph=g1)作为sess:
结果=sess.run(产品)
打印(结果)
运行此代码时,会收到以下错误消息:

Tensor Tensor("g2/MatMul:0", shape=(1, 1), dtype=float32) is not an element of this graph.
我同意“g2/MatMul”不是图
g1
的一个元素,但当会话图设置为
g1
时,为什么选择“g2/MatMul”?为什么不选择“g1/MatMul”


编辑 以下代码似乎有效:

将tensorflow导入为tf
g1=tf.Graph()
将g1.as_default()作为g:
g.name_范围(“g1”)作为g1_范围:
matrix1=tf.常数([[3,3.]]
matrix2=tf.常数([[2.],[2.]]
product=tf.matmul(matrix1,matrix2,name=“product”)
tf.reset_default_graph()
g2=tf.Graph()
将g2.as_default()作为g:
g.name_范围(“g2”)作为g2_范围:
matrix1=tf.常数([[4,4.]]
matrix2=tf.常数([[5.],[5.]]
product=tf.matmul(matrix1,matrix2,name=“product”)
tf.reset_default_graph()
使用_g1=False
如果(使用_g1):
g=g1
范围=g1\u范围
其他:
g=g2
范围=g2\U范围
将tf.Session(graph=g)作为sess:
tf.初始化所有变量()
结果=sess.run(sess.graph.get_tensor_by_name(作用域+“产品:0”))
打印(结果)

通过翻转开关
use_g1
,会话中将运行图形
g1
g2
。这就是名称范围界定的工作方式吗?

您的
产品是一个全局变量,您已将其设置为指向“g2/MatMul”

特别是

试一试

你会看到的

Tensor("g2/MatMul:0", shape=(1, 1), dtype=float32)
因此,系统采用“g2/MatMul:0”
,因为这是张量的名称,并尝试在图
g1
中找到它,因为这是为会话设置的图。顺便说一句,您可以看到图形中的所有节点
print[n.name代表g1中的n.as_graph\u def().node]

通常,使用多个图形很少有用。不能合并它们,也不能在它们之间传递张量。我建议你就这么做

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

这样,您将拥有一个默认图形和一个默认会话,并且在大多数情况下可以省略指定图形或会话。如果您需要显式引用它们,可以从
tf.get\u default\u graph()
tf.get\u default\u session()

处理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个图(g1或g2)

您可以通过id()看到3个图形

使用“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 )
以上代码工作

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


用类封装是好的?

这是一个很好的necro,但它仍然是与此相关的问题的顶级搜索结果,我认为它可能有助于使前面的答案(正确的)附带指出的一些非常明确的东西:

Q的变量
product
是一个python变量。因此,它指向一个对象:定义时,它指向matmul
tf.Operation的
tf.Tensor
输出,该输出定义在名称范围“g1”中。它后来被重新定义为指向另一个对象,即“g2”的
tf.Tensor
输出。这个python变量从未听说过
tf.name\u scope
s,也不在乎

这就是为什么需要通过tensorflow对象的名称属性进行查找。。。通过使用name_作用域,它们是唯一的且可访问的。或者生成不同的python变量——根据python作用域规则,这些变量是唯一和可访问的——以指向要引用的每个
tf.Tensor
对象


不知道这对其他人是否有帮助,但如果我忘记了,我会为此感谢我过去的自己。

你的问题是你调用的是最新的变量
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 )

我已经写了两段代码来做你想做的事情

第一个在图形之间切换,不使用name\u范围。第二种方法对这两种操作都使用默认的_图,并使用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)我已经取消了“product”变量,并为操作指定了一个名称

重要的开关码是

product_op = g2.get_tensor_by_name(  "productX:0" )
其中,我们使用两个图的变量名来区分两个产品ops

请注意,必须将恼人的“:0”放在变量名的末尾

现在使用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\u 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" )