我发现Tensorflow提供了scatter_update()
来为0维Tensor的切片赋值。例如,如果TensorT
是三维的,我可以为T[i, :, :]
赋值v[1, :, :]
。
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还提供了其他的功能吗?或者有什么简单的方法可以做到这一点吗?
5条答案
按热度按时间vsaztqbk1#
目前,您可以在TensorFlow中对变量进行切片赋值,没有具体的命名函数,但您可以选择一个切片并在其上调用
assign
:首先,请注意(在阅读了文档之后),
assign
的返回值似乎总是对应用更新后的 whole 变量的引用,即使应用于切片也是如此。编辑:下面的信息要么过时,要么不精确,要么总是错误的。事实上,
assign
的返回值是一个Tensor,可以很容易地使用,并且已经将依赖关系合并到赋值中,所以简单地计算它或在进一步的操作中使用它将确保它在不需要显式tf.control_dependencies
块的情况下执行。还要注意,这只会将赋值操作添加到图中,但不会运行它,除非它被显式执行或被设置为某个其他操作的依赖项。一个好的实践是在
tf.control_dependencies
上下文中使用它:您可以在TensorFlow第#4638期中了解更多信息。
xlpyo6sf2#
我相信您需要的是在ticket #206中讨论的
assign_slice_update
,不过它还没有上市。在
assign_slice_update
(或scatter_nd()
)可用之前,您可以构建一个所需行的块,其中包含您不想修改的值以及要更新的值,如下所示:这个例子生成一个1的Tensor并执行
a[i,j,:] = 5
。大部分的复杂性在于得到我们不想修改的值a[i,~j,:]
(否则scatter_update()
将替换那些值)。如果您希望按照要求执行
T[i,k,:] = a[1,1,:]
,则需要将前面示例中的5*tf.ones([1, 36])
替换为tf.gather_nd(a, [[1, 1]])
。另一种方法是创建一个掩码,从
tf.select()
中删除所需的元素,并将其赋值回变量,如下所示:它可能在内存方面效率较低,因为它需要两倍的内存来处理类似
a
的to_update
变量,但您可以轻松地修改最后一个示例,以从tf.select(...)
节点获得梯度保持操作。您可能还对查看另一个StackOverflow问题感兴趣:Conditional assignment of tensor values in TensorFlow.当TensorFlow函数可用时,应将这些不优雅的扭曲替换为对适当TensorFlow函数的调用。
wlsrxk513#
tf.scatter_update
可以修改第一维度的Tensor。如文档所述,indices:Tensor。必须是以下类型之一:int32,int64。进入ref的第一维的索引的Tensor。
你可以使用
scatter_nd_update
函数来做你想做的事情。如下所示,我已经测试过了。tuwxkamq4#
TF2的答案:
遗憾的是,在Tensorflow 2(TF2)中仍然没有优雅的方法来执行此操作。
我发现最好的方法是将assign解栈,然后重新堆栈:
xtfmy6hx5#
你可以用
tf.tensor_scatter_nd_update
来实现它,下面是一个例子,说明从一个二维数组中给一个切片赋值的具体情况。通过测试: