Имя переменных Tensorflow изменилось после вызова функции

Я пытаюсь написать свои собственные коды нормализации пакетов. Поэтому я тестирую коды ниже. Чтобы отслеживать среднее онлайн-среднее значение и дисперсию, я передаю их в качестве параметров в функцию getsta(). Однако я обнаружил, что имена «avg_mean» и «avg_variance» изменились. Хотя позже я мог бы принудительно изменить их имена вручную, кажется, что Tensorflow рассматривает каждое имя как отдельную переменную.

def getsta(x,avg_mean,avg_variance):
  print('getsta start...')

  decay=0.9

  mean = tf.get_variable(
          'mean', [1], tf.float32,
          initializer=tf.constant_initializer(0.0, tf.float32))
  variance = tf.get_variable(
          'howvariance', [1], tf.float32,
          initializer=tf.constant_initializer(1.0, tf.float32))
  '''
  if (avg_mean == 0.0): 
      avg_mean = tf.get_variable(
              'avg_mean', [1], tf.float32,
              initializer=tf.constant_initializer(0.0, tf.float32))
  if (avg_variance == 0.0):
      avg_variance = tf.get_variable(
              'avg_variance', [1], tf.float32,
              initializer=tf.constant_initializer(0.0, tf.float32))
  '''
  mean, variance = tf.nn.moments(x, [0], name='moments')

  avg_mean -= (1.0 - decay) * (avg_mean - mean)
  avg_variance -= (1.0 - decay) * (avg_variance - variance)

  return x, mean, variance, avg_mean, avg_variance

def train():
  x1 = tf.constant([1,2,3,4], tf.float32)
  x2 = tf.constant([5,6,7,8], tf.float32)
  x3 = tf.constant([1,3,5,7], tf.float32)
  x4 = tf.constant([4,8,12,16], tf.float32)

  with tf.variable_scope("AAA") as scopeA:
    avg_mean1 = tf.get_variable(
              'test1', [1], tf.float32,
              initializer=tf.constant_initializer(0.0, tf.float32))
    avg_variance1 = tf.get_variable(
              'test2', [1], tf.float32,
              initializer=tf.constant_initializer(0.0, tf.float32))
    print([avg_mean1.name, avg_variance1.name])
    y1, mean1, variance1, avg_mean1, avg_variance1 = getsta(x1,avg_mean1,avg_variance1)
    print([avg_mean1.name, avg_variance1.name])
    scopeA.reuse_variables()
    print([avg_mean1.name, avg_variance1.name])
    y1, mean1, variance1, avg_mean1, avg_variance1 = getsta(x2,avg_mean1,avg_variance1)
    print([avg_mean1.name, avg_variance1.name])
    avg_mean1 = tf.identity(avg_mean1, name='avg_mean')
    avg_variance1 = tf.identity(avg_variance1, name='avg_variance')
    print([avg_mean1.name, avg_variance1.name])

  with tf.variable_scope("BBB") as scopeB:
    avg_mean2 = tf.get_variable(
              'test1', [1], tf.float32,
              initializer=tf.constant_initializer(0.0, tf.float32))
    avg_variance2 = tf.get_variable(
              'test2', [1], tf.float32,
              initializer=tf.constant_initializer(0.0, tf.float32))
    print([avg_mean2.name, avg_variance2.name])
    y2, mean2, variance2, avg_mean2, avg_variance2 = getsta(x3, avg_mean2, avg_variance2)
    print([avg_mean2.name, avg_variance2.name])
    scopeB.reuse_variables()
    print([avg_mean2.name, avg_variance2.name])
    y2, mean2, variance2, avg_mean2, avg_variance2 = getsta(x4, avg_mean2, avg_variance2)
    print([avg_mean2.name, avg_variance2.name])
    avg_mean2 = tf.identity(avg_mean2, name='avg_mean')
    avg_variance2 = tf.identity(avg_variance2, name='avg_variance')
    print([avg_mean2.name, avg_variance2.name])

  saver = tf.train.Saver()
  sess = tf.InteractiveSession()
  sess.run(tf.global_variables_initializer())
  print(sess.run([y1, mean1, variance1, avg_mean1, avg_variance1]))
  print(sess.run([y2, mean2, variance2, avg_mean2, avg_variance2]))

  allVars = tf.global_variables()
  values = sess.run(allVars)
  for var, val in zip(allVars, values):
    print(var.name, val)

  saver.save(sess, "/tmp/test_EMA/var_save.ckpt")

После запуска вышеуказанной функции train() я получил вывод как

['AAA/test1:0', 'AAA/test2:0']
getsta start...
['AAA/sub_1:0', 'AAA/sub_3:0']
['AAA/sub_1:0', 'AAA/sub_3:0']
getsta start...
['AAA/sub_5:0', 'AAA/sub_7:0']
['AAA/avg_mean:0', 'AAA/avg_variance:0']
['BBB/test1:0', 'BBB/test2:0']
getsta start...
['BBB/sub_1:0', 'BBB/sub_3:0']
['BBB/sub_1:0', 'BBB/sub_3:0']
getsta start...
['BBB/sub_5:0', 'BBB/sub_7:0']
['BBB/avg_mean:0', 'BBB/avg_variance:0']
[array([ 5.,  6.,  7.,  8.], dtype=float32), 6.5, 1.25, array([ 0.875], dtype=float32), array([ 0.23750001], dtype=float32)]
[array([  4.,   8.,  12.,  16.], dtype=float32), 10.0, 20.0, array([ 1.36000001], dtype=float32), array([ 2.45000005], dtype=float32)]
AAA/test1:0 [ 0.]
AAA/test2:0 [ 0.]
AAA/mean:0 [ 0.]
AAA/howvariance:0 [ 1.]
BBB/test1:0 [ 0.]
BBB/test2:0 [ 0.]
BBB/mean:0 [ 0.]
BBB/howvariance:0 [ 1.]

У меня есть несколько вопросов:

  1. Есть ли способ записать «avg_mean» без изменения его имени? Я хочу загрузить окончательные обновленные значения при загрузке модели.
  2. Можно ли определить "avg_mean" внутри функции getsta(), сохраняя при этом ее как статическую переменную, т. е. ее начальное значение соответствует последнему вызову, но не всегда начинается с 0.
  3. Когда я распечатываю все переменные, почему имена и значения кажутся неверными в последних восьми строках вывода? Я ожидаю, что результат

    AAA/avg_mean:0 [0.875]
    AAA/avg_variance:0 [0.23750001]
    BBB/avg_mean:0 [1.36000001]
    BBB/avg_variance:0 [2.45000005]
    

Спасибо за вашу помощь заранее!

--------------------Обновлять--------------------

Я пересмотрел свои коды, как показано ниже

def train():
  x1 = tf.constant([1,2,3,4], tf.float32)
  x2 = tf.constant([5,6,7,8], tf.float32)
  x3 = tf.constant([1,3,5,7], tf.float32)
  x4 = tf.constant([4,8,12,16], tf.float32)

  with tf.variable_scope("AAA") as scopeA:
    avg_mean1 = tf.get_variable(
              'avg_mean', [1], tf.float32,
              initializer=tf.constant_initializer(0.0, tf.float32))
    avg_variance1 = tf.get_variable(
              'avg_variance', [1], tf.float32,
              initializer=tf.constant_initializer(0.0, tf.float32))
    y1, mean1, variance1 = getsta(x1,avg_mean1,avg_variance1)
    scopeA.reuse_variables()
    y1, mean1, variance1 = getsta(x2,avg_mean1,avg_variance1)
    print([avg_mean1.name, avg_variance1.name])

  with tf.variable_scope("BBB") as scopeB:
    avg_mean2 = tf.get_variable(
              'avg_mean', [1], tf.float32,
              initializer=tf.constant_initializer(0.0, tf.float32))
    avg_variance2 = tf.get_variable(
              'avg_variance', [1], tf.float32,
              initializer=tf.constant_initializer(0.0, tf.float32))
    y2, mean2, variance2 = getsta(x3, avg_mean2, avg_variance2)
    scopeB.reuse_variables()
    y2, mean2, variance2 = getsta(x4, avg_mean2, avg_variance2)
    print([avg_mean2.name, avg_variance2.name])

  saver = tf.train.Saver()
  sess = tf.InteractiveSession()
  sess.run(tf.global_variables_initializer())
  print(sess.run([y1, mean1, variance1, avg_mean1, avg_variance1]))
  print(sess.run([y2, mean2, variance2, avg_mean2, avg_variance2]))

  allVars = tf.global_variables()
  values = sess.run(allVars)
  for var, val in zip(allVars, values):
    print(var.name, val)

  saver.save(sess, "/tmp/test_EMA/var_save.ckpt")

Теперь имена переменных фиксированы. Однако выходные данные (значения переменных) кажутся неверными. Выходы

[array([ 5.,  6.,  7.,  8.], dtype=float32), 6.5, 1.25, array([ 0.], dtype=float32), array([ 0.], dtype=float32)]
[array([  4.,   8.,  12.,  16.], dtype=float32), 10.0, 20.0, array([ 0.], dtype=float32), array([ 0.], dtype=float32)]
AAA/avg_mean:0 [ 0.]
AAA/avg_variance:0 [ 0.]
AAA/mean:0 [ 0.]
AAA/variance:0 [ 1.]
BBB/avg_mean:0 [ 0.]
BBB/avg_variance:0 [ 0.]
BBB/mean:0 [ 0.]

Как мне изменить свои коды, чтобы получить правильные результаты? Спасибо.


person Brandon    schedule 31.03.2017    source источник


Ответы (1)


Вот проблемы в вашем коде, которые необходимо исправить:

1- В следующей строке вы заменяете avg_variance1 на operation, возвращаемый getsta. Вы не должны этого делать. Когда вы создадите переменную avg_variance1 и передадите ее в getsta, переменная будет обновлена ​​везде в графе вычислений, и TensorFlow позаботится об этом, вам не нужно делать это явно. Пока вы ссылаетесь на variable по его name, все в порядке. Переменные TensorFlow не похожи на обычные переменные Python.

y1, mean1, variance1, avg_mean1, avg_variance1 = getsta(x1,avg_mean1,avg_variance1)

(вам нужно исправить это для avg_mean1, avg_mean2 и т. д.)

2- avg_mean2, avg_variance2, avg_mean2 и avg_variance2 это Tensor, а не variable. Значит, их нет в списке variables, который вы распечатываете.

person Ali    schedule 01.04.2017
comment
Спасибо за добрый ответ. Теперь я знаю причину смены имени и могу это исправить. Однако я считаю, что результаты неверны; кажется, что переменные всегда обнуляются. Мои пересмотренные коды изменены в исходном сообщении. @Ali, не могли бы вы помочь взглянуть? Спасибо. - person Brandon; 03.04.2017