tensorflow 中 variable_scope 与name_scope函数解析

时间:2021-08-25 13:38:12

前言

还是那句老话,学习tensorflow最好的方法就是阅读他的官方API手册
知乎上面一个有意思的问答:tensorflow里面name_scope, variable_scope等如何理解?

先引用知乎上答主的话:

主要是因为 变量共享 的需求。而这就不得不谈到tf. get_variable()了。因为如果使用Variable 的话每次都会新建变量,但是大多数时候我们是希望一些变量重用的,所以就用到了get_variable()。它会去搜索变量名,然后没有就新建,有就直接用。既然用到变量名了,就涉及到了名字域的概念。通过不同的域来区别变量名,毕竟让我们给所有变量都直接取不同名字还是有点辛苦的。所以为什么会有scope 的概念。name_scope 作用于操作,variable_scope 可以通过设置reuse 标志以及初始化方式来影响域下的变量。当然对我们而言还有个更直观的感受就是:在tensorboard 里可视化的时候用名字域进行封装后会更清晰

作者:ycszen
链接:https://www.zhihu.com/question/54513728/answer/177901159
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
(这个表述里存在一点问题,即只有在非重用scope环境下get_variable才会在没有找到变量的时候创建新的变量,否则会报错)

相似函数及解析

开门见山:
name_scope
op_scope
variable_scope
variable_op_scope
VariableScope

四个函数(一个类)(有可能不全),简单来说,都是创造命名空间(返回上下文管理器),使得其域内变量加上(参数)前缀,这样能够简化编程过程中的参数命名,并且让代码更为简洁易读。
例如:
通过 with tf.name_scope(‘conv1’) as scope: 可以将scope 内生成的Variable 自动命名为 conv1/xxx,便于区分不同卷积层之间的组件。

name_scope:

此函数参数最为简单:
name_scope(
name,
default_name=None,
values=None
)

name 当然是scope 名称,当name 为none时, 该scope名称就由default_name 来,当前两项都为空而values不为空时,就会报错。 此外,name不允许以’/’结尾。
values是传入的张量参数列表。

注意

with name_scope(…) 与with name_scope(…) as scope 的区别:
后者将该域的名字储存在了scope变量中。

op_scope

op_scope( values, name, default_name=None )

官方不推荐使用
与name_scope唯一差别为参数顺序。

variable_scope

variable_scope(
    name_or_scope,
    default_name=None,
    values=None,
    initializer=None,
    regularizer=None,
    caching_device=None,
    partitioner=None,
    custom_getter=None,
    reuse=None,
    dtype=None,
    use_resource=None
)

name_or_scope、default_name和values参数与name_scope中的第一和第二项参数几乎是一样的(第一个参数除了名称外还可以是scope)。
initializer是选用的变量初始化器;
regularizer是选用的变量正则化器;
caching_device: default caching device for variables within this scope.
partitioner: default partitioner for variables within this scope.
custom_getter: default custom getter for variables within this scope.
(这三个就不翻译了,我没用过)

reuse 是一个很关键的参数,当reuse=True时,开启了重用模式(参数共享模式),使用get_variable创建变量时,会搜索现有的同名变量(没有就会报错),举个例子(官方例子):

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

或者:

with tf.variable_scope("foo") as scope:
    v = tf.get_variable("v", [1])
    scope.reuse_variables()
    v1 = tf.get_variable("v", [1])
assert v1 == v

reuse参数是会继承的,你懂的。

dtype:数据类型;
use_resource: If False, all variables will be regular Variables. If True, experimental ResourceVariables with well-defined semantics will be used instead. Defaults to False (will later change to True).

可能的报错:

ValueError:在重用模式下创建变量或非重用模式下重用变量;(即前边提到的知乎答主的表述问题)
TypeError:参数有问题。

variable_op_scope

variable_op_scope(
    values,
    name_or_scope,
    default_name=None,
    initializer=None,
    regularizer=None,
    caching_device=None,
    partitioner=None,
    custom_getter=None,
    reuse=None,
    dtype=None,
    use_resource=None
)

官方不推荐

VariableScope

VariableScope是定义在variable_scope.py 中的一个类,

__init__(
    reuse,
    name='',
    initializer=None,
    regularizer=None,
    caching_device=None,
    partitioner=None,
    custom_getter=None,
    name_scope='',
    dtype=tf.float32,
    use_resource=None
)

嗯,此处戛然而止。