TensorFlow 使用数组索引将 Tensor 分配给 Tensor [英] TensorFlow assign Tensor to Tensor with array indexing

查看:36
本文介绍了TensorFlow 使用数组索引将 Tensor 分配给 Tensor的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想在 TensorFlow 中做类似这段 Numpy 代码的事情:

I would like to do something like this piece of Numpy code, just in TensorFlow:

a = np.zeros([5, 2])
idx = np.random.randint(0, 2, (5,))
row_idx = np.arange(5)
a[row_idx, idx] = row_idx

意思是用另一个张量索引一个二维张量的所有行,然后为其分配一个张量.我对如何实现这一目标完全一无所知.

meaning indexing all rows of a 2D tensor with another tensor and then assigning a tensor to that. I am absolutely clueless on how to achieve this.

到目前为止我在 Tensorflow 中可以做的事情如下

What I can do so far in Tensorflow is the following

a = tf.Variable(tf.zeros((5, 2)))
idx = tf.constant([0, 1, 1, 0, 1])
row_idx = tf.range(5)
indices = tf.transpose([row_idx, idx])
r = tf.gather_nd(a, indices)
tf.assign(r, row_idx) # This line does not work

当我尝试执行此操作时,在最后一行出现以下错误:

When I try to execute this, I get the following error in the last line:

AttributeError: 'Tensor' object has no attribute 'assign'

有没有办法解决这个问题?必须有一些很好的方法来做到这一点,我不想用 for 循环遍历数据并在每个元素的基础上手动分配它.我知道现在数组索引不像 Numpy 的功能那么先进,但这应该仍然是可能的.

Is there a way around this? There must be some nice way to do this, I don't want to iterate with for loops over the data and manually assign this on a per-element basis. I know that right now array-indexing is not as advanced as Numpy's functionality, but this should still be possible somehow.

推荐答案

您经常尝试使用 tf.scatter_nd_update.但是,这在大多数情况下不是正确的方法,您不应该需要一个变量,只需要从原始张量生成的另一个张量,并带有一些替换值.不幸的是,通常没有直接的方法可以做到这一点.如果你的原始张量真的全为零,那么你可以简单地使用 tf.scatter_nd:

What you are trying to do is frequently done with tf.scatter_nd_update. However, that is most times not the right way to do it, you should not need a variable, just another tensor produced from the original tensor with some replaced values. Unfortunately, there is no straightforward way to do this in general. If your original tensor is really all zeros, then you can simply use tf.scatter_nd:

import tensorflow as tf

idx = tf.constant([0, 1, 1, 0, 1])
row_idx = tf.range(5)
indices = tf.stack([row_idx, idx], axis=1)
a = tf.scatter_nd(indices, row_idx, (5, 2))
with tf.Session() as sess:
    print(sess.run(a))
# [[0 0]
#  [0 1]
#  [0 2]
#  [3 0]
#  [0 4]]

然而,如果初始张量不全为零,那就更复杂了.一种方法是和上面一样,然后为更新做一个掩码,并根据掩码在原始和更新之间进行选择:

However, if the initial tensor is not all zeros, it is more complicated. One way to do that is do the same as above, then make a mask for the updated, and select between the original and the update according to the mask:

import tensorflow as tf

a = tf.ones((5, 2), dtype=tf.int32)
idx = tf.constant([0, 1, 1, 0, 1])
row_idx = tf.range(5)
indices = tf.stack([row_idx, idx], axis=1)
a_update = tf.scatter_nd(indices, row_idx, (5, 2))
update_mask = tf.scatter_nd(indices, tf.ones_like(row_idx, dtype=tf.bool), (5, 2))
a = tf.where(update_mask, a_update, a)
with tf.Session() as sess:
    print(sess.run(a))
# [[0 1]
#  [1 1]
#  [1 2]
#  [3 1]
#  [1 4]]

这篇关于TensorFlow 使用数组索引将 Tensor 分配给 Tensor的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆