http://wiki.jikexueyuan.com/project/tensorflow-zh/how_tos/variable_scope.html
变量作用域机制在TensorFlow中主要由两部分组成:
方法 tf.get_variable() 用来获取或创建一个变量,而不是直接调用tf.Variable.它采用的不是像`tf.Variable这样直接获取值来初始化的方法.一个初始化就是一个方法,创建其形状并且为这个形状提供一个张量.
所以,通过tf.get_variable()
就可以避免重复创建变量。
tf.get_variable()
通常我们这样调用tf.variable()
v = tf.get_variable(name, scope, dtype, initializer)
此调用做了有关作用域的两件事中的其中之一,方法调入.总的有两种情况.
tf.get_variable_scope().reuse == False
时,作用域就是为创建新变量所设置的。这种情况下,v将通过tf.Variable所提供的形状和数据类型来重新创建.创建变量的全称将会由当前变量作用域名+所提供的名字所组成,并且还会检查来确保没有任何变量使用这个全称.如果这个全称已经有一个变量使用了,那么方法将会抛出ValueError错误.如果一个变量被创建,他将会用initializer(shape)进行初始化.比如:
with tf.variable_scope("foo"):
v = tf.get_variable("v", [1])
with tf.variable_scope("foo", reuse=True):
v1 = tf.get_variable("v", [1])
assert v1 == v
tf.variable_scope()
变量作用域的主方法带有一个名称,它将会作为前缀用于变量名,并且带有一个重用标签来区分以上的两种情况.嵌套的作用域附加名字所用的规则和文件目录的规则很类似:
with tf.variable_scope("foo"):
with tf.variable_scope("bar"):
v = tf.get_variable("v", [1])
assert v.name == "foo/bar/v:0"
当前变量作用域可以用tf.get_variable_scope()进行检索并且reuse 标签可以通过调用tf.get_variable_scope().reuse_variables()设置为True .
with tf.variable_scope("foo"):
v = tf.get_variable("v", [1])
tf.get_variable_scope().reuse_variables()
v1 = tf.get_variable("v", [1])
assert v1 == v
reuse 参数是不可继承
当开启一个变量作用域,使用一个预先已经存在的作用域时,我们会跳过当前变量作用域的前缀而直接成为一个完全不同的作用域.这就是我们做得完全独立的地方.
with tf.variable_scope("foo") as foo_scope:
assert foo_scope.name == "foo"
with tf.variable_scope("bar")
with tf.variable_scope("baz") as other_scope:
assert other_scope.name == "bar/baz"
with tf.variable_scope(foo_scope) as foo_scope2:
assert foo_scope2.name == "foo" # Not changed.
使用tf.get_variable()允许你重写方法来创建或者重用变量,并且可以被外部透明调用.但是如果我们想改变创建变量的初始化器那要怎么做呢?是否我们需要为所有的创建变量方法传递一个额外的参数呢?那在大多数情况下,当我们想在一个地方并且为所有的方法的所有的变量设置一个默认初始化器,那又改怎么做呢?为了解决这些问题,变量作用域可以携带一个默认的初始化器.他可以被子作用域继承并传递给tf.get_variable() 调用.但是如果其他初始化器被明确地指定,那么他将会被重写.
with tf.variable_scope("foo", initializer=tf.constant_initializer(0.4)):
v = tf.get_variable("v", [1])
assert v.eval() == 0.4 # Default initializer as set above.
w = tf.get_variable("w", [1], initializer=tf.constant_initializer(0.3)):
assert w.eval() == 0.3 # Specific initializer overrides the default.
with tf.variable_scope("bar"):
v = tf.get_variable("v", [1])
assert v.eval() == 0.4 # Inherited default initializer.
with tf.variable_scope("baz", initializer=tf.constant_initializer(0.2)):
v = tf.get_variable("v", [1])
assert v.eval() == 0.2 # Changed default initializer.
tf.variable_scope()
中ops的名称我们讨论 tf.variable_scope 怎么处理变量的名字.但是又是如何在作用域中影响到 其他ops的名字的呢?ops在一个变量作用域的内部创建,那么他应该是共享他的名字,这是很自然的想法.出于这样的原因,当我们用with tf.variable_scope(“name”)时,这就间接地开启了一个tf.name_scope(“name”).比如:
with tf.variable_scope("foo"):
x = 1.0 + tf.get_variable("v", [1])
assert x.op.name == "foo/add"
名称作用域可以被开启并添加到一个变量作用域中,然后他们只会影响到ops的名称,而不会影响到变量.
with tf.variable_scope("foo"):
with tf.name_scope("bar"):
v = tf.get_variable("v", [1])
x = 1.0 + v
assert v.name == "foo/v:0"
assert x.op.name == "foo/bar/add"
https://www.zhihu.com/question/54513728
在建立神经网络的时候,我们会有大量的变量需要建立,为了每个变量名,操作名不重复,但是起名又比较麻烦,所以需要scope这样一个东西,
我们可以用tf.Variable
创建一个新变量,
tf.get_variable
用于获取一个变量,不受name_scope的约束,如果这个变量存在,则获取它,如果不存在,则创建它。
tf.name_scope
主要用于管理一个图里面的op,返回一个以scope_name命名的context manager。一个图会维护一个name_space的堆,每一个namespace可以定义各种op,或者子namespace,以避免各个op之间的命名冲突
tf.variable_scope
一般与tf.name_scope
配合使用,用于管理一个graph中变量的名字。
暂时就先理解为,为了避免重复地编写代码,比如padding,initializer,regularizer这些,可以在arg_scope中指定,那么下面的变量都会带上这些参数,同时也可以override,来自己指定。
tensorflow.contrib.framework.python.ops.arg_scope
tensorflow.contrib.slim.arg_scope
Example of how to use tf.contrib.framework.arg_scope:
from third_party.tensorflow.contrib.layers.python import layers
arg_scope = tf.contrib.framework.arg_scope
with arg_scope([layers.conv2d], padding='SAME',
initializer=layers.variance_scaling_initializer(),
regularizer=layers.l2_regularizer(0.05)):
net = layers.conv2d(inputs, 64, [11, 11], 4, padding='VALID', scope='conv1')
net = layers.conv2d(net, 256, [5, 5], scope='conv2')
The first call to conv2d will behave as follows:
layers.conv2d(inputs, 64, [11, 11], 4, padding='VALID',
initializer=layers.variance_scaling_initializer(),
regularizer=layers.l2_regularizer(0.05), scope='conv1')
The second call to conv2d will also use the arg_scope’s default for padding:
layers.conv2d(inputs, 256, [5, 5], padding='SAME',
initializer=layers.variance_scaling_initializer(),
regularizer=layers.l2_regularizer(0.05), scope='conv2')
tf.contrib.framework.arg_scope(list_ops_or_scope, **kwargs)
Stores the default arguments for the given set of list_ops.
For usage, please see examples at top of the file.
Args:
list_ops_or_scope: List or tuple of operations to set argument scope for or a dictionary containing the current scope. When list_ops_or_scope is a dict, kwargs must be empty. When list_ops_or_scope is a list or tuple, then every op in it need to be decorated with @add_arg_scope to work.
**kwargs:
keyword=value that will define the defaults for each op in list_ops. All the ops need to accept the given set of arguments.
也就是说,list_ops中的所有op都被赋予了arg_scope的参数