TensorFlow - 类似numpy的张量索引

LDG*_*DGN 26 python tensorflow

在numpy中,我们可以这样做:

x = np.random.random((10,10))
a = np.random.randint(0,10,5)
b = np.random.randint(0,10,5)
x[a,b] # gives 5 entries from x, indexed according to the corresponding entries in a and b
Run Code Online (Sandbox Code Playgroud)

当我在TensorFlow中尝试相同的东西时:

xt = tf.constant(x)
at = tf.constant(a)
bt = tf.constant(b)
xt[at,bt]
Run Code Online (Sandbox Code Playgroud)

最后一行给出"Bad slice index tensor"异常.似乎TensorFlow不支持像numpy或Theano这样的索引.

有没有人知道是否有TensorFlow方法这样做(用任意值索引张量).我已经看过tf.nn.embedding部分了,但是我不确定它们是否可以用于此,即使它们可以,但对于这种简单的事情来说,这是一个巨大的解决方法.

(现在,我正在将数据x作为输入提供并在numpy中进行索引,但我希望将其放入xTensorFlow以获得更高的效率)

jde*_*esa 12

你现在可以实现这一点tf.gather_nd.假设你有一个m如下矩阵:

| 1 2 3 4 |
| 5 6 7 8 |
Run Code Online (Sandbox Code Playgroud)

并且你想构建一个r大小的矩阵,比方说,3x2,由元素构建m,如下所示:

| 3 6 |
| 2 7 |
| 5 3 |
| 1 1 |
Run Code Online (Sandbox Code Playgroud)

每个元素r对应一个行和列m,你可以有矩阵rowscols这些索引(从零开始,因为我们编程,不做数学!):

       | 0 1 |         | 2 1 |
rows = | 0 1 |  cols = | 1 2 |
       | 1 0 |         | 0 2 |
       | 0 0 |         | 0 0 |
Run Code Online (Sandbox Code Playgroud)

你可以像这样堆叠成三维张量:

| | 0 2 | | 1 1 | |
| | 0 1 | | 1 2 | |
| | 1 0 | | 2 0 | |
| | 0 0 | | 0 0 | |
Run Code Online (Sandbox Code Playgroud)

通过这种方式,你可以从mr通过rowscols如下:

import numpy as np
import tensorflow as tf

m = np.array([[1, 2, 3, 4], [5, 6, 7, 8]])
rows = np.array([[0, 1], [0, 1], [1, 0], [0, 0]])
cols = np.array([[2, 1], [1, 2], [0, 2], [0, 0]])

x = tf.placeholder('float32', (None, None))
idx1 = tf.placeholder('int32', (None, None))
idx2 = tf.placeholder('int32', (None, None))
result = tf.gather_nd(x, tf.stack((idx1, idx2), -1))

with tf.Session() as sess:
    r = sess.run(result, feed_dict={
        x: m,
        idx1: rows,
        idx2: cols,
    })
print(r)
Run Code Online (Sandbox Code Playgroud)

输出:

[[ 3.  6.]
 [ 2.  7.]
 [ 5.  3.]
 [ 1.  1.]]
Run Code Online (Sandbox Code Playgroud)


dga*_*dga 10

LDGN的评论是正确的.目前这是不可能的,并且是请求的功能.如果您在github上关注问题#206,则会在/当可用时更新.很多人都喜欢这个功能.