Tensorflow One Hot Encoder?

Имеет ли тензорный поток нечто похожее на scikit learn один горячий кодировщик для обработки категориальных данных? Использует ли местозаполнитель tf.string как категориальные данные?

Я понимаю, что я могу вручную предварительно обработать данные, прежде чем отправлять их в тензорный поток, но с его встроенным очень удобно.

Ответ 1

Начиная с TensorFlow 0.8, теперь существует native one-hot op, tf.one_hot, который может преобразовать набор разреженных меток в плотное одноразовое представление. Это в дополнение к tf.nn.sparse_softmax_cross_entropy_with_logits, что в некоторых случаях позволяет вам вычислить кросс-энтропию непосредственно на разреженных ярлыках, а не конвертировать их в один -Hot.

Предыдущий ответ, если вы хотите сделать это по-старому: Ответ @Salvador правильный - там (раньше было) нет родного op для этого. Вместо того, чтобы делать это в 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-02-12 (который, как я полагаю, в конечном итоге станет частью выпуска 0.7), TensorFlow также имеет tf.nn.sparse_softmax_cross_entropy_with_logits op, который в некоторых случаях может позволить вам тренироваться без необходимости конвертировать в одноразовое кодирование.

Отредактировано для добавления: в конце вам может потребоваться явно установить форму меток. Вывод формы не распознает размер компонента num_labels. Если вам не нужен динамический размер пакета с производным_разделом, это можно упростить.

Отредактировано 2016-02-12, чтобы изменить назначение outshape для комментария ниже.

Ответ 2

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.

Ответ 3

numpy делает это!

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

Ответ 4

В последних версиях TensorFlow (ночные и, возможно, даже 0.7.1) есть операционная система tf.one_hot, которая делает то, что вы хотите. Проверьте это!

С другой стороны, если у вас есть плотная матрица, и вы хотите искать и суммировать значения в ней, вы хотели бы использовать функцию embedding_lookup.

Ответ 5

Простой и короткий путь к одноструйному кодированию любого целого числа или списка интергеров:

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)

Ответ 6

Возможно, это связано с изменениями Tensorflow с ноября 2015 года, но ответ @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)

Ответ 7

Посмотрите tf.nn.embedding_lookup. Он отображает от категориальных идентификаторов к их вложениям.

Пример того, как он используется для входных данных, см. здесь.

Ответ 8

Вы можете использовать tf.sparse_to_dense:

Аргумент sparse_indices указывает, куда должны идти теги, output_shape должен быть установлен на количество возможных выходов (например, количество меток), а sparse_values ​​должно быть 1 с нужным типом (он будет определять тип вывода из тип разреженных_значений).

Ответ 10

Здесь embedding_ops в Scikit Flow и примеры, относящиеся к категориальным переменным и т.д.

Если вы только начинаете изучать TensorFlow, я предлагаю вам попробовать examples в TensorFlow/skflow, а затем, когда вы более знакомы с TensorFlow, вам будет легко вставить код TensorFlow для создания пользовательской модели, которую вы хотите (есть примеры для этого).

Надеюсь, что эти примеры для понимания изображений и текста помогут вам начать работу и сообщить нам, если у вас возникнут какие-либо проблемы! (проблемы с сообщениями или тег skflow в SO).

Ответ 11

Есть несколько способов сделать это.

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

Ответ 12

Моя версия примера @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)

Ответ 13

Как уже упоминалось выше @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()

Ответ 14

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.