简体   繁体   English

如何在 Tensorflow 张量中仅舍入 k 个最大元素

[英]how to round up only k greatest elements in a Tensorflow tensor

Let there be a TensorFlow tensor - for example [0.1,0.2,0.3,0.4].假设有一个 TensorFlow 张量 - 例如 [0.1,0.2,0.3,0.4]。 I want to round up k greatest elements and round down the rest.我想四舍五入k最大元素并向下舍入 rest。 (for example, when k =2, I wish to get [0,0,1,1]. When k =3, I wish to get [0,1,1,1].) (例如,当k =2时,我希望得到[0,0,1,1]。当k =3时,我希望得到[0,1,1,1]。)

I want to implement this function using only TensorFlow operations.我想只使用 TensorFlow 操作来实现这个 function 。 How do I achieve this?我如何实现这一目标?

Try something like this:尝试这样的事情:

import tensorflow as tf

x = tf.constant([0.1,0.2,0.3,0.4])
k = 3
greatest = tf.math.top_k(x, k=k).indices 
tensor = tf.tensor_scatter_nd_update(tf.zeros_like(x), tf.reshape(greatest, (tf.shape(greatest)[0], 1)), tf.ones_like(tf.gather(x, greatest)))

k = 3: k = 3:

tf.Tensor([0. 1. 1. 1.], shape=(4,), dtype=float32)

k = 2: k = 2:

tf.Tensor([0. 0. 1. 1.], shape=(4,), dtype=float32)

This method does not really round, since rounding 0.3 and 0.4 to the nearest integer would results in zeros and that is not what you want.这种方法并没有真正舍入,因为将0.30.4舍入到最接近的 integer 会导致零,这不是您想要的。 So I simply convert the highest k values in the tensor to ones and the rest to zeros, but that should be sufficient for your use case if it is still binary classification.因此,我只需将张量中的最高k值转换为 1,并将 rest 转换为零,但如果它仍然是二进制分类,这对于您的用例来说应该足够了。

If you really want to round up the greatest k values, then use tf.math.ceil instead of tf.ones_like :如果您真的想四舍五入最大的k值,请使用tf.math.ceil而不是tf.ones_like

tensor = tf.tensor_scatter_nd_update(tf.zeros_like(x), tf.reshape(greatest, (tf.shape(greatest)[0], 1)), tf.ceil((tf.gather(x, greatest))))

You can use tf.math.top_k for this.您可以为此使用tf.math.top_k The function will return the values and indices of the k-largest elements in a given tensor. function 将返回给定张量中 k 最大元素的值和索引。

https://www.tensorflow.org/api_docs/python/tf/math/top_k https://www.tensorflow.org/api_docs/python/tf/math/top_k

Then you can use the indices that get returned, to set the values within the tensor to a specific value.然后,您可以使用返回的索引将张量中的值设置为特定值。

The following solution rounds the values as mentioned in the question.以下解决方案将问题中提到的值四舍五入。

import tensorflow as tf

x = tf.constant([0.1,0.2,0.3,0.4])
k = 3

# retrieve min and max values
max_value = tf.math.ceil(tf.math.reduce_max(x))
min_value = tf.math.floor(tf.math.reduce_min(x))

# retrieve the k largest elements
k_largest = tf.math.top_k(x, k=k)

# reshape the indices, required for ‘scatter‘ function
indices = tf.reshape(k_largest.indices, (-1,1))
values = k_largest.values

# initialize update tensor with max_value
updates = max_value * tf.ones_like(values)
# initialize result with min_value
x_new = min_value * tf.ones_like(x)
# update values for k_largest indices
x_new = tf.tensor_scatter_nd_update(
    x_new, indices, updates)

print(x_new)

In case the ceil and floor operation you are asking for should be applied per element instead of applying it to the min and max value within the tensor, this would look like this:如果您要求的ceilfloor操作应针对每个元素应用,而不是应用于张量内的minmax ,则如下所示:

import tensorflow as tf

x = tf.constant([0.1,0.2,0.3,0.4])
k = 3

# retrieve the k largest elements
k_largest = tf.math.top_k(x, k=k)
# reshape the indices, required for ‘scatter‘ function
indices = tf.reshape(k_largest.indices, (-1,1))

# get floored values
floored_values = tf.math.floor(x)
# get ceiled values only for top-k
ceiled_values = tf.math.ceil(k_largest.values)

# initialize result with per element floored values
x_new = floored_values
# update values for k_largest indices with per element ceiled values
x_new = tf.tensor_scatter_nd_update(
    floored_values, indices, ceiled_values)

print(x_new)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM