如何在没有默认创建新范围的情况下在tensorflow中重用变量范围?

问题描述 投票:7回答:2

我在图的一部分中创建了一个变量作用域,稍后在图的另一部分中我想将OP添加到现有作用域。这相当于这个蒸馏的例子:

import tensorflow as tf

with tf.variable_scope('myscope'):
  tf.Variable(1.0, name='var1')

with tf.variable_scope('myscope', reuse=True):
  tf.Variable(2.0, name='var2')

print([n.name for n in tf.get_default_graph().as_graph_def().node])

产量:

['myscope/var1/initial_value', 
 'myscope/var1', 
 'myscope/var1/Assign', 
 'myscope/var1/read', 
 'myscope_1/var2/initial_value', 
 'myscope_1/var2', 
 'myscope_1/var2/Assign', 
 'myscope_1/var2/read']

我想要的结果是:

['myscope/var1/initial_value', 
 'myscope/var1', 
 'myscope/var1/Assign', 
 'myscope/var1/read', 
 'myscope/var2/initial_value', 
 'myscope/var2', 
 'myscope/var2/Assign', 
 'myscope/var2/read']

我看到这个问题似乎没有直接回答这个问题的答案:TensorFlow, how to reuse a variable scope name

python tensorflow machine-learning deep-learning tensor
2个回答
3
投票

以下是在上下文管理器中使用assomename执行此操作的一种简单方法。使用此somename.original_name_scope属性,您可以检索该范围,然后向其中添加更多变量。以下是插图:

In [6]: with tf.variable_scope('myscope') as ms1:
   ...:   tf.Variable(1.0, name='var1')
   ...: 
   ...: with tf.variable_scope(ms1.original_name_scope) as ms2:
   ...:   tf.Variable(2.0, name='var2')
   ...: 
   ...: print([n.name for n in tf.get_default_graph().as_graph_def().node])
   ...: 
['myscope/var1/initial_value', 
 'myscope/var1', 
 'myscope/var1/Assign', 
 'myscope/var1/read', 
 'myscope/var2/initial_value', 
 'myscope/var2', 
 'myscope/var2/Assign', 
 'myscope/var2/read']

备注 另请注意,设置reuse=True是可选的;也就是说,即使你通过reuse=True,你仍然会得到相同的结果。


另一种方式(感谢OP本人!)只是在重用时将/添加到变量范围的末尾,如下例所示:

In [13]: with tf.variable_scope('myscope'):
    ...:   tf.Variable(1.0, name='var1')
    ...: 
    ...: # reuse variable scope by appending `/` to the target variable scope
    ...: with tf.variable_scope('myscope/', reuse=True):
    ...:   tf.Variable(2.0, name='var2')
    ...: 
    ...: print([n.name for n in tf.get_default_graph().as_graph_def().node])
    ...: 
['myscope/var1/initial_value', 
 'myscope/var1', 
 'myscope/var1/Assign', 
 'myscope/var1/read', 
 'myscope/var2/initial_value', 
 'myscope/var2', 
 'myscope/var2/Assign', 
 'myscope/var2/read']

备注: 请注意,设置reuse=True也是可选的;也就是说,即使你通过reuse=True,你仍然会得到相同的结果。


0
投票

kmario23提到的答案是正确的,但有一个棘手的案例,由tf.get_variable创建的变量:

with tf.variable_scope('myscope'):
    print(tf.get_variable('var1', shape=[3]))

with tf.variable_scope('myscope/'):
    print(tf.get_variable('var2', shape=[3]))

此代码段将输出:

<tf.Variable 'myscope/var1:0' shape=(3,) dtype=float32_ref>
<tf.Variable 'myscope//var2:0' shape=(3,) dtype=float32_ref>

似乎tensorflow还没有提供正式的方法来处理这种情况。我找到的唯一可能的方法是手动分配正确的名称(警告:不保证正确性):

with tf.variable_scope('myscope'):
    print(tf.get_variable('var1', shape=[3]))

with tf.variable_scope('myscope/') as scope:
    scope._name = 'myscope'
    print(tf.get_variable('var2', shape=[3]))

然后我们可以得到正确的名字:

<tf.Variable 'myscope/var1:0' shape=(3,) dtype=float32_ref>
<tf.Variable 'myscope/var2:0' shape=(3,) dtype=float32_ref>
© www.soinside.com 2019 - 2024. All rights reserved.