根据一维索引张量(Tensorflow)从 3D 张量中选择列

Selecting columns from 3D tensor according to a 1D tensor of indices (Tensorflow)

我正在 tensorflow 中寻找一种方法,给定两个输入:

  1. input1,形状为 (batch_size, x, y)
  2. 的 3D 张量
  3. input2,形状为(batch_size,)的一维张量,其值都在[0, y - 1](含)范围内。

return 形状为 (batch_size, x) 的二维张量,使得输出中的 ith 元素等于 input2[i]-th input1ith 元素的列。

示例: 如果input1 = [[[1,2], [3,4]], [[5,6], [7,8]], [[9,10], [11,12]]] (所以 input1 的形状是 (3, 2, 2)) 和

input2 = [0, 1, 1], 那么我想要的输出是 [[1,3], [6,8], [10,12]]

解释:输出中第0个元素为[1,3],因为input2中第0个元素为0;因此,它成为 input1 的第 0 个元素中的第 0 列。输出中的最后一个元素是[6,8],因为input2中的最后一个元素是1;因此,它成为 input1.

最后一个元素的第一列

尝试次数:

我尝试使用 tf.one_hot 来完成此操作,(tf.reduce_sum(input1 * tf.one_hot(input2, y), 2)) 但是 Tensorflow 在进行乘法时变得不高兴,说 "ValueError: Dimensions must be equal, but are 2 and 3 for 'mul' (op: 'Mul') with input shapes: [3,2,2], [3,2]."

任何帮助将不胜感激,谢谢!

你可以用tf.map_fn()来实现。

import tensorflow as tf
import numpy as np

input1 = [[[1,2], [3,4]], [[5,6], [7,8]], [[9,10], [11,12]]]
input2 = [0, 1, 1]

tf_input1 = tf.placeholder(shape=(None,2,2),dtype=tf.int32)
tf_input2 = tf.placeholder(shape=(None),dtype=tf.int32)

result = tf.map_fn(lambda x: x[0][:,x[1]], [tf_input1,tf_input2], dtype=tf.int32)

with tf.Session()as sess:
    result = sess.run(result,feed_dict={tf_input1:np.array(input1)
        ,tf_input2:np.array(input2)})
    print(result)

# print
[[ 1  3]
 [ 6  8]
 [10 12]]

编辑

tf.map_fn() 与矢量化操作相比速度较慢。我加了一个矩阵乘法运算。

# shape= (3,2,1)
result = tf.cast(tf.expand_dims(tf.one_hot(input2, 2),-1),tf.int32)
# shape= (3,2)
result = tf.squeeze(tf.matmul(tf_input1, result))