如何在 TensorFlow 中执行 PyTorch 风格的张量切片更新?
How to perform PyTorch style tensor slice update in TensorFlow?
在 Pytorch 中,您可以像这样轻松更新张量:
for i in range(x_len):
tensor_abc[:, i, i] = 0
我们如何在 tensorflow 中更新像这样的张量?
我尝试了 tf.assign
和 tf.scatter_update
,但都没有用。
此答案仅适用于变量。
import tensorflow as tf
sess = tf.InteractiveSession()
v = tf.zeros((5,5,5))
var = tf.Variable(initial_value=v)
init = tf.variables_initializer([var])
sess.run(init)
var = var[ 1 : 2 ,
1 : 2 ,
1 : 2 ].assign(tf.ones((1,1,1)))
print(sess.run(var))
这会产生
[[[0. 0. 0. 0. 0.]
[0. 0. 0. 0. 0.]
[0. 0. 0. 0. 0.]
[0. 0. 0. 0. 0.]
[0. 0. 0. 0. 0.]]
[[0. 0. 0. 0. 0.]
[0. 1. 0. 0. 0.]
[0. 0. 0. 0. 0.]
[0. 0. 0. 0. 0.]
[0. 0. 0. 0. 0.]]
[[0. 0. 0. 0. 0.]
[0. 0. 0. 0. 0.]
[0. 0. 0. 0. 0.]
[0. 0. 0. 0. 0.]
[0. 0. 0. 0. 0.]]
[[0. 0. 0. 0. 0.]
[0. 0. 0. 0. 0.]
[0. 0. 0. 0. 0.]
[0. 0. 0. 0. 0.]
[0. 0. 0. 0. 0.]]
[[0. 0. 0. 0. 0.]
[0. 0. 0. 0. 0.]
[0. 0. 0. 0. 0.]
[0. 0. 0. 0. 0.]
[0. 0. 0. 0. 0.]]]
还有这个
var = var[ 1 : 2 ,
0 : 1 ,
0 : 1 ].assign(tf.ones((1,1,1)))
产生
[[[0. 0. 0. 0. 0.]
[0. 0. 0. 0. 0.]
[0. 0. 0. 0. 0.]
[0. 0. 0. 0. 0.]
[0. 0. 0. 0. 0.]]
[[1. 0. 0. 0. 0.]
[0. 0. 0. 0. 0.]
[0. 0. 0. 0. 0.]
[0. 0. 0. 0. 0.]
[0. 0. 0. 0. 0.]]
....
....]]
另一个例子是
var = var[ 1 : 2 ,
: 2 ,
: 2 ].assign(tf.ones((1,2,2)))
[[[0. 0. 0. 0. 0.]
[0. 0. 0. 0. 0.]
[0. 0. 0. 0. 0.]
[0. 0. 0. 0. 0.]
[0. 0. 0. 0. 0.]]
[[1. 1. 0. 0. 0.]
[1. 1. 0. 0. 0.]
[0. 0. 0. 0. 0.]
[0. 0. 0. 0. 0.]
[0. 0. 0. 0. 0.]]
....
....]]
您应该探索 tf.scatter_nd 张量。
tf.Variable
是唯一可以更新的张量。对于变量,您可以使用 gather
和 scatter_update
之类的代码进行切片。
请注意,其他张量不适合赋值。如果这是你想要做的,我想知道为什么它是必要的。然而,仍然可以用你想要的值创建新的张量(而不是就地分配),代码有点复杂。例如,以下内容不起作用:
index = ... tensor = tf.constant([0,1,2,3,4])
tensor[i] = 0
## Doesn't work (TypeError: `Tensor` object does not support item assignment)
但其中任何一个都可以做同样的事情:
tensor = tf.constant([0,1,2,3,4])
tensor = tf.concat([tensor[:i], tf.zeros_like(tensor[i:i+1]), tensor[i+1:]], 0)
## This works, creates a new tensor
张量 = tf.constant([0,1,2,3,4])
张量 = tf.concat([张量[:i], tf.fill([1], 0), 张量[i+1:]], 0)
## 这行得通,创建了一个新的张量
在 Pytorch 中,您可以像这样轻松更新张量:
for i in range(x_len):
tensor_abc[:, i, i] = 0
我们如何在 tensorflow 中更新像这样的张量?
我尝试了 tf.assign
和 tf.scatter_update
,但都没有用。
此答案仅适用于变量。
import tensorflow as tf
sess = tf.InteractiveSession()
v = tf.zeros((5,5,5))
var = tf.Variable(initial_value=v)
init = tf.variables_initializer([var])
sess.run(init)
var = var[ 1 : 2 ,
1 : 2 ,
1 : 2 ].assign(tf.ones((1,1,1)))
print(sess.run(var))
这会产生
[[[0. 0. 0. 0. 0.]
[0. 0. 0. 0. 0.]
[0. 0. 0. 0. 0.]
[0. 0. 0. 0. 0.]
[0. 0. 0. 0. 0.]]
[[0. 0. 0. 0. 0.]
[0. 1. 0. 0. 0.]
[0. 0. 0. 0. 0.]
[0. 0. 0. 0. 0.]
[0. 0. 0. 0. 0.]]
[[0. 0. 0. 0. 0.]
[0. 0. 0. 0. 0.]
[0. 0. 0. 0. 0.]
[0. 0. 0. 0. 0.]
[0. 0. 0. 0. 0.]]
[[0. 0. 0. 0. 0.]
[0. 0. 0. 0. 0.]
[0. 0. 0. 0. 0.]
[0. 0. 0. 0. 0.]
[0. 0. 0. 0. 0.]]
[[0. 0. 0. 0. 0.]
[0. 0. 0. 0. 0.]
[0. 0. 0. 0. 0.]
[0. 0. 0. 0. 0.]
[0. 0. 0. 0. 0.]]]
还有这个
var = var[ 1 : 2 ,
0 : 1 ,
0 : 1 ].assign(tf.ones((1,1,1)))
产生
[[[0. 0. 0. 0. 0.]
[0. 0. 0. 0. 0.]
[0. 0. 0. 0. 0.]
[0. 0. 0. 0. 0.]
[0. 0. 0. 0. 0.]]
[[1. 0. 0. 0. 0.]
[0. 0. 0. 0. 0.]
[0. 0. 0. 0. 0.]
[0. 0. 0. 0. 0.]
[0. 0. 0. 0. 0.]]
....
....]]
另一个例子是
var = var[ 1 : 2 ,
: 2 ,
: 2 ].assign(tf.ones((1,2,2)))
[[[0. 0. 0. 0. 0.]
[0. 0. 0. 0. 0.]
[0. 0. 0. 0. 0.]
[0. 0. 0. 0. 0.]
[0. 0. 0. 0. 0.]]
[[1. 1. 0. 0. 0.]
[1. 1. 0. 0. 0.]
[0. 0. 0. 0. 0.]
[0. 0. 0. 0. 0.]
[0. 0. 0. 0. 0.]]
....
....]]
您应该探索 tf.scatter_nd 张量。
tf.Variable
是唯一可以更新的张量。对于变量,您可以使用 gather
和 scatter_update
之类的代码进行切片。
请注意,其他张量不适合赋值。如果这是你想要做的,我想知道为什么它是必要的。然而,仍然可以用你想要的值创建新的张量(而不是就地分配),代码有点复杂。例如,以下内容不起作用:
index = ... tensor = tf.constant([0,1,2,3,4])
tensor[i] = 0
## Doesn't work (TypeError: `Tensor` object does not support item assignment)
但其中任何一个都可以做同样的事情:
tensor = tf.constant([0,1,2,3,4])
tensor = tf.concat([tensor[:i], tf.zeros_like(tensor[i:i+1]), tensor[i+1:]], 0)
## This works, creates a new tensor
张量 = tf.constant([0,1,2,3,4]) 张量 = tf.concat([张量[:i], tf.fill([1], 0), 张量[i+1:]], 0) ## 这行得通,创建了一个新的张量