递增2d变量

时间:2017-12-04 14:58:50

标签: python tensorflow

在2d变量数组中递增条目的正确方法是什么? 似乎变体A(下面)应该有效,但它失败了:

  

AttributeError:'Tensor'对象没有属性'assign_add'

有什么方法可以解决这个问题吗? 变体B确实有效,但是它执行的操作多于必要的操作,我更喜欢使用适当的assign_add作为原子操作。
有点奇怪的是,下面的变体C也可以工作,并且比变体B更快,虽然看起来它做了更多(不必要的)工作。

变式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)

1 个答案:

答案 0 :(得分: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那样分配整行。