2017-12-04 5 views
0

2d変数配列のエントリをインクリメントする正しい方法は何ですか?これは、バリアントA(下記)のように思える が働いているはずですが、それはで失敗します。2d変数のエントリをインクリメントする

AttributeError: 'Tensor' object has no attribute 'assign_add'

は、この問題を解決する方法はありますか?
バリアントBは動作しますが、必要以上に多くの操作を実行するため、アトミック操作として適切なassign_addを使用します。
多少不思議なことに、下のバリアントCも動作し、がより速いです。

変法A:

graph = tf.get_default_graph() 
i = tf.Variable(5,tf.int32) 
j = tf.Variable(3,tf.int32) 
tbl = tf.Variable(np.zeros((10,10)),dtype = tf.float32) 

p_op = tf.assign_add(tbl[i,j],1) 
sess = tf.Session(graph = graph)      
tf.global_variables_initializer().run(session=sess) 
res = sess.run(p_op) 

変法B:

p_op = tbl[i,j].assign(tbl[i,j]+1) 
sess = tf.Session(graph = graph)      
tf.global_variables_initializer().run(session=sess) 
res = sess.run(p_op) 

バリアントC:グラフを構築する場合

p_op = tf.scatter_add(tbl, [i], [tf.one_hot(j,10)]) 
sess = tf.Session(graph = graph)      
tf.global_variables_initializer().run(session=sess) 
res = sess.run(p_op) 
+0

['tf.assgn_add()'](https://www.tensorflow.org/api_docs/python/tf/assign_add)は 'テンソル '。あなたは 'p_op = tf.assign_add(i、1)'を呼び出す必要があります。 – GPhilo

+0

それを試してみてください。これは、メソッドとしてtbl [i、j] .assign_addを実行しようとするtf.assign_addになり、同じエラーが発生します。それでも、質問を編集しました。 – komark

+0

ちょうど 'tbl [i、j] + = 1'を試して、それが何を解決するか見てみましたか?それはBと同じですか? – scnerd

答えて

1

、良い方法がありません作るにはvariable[indices] += valueは、セッションで実行できる操作を返します。そして、スライスが行われたら(tf.assign_add(variable[indices], value)のように)、代入を変数に戻すことはむしろ困難です(有用な特別なケースでは不可能ではなく、機能要求をファイルに書き留めるか、プルリクエストをまとめることをお勧めします)。

単一の要素をインクリメントする最速の方法は、(あなたの例を修正する)のように、scatter_nd_addである可能性が高い:

import tensorflow as tf 
with tf.Graph().as_default(): 
    i = tf.Variable(5,tf.int32) 
    j = tf.Variable(3,tf.int32) 
    tbl = tf.Variable(tf.zeros((10,10)),dtype = tf.float32) 

    assign_op = tf.scatter_nd_add(tbl, [[i, j]], [1]) 
    init_op = tf.global_variables_initializer() 
    with tf.Session() as session: 
    session.run(init_op) 
    session.run(assign_op) 
    print(tbl.eval()) 

これは、配列決定読み取り>は、あなたのバリアントBのように書く回避(すなわち、原子です)、行Cのように行全体を割り当てるのを避けます。

関連する問題