这是TensorFlow中的单热编码吗?或出于任何原因有缺陷?

rd1*_*d11 4 tensorflow

关于使用TensorFlow计算单热嵌入有一些堆栈溢出问题,这是可接受的解决方案:

num_labels = 10
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.reshape(tf.concat(0, [derived_size, [num_labels]]), [-1])
labels = tf.sparse_to_dense(concated, outshape, 1.0, 0.0)
Run Code Online (Sandbox Code Playgroud)

这几乎与官方教程中的代码相同:https://www.tensorflow.org/versions/0.6.0/tutorials/mnist/tf/index.html

对我而言,似乎既然tf.nn.embedding_lookup存在,它可能更有效率.这是一个使用它的版本,它支持任意形状的输入:

def one_hot(inputs, num_classes):
    with tf.device('/cpu:0'):
        table = tf.constant(np.identity(num_classes, dtype=np.float32))
        embeddings = tf.nn.embedding_lookup(table, inputs)
    return embeddings
Run Code Online (Sandbox Code Playgroud)

您是否希望此实施更快?它是否有任何其他原因的缺陷?

mrr*_*rry 23

one_hot()您问题中的功能看起来是正确的.但是,我们不建议以这种方式编写代码的原因是它的内存效率非常低.为了理解原因,假设您的批量大小为32,并且有1,000,000个类.

  • 在本教程中建议的版本中,最大张量将是结果tf.sparse_to_dense(),将是32 x 1000000.

  • 在问题中的one_hot()函数中,最大张量将np.identity(1000000)是4 TB的结果.当然,分配这个张量可能不会成功.即使类的数量要小得多,它仍然会浪费内存来显式存储所有这些零 - TensorFlow不会自动将您的数据转换为稀疏表示,即使它可能有利可图.

最后,我想为最近添加到开源存储库的新功能提供一个插件,并将在下一个版本中提供.tf.nn.sparse_softmax_cross_entropy_with_logits()允许您指定整数向量作为标签,从而使您不必构建密集的单热表示.它应该是更高效,无论是对于大量的类解决方案.

  • 在mrry的回答中提示,我已经改变了现有的MNIST卷积.py和CIFAR模型来使用这个新的op,所以它们作为一个例子是有用的:https://github.com/tensorflow/tensorflow/blob/master/tensorflow /models/image/cifar10/cifar10.py#L270 (2认同)