【问题标题】:Extract multiple submatrices from a Tensor从张量中提取多个子矩阵
【发布时间】:2018-10-15 12:21:25
【问题描述】:

很抱歉,我不得不问这个问题,因为它看起来很简单,但我正在尝试在 Tensorflow 中找到一种专门的方法。

我有一个如下的张量矩阵:

    [0 0 1 1]
X = [0 0 1 1]
    [1 1 0 0]
    [1 1 0 0]

我需要提取两个补丁:

  [1,1]     [1,1]
  [1,1] &   [1,1]

我还给出了指向上面给出的子矩阵的左元素的索引列表。例如。

[[0,2]
 [2,0]]

我需要在 Tensorflow 中提取补丁。谢谢。

【问题讨论】:

    标签: python python-3.x tensorflow


    【解决方案1】:

    您也可以使用 tf.gather_nd 来执行此操作。下面是一个显示所有工作位的示例,以及您可以使用gather_nd 做什么。您应该能够构建索引,这样您只需要一个 collect_nd 操作即可获得您想要的所有子矩阵。我刚刚包含了变量索引,以表明您可以使用它从您提前不知道的张量中获取子矩阵。因此,例如,如果您计算图中的一些内容并希望根据这些内容获取子矩阵。

    import tensorflow as tf
    import numpy as np
    
    # build a tensor
    x = np.arange(25)
    x = np.reshape(x, [5, 5])
    y = x + 4
    three_d_array = np.stack([x, y], axis=2)
    # just so you can see the shape its made of
    print(np.all(x == three_d_array[:,:,0]))
    print(np.all(y == three_d_array[:,:,1]))
    # make it into a tf tensor
    three_d_tensor = tf.constant(three_d_array)
    
    # create a variable for tensor valued slice indices
    row_0, col_0 = 0, 0
    row_1, col_1 = 0, 1
    row_2, col_2 = 1, 0
    row_3, col_3 = 1, 1
    slice_tensor = tf.constant([
        [row_0, col_0],
        [row_1, col_1],
        [row_2, col_2],
        [row_3, col_3]
    ])
    slices = tf.Variable(initial_value=slice_tensor)
    
    # op to get the sub matrices
    gather_op = tf.gather_nd(three_d_tensor, slices)
    
    with tf.Session() as sess:
      init = tf.global_variables_initializer()
      sess.run(init)
    
      submatrices = sess.run(gather_op)
      print(submatrices[0,:] == three_d_array[row_0, col_0])
      print(submatrices[1,:] == three_d_array[row_1, col_1])
      print(submatrices[2,:] == three_d_array[row_2, col_2])
      print(submatrices[3,:] == three_d_array[row_3, col_3])
    
      # shift down 2 along 2
      offset_top_left = tf.constant([2,2])
      update_variable_op = tf.assign(slices, slices + offset_top_left[None,:])
      sess.run(update_variable_op)
      submatrices = sess.run(gather_op)
      print(submatrices[0, :] == three_d_array[row_0 + 2, col_0 + 2])
      print(submatrices[1, :] == three_d_array[row_1 + 2, col_1 + 2])
      print(submatrices[2, :] == three_d_array[row_2 + 2, col_2 + 2])
      print(submatrices[3, :] == three_d_array[row_3 + 2, col_3 + 2])
    

    【讨论】:

    • @Ahsan 欢迎您。如果这有帮助,您能否接受答案。
    【解决方案2】:

    好吧,如果您知道需要提取哪些子矩阵,tf.slice() 是最佳选择。

    文档是here

    对于您提供的示例,使用 tf.slice() 的解决方案是:

    import tensorflow as tf
    
    x = [[0, 0, 1, 1],
         [0, 0, 1, 1],
         [1, 1, 0, 0],
         [1, 1, 0, 0]]
    X = tf.Variable(x)
    s1 = tf.slice(X, [2,0], [2,2])
    s1 = tf.slice(X, [0,2], [2,2])
    
    
    with tf.Session() as sess:
      init = tf.global_variables_initializer()
      sess.run(init)
      print(sess.run([s1, s1]))
    

    此代码呈现以下结果:

    [array([[1, 1], [1, 1]], dtype=int32), 
    array([[1, 1], [1, 1]], dtype=int32)]
    

    编辑:

    对于更自动且不那么冗长的方式,您可以使用 tensorflow 中的 getitem 属性并像对 npArray 进行切片一样对其进行切片。

    代码可能是这样的:

    import tensorflow as tf
    
    var = [[0, 0, 1, 1],
           [0, 0, 1, 1],
           [1, 1, 0, 0],
           [1, 1, 0, 0]]
    X = tf.Variable(var)
    slices = [[0,2], [2,0]]
    
    s = []
    for sli in slices:
      y = sli[0]
      x = sli[1]
      s.append(X[y:y+2, x:x+2])
    
    
    with tf.Session() as sess:
      init = tf.global_variables_initializer()
      sess.run(init)
      print(sess.run(s))
    

    此代码呈现以下结果:

    [array([[1, 1], [1, 1]], dtype=int32), 
    array([[1, 1], [1, 1]], dtype=int32)]
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-10-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-05-12
      相关资源
      最近更新 更多