在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)
答案 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那样分配整行。