当前位置:  开发笔记 > 编程语言 > 正文

TensorFlow中variable_scope和name_scope之间的区别

如何解决《TensorFlow中variable_scope和name_scope之间的区别》经验,为你挑选了2个好方法。

variable_scope和之间有什么区别name_scope?该变量的作用域教程挂在嘴边variable_scope隐含打开name_scope.我还注意到,在a中创建变量也会name_scope自动扩展其名称以及作用域名称.那么区别是什么呢?



1> Salvador Dal..:

在尝试通过创建一个简单示例来可视化所有内容之前,我在理解variable_scope和name_scope之间的区别(它们看起来几乎相同)时遇到了问题:

import tensorflow as tf
def scoping(fn, scope1, scope2, vals):
    with fn(scope1):
        a = tf.Variable(vals[0], name='a')
        b = tf.get_variable('b', initializer=vals[1])
        c = tf.constant(vals[2], name='c')
        with fn(scope2):
            d = tf.add(a * b, c, name='res')

        print '\n  '.join([scope1, a.name, b.name, c.name, d.name]), '\n'
    return d

d1 = scoping(tf.variable_scope, 'scope_vars', 'res', [1, 2, 3])
d2 = scoping(tf.name_scope,     'scope_name', 'res', [1, 2, 3])

with tf.Session() as sess:
    writer = tf.summary.FileWriter('logs', sess.graph)
    sess.run(tf.global_variables_initializer())
    print sess.run([d1, d2])
    writer.close()

在这里,我创建了一个函数,它创建了一些变量和常量,并在范围内对它们进行分组(取决于我提供的类型).在这个函数中,我还打印所有变量的名称.之后,我执行图形以获取结果值的值并保存事件文件以在tensorboard中调查它们.如果你运行它,你将得到以下内容:

scope_vars
  scope_vars/a:0
  scope_vars/b:0
  scope_vars/c:0
  scope_vars/res/res:0 

scope_name
  scope_name/a:0
  b:0
  scope_name/c:0
  scope_name/res/res:0 

如果打开TB,您会看到类似的模式(如您所见b,在scope_name矩形之外): 在此输入图像描述


这给你答案:

现在你看到tf.variable_scope()为所有变量的名称添加前缀(无论你如何创建它们),ops,常量.另一方面tf.name_scope()忽略使用创建的变量,tf.get_variable()因为它假设您知道要使用哪个变量以及在哪个范围内.

关于共享变量的好文档告诉你

tf.variable_scope():管理传递给的名称的名称空间tf.get_variable().

相同的文档提供了有关变量范围如何工作以及何时有用的更多详细信息.


我建议通过删除`vals`参数来简化这个非常有用的例子
我还建议从'res'更改'd'的名称.我假设这与你作为scope2传入的'res'无关.

2> cesarsalgado..:

当您使用tf.get_variable而不是创建变量时tf.Variable,Tensorflow将开始检查使用相同方法创建的变量的名称,以查看它们是否发生冲突.如果他们这样做,将引发例外.如果您tf.get_variable使用tf.name_scope上下文管理器创建了一个var 并尝试更改变量名的前缀,则这不会阻止Tensorflow引发异常.tf.variable_scope在这种情况下,只有上下文管理器才能有效地更改var的名称.或者,如果要重用变量,则应在第二次创建var之前调用scope.reuse_variables().

总之,tf.name_scope只需为该范围内创建的所有张量添加前缀(除了使用其创建的变量tf.get_variable),并tf.variable_scope为使用的变量添加前缀tf.get_variable.


您能否再说一下为什么需要两种范围机制?
我可以推测.我认为存在两种创建变量的方法(tf.Variable和tf.get_variable)的原因是因为通常你不想共享一个变量.如果要共享,则需要使用tf.get_variable创建var,并使用tf.variable_scope更改范围,以明确表示您正在处理可共享的变量.如果在这种情况下可以使用tf.name_scope,可能会降低代码的可读性.
我不知道.也许你应该在github上创建一个问题,要求更好地记录这两种机制之间的区别.
推荐阅读
周扒pi
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有