Reputation: 2678
I'd like to assign multiple values to a tensor, but it seems that it's not supported at least in the way that is possible using numpy.
a = np.zeros((4, 4))
v = np.array([0, 2, 3, 1])
r = np.arange(4)
a[r, v] = 1
>>> a
array([[1., 0., 0., 0.],
[0., 0., 1., 0.],
[0., 0., 0., 1.],
[0., 1., 0., 0.]])
The above works, but the tensorflow equivalent doesn't:
import tensorflow as tf
a = tf.zeros((4, 4))
v = tf.Variable([0, 2, 3, 1])
r = tf.range(4)
a[r, v].assign(1)
TypeError: Only integers, slices, ellipsis, tf.newaxis and scalar tensors are valid indices, got <tf.Tensor: shape=(4,), dtype=int32, numpy=array([0, 1, 2, 3])>
How could this be achieved? Are loops the only option? In my case the resulting array is indeed only slices of an identity matrix rearranged, so maybe that could be taken advantage of somehow.
Upvotes: 1
Views: 201
Reputation: 11651
Your example, which is updating a zero tensor at some indices to a certain value is most of time achieved through tf.scatter_nd
:
idx = tf.stack([r,v],axis=-1)
tf.scatter_nd(idx, updates=tf.ones(4), shape=(4,4))
For more complex cases, you can look at the following functions:
tf.tensor_scatter_nd_add
: Adds sparse updates to an existing tensor according to indices.tf.tensor_scatter_nd_sub
: Subtracts sparse updates from an existing tensor according to indices.tf.tensor_scatter_nd_max
: to copy element-wise maximum values from one tensor to another.tf.tensor_scatter_nd_min
: to copy element-wise minimum values from one tensor to another.tf.tensor_scatter_nd_update
: Scatter updates into an existing tensor according to indices.You can read more in the guide: Introduction to tensor slicing
Upvotes: 3