Как вы можете повторно использовать переменную область в тензорном потоке без создания новой области по умолчанию?

Я создал переменную область в одной части моего графика, а позже в другой части графика я хочу добавить 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, как повторно использовать имя области видимости


person David Parks    schedule 14.03.2018    source источник


Ответы (2)


Вот один простой способ сделать это, используя as с somename в менеджере контекста. Используя это свойство 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, вы все равно получите тот же результат.

person kmario23    schedule 14.03.2018
comment
var2 не ниже myscope, я что-то упустил? - person David Parks; 14.03.2018
comment
Вы случайно не знаете, есть ли способ запросить tensorflow для ms1 в этом примере? В моем фактическом использовании я не создавал исходную область переменных, она была создана для меня в тензорном потоке, и я на самом деле просто пытаюсь добавить некоторые переменные в эту область. Это часть реализации оптимизатора, и тензорный поток обрабатывает некоторые области видимости таким образом, который не обрабатывался фреймворком для одной детали моего варианта использования. Если не беспокойтесь, есть альтернативный способ справиться с этим. - person David Parks; 14.03.2018
comment
Ах, вы можете просто использовать tf.variable_scope('myscope/'): вместо tf.variable_scope(ms1.original_name_scope) Я не знал, что использование '/' было необходимо. Теперь все это имеет смысл! Спасибо еще раз. - person David Parks; 15.03.2018

Ответ, упомянутый 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>
person Kipsora Lawrence    schedule 07.09.2018