如何在Tensorflow中进行切片分配
python-2.7
tensorflow
5
0

我发现Tensorflow提供了scatter_update()来将值分配给0维中的张量切片。例如,如果张量T是三维的,我可以将值v[1, :, :]分配给T[i, :, :]

a = tf.Variable(tf.zeros([10,36,36]))   
value = np.ones([1,36,36])   
d = tf.scatter_update(a,[0],value)

with tf.Session() as sess:
    sess.run(tf.initialize_all_variables())
    print a.eval()
    sess.run(d)
    print a.eval()

但是如何将值v[1,1,:]分配给T[i,j,:]

a = tf.Variable(tf.zeros([10,36,36]))   
value1 = np.random.randn(1,1,36)    
e = tf.scatter_update(a,[0],value1) #Error

with tf.Session() as sess:
    sess.run(tf.initialize_all_variables())
    print a.eval()
    sess.rum(e)
    print a.eval()

TF是否提供其他功能或执行此操作的简单方法?

参考资料:
Stack Overflow
收藏
评论
共 3 个回答
高赞 时间 活跃

tf.scatter_update可以在第一维上修改张量。如文档中所述,

指数:张量。必须是以下类型之一:int32,int64。 ref的第一维的索引张量。

您可以使用scatter_nd_update函数执行所需的操作。如下所示,这是我测试过的。

a = tf.Variable(tf.zeros([10,36,36])) 
value1 = np.random.randn(1,36)
e = tf.scatter_nd_update(a,[[0,1]],value1)
init= tf.global_variables_initializer()
sess.run(init)
print(a.eval())
sess.run(e)
收藏
评论

我相信您需要的是票证#206中讨论的assign_slice_update但是,它尚不可用。

更新:现在已实现。参见jdehesa的答案: https ://stackoverflow.com/a/43139565/6531137


assign_slice_update (或scatter_nd() )可用之前,您可以构建所需行的块,其中包含不需要修改的值以及所需更新的值,如下所示:

import tensorflow as tf

a = tf.Variable(tf.ones([10,36,36]))

i = 3
j = 5

# Gather values inside the a[i,...] block that are not on column j
idx_before = tf.concat(1, [tf.reshape(tf.tile(tf.Variable([i]), [j]), [-1, 1]), tf.reshape(tf.range(j), [-1, 1])])
values_before = tf.gather_nd(a, idx_before)
idx_after = tf.concat(1, [tf.reshape(tf.tile(tf.Variable([i]), [36-j-1]), [-1, 1]), tf.reshape(tf.range(j+1, 36), [-1, 1])])
values_after = tf.gather_nd(a, idx_after)

# Build a subset of tensor `a` with the values that should not be touched and the values to update
block = tf.concat(0, [values_before, 5*tf.ones([1, 36]), values_after])

d = tf.scatter_update(a, i, block)

with tf.Session() as sess:
    sess.run(tf.initialize_all_variables())
    sess.run(d)
    print(a.eval()[3,4:7,:]) # Print a subset of the tensor to verify

该示例生成一个张量张量,并执行a[i,j,:] = 5 。大多数复杂性在于获取我们不想修改的值a[i,~j,:] scatter_update() a[i,~j,:] (否则scatter_update()将替换这些值)。

如果要按照要求执行T[i,k,:] = a[1,1,:] ,则需要将上一个示例中的5*tf.ones([1, 36])替换为tf.gather_nd(a, [[1, 1]])

另一种方法是从tf.select()创建所需的元素的掩码, tf.select()其分配回变量,如下所示:

import tensorflow as tf

a = tf.Variable(tf.zeros([10,36,36]))

i = tf.Variable([3])
j = tf.Variable([5])

# Build a mask using indices to perform [i,j,:]
atleast_2d = lambda x: tf.reshape(x, [-1, 1])
indices = tf.concat(1, [atleast_2d(tf.tile(i, [36])), atleast_2d(tf.tile(j, [36])), atleast_2d(tf.range(36))])
mask = tf.cast(tf.sparse_to_dense(indices, [10, 36, 36], 1), tf.bool)

to_update = 5*tf.ones_like(a)
out = a.assign( tf.select(mask, to_update, a) ) 

with tf.Session() as sess:
    sess.run(tf.initialize_all_variables())
    sess.run(out)
    print(a.eval()[2:5,5,:])

就内存而言,它的效率可能较低,因为它需要两倍的内存来处理to_update ato_update变量,但是您可以轻松地修改最后一个示例,以从tf.select(...)节点获取梯度保留操作tf.select(...) 。您可能还想看看另一个StackOverflow问题: TensorFlow中的张量值的条件赋值

那些笨拙的扭曲应该替换为对适当的TensorFlow函数的调用(如果有)。

收藏
评论

当前,您可以在TensorFlow中对变量进行切片分配。它没有特定的命名函数,但是您可以选择一个切片并对其调用assign

my_var = my_var[4:8].assign(tf.zeros(4))

首先,请注意(在阅读了文档之后 )似乎assign的返回值(即使应用于切片)在应用更新后似乎始终是对整个变量的引用。

编辑:以下信息已被弃用,不精确或总是错误的。事实是assign的返回值是一个易于使用的张量,并且已经将依赖项并入了赋值中,因此,只需对其进行评估或在以后的操作中使用它即可确保无需明确的tf.control_dependencies块即可执行该tf.control_dependencies


还要注意,这只会将分配操作添加到图形,而不会运行它,除非它被明确执行或设置为其他操作的依赖项。一个好的做法是在tf.control_dependencies上下文中使用它:

with tf.control_dependencies([my_var[4:8].assign(tf.zeros(4))]):
    my_var = tf.identity(my_var)

您可以在TensorFlow 第4638期中阅读更多有关它的内容。

收藏
评论
新手导航
  • 社区规范
  • 提出问题
  • 进行投票
  • 个人资料
  • 优化问题
  • 回答问题

关于我们

常见问题

内容许可

联系我们

@2020 AskGo
京ICP备20001863号