Tensorflow一个热编码器?


Answers:


67

从TensorFlow 0.8开始,现在有一个原生的一站式操作,tf.one_hot可以将一组稀疏标签转换为密集的一站式表示形式。这是的补充tf.nn.sparse_softmax_cross_entropy_with_logits,在某些情况下,您可以使您直接在稀疏标签上计算交叉熵,而不必将其转换为单热点。

以前的答案,以防您想采用旧方法: @Salvador的答案是正确的-以前(过去)没有本机操作。但是,您可以使用稀疏到密集运算符在tensorflow中本地执行此操作,而不是在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)

输出,labels,是batch_size x num_labels的单矩阵。

还要注意的是,从2016年2月12日开始(我认为最终将成为0.7版本的一部分),TensorFlow还提供了tf.nn.sparse_softmax_cross_entropy_with_logitsop,在某些情况下可以让您进行培训而无需转换为单编码。

编辑添加:最后,您可能需要显式设置标签的形状。形状推断无法识别num_labels组件的大小。如果您不需要带有Derived_size的动态批处理大小,则可以简化此过程。

编辑于2016年2月12日,更改了以下每个注释的形状分配。


1
就像@CFB在下面已经提到的那样,由于TensorFlow的更改,这可能不再起作用。抛出IndexError: list index out of range。分配outshape = tf.pack([derived_size, num_labels])对我有用。
mackcmillion

该代码对我有用。最好使用tf.nn.sparse_softmax_cross_entropy_with_logits,我们也可以将其转换为一个热点tf.nn.softmax_cross_entropy_with_logits

2
如果将其与TensorFlow 1.0一起使用,则需要进行一些更改。tf.concat([indices, sparse_labels], 1)outshape = tf.stack([derived_size, num_labels])
Marc Belmont

50

tf.one_hot() 可在TF中使用,易于使用。

假设您有4种可能的类别(猫,狗,鸟,人)和2个实例(猫,人)。所以你depth=4和你的indices=[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中执行此操作


如果我们不知道“深度”或“ num_classes”怎么办?与sklearn.preprocessing.OneHotEncoder()相比,这不是一个缺点吗?
Yatharth Varshney,

18

numpy 可以!

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

target_vector在这里做什么?
Rishabh Agrahari

@Rishabh Agrahari这是的精美索引np.ndarray。假设目标向量为[2,0],np.eye(n_labels)[target_vector]则将返回单位矩阵的第三行和第一行(按此顺序)。这很漂亮。
LucG

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)

我收到TypeError:传递给参数'indices'的值的DataType float32不在允许的值列表中:int32,int64。可能是因为TF更新
。.– Aerin

看来您必须通过使用abtf.cast
Rajarshee Mitra,

6

TensorFlow的最新版本(每夜甚至是0.7.1)都有一个名为tf.one_hot的操作,可以完成您想要的操作。看看这个!

另一方面,如果您有一个密集矩阵,并且想要查找并汇总其中的值,则需要使用embedding_lookup函数。




4

也许是由于自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)


2

您可以使用tf.sparse_to_dense

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


2

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

如果你只是开始学习TensorFlow,我建议你尝试的例子TensorFlow / skflow第一,然后,一旦你更熟悉TensorFlow这将是很容易让你插入TensorFlow代码来构建你想自定义模型(有与此相关的示例)。

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



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()中的顺序


0

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

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]]

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)

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


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

有关更多信息,请参考TF_Transform上的教程

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.