Tensorflow One Hot Encoder?

时间:2015-11-12 21:16:01

标签: python machine-learning neural-network tensorflow

tensorflow是否与scikit learn zero-value类似,用于处理分类数据?使用tf.string的占位符会表现为分类数据吗?

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

14 个答案:

答案 0 :(得分:63)

从TensorFlow 0.8开始,现在有一个native one-hot op, tf.one_hot可以将一组稀疏标签转换为密集的单热表示。这是tf.nn.sparse_softmax_cross_entropy_with_logits的补充,在某些情况下,您可以直接在稀疏标签上计算交叉熵,而不是将它们转换为单热。

以前的答案,如果您想以旧方式执行此操作: @ Salvador的答案是正确的 - 那里(以前)没有本地操作。不过,不是在numpy中进行,而是可以使用稀疏到密集的运算符在tensorflow中本地执行:

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)

输出标签是batch_size x num_labels的一个热矩阵。

另请注意,截至2016-02-12(我假设最终将成为0.7版本的一部分),TensorFlow也有tf.nn.sparse_softmax_cross_entropy_with_logits op,在某些情况下可以让你进行培训而无需转换为单热编码。

编辑添加:最后,您可能需要明确设置标签的形状。形状推断无法识别num_labels组件的大小。如果您不需要使用derived_size的动态批量大小,则可以简化此操作。

编辑2016-02-12更改以下评论的outshape分配。

答案 1 :(得分:45)

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 documentation之后,我没有找到类似的东西。有一件事加强了我对它不存在的信念,那就是在their own example中他们手动编写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

中执行此操作

答案 2 :(得分:17)

numpy做到了!

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

答案 3 :(得分:8)

对一个整数或整数列表进行单热编码的简单方法:

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)

答案 4 :(得分:6)

TensorFlow的最新版本(nightlies甚至可能是0.7.1)有一个名为tf.one_hot的操作,可以完成你想要的操作。看看吧!

另一方面,如果你有一个密集矩阵,并且想要查找并聚合其中的值,你可能想要使用embedding_lookup函数。

答案 5 :(得分:4)

也许是因为自2015年11月以来Tensorflow发生了变化,但@ dga的答案产生了错误。我确实让它与以下修改一起工作:

webdriver.Firefox

答案 6 :(得分:2)

看看tf.nn.embedding_lookup。它从分类ID映射到嵌入。

有关如何将其用于输入数据的示例,请参阅here

答案 7 :(得分:2)

您可以使用tf.sparse_to_dense

sparse_indices参数指示应该去哪里,output_shape应该设置为可能的输出数量(例如标签的数量),sparse_values应该是1,具有所需的类型(它将确定输出的类型) sparse_values的类型。)

答案 8 :(得分:2)

Scikit Flow中的embedding_ops以及处理分类变量的示例等。

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

希望这些图片和文字理解示例可以帮助您入门,如果您遇到任何问题,请告诉我们! (在SO中发布问题或标记skflow)。

答案 9 :(得分:1)

当前版本的tensorflow实现了以下用于创建单热张量的函数:

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

答案 10 :(得分:1)

正如上面提到的@dga,Tensorflow现在有tf.one_hot

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()

中的参数顺序

答案 11 :(得分: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)

答案 12 :(得分:0)

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月。

答案 13 :(得分:0)

与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

有关更多信息,请参阅此Tutorial on TF_Transform