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

时间:2019-01-20 06:14:32

标签: python tensorflow matrix-multiplication one-hot-encoding

鉴于两种输入,我正在寻找一种通往tensorflow的方法:

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

返回形状为(batch_size, x)的2D张量,以使输出中的ith元素等于input2[i]-th的{​​{1}}列ith中的元素。

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

(3, 2, 2), 那么我想要的输出是input2 = [0, 1, 1]

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

尝试:

我尝试使用tf.one_hot来完成此操作(input1),但是Tensorflow在进行乘法运算时感到不满意,并说“ ValueError:尺寸必须相等,但'mul'必须为2和3(op: 'Mul'),输入形状为[3,2,2],[3,2]。“

非常感谢您的帮助!

1 个答案:

答案 0 :(得分:1)

您可以使用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))