Об именах переменной scope в тензорном потоке

Недавно я пытался научиться использовать TensorFlow, и я не понимаю, как работают переменные области. В частности, у меня есть следующая проблема:

import tensorflow as tf
from tensorflow.models.rnn import rnn_cell
from tensorflow.models.rnn import rnn

inputs = [tf.placeholder(tf.float32,shape=[10,10]) for _ in range(5)]
cell = rnn_cell.BasicLSTMCell(10)
outpts, states = rnn.rnn(cell, inputs, dtype=tf.float32)

print outpts[2].name
# ==> u'RNN/BasicLSTMCell_2/mul_2:0'

Откуда '_2' в 'BasicLSTMCell_2'? Как это работает, если позже использовать tf.get_variable(reuse=True), чтобы снова получить одну и ту же переменную?

edit: Я думаю, что я нашел связанную проблему:

def creating(s):
    with tf.variable_scope('test'):
        with tf.variable_scope('inner'):
            a=tf.get_variable(s,[1])
    return a

def creating_mod(s):
    with tf.variable_scope('test'):
        with tf.variable_scope('inner'):
            a=tf.Variable(0.0, name=s)
    return a

tf.ops.reset_default_graph()
a=creating('a')
b=creating_mod('b')
c=creating('c')
d=creating_mod('d')

print a.name, '\n', b.name,'\n', c.name,'\n', d.name

Выходной сигнал

test/inner/a:0 
test_1/inner/b:0 
test/inner/c:0 
test_3/inner/d:0

Я смущен...

Ответ 1

"_2" в "BasicLSTMCell_2" относится к области имен, в которой был создан op outpts[2]. Каждый раз, когда вы создаете новую область имен (tf.name_scope()) или область видимости переменной (tf.variable_scope()) уникальный уникальный суффикс добавляется в текущую область имен на основе данной строки, возможно, с дополнительным суффиксом, чтобы сделать ее уникальной. Вызов rnn.rnn(...) имеет следующий псевдокод (упрощенное и использующее общедоступные методы API для ясности):

outputs = []
with tf.variable_scope("RNN"):
  for timestep, input_t in enumerate(inputs):
    if timestep > 0:
      tf.get_variable_scope().reuse_variables()
    with tf.variable_scope("BasicLSTMCell"):
      outputs.append(...)
return outputs

Если вы посмотрите на имена тензоров в outpts, вы увидите, что они следующие:

>>> print [o.name for o in outpts]
[u'RNN/BasicLSTMCell/mul_2:0',
 u'RNN/BasicLSTMCell_1/mul_2:0',
 u'RNN/BasicLSTMCell_2/mul_2:0',
 u'RNN/BasicLSTMCell_3/mul_2:0',
 u'RNN/BasicLSTMCell_4/mul_2:0']

Когда вы вводите новую область имен (путем ввода with tf.name_scope("..."): или with tf.variable_scope("..."):), TensorFlow создает новое уникальное имя для области. При первом вводе области "BasicLSTMCell" TensorFlow использует это имя дословно, потому что ранее оно не использовалось (в области "RNN/"). В следующий раз TensorFlow добавит "_1" к области, чтобы сделать ее уникальной, и так далее до "RNN/BasicLSTMCell_4".

Основное различие между областями переменных и областями имен заключается в том, что область переменной также имеет набор привязок name-to-tf.Variable, Вызывая tf.get_variable_scope().reuse_variables(), мы рекомендуем TensorFlow повторно использовать, а не создавать переменные для области "RNN/" (и ее дочерних элементов) после timestep 0. Это гарантирует правильное распределение весов между несколькими ячейками RNN.

Ответ 2

Ответ выше как-то ошибочный.

Позвольте мне ответить, почему у вас есть два разных имени области, хотя похоже, что вы определили две идентичные функции: creating и creating_mod.

Это просто потому, что вы использовали tf.Variable(0.0, name=s) для создания переменной в функции creating_mod.

ВСЕГДА используйте tf.get_variable, если вы хотите, чтобы ваша переменная была распознана по области!

Подробнее см. issue.

Спасибо!