【问题标题】:How to create a one-hot tensor for k largest elements in 4d tensor?如何为 4d 张量中的 k 个最大元素创建一个单热张量?
【发布时间】:2019-04-13 12:12:50
【问题描述】:

给定一个形状为 (2,3,3,1) 的张量,其中批量大小为 2,每个矩阵的形状为 (3,3,1)。如何从每个矩阵中找到 k 个最大元素并创建一个单热矩阵,以使这些 k 个位置的条目在其他位置为 1 和 0。 示例:(注意每个条目将是一个浮点数,为简单起见使用整数)

input_tensor=[[[1, 5, 7],
      [2, 8, 1],
      [3, 9, 1],
     ],
     [[0, 9, 5],
      [6, 0, 4],
      [3, 0, 8]
     ]
    ]

k=3 的单热张量:

output_tensor=[[[0, 0, 1],
      [0, 1, 0],
      [0, 1, 0],
     ],
     [[0, 1, 0],
      [1, 0, 0],
      [0, 0, 1]
     ]
    ]

tf.nn.top_k 将仅从最后一个维度返回 k 个最大元素。如何从 3d 张量 ex:(3,3,1) 中获取 k 个最大元素。 此外 tf.one_hot 将在每一行中为指定的深度和给定的索引放置一个,这不是这里的情况。

【问题讨论】:

  • 您在示例中显示的input_tensor 的大小为 (2X3X3) 您能否更正您的示例或问题描述是否正确。

标签: python tensorflow deep-learning


【解决方案1】:

如果要从每个矩阵中找出k最大的元素,可以使用下面的方法。

import tensorflow as tf

input_tensor = tf.constant([[[1, 5, 7],[2, 8, 1],[3, 9, 1]],
                            [[0, 9, 5],[6, 0, 4],[3, 0, 8]]],dtype=tf.int32)

k_tf = tf.placeholder(shape=(),dtype=tf.int32)

temp = tf.reshape(input_tensor,shape=(input_tensor.shape[0],-1))
# [[1 5 7 2 8 1 3 9 1]
#  [0 9 5 6 0 4 3 0 8]]
result = tf.reduce_sum(tf.one_hot(indices=tf.nn.top_k(temp,k=k_tf)[1], depth=temp.shape[1]), axis=1)
# [[0. 0. 1. 0. 1. 0. 0. 1. 0.]
#  [0. 1. 0. 1. 0. 0. 0. 0. 1.]]
result = tf.reshape(result,input_tensor.shape)

with tf.Session() as sess:
    print('k=2:')
    print(sess.run(result, feed_dict={k_tf: 2}))
    print('k=3:')
    print(sess.run(result,feed_dict={k_tf:3}))

k=2:
[[[0. 0. 0.]
  [0. 1. 0.]
  [0. 1. 0.]]

 [[0. 1. 0.]
  [0. 0. 0.]
  [0. 0. 1.]]]
k=3:
[[[0. 0. 1.]
  [0. 1. 0.]
  [0. 1. 0.]]

 [[0. 1. 0.]
  [1. 0. 0.]
  [0. 0. 1.]]]

【讨论】:

    【解决方案2】:

    考虑到你的例子,它实际上是形状 2,3,3

    output = tf.one_hot(tf.math.argmax(inp, 2), 3)
    

    首先我们取所需轴上最大条目的索引,在本例中为 2。然后应用一个具有所需深度的热编码,3

    【讨论】:

      【解决方案3】:
      import numpy as np
      import tensorflow as tf
      
      inputs=np.array([[[1, 5, 7],
            [2, 8, 1],
            [3, 9, 1],
           ],
           [[0, 9, 5],
            [6, 0, 4],
            [3, 0, 8]
           ]
          ])
      
      j = tf.placeholder(tf.int32)
      input_tensor = tf.placeholder(tf.float64, shape=(2,3,3))    
      _, inds = tf.nn.top_k(input_tensor, 3)    
      r = tf.reshape(inds[:,:,3-j], [-1])
      encoded_tensor = tf.reshape(tf.one_hot(r, 3),tf.shape(input_tensor))
      
      with tf.Session() as sess:
          for k in [1,2,3]:
              print ("K:",k)
              print (sess.run(encoded_tensor , feed_dict={j: k, input_tensor: inputs}))  
      

      输出:

      K: 1
      [[[1. 0. 0.]
        [0. 0. 1.]
        [0. 0. 1.]]
      
       [[1. 0. 0.]
        [0. 1. 0.]
        [0. 1. 0.]]]
      K: 2
      [[[0. 1. 0.]
        [1. 0. 0.]
        [1. 0. 0.]]
      
       [[0. 0. 1.]
        [0. 0. 1.]
        [1. 0. 0.]]]
      K: 3
      [[[0. 0. 1.]
        [0. 1. 0.]
        [0. 1. 0.]]
      
       [[0. 1. 0.]
        [1. 0. 0.]
        [0. 0. 1.]]]
      
      • 使用top_k获取顺序中的所有索引
      • 根据k 的值选择所需的索引
      • 展平并创建 3 级的 one-hot 编码(因为矩阵中的列是 3)
      • 重塑为 input_tensor 的形状。

      【讨论】:

      • 我认为 OP 的意思是从二维矩阵 (3x3) 的元素中找到顶部的 k 元素
      猜你喜欢
      • 2022-06-30
      • 2023-02-15
      • 1970-01-01
      • 2018-01-26
      • 2015-09-21
      • 2018-06-20
      • 2017-11-11
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多