2015-12-11 3 views
52

В чем разница между variable_scope и name_scope? variable scope tutorial рассказывает о variable_scope неявно открытии name_scope. Я также заметил, что создание переменной в name_scope автоматически расширяет свое имя с именем области. Так в чем же разница?Разница между переменной_scope и name_scope в TensorFlow

+0

FYI [В чем разница в области имени и переменной области в тензорном потоке?] (Http://stackoverflow.com/q/35919020/395857) –

+0

Я видел :-) Спасибо за обмен. Должен ли мы отметить этот вопрос как дубликат другого вопроса? –

+0

Возможный дубликат [Какая разница в области имен и области переменных в тензорном потоке?] (Https://stackoverflow.com/questions/35919020/whats-the-difference-of-name-scope-and-a-variable- scope-in-tensorflow) –

ответ

34

Когда вы создаете переменную с tf.get_variable вместо tf.Variable, Tensorflow начнет проверять имена варов, созданных с помощью того же метода, чтобы увидеть, столкнулись ли они. Если они это сделают, будет сделано исключение. Если вы создали var с tf.get_variable, и вы пытаетесь изменить префикс имен переменных с помощью диспетчера контекстов tf.name_scope, это не помешает Tensorflow для создания исключения. Контент-менеджер tf.variable_scope эффективно изменит имя вашего var в этом случае. Или если вы хотите повторно использовать переменную, вы должны вызвать scope.reuse_variables() перед созданием var во второй раз.

В целом, tf.name_scope просто добавить префикс для всех тензора, созданного в этой области видимости (кроме Варса, созданный с tf.get_variable) и tf.variable_scope добавить префикс к переменным, созданному с tf.get_variable.

+4

Не могли бы вы сказать немного больше о том, почему нужны два механизма обзора? –

+2

Не знаю. Возможно, вы должны создать проблему в github, чтобы лучше документировать разницу между этими двумя механизмами. – cesarsalgado

+4

Я могу предположить. Я думаю, что причиной существования двух способов создания переменной (tf.Variable и tf.get_variable) является то, что обычно вы не хотите делиться переменной. Если вы хотите поделиться потом, вам нужно создать var с tf.get_variable и использовать tf.variable_scope, чтобы изменить область, чтобы четко указать, что вы обрабатываете совместно используемые вары. Если бы в этом случае можно было использовать tf.name_scope, возможно, это уменьшило бы читаемость кода. – cesarsalgado

28

У меня были проблемы с пониманием разницы между 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() 

Здесь я создаю функцию, которая создает некоторые переменные и константы и группирует их в области (в зависимости от типа I). В этой функции я также печатаю имена всех переменных. После этого я выполняю график, чтобы получить значения полученных значений и сохранить файлы событий, чтобы исследовать их в тензограмме. Если запустить это, вы получите следующее:

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 

Вы видите подобную картину, если вы открыты ТБ (как вы видите b находится вне scope_name прямоугольной): enter image description here


Это дает вам ответ:

Теперь вы видите, что tf.variable_scope() добавляет префикс к именам всех переменных (независимо от того, как вы создать их), ops, константы. С другой стороны, tf.name_scope() игнорирует переменные, созданные с помощью tf.get_variable(), потому что предполагается, что вы знаете, какую переменную и в какой области вы хотели использовать.

Хорошая документация по Sharing variables говорит вам, что

tf.variable_scope(): Управление пространств имен для имен переданных tf.get_variable().

В той же документации приводится более подробная информация о том, как работает переменная область действия и когда она полезна.

+0

Я бы предложил упростить этот очень полезный пример, отбросив аргумент 'vals' –

+0

Я также предложил бы изменить имя 'd' из 'res'. Я предполагаю, что это не связано с «res», которое вы передали как scope2. –