Tensorflow One Hot Encoder?


¿tensorflow tiene algo similar al one hot encoder de scikit learn para procesar datos categóricos? Usaría un marcador de posición de tf.cadena comportarse como datos categóricos?

Me doy cuenta de que puedo preprocesar manualmente los datos antes de enviarlos a tensorflow, pero tenerlo incorporado es muy conveniente.

Author: alvas, 2015-11-13

14 answers

A partir de TensorFlow 0.8, ahora hay un nativo-hot op, tf.one_hot eso puede convertir un conjunto de etiquetas dispersas en una representación densa y caliente. Esto es además de tf.nn.sparse_softmax_cross_entropy_with_logits, lo que en algunos casos puede permitirle calcular la entropía cruzada directamente en las etiquetas dispersas en lugar de convertirlas en una caliente.

Respuesta anterior, en caso de que desee hacerlo de la manera antigua: La respuesta de @Salvador es correcta - no había (solía haber) ninguna operación nativa para hacerlo. En lugar de hacerlo en numpy, sin embargo, puede hacerlo de forma nativa en tensorflow utilizando los operadores de dispersión a densidad:

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)

La salida, labels, es una matriz en caliente de batch_size x num_labels.

Tenga en cuenta también que a partir de 2016-02-12 (que asumo que eventualmente será parte de una versión 0.7), TensorFlow también tiene el tf.nn.sparse_softmax_cross_entropy_with_logits op, que en algunos casos puede permitirle hacer entrenamiento sin necesidad de convertir a una codificación one-hot.

Editado para agregar: Al final, es posible que necesite establecer explícitamente la forma de las etiquetas. La inferencia de forma no reconoce el tamaño del componente num_labels. Si no necesita un tamaño de lote dinámico con derived_size, esto se puede simplificar.

Editado 2016-02-12 para cambiar la asignación de outshape por comentario a continuación.

 58
Author: dga,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-29 16:35:58

tf.one_hot() está disponible en TF y es fácil de usar.

Supongamos que tiene 4 categorías posibles (gato, perro, pájaro, humano) y 2 instancias (gato, humano). Así que tu {[3] } y tu 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)

Tenga en cuenta que si proporciona index=-1 obtendrá todos los ceros en su vector one-hot.

Respuesta antigua, cuando esta función no estaba disponible.

Después de mirar la documentación de python , no he encontrado nada similar. Una cosa que fortalecer mi creencia de que no existe es que en su propio ejemplo escriben one_hot manualmente.

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

También puedes hacer esto en scikitlearn.

 40
Author: Salvador Dali,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-07-21 06:57:44

numpy lo hace!

import numpy as np
np.eye(n_labels)[target_vector]
 16
Author: Prakhar Agrawal,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-10-16 06:22:42

Una forma simple y corta de codificar en caliente cualquier entero o lista de intergers:

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)
 8
Author: Rajarshee Mitra,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-08-16 19:00:34

Las versiones recientes de TensorFlow (nightlies y quizás incluso 0.7.1) tienen un op llamado tf.one_hot que hace lo que quiere. ¡Mira esto!

Por otro lado, si tiene una matriz densa y desea buscar y agregar valores en ella, debería usar la función embedding_lookup.

 6
Author: Eugene Brevdo,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-03-09 20:53:13

Tal vez se deba a cambios en Tensorflow desde noviembre de 2015, pero la respuesta de @dga produjo errores. Hice que funcionara con las siguientes modificaciones:

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)
 4
Author: CFB,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-02-06 18:54:51

Echa un vistazo a tf.nn.embedding_lookup . Se asigna desde identificadores categóricos a sus incrustaciones.

Para un ejemplo de cómo se usa para los datos de entrada, vea aquí.

 2
Author: Markus Dreyer,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-11-19 17:26:19

Puede usar tf.sparse_to_dense :

El argumento sparse_indices indica hacia dónde deben ir, output_shape se debe establecer en el número de salidas posibles (por ejemplo, el número de etiquetas), y sparse_values debe ser 1 con el tipo deseado (determinará el tipo de la salida del tipo de sparse_values).

 2
Author: Josh11b,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-02-06 02:30:49

Hay embedding_ops en Scikit Flow y ejemplos que tratan con variables categóricas, etc.

Si acaba de empezar a aprender TensorFlow, le sugeriría que pruebe ejemplos en TensorFlow/skflow primero y luego, una vez que esté más familiarizado con TensorFlow, sería bastante fácil para usted insertar código TensorFlow para construir un modelo personalizado que desee (también hay ejemplos para esto).

Espero que esos ejemplos para la comprensión de imágenes y texto puedan empezar y háganos saber si usted encuentra cualquier problema! (publicar problemas o etiquetar skflow en SO).

 2
Author: Yuan Tang,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-02-17 03:57:23

Las versiones actuales de tensorflow implementan la siguiente función para crear tensores one-hot:

Https://www.tensorflow.org/versions/master/api_docs/python/array_ops.html#one_hot

 1
Author: Peteris,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-06-05 09:41:53

Hay un par de maneras de hacerlo.

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

La otra forma de hacerlo es.

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]]
 0
Author: Apurv,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-12-02 23:55:55

Mi versión de @CFB y @dga ejemplo, acortado un poco para facilitar la comprensión.

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)
 0
Author: VladimirLenin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-01-21 07:38:24

Como se mencionó anteriormente por @dga, Tensorflow tiene tf.one_hot ahora:

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)

Es necesario especificar la profundidad, de lo contrario obtendrá un tensor podado-caliente.

Si te gusta hacerlo manualmente:

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)

Observe el orden de los argumentos en tf.concat ()

 0
Author: Alexander Svetkin,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-07-04 16:58:45
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.]])

Funciona en la versión 1.3.0 de TF. A partir de Sep 2017.

 0
Author: Aaron,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-09-27 16:50:29