tf nn embedding lookup函式原理?

時間 2021-05-06 06:44:42

1樓:Anticoder

這麼多優秀的答案,那我從tf的角度來說下

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

這個函式的目的是按照ids從params這個矩陣中拿向量(行),所以ids就是這個矩陣索引(行號),需要int型別。

tf是簡單的通過tf.gather(params, ids)來獲取。(至於這個gather的實現就不談了)

tf.gather (indices就是ids,如果params是多維的,就是按照第一維來拿第幾個。)

這就是它的原理了。

補充一些引數的說明。

比如你的params非常大,可以把它切分成多份(tf.fixed_size_partitioner()), 那你的params其實是很多塊,比如分了10塊,每塊裡面有100行。這時只需要按照你的id,先找它屬於第幾塊(id % 10),再找第幾行 (id / 10) 就ok了

比如id = 234, 這個編號屬於 1234 % 10 = 4, 在第23行。這就是它預設partition_strategy='mod'模式,只要ids < 1000,就肯定能找到唯一的向量。tf對於這種分割槽查詢是通過tf.

dynamic_partition先按照ids % 10把ids按照其屬於某塊分開,然後再根據ids / 10查其對於的行號;之後利用tf.gather(params[i], ids[i] // 10)找到對於的向量,最後在利用tf.dynamic_stitch按照tf.

dynamic_partition拼回去。(tf.dynamic_partition和tf.

dynamic_stitch是互逆的操作)

還有就是ids可能是多維的,比如二維。它還是按照第一維度來獲取向量,只是這時每乙個維度是由多行向量聚合而成,就涉及乙個引數combiner,告訴它你想要的聚合方式,目前有mean, sum等。這樣做好處就是如果不聚合,可能每行的id數量不一樣,就無法生成乙個tensor。

比如ids =[[2, 3, 4], [5, 3, 1], [2, 4, 5]],那就是輸出的第一行是按照params中第2,3,4行向量的聚合。tf是通過tf.math.

segment_sum (tf.math.segment_mean,...

)來實現的。因為tf中segment操作就幾種,sum,mean,sqrtn,所以這引數也就只能選這三個。。

tf.segment_sum

3. 最後就說一下有個max_norm=None引數,這個就是按照你獲取到的向量的l2 norm來clip,因為params可以是variable (tf.get_variable()), 也就是可訓練的,過程中可能會變得很大,這個引數就是通過L2 norm來對獲取到的向量約束,通過tf.

clip_by_norm()來實現的。因為是l2 norm,那理論上就是通過縮放來實現(l1是絕對規約),實際上就是x * max_norm / norm(x)https://

2樓:蘇劍林

@rube 說得沒錯,embedding_lookup(params, ids)其實就是按照ids順序返回params中的第ids行。

其實題主提出這個問題,我相信是從embedding想到詞向量去了。這裡要強調的是,embedding_lookup跟詞向量沒半毛錢關係,雖然訓練詞向量可以用得到它,但是這不意味著它就是詞向量有什麼關係了。訓練詞向量還用到了加減乘除呢,我們看到加減乘除也不會想到詞向量吧?

關於詞向量和embeeding的關係,請看:

詞向量與Embedding究竟是怎麼回事? - 科學空間|Scientific Spaces

3樓:Charles

這個通俗易懂:

tf.nn.embedding_lookup補充一句:

返回的tensor的shape = shape(ids) + shape(params)[1:]

e.g.: ids.shape()=[A,B,Cparams.shape()=[X,Y];

那麼: results.shape()=[A,B,C,Y]

4樓:

Here's a small example to give you a visual.

This means that the hidden layer of this model is really just operating as a lookup table. The output of the hidden layer is just the 「word vector」 for the input word.

5樓:Ning Lee

問題本質

只是想做一次常規的線性變換而已,Z = WX + b2. Embedding

由於輸入都是One-Hot Encoding,和矩陣相乘相當於是取出Weights矩陣中對應的那一行,所以tensoflow封裝了方法 tf.nn.embedding_lookup(params, ids)介面,更加方便的表示意思。

查詢params對應的ids行。

等於說變相的進行了一次矩陣相乘運算,其實就是一次線性變換。

6樓:管戈

import tensorflow as tf

import numpy as np

sess=tf.InteractiveSession()

embedding=tf.Variable(np.identity(5,dtype=np.int32))

input_ids=tf.placeholder(dtype=tf.int32,shape=[None])

input_embedding=tf.nn.embedding_lookup(embedding,input_ids)

tf.global_variables_initializer().run()

print (sess.run(embedding))

print (sess.run(input_embedding,feed_dict=))

輸出:[[1 0 0 0 0]

[0 1 0 0 0]

[0 0 1 0 0]

[0 0 0 1 0]

[0 0 0 0 1]]

[[0 1 0 0 0]

[0 0 1 0 0]

[0 0 0 1 0]

[1 0 0 0 0]

[0 0 0 1 0]

[0 0 1 0 0]

[0 1 0 0 0]]

7樓:熊俊傑

從這裡看到的What does tf.nn.embedding_lookup function do?

作用和下面類似:

matrix=np

.random

.random

([1024,64

])# 64-dimensional embeddingsids=np.

array([0

,5,17

,33])print

matrix

[ids

]# prints a matrix of shape [4, 64]

8樓:yuzz

其實針對輸入是超高維,但是是one hot向量的一種特殊的全連線層的實現方法。由於輸入one hot 的原因,Wx的矩陣乘法看起來就像是取了W中對應的一列,看起來就像是在查表

9樓:豬豬專業戶

假設一共有個物體,每個物體有自己唯一的id,那麼從物體的集合到有乙個trivial的嵌入,就是把它對映到中的標準基,這種嵌入叫做One-hot embedding/encoding.

應用中一般將物體嵌入到乙個低維空間,只需要再compose上乙個從到的線性對映就好了。每乙個的矩陣都定義了到的乙個線性對映: 。

當是乙個標準基向量的時候,對應矩陣中的一列,這就是對應id的向量表示。這個概念用神經網路圖來表示如下:

從id(索引)找到對應的One-hot encoding,然後紅色的weight就直接對應了輸出節點的值(注意這裡沒有activation function),也就是對應的embedding向量。

10樓:

embedding_lookup(params, ids)其實就是按照ids順序返回params中的第ids行。

比如說,ids=[1,3,2],就是返回params中第1,3,2行。返回結果為由params的1,3,2行組成的tensor.

最近在看,一起學習。

固體物理中的格林函式是如何從格林函式的原始數學定義(點源的場)得到的?

yang元祐 格林函式是點源產生的場在時空中的分布,在空間是源函式,在時空是傳播函式。衛崇德老師的書沒看過,翻過幾次 上面是這樣的 格林函式就是乙個傳播子,這裡面的T 是戴森時間序算符,是場算符。王懷玉老師的 凝聚態物理的格林函式理論 敘述豐富的多。這是我們最早看到的關於電勢的泊松方程,為了求解這個...

如何判斷乙個函式是否黎曼可積以及是否有原函式?

何門 首先你這個函式一定是黎曼不可積的,黎曼可積要求在閉區間上有定義,你這個函式在0處無定義怎麼積。如果補充定義f x 0當x 0時,那麼是可積的,連續函式必可積。而且連續函式必存在原函式。 已登出 不可積例子 可積是有條件的,不可積是有例項的,最著名的就是狄利克雷函式,有理數取1,無理數取0這個函...

有沒有朋友能夠講一下C 中轉換建構函式的原理 看Primer上的例子沒看明白 ?

冰仔 所謂裝換建構函式就是只有乙個非本類型別形參的建構函式,例子中的建構函式形參只有乙個double型別的引數,就好像是乙個double型別轉換成了乙個complex型別。如果乙個函式這樣定義void func Complex a 你呼叫這個函式的時候,你就可以給它傳遞乙個double型別就可以,內...