如何在4d张量中为k个最大元素创建单热张量?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何在4d张量中为k个最大元素创建单热张量?相关的知识,希望对你有一定的参考价值。

给定一个形状的张量,可以说(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得到k个最大元素:(3,3,1)。此外,tf.one_hot将在指定深度的每一行中放置一个,并给出索引,这不是这里的情况。

答案

如果要从每个矩阵中找到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,3,3

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

因此,首先我们采用所需轴中最大条目的索引,在这种情况下为2。然后应用一个具有所需深度的热编码,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级的单热编码(因为矩阵中的列为3)
  • 重塑为input_tensor的形状。

以上是关于如何在4d张量中为k个最大元素创建单热张量?的主要内容,如果未能解决你的问题,请参考以下文章

在 CUDA 中处理 4D 张量的内核

来自密集张量 Tensorflow 的稀疏张量(矩阵)

如何从 resnet 层循环遍历 4D(无,x,y,z)激活张量的 2D 矩阵?

如何在张量流中为非分类对象创建一个类?

Tensorflow - 为图像张量中的每个像素查找最大3个相邻像素

在 PyTorch 中将 5D 张量转换为 4D 张量