如何根据1在tf.int64索引实现的N-热编码? 输入被张量含有几个tf.int64。 所述N个热编码的目的是在tf.slim替换一个热编码。
所述one_hot编码被实现为以下内容:
def dense_to_one_hot(labels_dense, num_classes):
"""Convert class labels from scalars to one-hot vectors."""
num_labels = labels_dense.shape[0]
index_offset = numpy.arange(num_labels) * num_classes
labels_one_hot = numpy.zeros((num_labels, num_classes))
labels_one_hot.flat[index_offset + labels_dense.ravel()] = 1
return labels_one_hot
在N不编码手段:19 = 00010011,编码后的结果是[0,0,0,1,0,0,1,1]。
这是一个解决方案:
import numpy as np
import tensorflow as tf
def n_hot_encoding(a, n):
a = tf.convert_to_tensor(a)
m = 1 << np.arange(n)[::-1]
shape = np.r_[np.ones(len(a.shape), dtype=int), -1]
m = m.reshape(shape)
hits = tf.bitwise.bitwise_and(a[..., tf.newaxis], tf.cast(m, a.dtype))
return tf.not_equal(hits, 0)
with tf.Graph().as_default(), tf.Session() as sess:
n_hot = n_hot_encoding([19, 20, 21], 10)
print(sess.run(tf.cast(n_hot, tf.int32)))
输出:
[[0 0 0 0 0 1 0 0 1 1]
[0 0 0 0 0 1 0 1 0 0]
[0 0 0 0 0 1 0 1 0 1]]
它假定N
是一个普通的标量(不是TensorFlow值),并且该阵列将转换的维数是已知的(每个维度的大小可以是动态的,但a.shape
不应该只是None
)。 该功能可以适应TensorFlow,只有这样计算:
import tensorflow as tf
def n_hot_encoding(a, n):
a = tf.convert_to_tensor(a)
n = tf.convert_to_tensor(n)
m = tf.bitwise.left_shift(1, tf.range(n)[::-1])
shape = tf.concat([tf.ones([tf.rank(a)], dtype=tf.int64), [-1]], axis=0)
m = tf.reshape(m, shape)
hits = tf.bitwise.bitwise_and(a[..., tf.newaxis], tf.cast(m, a.dtype))
return tf.not_equal(hits, 0)
这应该与任一输入工作,但可以多做一点额外的工作,在每个图运行。
找到一个替代下方@jdehesa伟大的答案。 这个版本计算的位长度N
本身(但适用于只单值张量-或含有相同比特长度的值张量):
import tensorflow as tf
def logn(x, n):
numerator = tf.log(x)
denominator = tf.log(tf.cast(n, dtype=numerator.dtype))
return numerator / denominator
def count_bits(x):
return tf.cast((logn(tf.cast(x, dtype=tf.float32), 2)) + 1, dtype=x.dtype)
def n_hot_encode(x):
"""
Unpack an integer into its variable-length bit representation
:param x: Int tensor of shape ()
:return: Bool tensor of shape (N,) with N = bit length of x
"""
N = count_bits(x)
bins = tf.bitwise.left_shift(1, tf.range(N))[::-1]
x_unpacked = tf.reshape(tf.bitwise.bitwise_and(x, bins), [-1])
x_bits = tf.cast(x_unpacked, dtype=tf.bool)
return x_bits
with tf.Session() as sess:
result = sess.run(n_hot_encode(tf.constant(19)))
print(result)
# > [ True False False True True]
result = sess.run(n_hot_encode(tf.constant(255)))
print(result)
# > [ True True True True True True True True]
以前的答案:
使用tf.one_hot()
labels_one_hot = tf.one_hot(labels_dense, num_classes)