Apa fungsi tf.nn.embedding_lookup?

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

Saya tidak dapat memahami tugas dari fungsi ini. Apakah ini seperti tabel pencarian? Yang berarti mengembalikan parameter yang sesuai dengan setiap id (dalam id)?

Misalnya, dalam skip-grammodel jika kita gunakan tf.nn.embedding_lookup(embeddings, train_inputs), maka untuk masing-masing train_inputmenemukan embedding yang sesuai?

Poorya Pzm
sumber
"Apakah ini seperti meja pencarian?" tldr - Ya. Untuk setiap x (id) beri saya associate y (params).
David Refaeli

Jawaban:

147

embedding_lookupfungsi mengambil baris paramstensor. Perilaku ini mirip dengan menggunakan pengindeksan dengan array dalam numpy. Misalnya

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] 

paramsArgumen dapat juga merupakan daftar tensor dalam hal mana idsakan didistribusikan di antara tensor. Sebagai contoh, diberikan daftar 3 tensor [2, 64], perilaku default adalah bahwa mereka akan mewakili ids: [0, 3], [1, 4],[2, 5] .

partition_strategymengontrol cara idsdistribusi di antara daftar. Partisi berguna untuk masalah skala yang lebih besar ketika matriks mungkin terlalu besar untuk tetap utuh.

Rafał Józefowicz
sumber
21
Mengapa mereka menyebutnya seperti ini dan tidak select_rows?
Lenar Hoyt
12
@LenarHoyt karena ide pencarian ini berasal dari Word Embeddings. dan "baris" adalah representasi (embeddings) dari kata-kata, ke dalam ruang vektor - dan berguna dalam diri mereka sendiri. Seringkali lebih dari jaringan yang sebenarnya.
Lyndon White
2
Bagaimana tensorflow mempelajari struktur penyematan? Apakah fungsi ini mengatur proses itu juga?
vgoklani
19
@vgoklani, tidak, embedding_lookuphanya menyediakan cara yang nyaman (dan paralel) untuk mengambil hiasan yang terkait dengan id ids. The paramstensor biasanya variabel tf yang dipelajari sebagai bagian dari proses pelatihan - variabel tf yang komponen yang digunakan, langsung atau tidak langsung, dalam fungsi kerugian (seperti tf.l2_loss) yang dioptimalkan oleh optimizer (seperti tf.train.AdamOptimizer).
Shobhit
5
@ Rafał Józefowicz Mengapa "perilaku default adalah bahwa mereka akan mewakili id: [0, 3], [1, 4], [2, 5]."? Bisakah Anda jelaskan?
Aerin
219

Ya, fungsi ini sulit dimengerti, sampai Anda mengerti maksudnya.

Dalam bentuknya yang paling sederhana, mirip dengan tf.gather. Ini mengembalikan elemen paramssesuai dengan indeks yang ditentukan oleh ids.

Misalnya (dengan asumsi Anda ada di dalam tf.InteractiveSession())

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

akan kembali [10 20 30 40], karena elemen pertama (indeks 0) dari params adalah 10, elemen kedua dari params (indeks 1) adalah 20, dll.

Demikian pula,

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

akan kembali [20 20 40].

Tetapi embedding_lookuplebih dari itu. The paramsArgumen bisa menjadi daftar dari tensor, daripada tensor tunggal.

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)

Dalam kasus seperti itu, indeks, ditentukan dalam ids, sesuai dengan elemen tensor sesuai dengan strategi partisi , di mana strategi partisi default adalah 'mod'.

Dalam strategi 'mod', indeks 0 sesuai dengan elemen pertama dari tensor pertama dalam daftar. Indeks 1 sesuai dengan elemen pertama dari tensor kedua . Indeks 2 sesuai dengan elemen pertama dari tensor ketiga , dan seterusnya. Cukup indeks isesuai dengan elemen pertama dari tensor (i + 1), untuk semua indeks 0..(n-1), dengan asumsi params adalah daftar ntensor.

Sekarang, indeks ntidak dapat sesuai dengan tensor n +1, karena daftar paramshanya berisi ntensor. Jadi indeks nsesuai dengan elemen kedua dari tensor pertama. Demikian pula, indeks n+1berhubungan dengan elemen kedua dari tensor kedua, dll.

Jadi, dalam kodenya

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)

indeks 0 sesuai dengan elemen pertama dari tensor pertama: 1

indeks 1 sesuai dengan elemen pertama dari tensor kedua: 10

indeks 2 sesuai dengan elemen kedua dari tensor pertama: 2

indeks 3 sesuai dengan elemen kedua dari tensor kedua: 20

Dengan demikian, hasilnya adalah:

[ 2  1  2 10  2 20]
Asher Stern
sumber
8
catatan: Anda dapat menggunakan partition_strategy='div', dan akan mendapatkan [10, 1, 10, 2, 10, 20], yaitu id=1elemen kedua dari param pertama. Pada dasarnya: partition_strategy=mod(default) id%len(params): indeks param di params id//len(params): indeks elemen di param di atas partition_strategy=*div*sebaliknya
Mario Alemi
3
@ asher-stern dapatkah Anda menjelaskan mengapa strategi "mod" default? tampaknya strategi "div" lebih mirip dengan slor tensor standar (pilih-baris dengan indeks yang diberikan). Apakah ada beberapa masalah kinerja dalam kasus "div"?
svetlov.vsevolod
46

Ya, tujuan tf.nn.embedding_lookup()fungsinya adalah untuk melakukan pencarian dalam matriks penyematan dan mengembalikan embeddings (atau secara sederhana representasi vektor) dari kata-kata.

Matriks penyematan sederhana (bentuk:) vocabulary_size x embedding_dimensionakan terlihat seperti di bawah ini. (Yaitu setiap kata akan diwakili oleh vektor angka; maka nama word2vec )


Matriks Embedding

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 

Saya membagi atas embedding matriks dan dimuat hanya kata-kata di vocabyang akan menjadi kosa kata dan yang sesuai vektor di embberbagai.

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)

Menanamkan Pencarian di TensorFlow

Sekarang kita akan melihat bagaimana kita bisa melakukan pencarian embedding untuk beberapa kalimat input sewenang-wenang.

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)

Amati bagaimana kami mendapatkan embeddings dari matriks embedding asli kami (dengan kata-kata) menggunakan indeks kata-kata dalam kosakata kami.

Biasanya, pencarian embedding dilakukan oleh lapisan pertama (disebut lapisan Embedding ) yang kemudian melewati embeddings ini ke lapisan RNN / LSTM / GRU untuk diproses lebih lanjut.


Catatan Samping : Biasanya kosa kata juga akan memiliki unktoken khusus . Jadi, jika token dari kalimat input kami tidak ada dalam kosakata kami, maka indeks yang sesuai untuk unkakan dicari dalam matriks embedding.


Catatan PS yang embedding_dimensionmerupakan hyperparameter bahwa seseorang harus menyetel untuk aplikasi mereka tetapi model populer seperti Word2Vec dan GloVe menggunakan 300vektor dimensi untuk mewakili setiap kata.

Bonus Membaca model skip-gram word2vec

kmario23
sumber
17

Berikut adalah gambar yang menggambarkan proses menanamkan pencarian.

Gambar: Proses pencarian embedding

Singkatnya, ia mendapat baris yang sesuai dari lapisan embedding, ditentukan oleh daftar ID dan menyediakannya sebagai tensor. Itu dicapai melalui proses berikut.

  1. Tentukan placeholder lookup_ids = tf.placeholder([10])
  2. Tentukan layer embedding embeddings = tf.Variable([100,10],...)
  3. Tentukan operasi tensorflow embed_lookup = tf.embedding_lookup(embeddings, lookup_ids)
  4. Dapatkan hasilnya dengan menjalankan lookup = session.run(embed_lookup, feed_dict={lookup_ids:[95,4,14]})
thushv89
sumber
6

Ketika tensor params dalam dimensi tinggi, id hanya mengacu pada dimensi atas. Mungkin sudah jelas bagi kebanyakan orang tetapi saya harus menjalankan kode berikut untuk memahami bahwa:

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)

Hanya mencoba strategi 'div' dan untuk satu tensor, tidak ada bedanya.

Berikut hasilnya:

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

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

 [[11 11]
  [12 12]
  [13 13]
  [14 14]]]
Yan Zhao
sumber
3

Cara lain untuk melihatnya adalah, asumsikan bahwa Anda meratakan tensor ke satu array dimensi, dan kemudian Anda melakukan pencarian.

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

Tensor keluar yang rata adalah sebagai berikut [1,4,7,2,5,8,3,6,9]

Sekarang ketika Anda melakukan pencarian [0,3,4,1,7] itu akan lebih baik [1,2,5,4,6]

(i, e) jika nilai pencarian adalah 7 misalnya, dan kami memiliki 3 tensor (atau tensor dengan 3 baris),

7/3: (Pengingat adalah 1, Quotient adalah 2) Jadi elemen ke-2 dari Tensor1 akan ditampilkan, yaitu 6

Shanmugam Ramasamy
sumber
2

Karena saya juga tertarik dengan fungsi ini, saya akan memberikan dua sen.

Cara saya melihatnya dalam kasus 2D hanya sebagai perkalian matriks (mudah untuk menggeneralisasi ke dimensi lain).

Pertimbangkan kosakata dengan simbol N. Kemudian, Anda dapat mewakili simbol x sebagai vektor dimensi Nx1, satu-panas-disandikan.

Tetapi Anda ingin representasi simbol ini bukan sebagai vektor Nx1, tetapi sebagai satu dengan dimensi Mx1, yang disebut y .

Jadi, untuk mengubah x menjadi y , Anda dapat menggunakan dan menanamkan matriks E , dengan dimensi MxN:

y = E x .

Ini pada dasarnya adalah apa yang dilakukan tf.nn.embedding_lookup (params, ids, ...), dengan nuansa bahwa id hanya satu angka yang mewakili posisi angka 1 dalam vektor yang dikodekan satu-panas x .

joaoaccarvalho
sumber
0

Menambah jawaban Asher Stern, paramsdiartikan sebagai partisi dari tensor embedding besar. Ini bisa berupa tensor tunggal yang mewakili tensor penyisipan lengkap, atau daftar tensor X semua dengan bentuk yang sama kecuali untuk dimensi pertama, mewakili tensor penyisipan sharded.

Fungsi tf.nn.embedding_lookupini ditulis mengingat fakta bahwa penyematan (params) akan besar. Karena itu kami membutuhkannya partition_strategy.

Aerin
sumber