Подтвердить что ты не робот

Tensorflow One Hot Encoder?

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

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

4b9b3361

Ответ 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.