有人可以向我解释一下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
,图表g1
或g2
将在会话中运行。这是名称范围界定的方式吗?
答案 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切换的优点和缺点是什么?如果有人写了博客,我会读它!
然而,我并不认为图表和会话之间的切换速度非常快。