web-dev-qa-db-fra.com

Tensorflow One Hot Encoder?

Tensorflow a-t-il quelque chose de similaire à scikit learn n encodeur à chaud pour le traitement de données catégoriques? L'utilisation d'un espace réservé de tf.string se comporterait-elle comme des données catégoriques?

Je me rends compte que je peux pré-traiter manuellement les données avant de les envoyer à tensorflow, mais les intégrer est très pratique.

63
Robert Graves

Depuis TensorFlow 0.8, il existe maintenant un natif one-hot op, tf.one_hot qui permet de convertir un ensemble d'étiquettes clairsemées en une représentation dense one-hot. Cela s'ajoute à tf.nn.sparse_softmax_cross_entropy_with_logits , qui peut dans certains cas vous permettre de calculer l'entropie croisée directement sur les étiquettes clairsemées au lieu de les convertir en one-hot.

Réponse précédente, au cas où vous voudriez le faire à l'ancienne: @ La réponse de Salvador est correcte - il n'y avait pas d'opérateur natif pour le faire . Au lieu de le faire numpy, vous pouvez le faire de manière native dans tensorflow en utilisant les opérateurs peu dense à dense:

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 sortie, labels, est une matrice one-hot de batch_size x num_labels.

Notez également qu'à compter du 2016-02-12 (qui, je suppose, fera éventuellement partie d'une version 0.7), TensorFlow possède également le tf.nn.sparse_softmax_cross_entropy_with_logits op, qui peut dans certains cas vous permettre de suivre une formation sans avoir à convertir en un seul encodage. .

Modifié pour ajouter: À la fin, vous devrez peut-être explicitement définir la forme des étiquettes. L'inférence de forme ne reconnaît pas la taille du composant num_labels. Si vous n'avez pas besoin d'une taille de lot dynamique avec la taille dérivée, cela peut être simplifié.

Édité le 12/02/2016 pour modifier l'attribution de outshape par commentaire ci-dessous.

64
dga

tf.one_hot() est disponible dans TF et facile à utiliser.

Supposons que vous avez 4 catégories possibles (chat, chien, oiseau, humain) et 2 instances (chat, humain). Donc, votre depth=4 et votre 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)

Gardez à l'esprit que si vous fournissez index = -1, vous obtiendrez tous les zéros dans votre vecteur one-hot.

Ancienne réponse, lorsque cette fonction n'était pas disponible.

Après avoir jeté un œil sur le documentation python , je n'ai rien trouvé de semblable. Une chose qui renforce ma conviction que cela n'existe pas, c'est que leur propre exemple ils écrivent one_hot manuellement.

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

Vous pouvez également le faire dans scikitlearn .

46
Salvador Dali

numpy le fait!

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

Un moyen simple et rapide d’encoder à chaud un entier ou une liste d’entiers:

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
Rajarshee Mitra

Les versions récentes de TensorFlow (nightlies et peut-être même 0.7.1) ont un op appelé tf.one_hot qui fait ce que vous voulez. Vérifiez-le!

D'autre part, si vous avez une matrice dense et que vous souhaitez y rechercher et y agréger des valeurs, vous souhaiterez utiliser la fonction embedding_lookup.

6
Eugene Brevdo

Cela est peut-être dû aux modifications apportées à Tensorflow depuis novembre 2015, mais la réponse de @ dga a généré des erreurs. Je l'ai fait fonctionner avec les modifications suivantes:

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
CFB

Jetez un coup d'oeil à tf.nn.embedding_lookup . Il mappe des identifiants catégoriels à leurs intégrations.

Pour un exemple d'utilisation des données d'entrée, voir here .

2
Markus

Vous pouvez utiliser tf.sparse_to_dense :

L'argument sparse_indices indique où aller ceux-ci, output_shape doit être défini sur le nombre de sorties possibles (par exemple le nombre d'étiquettes) et sparse_values ​​doit être 1 avec le type souhaité (il déterminera le type de sortie à partir du type de sparse_values).

2
Josh11b

Il y a embedding_ops dans Scikit Flow et des exemples traitant des variables catégorielles, etc.

Si vous commencez juste à apprendre TensorFlow, je vous suggérerais d'essayer exemples dans TensorFlow/skflow d'abord, puis une fois que vous maîtriserez mieux TensorFlow, ce sera assez facile pour vous. insérer du code TensorFlow pour créer le modèle personnalisé souhaité (il existe également des exemples).

J'espère que ces exemples de compréhension d'images et de texte pourront vous aider à démarrer et à nous signaler si vous rencontrez des problèmes! (publier des numéros ou tag skflow dans SO).

2
Yuan Tang

Les versions actuelles de tensorflow implémentent la fonction suivante pour créer des tenseurs one-hot:

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

1
Peteris

Comme mentionné ci-dessus par @dga, Tensorflow a tf.one_hot maintenant:

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)

Vous devez spécifier la profondeur, sinon vous obtiendrez un tenseur one-hot élagué.

Si vous aimez le faire manuellement:

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)

Remarquez les arguments dans tf.concat ()

1
Alexander Svetkin
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.]])

fonctionne sur TF version 1.3.0. À partir de septembre 2017.

0
Aerin

Il y a plusieurs façons de le faire.

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

L'autre façon de le faire est.

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
Apurv

Ma version de @CFB et de @dga, par exemple, a été légèrement raccourcie pour faciliter la compréhension.

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
VladimirLenin