Tensorflow Один Горячий Кодер?
есть ли у tensorflow что-то похожее на scikit learn's один горячий кодер для обработки категориальных данных? Будет использовать заполнитель tf.строка ведет себя как категориальные данные?
Я понимаю, что могу вручную предварительно обработать данные перед отправкой их в tensorflow, но иметь его встроенным очень удобно.
14 ответов:
по состоянию на TensorFlow 0.8, теперь есть родной один-горячий op,
tf.one_hot
который может преобразовать набор разреженных меток в плотное одно-горячее представление. Это в дополнение кtf.nn.sparse_softmax_cross_entropy_with_logits
, который может в некоторых случаях позволить вам вычислить перекрестную энтропию непосредственно на разреженных метках вместо преобразования их в один горячий.предыдущий ответ, если вы хотите сделать это по-старому: @Salvador ответ правильный - там (раньше) не было родного op сделать его. Однако вместо того, чтобы делать это в numpy, вы можете сделать это изначально в tensorflow, используя разреженные до плотных операторы:
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. Если вам не нужен динамический размер пакета с derived_size, это можно упростить.
отредактировано 2016-02-12, чтобы изменить назначение outshape на комментарий ниже.
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.
простой и короткий способ 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)
последние версии TensorFlow (nightlies и, возможно, даже 0.7.1) имеют op под названием tf.one_hot, что делает то, что вы хотите. Зацени!
с другой стороны, если у вас есть плотная матрица, и вы хотите посмотреть и агрегировать значения в ней, вы хотели бы использовать функцию embedding_lookup.
возможно, это связано с изменениями 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)
посмотри tf.НН.embedding_lookup. Он отображает от категориальных идентификаторов к их вложениям.
пример его использования для входных данных см. В разделе здесь.
можно использовать tf.sparse_to_dense:
аргумент sparse_indices указывает, куда они должны идти, output_shape должен быть установлен на количество возможных выходов (например, количество меток), а sparse_values должен быть 1 с желаемым типом (он будет определять тип выхода из типа sparse_values).
здесь embedding_ops в потоке Scikit и примерах, которые имеют дело с категориальными переменными и т. д.
Если вы только начинаете изучать TensorFlow, я бы предложил вам попробовать примеры на TensorFlow / skflow сначала, а затем, когда вы больше знакомы с TensorFlow, вам будет довольно легко вставить код TensorFlow для создания пользовательской модели, которую вы хотите (есть также примеры для этого).
надеюсь, что эти примеры для изображения и понимание текста могут помочь вам начать работу и сообщить нам, если у вас возникнут какие-либо проблемы! (сообщение проблемы или тег skflow в SO).
текущие версии tensorflow реализуют следующую функцию для создания однократных тензоров:
https://www.tensorflow.org/versions/master/api_docs/python/array_ops.html#one_hot
есть несколько способов сделать это.
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 ()