is_variable_initialized上tf.cond的非确定性行为

时间:2017-06-04 14:06:56

标签: tensorflow

考虑这个演示代码:

import logging
logging.getLogger('tensorflow').disabled = True
import tensorflow as tf
import sys

sess = tf.InteractiveSession()


def test_var_2():
  v = tf.Variable(initial_value=True, trainable=False, name="test_var_3")
  print("is initialized:", tf.is_variable_initialized(v).eval(), file=sys.__stdout__)

  def make_init():
    with tf.control_dependencies([tf.Print(0, ["var is not initialized", tf.is_variable_initialized(v)])]):
      return tf.variables_initializer([v])

  def on_already_init():
    return tf.group(tf.no_op(), tf.Print(0, ["var is initialized", tf.is_variable_initialized(v)]))

  maybe_init = tf.cond(
    tf.is_variable_initialized(v),
    on_already_init,
    make_init,
    name="init")
  with tf.control_dependencies([maybe_init, tf.Print(0, ["cd init"])]):
    x = tf.where(v.read_value(), True, False)

  print("x:", x.eval())
  print("is initialized:", tf.is_variable_initialized(v).eval(), file=sys.__stdout__)
  print("x:", x.eval())
  print("is initialized:", tf.is_variable_initialized(v).eval(), file=sys.__stdout__)


if __name__ == "__main__":
  test_var_2()

输出是非确定性的。我得到这个(1):

is initialized: False
.../logging_ops.cc:79] [cd init]
.../logging_ops.cc:79] [var is not initialized][0]
x: True
is initialized: True
.../logging_ops.cc:79] [cd init]
.../logging_ops.cc:79] [var is initialized][1]
x: True
is initialized: True

或者这(2):

is initialized: False
.../logging_ops.cc:79] [cd init]
.../logging_ops.cc:79] [var is not initialized][1]
x: True
is initialized: True
.../logging_ops.cc:79] [cd init]
.../logging_ops.cc:79] [var is initialized][1]
x: True
is initialized: True

或者这(3):

is initialized: False
.../logging_ops.cc:79] [cd init]
.../logging_ops.cc:79] [var is initialized][1]
x: True
is initialized: True
.../logging_ops.cc:79] [cd init]
.../logging_ops.cc:79] [var is initialized][1]
x: True
is initialized: True

变体3(var在第一个x.eval()处初始化)对我来说毫无意义。怎么能最终进入那个cond-branch?它为什么突然初始化?

变体1和2之间的区别可能是因为tf.Print未作为tf.control_dependencies的一部分进行完全评估?

1 个答案:

答案 0 :(得分:0)

thisthis这是一个更棘手的案例。关键是tf.variables_initializer([v])并没有真正为init创建一个新的op(即赋值给初始值)但是这个assign-op早先已经创建了(在tf.Variable构造函数内)并且只是在这里使用因此,我的解决方案是不使用此初始值设定项,而是创建自己的初始化程序,必须在make_init函数内创建,即:

def make_init():
  with tf.control_dependencies([tf.Print(0, ["var is not initialized", tf.is_variable_initialized(v)])]):
    return tf.assign(v, True)

这解决了这个问题。