¿Qué hace tf.nn.incrustar la función de búsqueda hacer?


tf.nn.embedding_lookup(params, ids, partition_strategy='mod', name=None)

No puedo entender el deber de esta función. ¿Es como una mesa de consulta? ¿Qué significa devolver los parámetros correspondientes a cada id (en ids)?

Por ejemplo, en el skip-gram modelo si usamos tf.nn.embedding_lookup(embeddings, train_inputs), entonces para cada train_input se encuentra la corresponden incrustación?

Author: kmario23, 2016-01-19

8 answers

embedding_lookup la función recupera filas del tensor params. El comportamiento es similar al uso de indexación con matrices en numpy. Por ejemplo,

matrix = np.random.random([1024, 64])  # 64-dimensional embeddings
ids = np.array([0, 5, 17, 33])
print matrix[ids]  # prints a matrix of shape [4, 64] 

params el argumento puede ser también una lista de tensores en cuyo caso el ids se distribuirá entre los tensores. Por ejemplo, dada una lista de 3 tensores [2, 64], el comportamiento predeterminado es que representarán ids: [0, 3], [1, 4], [2, 5].

partition_strategy controla cómo se distribuyen los ids entre la lista. El particionamiento es útil para problemas de mayor escala cuando la matriz puede ser demasiado grande para mantenerla en una sola pieza.

 117
Author: Rafał Józefowicz,
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-11-20 16:54:03

Sí, esta función es difícil de entender, hasta que obtengas el punto.

En su forma más simple, es similar a tf.gather. Devuelve los elementos de params de acuerdo con los índices especificados por ids.

Por ejemplo (suponiendo que estás dentro tf.InteractiveSession())

params = tf.constant([10,20,30,40])
ids = tf.constant([0,1,2,3])
print tf.nn.embedding_lookup(params,ids).eval()

Devolvería [10 20 30 40], porque el primer elemento (índice 0) de parámetros es 10, el segundo elemento de parámetros (índice 1) es 20, etc.

Del mismo modo,

params = tf.constant([10,20,30,40])
ids = tf.constant([1,1,3])
print tf.nn.embedding_lookup(params,ids).eval()

Volvería [20 20 40].

Pero embedding_lookup es más que eso. El argumento params puede ser una lista de tensores, en lugar de un solo tensor.

params1 = tf.constant([1,2])
params2 = tf.constant([10,20])
ids = tf.constant([2,0,2,1,2,3])
result = tf.nn.embedding_lookup([params1, params2], ids)

En tal caso, los índices, especificados en ids, corresponden a elementos de tensores de acuerdo con una estrategia de partición , donde la estrategia de partición predeterminada es 'mod'.

En la estrategia 'mod', el índice 0 corresponde al primer elemento del primer tensor de la lista. El índice 1 corresponde al primer elemento del segundo tensor . El índice 2 corresponde al primer elementodel tercer tensor, y así sucesivamente. Simplemente index i corresponde al primer elemento del tensor (i+1), para todos los índices 0..(n-1), asumiendo que params es una lista de tensores n.

Ahora, index n no puede corresponder al tensor n+1, porque la lista params contiene solo tensores n. Entonces index ncorresponde al segundo elemento del primer tensor. Del mismo modo, índice n+1 corresponde al segundo elemento del segundo tensor, etc.

Así, en el código

params1 = tf.constant([1,2])
params2 = tf.constant([10,20])
ids = tf.constant([2,0,2,1,2,3])
result = tf.nn.embedding_lookup([params1, params2], ids)

El índice 0 corresponde al primer elemento del primer tensor: 1

El índice 1 corresponde al primer elemento del segundo tensor: 10

El índice 2 corresponde al segundo elemento del primer tensor: 2

El índice 3 corresponde al segundo elemento del segundo tensor: 20

Así, el resultado sería:{[25]]}

[ 2  1  2 10  2 20]
 176
Author: Asher Stern,
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-11-11 20:57:23

Sí, el propósito de tf.nn.embedding_lookup() la función es realizar una búsqueda en la matriz de incrustación y devolver las incrustaciones (o en términos simples la representación vectorial) de las palabras.

Una matriz de incrustación simple (de forma: vocabulary_size x embedding_dimension) se vería como abajo. (es decir, cada palabra estará representada por un vector de números; de ahí el nombre word2vec )


Incrustación Matriz

the 0.418 0.24968 -0.41242 0.1217 0.34527 -0.044457 -0.49688 -0.17862
like 0.36808 0.20834 -0.22319 0.046283 0.20098 0.27515 -0.77127 -0.76804
between 0.7503 0.71623 -0.27033 0.20059 -0.17008 0.68568 -0.061672 -0.054638
did 0.042523 -0.21172 0.044739 -0.19248 0.26224 0.0043991 -0.88195 0.55184
just 0.17698 0.065221 0.28548 -0.4243 0.7499 -0.14892 -0.66786 0.11788
national -1.1105 0.94945 -0.17078 0.93037 -0.2477 -0.70633 -0.8649 -0.56118
day 0.11626 0.53897 -0.39514 -0.26027 0.57706 -0.79198 -0.88374 0.30119
country -0.13531 0.15485 -0.07309 0.034013 -0.054457 -0.20541 -0.60086 -0.22407
under 0.13721 -0.295 -0.05916 -0.59235 0.02301 0.21884 -0.34254 -0.70213
such 0.61012 0.33512 -0.53499 0.36139 -0.39866 0.70627 -0.18699 -0.77246
second -0.29809 0.28069 0.087102 0.54455 0.70003 0.44778 -0.72565 0.62309 

Dividí la matriz de incrustación anterior y cargé solo las palabras en vocab que serán nuestro vocabulario y los vectores correspondientes en emb matriz.

vocab = ['the','like','between','did','just','national','day','country','under','such','second']

emb = np.array([[0.418, 0.24968, -0.41242, 0.1217, 0.34527, -0.044457, -0.49688, -0.17862],
   [0.36808, 0.20834, -0.22319, 0.046283, 0.20098, 0.27515, -0.77127, -0.76804],
   [0.7503, 0.71623, -0.27033, 0.20059, -0.17008, 0.68568, -0.061672, -0.054638],
   [0.042523, -0.21172, 0.044739, -0.19248, 0.26224, 0.0043991, -0.88195, 0.55184],
   [0.17698, 0.065221, 0.28548, -0.4243, 0.7499, -0.14892, -0.66786, 0.11788],
   [-1.1105, 0.94945, -0.17078, 0.93037, -0.2477, -0.70633, -0.8649, -0.56118],
   [0.11626, 0.53897, -0.39514, -0.26027, 0.57706, -0.79198, -0.88374, 0.30119],
   [-0.13531, 0.15485, -0.07309, 0.034013, -0.054457, -0.20541, -0.60086, -0.22407],
   [ 0.13721, -0.295, -0.05916, -0.59235, 0.02301, 0.21884, -0.34254, -0.70213],
   [ 0.61012, 0.33512, -0.53499, 0.36139, -0.39866, 0.70627, -0.18699, -0.77246 ],
   [ -0.29809, 0.28069, 0.087102, 0.54455, 0.70003, 0.44778, -0.72565, 0.62309 ]])


emb.shape
# (11, 8)

Búsqueda de incrustación en TensorFlow

Ahora veremos cómo podemos realizar la búsqueda de incrustación para alguna oración de entrada arbitraria.

In [54]: from collections import OrderedDict

# embedding as TF tensor (for now constant; could be tf.Variable() during training)
In [55]: tf_embedding = tf.constant(emb, dtype=tf.float32)

# input for which we need the embedding
In [56]: input_str = "like the country"

# build index based on our `vocabulary`
In [57]: word_to_idx = OrderedDict({w:vocab.index(w) for w in input_str.split() if w in vocab})

# lookup in embedding matrix & return the vectors for the input words
In [58]: tf.nn.embedding_lookup(tf_embedding, list(word_to_idx.values())).eval()
Out[58]: 
array([[ 0.36807999,  0.20834   , -0.22318999,  0.046283  ,  0.20097999,
         0.27515   , -0.77126998, -0.76804   ],
       [ 0.41800001,  0.24968   , -0.41242   ,  0.1217    ,  0.34527001,
        -0.044457  , -0.49687999, -0.17862   ],
       [-0.13530999,  0.15485001, -0.07309   ,  0.034013  , -0.054457  ,
        -0.20541   , -0.60086   , -0.22407   ]], dtype=float32)

Observe cómo obtuvimos las incrustaciones de nuestra matriz de incrustación original (con palabras) usando los índices de palabras en nuestro vocabulario.

Por lo general, dicha búsqueda de incrustación es realizada por la primera capa (llamada Capa de incrustación) que luego pasa estas incrustaciones a las capas RNN/LSTM/GRU para su posterior procesamiento.


Nota al margen : Normalmente el vocabulario también tendrá un token especial unk. Por lo tanto, si un token de nuestra oración de entrada no está presente en nuestro vocabulario, entonces el índice correspondiente a unk será buscado en la matriz de incrustación.


P.d. Tenga en cuenta que embedding_dimension es un hiperparámetro que uno tiene que ajustar para su aplicación, pero los modelos populares como Word2Vec y Guante utiliza 300 vector de dimensión para representar cada palabra.

Lectura de Bonos word2vec skip - gram model

 24
Author: kmario23,
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
2018-07-13 12:17:08

Cuando el tensor params está en dimensiones altas, el ids solo se refiere a la dimensión superior. Tal vez es obvio para la mayoría de la gente, pero tengo que ejecutar el siguiente código para entender que:

embeddings = tf.constant([[[1,1],[2,2],[3,3],[4,4]],[[11,11],[12,12],[13,13],[14,14]],
                          [[21,21],[22,22],[23,23],[24,24]]])
ids=tf.constant([0,2,1])
embed = tf.nn.embedding_lookup(embeddings, ids, partition_strategy='div')

with tf.Session() as session:
    result = session.run(embed)
    print (result)

Simplemente probando la estrategia 'div' y para un tensor, no hace ninguna diferencia.

Aquí está la salida:

[[[ 1  1]
  [ 2  2]
  [ 3  3]
  [ 4  4]]

 [[21 21]
  [22 22]
  [23 23]
  [24 24]]

 [[11 11]
  [12 12]
  [13 13]
  [14 14]]]
 4
Author: Yan Zhao,
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-11-25 03:15:07

Otra forma de verlo es, asumir que aplanas los tensores a una matriz dimensional, y luego estás realizando una búsqueda

(eg) Tensor0 = [1,2,3], Tensor1=[4,5,6], Tensor2 = [7,8,9]

El tensor aplanado será el siguiente [1,4,7,2,5,8,3,6,9]

Ahora cuando usted hace una búsqueda de [0,3,4,1,7] se yeild [1,2,5,4,6]

(i, e) si el valor de búsqueda es 7 por ejemplo , y tenemos 3 tensores (o un tensor con 3 filas) entonces,

7 / 3 : (Recordatorio es 1, Cociente es 2) Así que se mostrará el 2do elemento de Tensor1, que es 6

 3
Author: Shanmugam Ramasamy,
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-10-27 00:05:57

Aquí hay una imagen que representa el proceso de incrustación de búsqueda.

Imagen: Proceso de búsqueda de incrustación

Concisamente, obtiene las filas correspondientes de una capa de incrustación, especificada por una lista de IDs y proporciona eso como un tensor. Se logra a través del siguiente proceso.

  1. Definir un marcador de posición lookup_ids = tf.placeholder([10])
  2. Definir una capa de incrustación embeddings = tf.Variable([100,10],...)
  3. Definir la operación tensorflow embed_lookup = tf.embedding_lookup(embeddings, lookup_ids)
  4. Obtenga los resultados ejecutando lookup = session.run(embed_lookup, feed_dict={lookup_ids:[95,4,14]})
 2
Author: thushv89,
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
2018-08-05 11:52:02

Ya que también estaba intrigado por esta función, voy a dar mis dos centavos.

La forma en que lo veo en el caso 2D es como una multiplicación de matrices (es fácil de generalizar a otras dimensiones).

Considere un vocabulario con N símbolos. Entonces, puede representar un símbolo x como un vector de dimensiones Nx1, uno-codificado en caliente.

Pero desea una representación de este símbolo no como un vector de Nx1, sino como uno con dimensiones Mx1, llamado y.

Entonces, para transformar x en y, puede utilizar y matriz de incrustación E , con dimensiones MxN:

y = E x.

Esto es esencialmente lo que tf.nn.embedding_lookup (parámetros, ids,...) está haciendo, con el matiz de que ids son solo un número que representa la posición del 1 en el vector uno-codificado en caliente x.

 1
Author: joaoaccarvalho,
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
2018-02-01 22:28:32

Añadiendo a la respuesta de Asher Stern, params es interpretado como un particionamiento de un tensor de incrustación grande. Puede ser un solo tensor que representa el tensor de incrustación completo, o una lista de tensores X todos de la misma forma excepto la primera dimensión, representación de tensores de incrustación fragmentados.

La función tf.nn.embedding_lookup se escribe teniendo en cuenta el hecho de que la incrustación (parámetros) será grande. Por lo tanto necesitamos partition_strategy.

 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-08-16 23:31:13