【问题标题】:Scatter operation for middle dimension of a tensor张量中间维度的散点运算
【发布时间】:2017-11-21 21:02:34
【问题描述】:

我有一个 3d 张量,我需要在第二维中的某些位置保留向量,并将剩余向量归零。这些位置被指定为一维数组。我认为最好的方法是将张量与二进制掩码相乘。

这是一个简单的 Numpy 版本:

A.shape: (b, n, m) 
indices.shape: (b)

mask = np.zeros(A.shape)
for i in range(b):
  mask[i][indices[i]] = 1
result = A*mask

因此,对于 A 中的每个 nxm 矩阵,我需要保留由索引指定的行,并将其余行归零。

我正在尝试在 TensorFlow 中使用 tf.scatter_nd op 执行此操作,但我无法确定索引的正确形状:

shape = tf.constant([3,5,4])
A = tf.random_normal(shape)       
indices = tf.constant([2,1,4])   #???   
updates = tf.ones((3,4))           
mask = tf.scatter_nd(indices, updates, shape) 
result = A*mask

【问题讨论】:

    标签: tensorflow


    【解决方案1】:

    这是一种方法,创建一个蒙版并使用tf.where

    import tensorflow as tf
    import tensorflow.contrib.eager as tfe
    tfe.enable_eager_execution()
    
    shape = tf.constant([3,5,4])
    A = tf.random_normal(shape)
    
    array_shape = tf.shape(A)
    indices = tf.constant([2,1,4])
    non_zero_indices = tf.stack((tf.range(array_shape[0]), indices), axis=1)
    should_keep_row = tf.scatter_nd(non_zero_indices, tf.ones_like(indices),
                                    shape=[array_shape[0], array_shape[1]])
    print("should_keep_row", should_keep_row)
    masked = tf.where(tf.cast(tf.tile(should_keep_row[:, :, None],
                                      [1, 1, array_shape[2]]), tf.bool),
                       A,
                       tf.zeros_like(A))
    print("masked", masked)
    

    打印:

    should_keep_row tf.Tensor(
    [[0 0 1 0 0]
     [0 1 0 0 0]
     [0 0 0 0 1]], shape=(3, 5), dtype=int32)
    masked tf.Tensor(
    [[[ 0.          0.          0.          0.        ]
      [ 0.          0.          0.          0.        ]
      [ 0.02036316 -0.07163608 -3.16707373  1.31406844]
      [ 0.          0.          0.          0.        ]
      [ 0.          0.          0.          0.        ]]
    
     [[ 0.          0.          0.          0.        ]
      [-0.76696759 -0.28313264  0.87965059 -1.28844094]
      [ 0.          0.          0.          0.        ]
      [ 0.          0.          0.          0.        ]
      [ 0.          0.          0.          0.        ]]
    
     [[ 0.          0.          0.          0.        ]
      [ 0.          0.          0.          0.        ]
      [ 0.          0.          0.          0.        ]
      [ 0.          0.          0.          0.        ]
      [ 1.03188455  0.44305769  0.71291149  1.59758031]]], shape=(3, 5, 4), dtype=float32)
    

    (该示例使用的是 Eager Execution,但相同的操作将适用于 Session 中的图形执行)

    【讨论】:

    • 感谢您的帮助,但您的解决方案不能满足我的要求。请看一下我的 Numpy 示例。三个 5x4 矩阵中的每一个都应包含一个非零行,由索引中的相应元素指定。
    • 道歉。现在应该好多了:)
    • 好的,它有效,我会接受你的回答,但是,我有点失望,它是如此复杂。如果我可以简单地做 mask[non_zero_indices] = 1,或者如果 tf.scatter_nd 允许我直接做,可能会采用轴参数,那就太好了。哦,好吧,我想我们还没有。
    • 哈,我认为tf.scatter_nd 已经足够复杂了。我同意这并不好。 tf.gather 你想要的行然后tf.pad 到形状可能更简单。如果我首先回答了正确的问题,我可能会给出那个解决方案......
    猜你喜欢
    • 2021-12-19
    • 2022-01-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-03-08
    相关资源
    最近更新 更多