tf.cond для переменной. Ошибка с предварительным условием в tf.global_variables_initializer()

#python #tensorflow #deep-learning

#python #тензорный поток #глубокое обучение

Вопрос:

Я сталкиваюсь с ошибкой FailedPreconditionError в tf.global_variables_initializer() . Я обнулил следующую часть кода, чтобы быть виновником:

 def __init__(...):
    ...
    self.global_step = tf.get_variable(initializer=tf.zeros_initializer(), trainable=False, shape=(), name='global_step')
    ...
    step_rampup_value = self.step_rampup(self.global_step, self.rampup_length)

def step_rampup(self, global_step, rampup_length):
    result = tf.cond(global_step < rampup_length,
                     lambda: tf.constant(0.0),
                     lambda: tf.constant(1.0))
    return tf.identity(result, name="step_rampup")
session.run(tf.global_variables_initilizer())
  

self.global_step должен быть увеличен на 1 оптимизатором на каждой итерации. Ее значение должно измениться. Итак, это то поведение, которое я хочу.

Сообщение об ошибке:

 FailedPreconditionError ...
506         with tf.Session(graph=highgraph) as session:
--> 507             session.run(tf.global_variables_initializer())
...
FailedPreconditionError: Attempting to use uninitialized value global_step
 [[node global_step/read (defined at NML_U/sNeural.py:103)  = Identity[T=DT_FLOAT, _device="/job:localhost/replica:0/task:0/device:CPU:0"](global_step)]]
  

Почему эта часть кода является виновной?
Потому что работает следующий код

 def __init__(...):
    ...
    self.global_step = tf.get_variable(initializer=tf.zeros_initializer(), trainable=False, shape=(), name='global_step')
    ...
    step_rampup_value = self.step_rampup(self.global_step, self.rampup_length)

def step_rampup(self, global_step, rampup_length):
    result = tf.cond(global_step.initialized_value() < rampup_length,
                     lambda: tf.constant(0.0),
                     lambda: tf.constant(1.0))
    return tf.identity(result, name="step_rampup")
session.run(tf.global_variables_initilizer())
  

но это будет оценивать условие с инициализированным значением self.global_step(=0) каждый раз, когда это не является предполагаемым поведением

Также,

Этот код также работает:

 def __init__(...):
    ...
    self.global_step = tf.get_variable(initializer=tf.zeros_initializer(), trainable=False, shape=(), name='global_step')
    self.global_step = tf.assign(self.global_step,0.)
    ...
    step_rampup_value = self.step_rampup(self.global_step, self.rampup_length)

def step_rampup(self, global_step, rampup_length):
    result = tf.cond(global_step < rampup_length,
                     lambda: tf.constant(0.0),
                     lambda: tf.constant(1.0))
    return tf.identity(result, name="step_rampup")
session.run(tf.global_variables_initilizer())
  

Но (возможно) это снова приведет не к зависимости от global_step , а вместо этого от assign op, который будет продолжать присваивать 0 self.global_step

Как мне добиться такого поведения?

Комментарии:

1. Вы пробовали tf.variables_initializer ? Также рассмотрите возможность добавления полного кода

Ответ №1:

Вы не предоставили полный код, поэтому я могу только догадываться, что вы, возможно, вызываете tf.global_variables_initializer() раньше __init__() . Действительно, первый не будет инициализировать переменные, которые создаются после его вызова.

Комментарии:

1. Спасибо за ответ. Однако проблема заключалась в чем-то другом. Может быть обобщен как github.com/tensorflow/tensorflow/issues/8172 . Я ошибся в определении источника проблемы. Я использовал результат step_rampup для вычисления adam_beta_2 для моего оптимизатора adam, и adam не смог инициализировать его параметры, потому что global_step не был инициализирован во время выполнения при попытке инициализировать параметры adam, а результатом step_rampup является tf.cond (…) для global_step