Как получить детерминированное значение глобальной ступенчатой ​​переменной (строго после или строго до приращения)

Рассмотрим следующий код:

import tensorflow as tf

global_step = tf.train.create_global_step()
x = tf.Variable(100.0)
optimizer = tf.train.AdamOptimizer()
train_op = optimizer.minimize(x, global_step=global_step)

with tf.Session() as sess:
    sess.run(tf.global_variables_initializer())
    step, _ = sess.run([global_step, train_op])
    print(step)

На выходе я получил «1», но я думаю, что ничто не мешает Tensorflow дать мне вместо этого «0», то есть значение глобальной переменной step перед операцией «assign», которая увеличивает ее в train_op. На самом деле у меня есть другая, более сложная программа Tensorflow, которая демонстрирует такое поведение, где значение глобального шага, которое я получаю от Session.run([global_step, train_op]), отличается от одного за другим между двумя машинами, на которых я его запускаю.

Для глобальной ступенчатой ​​переменной, как я могу окончательно получить ее значение до train_op или окончательно получить ее значение после train_op?

Я знаю, что могу сделать sess.run([global_step]) отдельно до или после sess.run([train_op]), но я хотел бы сделать как можно больше в рамках одного session.run(), если это не связано с чрезмерным усложнением кода. Я знаю, что могу получить значение предварительного приращения, назначив global_step другой переменной и установив управляющую зависимость между tf.assign и train_op:

import tensorflow as tf

global_step = tf.train.create_global_step()
global_step2 = tf.get_variable('step-mirror', dtype=global_step.dtype, 
shape=global_step.shape)
global_step2 = tf.assign(global_step2, global_step)
x = tf.Variable(100.0)
optimizer = tf.train.AdamOptimizer()
with tf.control_dependencies([global_step2]):
    train_op = optimizer.minimize(x, global_step=global_step)

with tf.Session() as sess:
    sess.run(tf.global_variables_initializer())
    step, _ = sess.run([global_step2, train_op])
    print(step)

Но я ищу более простой способ, возможно, функцию Tensorflow, которую мне не хватает, для определения оценки переменной перед любым ее назначением.

Обновлено: в ответ на этот комментарий это не работает, и он печатает «1» вместо «0»:

import tensorflow as tf

global_step = tf.train.create_global_step()
x = tf.Variable(100.0)
optimizer = tf.train.AdamOptimizer()
with tf.control_dependencies([global_step]):
    train_op = optimizer.minimize(x, global_step=global_step)

with tf.Session() as sess:
    sess.run(tf.global_variables_initializer())
    step, _ = sess.run([global_step, train_op])
    print(step)
2
0
389
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Вы можете использовать это, чтобы прочитать глобальный шаг после train_op:

import tensorflow as tf

global_step = tf.train.create_global_step()
x = tf.Variable(100.0)
optimizer = tf.train.AdamOptimizer()
train_op = optimizer.minimize(x, global_step=global_step)

with tf.control_dependencies([train_op]):
    global_step_value = global_step.read_value()

with tf.Session() as sess:
    sess.run(tf.global_variables_initializer())
    step, _ = sess.run([global_step_value, train_op])
    print(step)

Здесь global_step_value больше не является переменной. Это тензор со значением global_step после вычисления train_op. Это описано здесь в разделе «Использование переменных».

Я попробовал ваше решение, и оно работает. Теперь, когда также нужен train_op, мне нужно оценить global_step_value, но когда train_op не нужен, мне нужно оценить global_step, поскольку оценка global_step_value влечет за собой оценку train_op. Таким образом, кажется более понятным, если есть способ указать оценку оценки global_stepперед любым для оценки train_op. Таким образом, мне не нужно заботиться о train_op, когда я оцениваю глобальный шаг, и у меня есть единообразный способ его оценки. Интересно, возможно ли это. Использование tf.control_dependencies в обратном направлении не помогает.

Joshua Chia 29.10.2018 23:46

Заставить train_op иметь управляющую зависимость от тензора global_step_value должно работать. Почему это не для тебя?

Alexandre Passos 05.11.2018 22:16

@AlexandrePassos Это не работает. Вот почему я сказал: «Использование tf.control_dependencies в обратном направлении не помогает».

Joshua Chia 09.11.2018 07:16

Чтобы это работало, вам нужно поместить весь прямой и обратный проход внутри блока control_dependencies, а не только сам train_op. Извините за то, что не пояснил ранее.

Alexandre Passos 09.11.2018 14:24

@AlexandrePassos Что вы имеете в виду под «проходом вперед» и «проходом назад»? С точки зрения кода, какие переменные вы имеете в виду? У тебя есть код?

Joshua Chia 14.11.2018 05:59

Я имею в виду все ваше модельное определение. Буквально все в блоке control_dependencies

Alexandre Passos 15.11.2018 18:50

Другие вопросы по теме