tf.nn.embedding_lookup(params, ids, partition_strategy='mod', name=None)
Nie rozumiem obowiązku tej funkcji. Czy to jest jak tabela przeglądowa? Co oznacza zwrócenie parametrów odpowiadających każdemu identyfikatorowi (w identyfikatorach)?
Na przykład w skip-gram
modelu, jeśli używamy tf.nn.embedding_lookup(embeddings, train_inputs)
, to dla każdego train_input
znajduje odpowiednie osadzenie?
Odpowiedzi:
embedding_lookup
funkcja pobiera wierszeparams
tensora. Zachowanie jest podobne do indeksowania za pomocą tablic w numpy. Na przykładparams
Argumentem może być również lista tensorów, w którym to przypadkuids
zostanie rozłożony na tensory. Na przykład, biorąc pod uwagę wykaz 3 tensorów[2, 64]
, domyślnym zachowaniem jest to, że będą reprezentowaćids
:[0, 3]
,[1, 4]
,[2, 5]
.partition_strategy
kontroluje sposóbids
dystrybucji na liście. Podział jest przydatny w przypadku problemów o większej skali, gdy macierz może być zbyt duża, aby zachować ją w jednym kawałku.źródło
select_rows
?embedding_lookup
po prostu zapewnia wygodny (i równoległy) sposób pobierania osadzeń odpowiadających identyfikatorowi wids
.params
Napinacz jest zwykle zmienna TF, które uczy się jako część procesu szkolenia - zmienna TF, których składniki są stosowane, bezpośrednio lub pośrednio, w funkcji strat (na przykładtf.l2_loss
), który jest optymalizowany przez optymalizator (takiego jaktf.train.AdamOptimizer
).Tak, ta funkcja jest trudna do zrozumienia, dopóki nie zrozumiesz, o co chodzi.
W swojej najprostszej formie jest podobny do
tf.gather
. Zwraca elementyparams
zgodnie z indeksami określonymi przezids
.Na przykład (zakładając, że jesteś w środku
tf.InteractiveSession()
)zwróci
[10 20 30 40]
, ponieważ pierwszym elementem (indeks 0) params jest10
, drugim elementem params (indeks 1) jest20
itd.Podobnie,
wróci
[20 20 40]
.Ale
embedding_lookup
to coś więcej.params
Argument może być lista tensorów, raczej niż pojedynczy tensor.W takim przypadku indeksy określone w sekcji
ids
odpowiadają elementom tensorów zgodnie ze strategią partycji , gdzie domyślną strategią podziału jest „mod”.W strategii „mod” indeks 0 odpowiada pierwszemu elementowi pierwszego tensora na liście. Indeks 1 odpowiada pierwszemu elementowi drugiego tensora. Indeks 2 odpowiada pierwszemu elementowi trzeciego tensora i tak dalej. Po prostu indeks
i
odpowiada pierwszemu elementowi tensora (i + 1), dla wszystkich indeksów0..(n-1)
, przy założeniu, że params to listan
tensorów.Teraz indeks
n
nie może odpowiadać tensorowi n + 1, ponieważ listaparams
zawiera tylkon
tensory. Tak więc indeksn
odpowiada drugiemu elementowi pierwszego tensora. Podobnie indeksn+1
odpowiada drugiemu elementowi drugiego tensora itp.A więc w kodzie
indeks 0 odpowiada pierwszemu elementowi pierwszego tensora: 1
indeks 1 odpowiada pierwszemu elementowi drugiego tensora: 10
indeks 2 odpowiada drugiemu elementowi pierwszego tensora: 2
indeks 3 odpowiada drugiemu elementowi drugiego tensora: 20
Zatem wynik byłby:
źródło
partition_strategy='div'
i dostać[10, 1, 10, 2, 10, 20]
, czyliid=1
jest to drugi element pierwszego parametru. Zasadniczo:partition_strategy=mod
(domyślnie)id%len(params)
: indeks parametru w paramsid//len(params)
: indeks elementu w powyższym parametrzepartition_strategy=*div*
na odwrótTak, celem
tf.nn.embedding_lookup()
funkcji jest wykonanie wyszukiwania w matrycy osadzania i zwrócenie osadzeń (lub w uproszczeniu reprezentacji wektorowej) słów.Prosta matryca osadzania (shape
vocabulary_size x embedding_dimension
:) wyglądałaby jak poniżej. (tj. każde słowo będzie reprezentowane przez wektor liczb; stąd nazwa word2vec )Matryca osadzania
Podzieliłem powyższą macierz osadzania i załadowałem tylko słowa, w
vocab
których będzie nasze słownictwo i odpowiadające im wektory wemb
tablicy.Osadzanie wyszukiwania w TensorFlow
Teraz zobaczymy, jak możemy przeprowadzić wyszukiwanie osadzające dla dowolnego dowolnego zdania wejściowego.
Obserwować, jak dostaliśmy zanurzeń z naszej oryginalnej matrycy osadzania (ze słowami) z wykorzystaniem indeksów słów w naszym słowniku.
Zazwyczaj takie wyszukiwanie osadzania jest wykonywane przez pierwszą warstwę (nazywaną warstwą osadzania ), która następnie przekazuje te osadzenia do warstw RNN / LSTM / GRU w celu dalszego przetwarzania.
Uwaga boczna : Zazwyczaj słownictwo będzie miało również specjalny
unk
token. Tak więc, jeśli token z naszego zdania wejściowego nie jest obecny w naszym słowniku, wówczas indeks odpowiadającyunk
zostanie wyszukany w matrycy osadzania.PS Zauważ, że
embedding_dimension
jest to hiperparametr, który trzeba dostroić do ich aplikacji, ale popularne modele, takie jak Word2Vec i GloVe, używają300
wektora wymiaru do reprezentowania każdego słowa.Bonusowe czytanie modelu pomijania gramów word2vec
źródło
Oto obraz przedstawiający proces wyszukiwania osadzania.
Dokładniej, pobiera odpowiednie wiersze warstwy osadzania, określone przez listę identyfikatorów i dostarcza je jako tensor. Osiąga się to poprzez następujący proces.
lookup_ids = tf.placeholder([10])
embeddings = tf.Variable([100,10],...)
embed_lookup = tf.embedding_lookup(embeddings, lookup_ids)
lookup = session.run(embed_lookup, feed_dict={lookup_ids:[95,4,14]})
źródło
Gdy tensor parametrów ma duże wymiary, identyfikatory odnoszą się tylko do wymiaru górnego. Może jest to oczywiste dla większości ludzi, ale muszę uruchomić następujący kod, aby to zrozumieć:
Samo wypróbowanie strategii „div” i dla jednego tensora nie ma znaczenia.
Oto wynik:
źródło
Innym sposobem spojrzenia na to jest założenie, że spłaszczasz tensory do jednowymiarowej tablicy, a następnie przeprowadzasz wyszukiwanie
(np.) Tensor0 = [1,2,3], Tensor1 = [4,5,6], Tensor2 = [7,8,9]
Spłaszczony tensor będzie następujący [1,4,7,2,5,8,3,6,9]
Teraz, gdy wyszukasz [0,3,4,1,7], będzie to [1,2,5,4,6]
(i, e) jeśli wartość wyszukiwania wynosi na przykład 7 i mamy 3 tensory (lub tensor z 3 wierszami), to
7/3: (Przypomnienie to 1, iloraz to 2) Więc pokazany zostanie drugi element Tensor1, czyli 6
źródło
Ponieważ również mnie zaintrygowała ta funkcja, dam dwa grosze.
Sposób, w jaki widzę to w przypadku 2D, to po prostu mnożenie macierzy (łatwo jest uogólnić na inne wymiary).
Rozważ słownictwo z N symbolami. Następnie możesz przedstawić symbol x jako wektor o wymiarach Nx1, zakodowany na gorąco.
Ale chcesz przedstawić ten symbol nie jako wektor Nx1, ale jako jeden o wymiarach Mx1, zwany y .
Tak więc, aby przekształcić x w y , możesz użyć i osadzić macierz E o wymiarach MxN:
y = E x .
To właśnie robi tf.nn.embedding_lookup (params, ids, ...) z niuansem, że ids to tylko jedna liczba, która reprezentuje pozycję 1 w zakodowanym na gorąco wektorze x .
źródło
Dodanie do odpowiedzi Ashera Sterna
params
jest interpretowane jako podział dużego tensora osadzającego. Może to być pojedynczy tensor reprezentujący cały tensor osadzania lub lista tensorów X o tym samym kształcie z wyjątkiem pierwszego wymiaru, reprezentujących tensory osadzania fragmentarycznego.Funkcja
tf.nn.embedding_lookup
została napisana z uwzględnieniem faktu, że osadzanie (parametry) będzie duże. Dlatego potrzebujemypartition_strategy
.źródło