张量流一个热编码器? ?

张量流是否有类似于 scikit Learning 的 一个热的编码器来处理分类数据?使用 tf.string 的占位符是否表现为绝对数据?

我意识到我可以在发送数据到张量流之前手动预处理数据,但是内置它是非常方便的。

85188 次浏览

tf.one_hot() 可用于 TF,使用方便。

假设您有4个可能的类别(猫、狗、鸟、人)和2个实例(猫、人)。所以你的 depth=4indices=[0, 3]

import tensorflow as tf
res = tf.one_hot(indices=[0, 3], depth=4)
with tf.Session() as sess:
print sess.run(res)

请记住,如果提供 index =-1,那么将得到单热向量中的所有零。

旧的答案,当这个函数不可用时。

在看了 Python 文档之后,我没有发现任何类似的东西。有一件事加强了我的信念,那就是它不存在于 他们自己的榜样中,他们手动编写 one_hot

def dense_to_one_hot(labels_dense, num_classes=10):
"""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

您也可以在 Scikitlearn中执行此操作。

从 TensorFlow 0.8开始,现在有了一个 本地一级紧急行动 tf.one_hot,它可以将一组稀疏的标签转换为密集的单热表示。这是对 tf.nn.sparse_softmax_cross_entropy_with_logits的补充,在某些情况下,tf.nn.sparse_softmax_cross_entropy_with_logits可以让您直接计算稀疏标签上的交叉熵,而不是将它们转换为一个热点。

以前的答案,如果你想用老方法来做: @ Salvador 的回答是正确的——(过去)没有本土的行动可以做到这一点。不过,你可以使用稀疏到密集运算符在张量流中进行本地运算,而不是在 numpy 中进行:

num_labels = 10


# label_batch is a tensor of numeric labels to process
# 0 <= label < num_labels


sparse_labels = tf.reshape(label_batch, [-1, 1])
derived_size = tf.shape(label_batch)[0]
indices = tf.reshape(tf.range(0, derived_size, 1), [-1, 1])
concated = tf.concat(1, [indices, sparse_labels])
outshape = tf.pack([derived_size, num_labels])
labels = tf.sparse_to_dense(concated, outshape, 1.0, 0.0)

标签(label)输出是一个一次性热矩阵,其中包含批处理大小 xnum _ label。

还要注意的是,截至2016-02-12(我认为这最终将成为0.7版本的一部分) ,TensorFlow 还有 tf.nn.sparse_softmax_cross_entropy_with_logits操作,在某些情况下,它可以让你进行培训,而无需转换为一次性编码。

编辑后添加: 最后,您可能需要显式设置标签的形状。形状推断不能识别 num _ label 组件的大小。如果不需要具有派生 _ size 的动态批处理大小,则可以简化此操作。

编辑于2016-02-12,以改变下面每条评论的外形分配。

看看 嵌入 _ lookup,它从分类 ID 映射到它们的嵌入。

有关如何将其用于输入数据的示例,请参见 给你

也许是因为自2015年11月以来 Tensorflow 的变化,但是@dga 的回答产生了错误。我做了以下的修改:

sparse_labels = tf.reshape(label_batch, [-1, 1])
derived_size = tf.shape(sparse_labels)[0]
indices = tf.reshape(tf.range(0, derived_size, 1), [-1, 1])
concated = tf.concat(1, [indices, sparse_labels])
outshape = tf.concat(0, [tf.reshape(derived_size, [1]), tf.reshape(num_labels, [1])])
labels = tf.sparse_to_dense(concated, outshape, 1.0, 0.0)

你可以使用 稀疏到密集:

Sparse _ index 参数指示输出应该放在哪里,output _ form 应该设置为可能输出的数量(例如标签的数量) ,Sparse _ value 应该为1,并且具有所需的类型(它将确定来自 Sparse _ value 类型的输出的类型)。

Scikit Flow 中有 嵌入操作系统,还有处理分类变量的例子等等。

如果你刚刚开始学习 TensorFlow,我建议你先在 TensorFlow/skflow中尝试 例子,然后一旦你更加熟悉 TensorFlow,你就可以很容易地插入 TensorFlow 代码来构建你想要的自定义模型(也有这方面的例子)。

希望这些图片和文本理解的例子能够帮助您开始,如果遇到任何问题,请让我们知道!(在 SO 中发布问题或标记 skflow)。

TensorFlow 的最新版本(夜间节目,甚至可能是0.7.1)有一个名为 tf.one _ hot 的操作,可以完成您想要的任务。看看这个!

另一方面,如果您有一个稠密矩阵,并且希望在其中查找和聚合值,则需要使用嵌入 _ lookup 函数。

目前版本的张量流实现以下功能,创建一个热张量:

Https://www.tensorflow.org/versions/master/api_docs/python/array_ops.html#one_hot

一个简单而简短的方法来一热编码任何整数或整数列表:

a = 5
b = [1, 2, 3]
# one hot an integer
one_hot_a = tf.nn.embedding_lookup(np.identity(10), a)
# one hot a list of integers
one_hot_b = tf.nn.embedding_lookup(np.identity(max(b)+1), b)

numpy做到了!

import numpy as np
np.eye(n_labels)[target_vector]

有几种方法可以做到这一点。

ans = tf.constant([[5, 6, 0, 0], [5, 6, 7, 0]]) #batch_size*max_seq_len
labels = tf.reduce_sum(tf.nn.embedding_lookup(np.identity(10), ans), 1)


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

另一种方法是。

labels2 = tf.reduce_sum(tf.one_hot(ans, depth=10, on_value=1, off_value=0, axis=1), 2)


>>> [[0 0 0 0 0 1 1 0 0 0]
>>> [0 0 0 0 0 1 1 1 0 0]]

我的@CFB 和@dga 例子的版本缩短了一点,以便于理解。

num_labels = 10
labels_batch = [2, 3, 5, 9]


sparse_labels = tf.reshape(labels_batch, [-1, 1])
derived_size = len(labels_batch)
indices = tf.reshape(tf.range(0, derived_size, 1), [-1, 1])
concated = tf.concat(1, [indices, sparse_labels])
labels = tf.sparse_to_dense(concated, [derived_size, num_labels], 1.0, 0.0)

正如上面@dga 提到的,Tensorflow 现在拥有 好烫:

labels = tf.constant([5,3,2,4,1])
highest_label = tf.reduce_max(labels)
labels_one_hot = tf.one_hot(labels, highest_label + 1)


array([[ 0.,  0.,  0.,  0.,  0.,  1.],
[ 0.,  0.,  0.,  1.,  0.,  0.],
[ 0.,  0.,  1.,  0.,  0.,  0.],
[ 0.,  0.,  0.,  0.,  1.,  0.],
[ 0.,  1.,  0.,  0.,  0.,  0.]], dtype=float32)

你需要指定深度,否则你会得到一个修剪的热张量。

如果你喜欢手动操作:

labels = tf.constant([5,3,2,4,1])
size = tf.shape(labels)[0]
highest_label = tf.reduce_max(labels)
labels_t = tf.reshape(labels, [-1, 1])
indices = tf.reshape(tf.range(size), [-1, 1])
idx_with_labels = tf.concat([indices, labels_t], 1)
labels_one_hot = tf.sparse_to_dense(idx_with_labels, [size, highest_label + 1], 1.0)


array([[ 0.,  0.,  0.,  0.,  0.,  1.],
[ 0.,  0.,  0.,  1.,  0.,  0.],
[ 0.,  0.,  1.,  0.,  0.,  0.],
[ 0.,  0.,  0.,  0.,  1.,  0.],
[ 0.,  1.,  0.,  0.,  0.,  0.]], dtype=float32)

注意 tf.concat ()中的参数顺序

In [7]: one_hot = tf.nn.embedding_lookup(np.eye(5), [1,2])


In [8]: one_hot.eval()
Out[8]:
array([[ 0.,  1.,  0.,  0.,  0.],
[ 0.,  0.,  1.,  0.,  0.]])

在 TF 版本1.3.0上工作,截至2017年9月。

Tensorflow 2.0兼容答案 : 您可以使用 Tensorflow Transform高效地完成。

使用 Tensorflow Transform执行单热编码的代码如下:

def get_feature_columns(tf_transform_output):
"""Returns the FeatureColumns for the model.


Args:
tf_transform_output: A `TFTransformOutput` object.


Returns:
A list of FeatureColumns.
"""
# Wrap scalars as real valued columns.
real_valued_columns = [tf.feature_column.numeric_column(key, shape=())
for key in NUMERIC_FEATURE_KEYS]


# Wrap categorical columns.
one_hot_columns = [
tf.feature_column.categorical_column_with_vocabulary_file(
key=key,
vocabulary_file=tf_transform_output.vocabulary_file_by_name(
vocab_filename=key))
for key in CATEGORICAL_FEATURE_KEYS]


return real_valued_columns + one_hot_columns

有关更多信息,请参考此 变换教程