2016-06-23 9 views
0

私は強化学習を行っており、私の例をTFグラフに保存して、PythonとTFの間でデータを移動させないようにしたいと考えています。私はTF.Variable()をセッション全体で持続し、必要に応じて最後にサンプルを追加するだけでよいので、TF.Variable()を使うことができると思いました。ここでのアプローチの一つの例である:単一セッション内の変数の永続性

import tensorflow as tf 

initx = [[1.0, 2.0, 3.0, 4.0], 
     [4.0, 5.0, 6.0, 7.0], 
     [7.0, 8.0, 9.0, 8.0]] 

x = tf.get_variable("x",dtype=tf.float32,validate_shape=False,initializer=tf.constant(initx)) 
xappend = tf.placeholder(dtype=tf.float32,shape=[None,4]) 
#xappend = tf.get_variable("xappend",shape=[1,4],dtype=tf.float32,validate_shape=False) 

x = tf.concat(0,[x,xappend]) 

with tf.Session('') as session: 
    session.run(tf.initialize_all_variables())  
    print session.run([x],feed_dict={xappend:[[-1.0,98.0,97.0,96.0]] }) 
    print session.run([x],feed_dict={xappend:[[-2.0,98.0,97.0,96.0]] }) 
    print session.run([x],feed_dict={xappend:[[-3.0,98.0,97.0,96.0]] }) 
    print session.run([x],feed_dict={xappend:[[-4.0,98.0,97.0,96.0]] }) 

私の考えでは、このテンソル「X」の末尾に「xappend」値を連結し、各観測が追加されるように成長するべきです。これは起こりそうなことではありません。実行ごとに、私は初期化された値にxappendの値を加えたものを得て、xappendのただ一つのインスタンスを得ます。私は-1、-2、-3、-4をセッション内のテンソルの最後に追加するようには見えません。ここでは、出力は次のようになります。

[array([[ 1., 2., 3., 4.], 
    [ 4., 5., 6., 7.], 
    [ 7., 8., 9., 8.], 
    [ -1., 98., 97., 96.]], dtype=float32)] 
[array([[ 1., 2., 3., 4.], 
    [ 4., 5., 6., 7.], 
    [ 7., 8., 9., 8.], 
    [ -2., 98., 97., 96.]], dtype=float32)] 
[array([[ 1., 2., 3., 4.], 
    [ 4., 5., 6., 7.], 
    [ 7., 8., 9., 8.], 
    [ -3., 98., 97., 96.]], dtype=float32)] 
[array([[ 1., 2., 3., 4.], 
    [ 4., 5., 6., 7.], 
    [ 7., 8., 9., 8.], 
    [ -4., 98., 97., 96.]], dtype=float32)] 

私はセッション内で別のアプローチを試してみましたが、同じ予期しない結果を得るています

... 
update = tf.assign(xappend, [[-1.0,98.0,97.0,96.0]], validate_shape=False) 
print session.run([update]) 
print session.run([x]) 
update = tf.assign(xappend, [[-2.0,98.0,97.0,96.0]], validate_shape=False) 
print session.run([update]) 
print session.run([x]) 
... 

私は重みを持っているとき、彼らは同じセッション内で呼び出しの間持続していることを知っています。私は、このグラフの "x"変数の持続性を許さないtf.concat()関数を使って、サイズの変更に関係していると確信しています。

このアプローチで何が問題になる可能性がありますか?より良いアプローチがありますか?

答えて

1

あなたはほとんどそこにいました。変数を変更したい場合は、割り当てopを作成する必要があります。この操作はsess.run()で実行され、変数の内容が更新されます。

ここでは、変数を割り当てるときにその形状を変更するというトリックがあります。引数validate_shape=Falsetf.assignを使用する必要があります。これは、ドキュメントに示唆された:

あなたは変数の形状を変更したい場合は、後であなたが

偽validate_shape =でアサインオペアンプを使用する必要があります。しかしtf.assignのドキュメントが存在しません。


initx = [[1.0, 2.0, 3.0, 4.0], 
     [4.0, 5.0, 6.0, 7.0], 
     [7.0, 8.0, 9.0, 8.0]] 

x = tf.get_variable("x",dtype=tf.float32,validate_shape=False,initializer=tf.constant(initx)) 
xappend = tf.placeholder(dtype=tf.float32,shape=[None,4]) 

new_x = tf.concat(0, [x, xappend]) 
append_op = tf.assign(x, new_x, validate_shape=False) 

with tf.Session() as sess: 
    sess.run(tf.initialize_all_variables()) 
    sess.run(append_op, feed_dict={xappend:[[-1.0,98.0,97.0,96.0]] }) 
    sess.run(append_op, feed_dict={xappend:[[-2.0,98.0,97.0,96.0]] }) 
    sess.run(append_op, feed_dict={xappend:[[-3.0,98.0,97.0,96.0]] }) 
    sess.run(append_op, feed_dict={xappend:[[-4.0,98.0,97.0,96.0]] }) 

    sess.run(x) # should give you the expected result, of shape [7, 4] 

あなたは常に変数の形状を変更するため、このコードはおそらく、非常に効率的ではありません。

より良い方法は、あらかじめmax_lenght引数を指定している形状の固定サイズの配列[max_length, 4]を使用し、配列を行単位で埋めることです(より良い方法です)。

+0

ありがとうOlivier、それは動作します。したがって、私の例で返された "x"の値は、何らかの形のローカル変数だったのですが、元の "x"にリセットされたときは明確ではありませんか?これは、 "ウェイト&バイアス"タイプの変数が目に見えない割り当て(アプリケーショングラディエントに埋もれているかもしれません)がなくても持続するように見えるので、形状の変更が必要なためだけですか? – mazecreator

+0

あなたの推薦では、Tensor [max、4]を推薦していますか?それはうまくいくだろうが、[5、]に「xappend」と言って挿入する方法がわからないのですが、テンソル関数は現在numpy型のインデックス付けを可能にしていますか? – mazecreator

+0

私はVariableの形を絶えず変えることは非常に時間がかかると思います。 '[max、4]という形では、[scatter_add(x、indice、new_state)](https://www.tensorflow.org/versions/r0.9/api_docs)で新しい状態をそれぞれのインデックスに挿入することができます。/python/state_ops。html#scatter_add) –

関連する問題