【问题标题】:tensorflow: slicing a tensor along the second dimensiontensorflow:沿第二维切片张量
【发布时间】:2017-07-29 03:22:02
【问题描述】:

我有一个形状为 (None, 56, 300, 1) 的张量 X,还有一个形状为 y 的张量 strong>(None, 15),这些张量的第一个维度是batch_size,我想用y作为索引得到一个张量z,z的形状是(None, 15, 300, 1) 。有什么体面的方法可以做到这一点吗?

我写了一个简单的代码来测试,因为我发现这对我来说很难,因为实际上我不知道batch_size(这些张量的第一维是None),

这是我的测试代码:

import numpy as np
import tensorflow as tf

# In this test code , batch_size is 4.
# params' shape is (4, 3, 2 ,1), in practice is (None, 56, 300, 1), 
params = [
            [[['a0'], ['b0']], [['d0'], ['e0']], [['f0'], ['g0']]], 
            [[['a1'], ['b1']], [['d1'], ['e1']], [['f1'], ['g1']]],
            [[['a2'], ['b2']], [['d2'], ['e2']], [['f2'], ['g2']]],
            [[['a3'], ['b3']], [['d3'], ['e3']], [['f3'], ['g3']]],
        ]

# ind's shape is (4, 2) (In practice is (None, 15)), 
# so I wanna get output whose's shape is (4, 2, 2, 1), (In practice is (None, 15, 300, 1))
ind = [[1, 0], [0, 2], [2, 0], [2, 1]]
#ouput = [
# [[['d0'], ['e0']], [['a0'], ['b0']]],
# [[['a1'], ['b1']], [['f1'], ['g1']]],
# [[['f2'], ['g2']], [['a2'], ['b2']]],
# [[['f3'], ['g3']], [['d3'], ['e3']]]
#]

with tf.variable_scope('gather') as scope:
    tf_par = tf.constant(params)
    tf_ind = tf.constant(ind)
    res = tf.gather_nd(tf_par, tf_ind)

with tf.Session() as sess:
    init = tf.global_variables_initializer()
    print sess.run(res)
    print res

【问题讨论】:

  • 能否添加您对示例代码的期望结果
  • 混淆了,我的理解[1, 0]应该是[['a1'], ['b1']],但你的期望是[['d0'], ['e0']]
  • @YuwenYan [[['a0'], ['b0']], [['d0'], ['e0']], [['f0'], ['g0' ]]] 是第一个样本。 [1, 0] 响应第一个样本,所以答案应该是 [['d0'], ['e0']], [['a0'], ['b0']]。注意ind的长度为4,每个元素对params中每个样本的响应

标签: python tensorflow


【解决方案1】:

ind沿第二维对x进行切片,即切片

  • 张量x的形状(d0, d1, d2,...)d0可能是None
  • 具有索引张量 ind 形状 (d0, n1)
  • 获得一个张量y,形状为(d0, n1, d2, ...)

您可以使用tf.gather_ndtf.shape 在运行时获取形状:

ind_shape = tf.shape(ind)
ndind = tf.stack([tf.tile(tf.range(ind_shape[0])[:, None], [1, ind_shape[1]]),
                  ind], axis=-1)
y = tf.gather_nd(x, ndind)

【讨论】:

  • 想评论否决票?我看到你的代表下降了 1 分@Vladimir,那肯定不是你吗?
  • 是的,我可以解释我的反对意见。如果我将X 更改为tf_pary 更改为tf_ind,您的代码将不起作用。我认为好主意是在问题中给出关于示例的代码。对不起。
  • @Vladimir 是的,有一个硬编码的15 由于OP第一段中对问题的描述,这确实与他后面的示例不一致。我用更通用的tf.shape(y)[1] 替换了它,它现在应该适用于所有情况。
【解决方案2】:

对于您假设的结果,您应该使用:

ind = [[0, 1], [0, 0], [1, 0], [1, 2], [2, 2], [2, 0], [3, 2], [3, 1]]

更新

您可以使用此代码通过当前输入获取您想要的内容:

with tf.variable_scope('gather') as scope:
    tf_par = tf.constant(params)
    tf_ind = tf.constant(ind)

    tf_par_shape = tf.shape(tf_par)
    tf_ind_shape = tf.shape(tf_ind)
    tf_r = tf.div(tf.range(0, tf_ind_shape[0] * tf_ind_shape[1]), tf_ind_shape[1])
    tf_r = tf.expand_dims(tf_r, 1)
    tf_ind = tf.expand_dims(tf.reshape(tf_ind, shape = [-1]), 1)
    tf_ind = tf.concat([tf_r, tf_ind], axis=1)

    res = tf.gather_nd(tf_par, tf_ind)
    res = tf.reshape(res, shape = (-1, tf_ind_shape[1], tf_par_shape[2], tf_par_shape[3]))

【讨论】:

  • 是的,我正在尝试这样做。但这样一来,我必须指定batch_size。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-08-12
  • 2020-03-11
  • 2017-12-06
  • 2019-05-30
  • 2019-10-21
  • 1970-01-01
相关资源
最近更新 更多