name_scope与variable_scope
写这篇文章的时候自己理解得并不好,所以不建议大家参考。
最近在使用Keras,这个库可以选择backend,它有三个backend,包括:TensorFlow,CNTK,Theano。我选择使用的是TensorFlow作为backend,在Keras的optimizers.py文件中有:
from . import backend as K
...
if K.backend() == 'tensorflow':
import tensorflow as tf
...
with K.name_scope(self.__class__.__name__):
...
也就是说,其中用到了TensorFlow的name_scope,所以我们在这里再来回顾一下name_scope与variable_scope。
首先我们来看一段代码:
with tf.name_scope("helloworld") as name_scope:
arr1=tf.get_variable("arr1",shape=[2,10],dtype=tf.float32)
print name_scope
print arr1.name
print "scope_name:%s" % tf.get_variable_scope().original_name_scope
输出结果如下:
由上面可知,1)tf.name_scope()返回的是一个string;2)在name_scope中定义的variable的name并没有helloworld/前缀;3)tf.get_variable_scope()的original_name_scope为空。
下面,我们通过一段代码来对variable_scope进行实验:
with tf.variable_scope("hello") as variable_scope:
arr1 = tf.get_variable("arr1", shape=[2, 10], dtype=tf.float32)
print variable_scope
print variable_scope.name
print arr1.name
print tf.get_variable_scope().original_name_scope
with tf.variable_scope("hi") as v_scope2:
print tf.get_variable_scope().original_name_scope
这段代码的输出为:
可以看出来,1)tf.variable_scope()返回的是一个op对象;2)我们在variable_scope中定义的variable的name加上了"hello/"的前缀;3)tf.get_variable_scope()的original_name_scope是嵌套后的scope name。
那如果我们将name_scope与variable_scope一起使用会有怎样的效果呢?
with tf.name_scope("name1"):
with tf.variable_scope("var1"):
w = tf.get_variable("w",shape=[2])
op_add = tf.add(w,[3])
print w.name
print op_add.name
输出结果为:
可见,无论是name_scope还是variable_scope都会给op加上前缀。
综上,1)name_scope对于get_variable()创建的变量的名字不会有任何影响,而我们在其中创建的op将会被加上前缀;2)tf.get_variable_scope()返回的只是variable_scope,并不管name_scope,所以我们在使用tf.get_variable_scope().reuse_variables()时可以无视name_scope。
不过,值得注意的是,name_scope虽然对于使用get_variable()创建的变量的名字不会有影响,但是对于使用tf.Variable()创建的变量的名字是有影响的:
with tf.name_scope("name1"):
a=tf.Variable(0,dtype='int64',name='a')
b=tf.get_variable("b",shape=[3])
print a.name
print b.name
得到的结果为:
也就是说,name_scope会为利用tf.Variable()创建的变量加上前缀。