Tensorflow One 热门编码器?
Tensorflow One Hot Encoder?
tensorflow 是否有类似于 scikit learn 的 one hot encoder 用于处理分类数据的东西?使用占位符 tf.string 会作为分类数据吗?
我意识到我可以在将数据发送到 tensorflow 之前手动预处理数据,但是内置它非常方便。
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 documentation, I have not found anything similar. One thing that strengthen my belief that it does not exist is that in 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 中执行此操作。
从 TensorFlow 0.8 开始,现在有一个 native one-hot op, tf.one_hot
that can convert a set of sparse labels to a dense one-hot representation. This is in addition to 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)
输出标签是 batch_size x num_labels 的单热矩阵。
另请注意,从 2016 年 2 月 12 日开始(我假设它最终将成为 0.7 版本的一部分),TensorFlow 也有 tf.nn.sparse_softmax_cross_entropy_with_logits
操作,在某些情况下,它可以让你在没有需要转换为单热编码。
编辑补充:最后,您可能需要明确设置标签的形状。形状推断无法识别 num_labels 组件的大小。如果您不需要 derived_size 的动态批量大小,这可以简化。
2016 年 2 月 12 日编辑以根据下面的评论更改 outshape 的分配。
看看tf.nn.embedding_lookup。它将分类 ID 映射到它们的嵌入。
有关如何将其用于输入数据的示例,请参阅 here。
可能是因为自 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)
您可以使用 tf.sparse_to_dense:
sparse_indices参数表示应该去哪里,output_shape应该设置为可能输出的数量(例如标签的数量),sparse_values应该是1使用所需的类型(它将根据 sparse_values 的类型确定输出的类型)。
Scikit Flow 中有 embedding_ops 和处理分类变量的示例等。
如果您刚开始学习 TensorFlow,我建议您先尝试 examples in TensorFlow/skflow,一旦您对 TensorFlow 更加熟悉,插入 TensorFlow 代码来构建自定义模型就会相当容易你想要的(也有这方面的例子)。
希望这些图像和文本理解示例可以帮助您入门,如果您遇到任何问题,请告诉我们! (post 问题或在 SO 中标记 skflow)。
最新版本的 TensorFlow(nightlies 甚至可能是 0.7.1)有一个名为 tf.one_hot 的操作可以满足您的需求。看看吧!
另一方面,如果您有一个密集矩阵,并且您想要在其中查找和聚合值,您会想要使用 embedding_lookup 函数。
当前版本的tensorflow实现了以下创建单热张量的功能:
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 现在有 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()
中的参数顺序
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
执行One-Hot Encoding的代码如下所示:
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。
tensorflow 是否有类似于 scikit learn 的 one hot encoder 用于处理分类数据的东西?使用占位符 tf.string 会作为分类数据吗?
我意识到我可以在将数据发送到 tensorflow 之前手动预处理数据,但是内置它非常方便。
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 documentation, I have not found anything similar. One thing that strengthen my belief that it does not exist is that in 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 中执行此操作。
从 TensorFlow 0.8 开始,现在有一个 native one-hot op, tf.one_hot
that can convert a set of sparse labels to a dense one-hot representation. This is in addition to 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)
输出标签是 batch_size x num_labels 的单热矩阵。
另请注意,从 2016 年 2 月 12 日开始(我假设它最终将成为 0.7 版本的一部分),TensorFlow 也有 tf.nn.sparse_softmax_cross_entropy_with_logits
操作,在某些情况下,它可以让你在没有需要转换为单热编码。
编辑补充:最后,您可能需要明确设置标签的形状。形状推断无法识别 num_labels 组件的大小。如果您不需要 derived_size 的动态批量大小,这可以简化。
2016 年 2 月 12 日编辑以根据下面的评论更改 outshape 的分配。
看看tf.nn.embedding_lookup。它将分类 ID 映射到它们的嵌入。
有关如何将其用于输入数据的示例,请参阅 here。
可能是因为自 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)
您可以使用 tf.sparse_to_dense:
sparse_indices参数表示应该去哪里,output_shape应该设置为可能输出的数量(例如标签的数量),sparse_values应该是1使用所需的类型(它将根据 sparse_values 的类型确定输出的类型)。
Scikit Flow 中有 embedding_ops 和处理分类变量的示例等。
如果您刚开始学习 TensorFlow,我建议您先尝试 examples in TensorFlow/skflow,一旦您对 TensorFlow 更加熟悉,插入 TensorFlow 代码来构建自定义模型就会相当容易你想要的(也有这方面的例子)。
希望这些图像和文本理解示例可以帮助您入门,如果您遇到任何问题,请告诉我们! (post 问题或在 SO 中标记 skflow)。
最新版本的 TensorFlow(nightlies 甚至可能是 0.7.1)有一个名为 tf.one_hot 的操作可以满足您的需求。看看吧!
另一方面,如果您有一个密集矩阵,并且您想要在其中查找和聚合值,您会想要使用 embedding_lookup 函数。
当前版本的tensorflow实现了以下创建单热张量的功能:
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 现在有 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()
中的参数顺序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
执行One-Hot Encoding的代码如下所示:
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。