我想根据global step
的值执行不同的计算。这是我想要做的最小例子:
import tensorflow as tf
global_step = tf.train.get_or_create_global_step()
incr_global_step = global_step.assign(global_step + 1)
w = tf.cond(tf.equal(tf.mod(global_step, 2), 0),
lambda : tf.get_variable('w1', initializer=tf.zeros([], dtype=tf.int32)),
lambda : tf.get_variable('w2', initializer=tf.ones([], dtype=tf.int32)))
with tf.Session() as sess:
sess.run(tf.global_variables_initializer())
for _ in range(4):
print(sess.run([w, incr_global_step]))
我收到以下错误:
FailedPreconditionError (see above for traceback): Attempting to use uninitialized value global_step
[[Node: global_step/read = Identity[T=DT_INT64, _class=["loc:@global_step"], _device="/job:localhost/replica:0/task:0/cpu:0"](global_step)]]
这是预期的行为吗?如果是这样,我做错了什么?
我正在使用tensorflow 1.2
答案 0 :(得分:2)
所以是的,这确实很奇怪。我能够通过以下修改来运行您的代码:
import tensorflow as tf
global_step = tf.train.get_or_create_global_step()
incr_global_step = global_step.assign(global_step + 1)
w = tf.cond(tf.equal(tf.mod(global_step.initialized_value(), 2), 0),
lambda : tf.get_variable('w1', initializer=tf.zeros([], dtype=tf.int32)),
lambda : tf.get_variable('w2', initializer=tf.ones([], dtype=tf.int32)).initialized_value())
with tf.Session() as sess:
sess.run(tf.global_variables_initializer())
for _ in range(4):
print(sess.run([w, incr_global_step]))
请注意,我必须在global_step
中添加initialized_value
,在'w2'
中添加变量tf.cond
,但不知道 到'w1'
(你也可以把它放在一起它会起作用,但是如果你不明显的话,就不会提交)。正如文档中提到的那样,这种方法通常不需要,它只是提供了一个"视图" 在初始化之后保证使用的变量。为什么tf.cond
要求您使用它,以及为什么以这种不一致的方式,我不知道。
除此之外,请注意您运行代码的方式实际上不是确定性的。一般来说,你会得到这个:
[1, 1]
[0, 2]
[1, 3]
[0, 4]
但并非总是如此。这是我刚刚得到的输出:
[0, 1]
[0, 2]
[1, 3]
[0, 4]
这是因为增量和条件的运行顺序不确定。最好明确依赖关系,所以如果你希望{<1}}在增量之后运行,你会这样做:
w
令人惊讶地要求我为import tensorflow as tf
global_step = tf.train.get_or_create_global_step()
incr_global_step = global_step.assign(global_step + 1)
with tf.control_dependencies([incr_global_step]):
w = tf.cond(tf.equal(tf.mod(global_step.initialized_value(), 2), 0),
lambda : tf.get_variable('w1', initializer=tf.zeros([], dtype=tf.int32)).initialized_value(),
lambda : tf.get_variable('w2', initializer=tf.ones([], dtype=tf.int32)).initialized_value())
with tf.Session() as sess:
sess.run(tf.global_variables_initializer())
for _ in range(4):
print(sess.run([w, incr_global_step]))
添加initialized_value
。这确实不一致。此外,这种情况下的输出是:
'w1'
现在,让我感到恼火的是,增量的结果从两点开始。看起来增量运行的次数超过了预期。所以我觉得[0, 2]
[1, 3]
[0, 4]
[1, 5]
以某种方式强制执行一次额外的第一次运行,这将是其奇怪行为的原因。
如果你想要相反,在增量之前让tf.cond
运行,你可以这样做:
w
是的,我再也不需要import tensorflow as tf
w = tf.cond(tf.equal(tf.mod(global_step.initialized_value(), 2), 0),
lambda : tf.get_variable('w1', initializer=tf.zeros([], dtype=tf.int32)),
lambda : tf.get_variable('w2', initializer=tf.ones([], dtype=tf.int32)).initialized_value())
with tf.control_dependencies([w]):
incr_global_step = global_step.assign(global_step + 1)
with tf.Session() as sess:
sess.run(tf.global_variables_initializer())
for _ in range(4):
print(sess.run([w, incr_global_step]))
&#39 {s} 'w1'
了。这会产生:
initialized_value
我认为这些增量是有意义的。
答案 1 :(得分:0)
您应该使用placeholder_with_default
。
global_step = tf.placeholder_with_default(1, shape=[], name='global_step')