2017-08-07 5 views
1

global stepの値に基づいて異なる計算を実行したいとします。ここで私が何をしようとしています何の最小限の例です。global_stepを使用してtf.condへの呼び出しの述部を計算する方法は?

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

答えて

1

だから、これは本当にかなり変です。私は以下のように変更して、あなたのコードを実行することができた:

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_stepinitialized_valueを追加する必要がありましたし、tf.cond内の変数'w2'、何とかない'w1'に(あなたはそれをあまりにもそれを置くことができますあなたがいなければ、それは提出されません、明らかに)。このメソッドは、ドキュメントに記載されているように、一般的には必要ではなく、の後でが使用されることが保証されている変数の「表示」を提供するだけです。なぜtf.condにそれを使用する必要があるのですか?そのような一貫性のない方法で、私はなぜわかりません。

さらに、コードを実行する方法は実際には決定的ではないことに注意してください。一般的には次のようになります。

[1, 1] 
[0, 2] 
[1, 3] 
[0, 4] 

いつもそうとは限りません。ここで得られた出力は次のとおりです。

[0, 1] 
[0, 2] 
[1, 3] 
[0, 4] 

これは、増分と条件を実行する順序が決定的ではないためです。依存関係について明示的にすることをお勧めしますので、あなたは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])) 

驚くほど、あまりにも'w1'ためinitialized_valueを追加するために私を必要とします。これは本当に矛盾しています。また、この場合の出力は次のようになります。今

[0, 2] 
[1, 3] 
[0, 4] 
[1, 5] 

、それは増加の結果は2から始まることを私を悩まします。インクリメントが予想よりも一度実行されたようです。だから、私はtf.condがどうにかして最初の1回の実行を余儀なくされたと感じています。それはその奇妙な動作の原因になります。

あなたは、反対のことをしたい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])) 

はい、私は再びもう'w1'initialized_valueを必要としません。これにより、次の結果が得られます。

[0, 1] 
[1, 2] 
[0, 3] 
[1, 4] 

ここで増分は意味をなさないと思います。

+0

ありがとうございましたが、global_stepがデフォルトでグローバル変数コレクションに追加されたようです。私の例では 'print(tf.global_variables())'は '[] ' – GeertH

+0

@GeertHあなたは本当に正しいですか、私はマシンで試しましたが、間違った場所を見ていました。 train.get_or_create_global_step'は、新しく作成されたグローバルステップをグローバル変数コレクションに追加していませんでした。私はもう一度見ます。 – jdehesa

+0

@GeertH私は答えを変えました。 – jdehesa

0

あなたはplaceholder_with_defaultを使用する必要がありますを使用しています。

global_step = tf.placeholder_with_default(1, shape=[], name='global_step') 
関連する問題