python как - Что делает функция tf.nn.embedding_lookup?




работает пример (7)

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

Я не могу понять обязанности этой функции. Это похоже на таблицу поиска? Что означает возврат параметров, соответствующих каждому id (в ids)?

Например, в модели skip-gram если мы используем tf.nn.embedding_lookup(embeddings, train_inputs) , то для каждого train_input он находит соответствующее вложение?


Answers

Поскольку я был также заинтригован этой функцией, я дам свои два цента.

То, как я вижу это в 2D-случае, - это как матричное умножение (его легко обобщить на другие измерения).

Рассмотрим словарь с N символами. Затем вы можете представить символ x в виде вектора размеров Nx1, с одним горячим кодированием.

Но вы хотите, чтобы представление этого символа не было вектором Nx1, а как одно с размерами Mx1, называемое y .

Итак, чтобы преобразовать x в y , вы можете использовать и внедрить матрицу E с размерами MxN:

y = E x .

Это по существу то, что делает tf.nn.embedding_lookup (params, ids, ...), с нюансом, что ids - это только одно число, которое представляет положение 1 в векторе x с горячим кодированием.


Когда тензор параметров находится в высоких размерах, идентификаторы относятся только к верхнему размеру. Возможно, это очевидно для большинства людей, но я должен запустить следующий код, чтобы понять это:

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)

Просто попробовав стратегию «div» и для одного тензора, это не имеет никакого значения.

Вот результат:

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

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

 [[11 11]
  [12 12]
  [13 13]
  [14 14]]]

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

(например, Tensor0 = [1,2,3], Tensor1 = [4,5,6], Tensor2 = [7,8,9]

Сплошный тензор будет выглядеть следующим образом [1,4,7,2,5,8,3,6,9]

Теперь, когда вы просматриваете [0,3,4,1,7], он будет получать [1,2,5,4,6]

(i, e) если значение поиска равно 7, и у нас есть 3 тензора (или тензор с 3 строками), тогда,

7/3: (Напоминание 1, Коэффициент 2). Будет показан 2-й элемент Tensor1, который равен 6


Да, целью функции tf.nn.embedding_lookup() является выполнение поиска в матрице встраивания и возврат вложений (или, проще говоря, векторного представления) слов.

Простая матрица вложения ( vocabulary_size x embedding_dimension ) будет выглядеть ниже. (т.е. каждое слово будет представлено вектором чисел, поэтому имя word2vec )

Встраиваемая матрица

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 

Я разделил указанную матрицу вложения и загрузил только слова в vocab которые будут нашим лексиконом и соответствующими векторами в массиве emb .

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)

Встраивание поиска в TensorFlow

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

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)

Обратите внимание, как мы получили вложения из нашей исходной матрицы вложения (со словами), используя индексы слов в нашем словаре.

Обычно такой поиск встраивания выполняется первым уровнем (называемым слоем Embedding ), который затем передает эти вложения в слои RNN / LSTM для дальнейшей обработки.

Сторона Примечание . Обычно словарь также имеет специальный токен. Итак, если токен из нашего входного предложения отсутствует в нашем словаре, тогда индекс, соответствующий unk будет просматриваться в матрице внедрения.

PS Обратите внимание, что embedding_dimension является гиперпараметром, который нужно настроить для своего приложения, но популярные модели, такие как Word2Vec и GloVe используют вектор измерения 300 для представления каждого слова.

Бонус Чтение word2vec skip-gram model


Да, эту функцию трудно понять, пока не получите смысл.

В простейшей форме он похож на tf.gather . Он возвращает элементы params соответствии с индексами, указанными ids .

Например (если вы находитесь внутри tf.InteractiveSession() )

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

вернет [10 20 30 40] , потому что первый элемент (индекс 0) параметров равен 10 , второй элемент параметров (индекс 1) равен 20 и т. д.

По аналогии,

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

вернется [20 20 40] .

Но embedding_lookup - это нечто большее. Аргумент params может быть списком тензоров, а не одним тензором.

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)

В этом случае индексы, указанные в ids , соответствуют элементам тензоров в соответствии с стратегией раздела , где стратегия раздела по умолчанию - «mod».

В стратегии «mod» индекс 0 соответствует первому элементу первого тензора в списке. Индекс 1 соответствует первому элементу второго тензора. Индекс 2 соответствует первому элементу третьего тензора и т. Д. Просто индекс i соответствует первому элементу тензора (i + 1) th для всех индексов 0..(n-1) , считая params - список n тензоров.

Теперь индекс n не может соответствовать тензору n + 1, поскольку параметры списка содержат только n тензоров. Таким образом, индекс n соответствует второму элементу первого тензора. Аналогично, индекс n+1 соответствует второму элементу второго тензора и т. Д.

Итак, в коде

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)

индекс 0 соответствует первому элементу первого тензора: 1

индекс 1 соответствует первому элементу второго тензора: 10

индекс 2 соответствует второму элементу первого тензора: 2

индекс 3 соответствует второму элементу второго тензора: 20

Таким образом, результатом будет:

[ 2  1  2 10  2 20]

Добавляя к ответу Ашера Стерна, params интерпретируются как разбиение большого тензора вложения. Это может быть один тензор, представляющий полный тензор вложения, или список X-тензоров одинаковой формы, за исключением первого измерения, представляющих тензоры вложенного вложения.

Функция tf.nn.embedding_lookup написана с учетом того, что вложение (params) будет большим. Поэтому нам нужна partition_strategy .


Если это просто поиск подстроки, вы можете использовать string.find("substring") .

Вы должны быть немного осторожны с find , index и, хотя, как и подстроками. Другими словами, это:

s = "This be a string"
if s.find("is") == -1:
    print "No 'is' here!"
else:
    print "Found 'is' in the string."

Он напечатает Found 'is' in the string. Аналогично, if "is" in s: будет оцениваться True . Это может быть или не быть тем, что вы хотите.





python tensorflow nlp deep-learning tensor