一、tf.name_scope的作用
在讲values的作用之前,我首先简单讲下tf.name_scope这个函数是用来干嘛的,已经了解tf.name_scope作用的读者可以直接跳过到第二部分。
tf.name_scope这个函数的目的是为了解决命名冲突问题,其接口如下:
tf.name_scope(name,default_name=None,values=None)
tf.name_scope具体用法如下例所示:
with tf.name_scope(None, "test_default_name",None):
op = tf.constant(0)
print(op.name) # 输出 test_default_name/Const:0
with tf.name_scope("test_name", "test_default_name",None):
op = tf.constant(0)
print(op.name) # 输出 test_name/Const:0
二、values这个参数的作用
从上面的例子可以看出,name和default_name这两个参数已经足以解决“命名冲突”问题了,那values这个参数不是多余的么?其实不然,values这个参数的规定了应该把在with tf.name_scope区域里生成的tensor放到哪个计算图(graph)里。更具体地讲,在with tf.name_scope(values)这个区域内声明的tensor,都被放到了values所在的graph里。该功能的意义在于,它为我们省去了显式地声明某些tensor需要被放在哪个图中的麻烦。另外,需要注意的是,values里的所有tensor都应该在同一个图里,否则会报错。
为什么需要规定把tensor放在哪个图里呢?因为,在编写比较复杂的程序时,不同的tensor可能需要被放在不同的graph里。例如,在需要对多个tensor进行并行计算时,我们可以把它们放进不同的graph里,然后分别丢给不同的session去run。
最后,我们可以通过一段代码来更直观地感受下values的作用。这段代码对比了在with tf.name_scope中使用values和不使用values的区别。可以看出,不用values时,在with tf.name_scope中声明的tensor都被放进了当前的“默认图”中。使用values时,在with tf.name_scope中声明的tensor被放进了tensor A所在的图中,即graph_tensor这个图中。
graph_tensor = tf.Graph()
with graph_tensor.as_default():
A = tf.constant(1)
graph_1 = tf.Graph()
graph_1.as_default()
with tf.name_scope(None, "namescope_1"):
op1 = tf.constant(0)
graph_2 = tf.Graph()
graph_2.as_default()
with tf.name_scope(None, "namescope_2",[A]):
op2 = tf.constant(0)
print(op1.graph == graph_tensor) # 输出 false
print(op2.graph == graph_tensor) # 输出 true
#结论 一个tf.name_scope里的新声明的tensor被放在了values所在的图里