2016-03-04 27 views
6

Zakładając, że chcę zaktualizować wstępnie wyszkoloną macierz osadzania słów podczas treningu, czy istnieje sposób na aktualizację tylko części macierzy osadzania wyrazów?Zaktualizuj tylko część macierzy osadzania wyrazów w Tensorflow

Szukałem na stronie Tensorflow API i stwierdziliśmy:

# Create an optimizer. 
opt = GradientDescentOptimizer(learning_rate=0.1) 

# Compute the gradients for a list of variables. 
grads_and_vars = opt.compute_gradients(loss, <list of variables>) 

# grads_and_vars is a list of tuples (gradient, variable). Do whatever you 
# need to the 'gradient' part, for example cap them, etc. 
capped_grads_and_vars = [(MyCapper(gv[0]), gv[1])) for gv in grads_and_vars] 

# Ask the optimizer to apply the capped gradients. 
opt.apply_gradients(capped_grads_and_vars) 

jak mogę zastosować jednak, że do matrycy słowo-osadzania. Załóżmy, że mam:

word_emb = tf.Variable(0.2 * tf.random_uniform([syn0.shape[0],s['es']], minval=-1.0, maxval=1.0, dtype=tf.float32),name='word_emb',trainable=False) 

gather_emb = tf.gather(word_emb,indices) #assuming that I pass some indices as placeholder through feed_dict 

opt = tf.train.AdamOptimizer(1e-4) 
grad = opt.compute_gradients(loss,gather_emb) 

Jak następnie użyć opt.apply_gradients i tf.scatter_update zaktualizować oryginalną embeddign matrycę? (Również tensorflow zgłasza błąd jeśli drugi argument compute_gradient nie jest tf.Variable)

+0

Jak zdefiniować "podzbiór" tutaj ? – viksit

+0

Tylko podzbiór wierszy w matrycy osadzania.Ponieważ każdy wiersz jest wektorem do osadzania słów, jest tylko podzbiorem wektorów osadzających słowa z oryginalnej macierzy osadzania słów – user1718064

+0

http://deeplearning.net/software/theano/tutorial/faq_tutorial.html To jest to, co chciałbym chcesz osiągnąć, ale w Tensorflow – user1718064

Odpowiedz

11

TL; DR: Domyślna implementacja opt.minimize(loss), TensorFlow wygeneruje rzadki aktualizacji dla word_emb który modyfikuje tylko rzędy word_emb, które uczestniczyły w przekazywaniu dalej.

Gradient tf.gather(word_emb, indices) op względem word_emb jest tf.IndexedSlices przedmiot (see the implementation for more details). Ten obiekt reprezentuje rzadki tensor, który wynosi zero, z wyjątkiem wierszy zaznaczonych przez indices. Wywołanie opt.minimize(loss) dzwoni pod numer AdamOptimizer._apply_sparse(word_emb_grad, word_emb), który wywołuje numer tf.scatter_sub(word_emb, ...) *, który aktualizuje tylko wiersze word_emb, które zostały wybrane przez indices.

Jeśli natomiast chcesz zmodyfikować tf.IndexedSlices, który jest zwracany przez opt.compute_gradients(loss, word_emb) można wykonywać dowolne operacje TensorFlow na jego indices i values właściwości, a także tworzyć nowe tf.IndexedSlices które mogą być przekazywane do opt.apply_gradients([(word_emb, ...)]). Na przykład, można cap gradienty używając MyCapper() (jak w przykładzie), stosując następujące połączenia:

grad, = opt.compute_gradients(loss, word_emb) 
train_op = opt.apply_gradients(
    [tf.IndexedSlices(MyCapper(grad.values), grad.indices)]) 

Podobnie można zmienić zestaw wskaźników, który zostanie zmodyfikowany poprzez utworzenie nowej tf.IndexedSlices z różnych indeksów .


*   W ogóle, jeśli chcesz zaktualizować tylko część zmienną w TensorFlow, można użyć tf.scatter_update(), tf.scatter_add(), or tf.scatter_sub() operators, który odpowiednio ustawiony, dodać do (+=) lub odejmowanie (-=) wartość uprzednio przechowywane w zmiennej.

+0

jesteś pewien, że działa tak jak w reklamie? Zobacz moje pytanie [tutaj] (http://stackoverflow.com/questions/35828037/training-a-cnn-with-pre-trained-word-embeddings-is-very-slow-tensorflow) i linki w nim zawarte. Wydaje się, że z jakiegoś powodu TensorFlow przekształca IndexedSlices w gęsty tensor, a aktualizacje spowalniają. – hillel

+0

Z pewnością zadziała, jeśli twoja zmienna osadzająca jest bezpośrednim argumentem 'params' dla' tf.gather() '(lub' tf.nn.embedding_lookup() '). 'IndexedSlices' jest konwertowany na tensor gęsty, jeśli gradient wzmaga odwzorowanie przez kolejne operacje, które nie mają funkcji gradientowych wyspecjalizowanych do obsługi' IndexedSlices' (obecnie uważam, że tylko 'tf.concat()' ma taką specjalizację). – mrry

+0

Zastanawiasz się, czy można to wykorzystać do aktualizacji określonych wektorów słów, tak jak w przypadku, gdy mam wcześniej wyszkolone wektory dla większości moich słów, ale kilka jest nowych i wymaga szkolenia. – TheM00s3

4

Ponieważ chcesz tylko wybrać elementy do zaktualizowania (i nie zmieniać gradientów), możesz wykonać następujące czynności.

Let indices_to_update być logiczna tensor wskazująca indeksy, które chcesz zaktualizować, a entry_stop_gradients jest zdefiniowana w link, a następnie:

gather_emb = entry_stop_gradients(gather_emb, indices_to_update) 

(Source)