2016-02-28 18 views
65

Ostatnio dokonałem przeglądu interesującej implementacji dla convolutional text classification. Jednak cały kod TensorFlow Sprawdziliśmy używa losowych (nie wstępnie przeszkolony) osadzanie wektory tak:Korzystanie ze wstępnie wyszkolonego osadzania słów (word2vec lub Glove) w TensorFlow

with tf.device('/cpu:0'), tf.name_scope("embedding"): 
    W = tf.Variable(
     tf.random_uniform([vocab_size, embedding_size], -1.0, 1.0), 
     name="W") 
    self.embedded_chars = tf.nn.embedding_lookup(W, self.input_x) 
    self.embedded_chars_expanded = tf.expand_dims(self.embedded_chars, -1) 

Czy ktoś wie, jak wykorzystać wyniki Word2vec lub rękawicy wstępnie przeszkolony słowo zamiast osadzania losowy?

Odpowiedz

97

Istnieje kilka sposobów użycia wstępnie wytrenowanego osadzania w TensorFlow. Załóżmy, że masz osadzenie w tablicy NumPy o nazwie embedding, z vocab_size kolumnami i embedding_dim kolumnami i chcesz utworzyć tensor W, który może być użyty w połączeniu z tf.nn.embedding_lookup().

  1. Wystarczy utworzyć W jako tf.constant() który zabierze embedding jako jego wartość:

    W = tf.constant(embedding, name="W") 
    

    To najprostszy podejście, ale nie jest to pamięć wydajny, ponieważ wartość tf.constant() są zapisywane wielokrotnie w pamięć. Ponieważ embedding może być bardzo duży, powinieneś używać tego podejścia tylko dla przykładów zabawek.

  2. Tworzenie W jako tf.Variable i zainicjować go z tablicy numpy za pośrednictwem tf.placeholder():

    W = tf.Variable(tf.constant(0.0, shape=[vocab_size, embedding_dim]), 
           trainable=False, name="W") 
    
    embedding_placeholder = tf.placeholder(tf.float32, [vocab_size, embedding_dim]) 
    embedding_init = W.assign(embedding_placeholder) 
    
    # ... 
    sess = tf.Session() 
    
    sess.run(embedding_init, feed_dict={embedding_placeholder: embedding}) 
    

    tego uniknąć przechowywania kopii embedding na wykresie, ale wymaga tyle pamięci, aby zachować dwie kopie macierz w pamięci naraz (jeden dla tablicy NumPy, a drugi dla tf.Variable). Zauważ, że założyłem, że chcesz utrzymać stałą matrycy osadzania podczas treningu, więc W jest tworzone z trainable=False.

  3. Jeśli osadzanie zostało przeszkolone jako część innego modelu TensorFlow, można użyć wartości tf.train.Saver w celu załadowania wartości z pliku punktu kontrolnego innego modelu. Oznacza to, że macierz osadzania może całkowicie ominąć Python. Tworzenie W jak w wariancie 2, a następnie wykonaj następujące czynności:

    W = tf.Variable(...) 
    
    embedding_saver = tf.train.Saver({"name_of_variable_in_other_model": W}) 
    
    # ... 
    sess = tf.Session() 
    embedding_saver.restore(sess, "checkpoint_filename.ckpt") 
    
+0

tworzę W następująco: W = np.loadtxt ("/ media/w2vTest.txt" dtype = 'string', delimiter = ''), który tworzy wiersz: ['in' '0.070312 ......'- 0.0625']. Tutaj są problemy! czy będę uważał to za mój W po usunięciu "in" i konwersji liczb z ciągu na float32? jeśli tak, to jak podłączyć "in" do odpowiedniego wektora? LUB muszę przekonwertować dane na float32, a następnie pozostawić "in", jak jest; oczekując, że tensorflow wykona wszystkie wymagane przetwarzanie? Dzięki! – user3147590

+3

Ach, masz tu kilka opcji. Możesz * użyć * TensorFlow 'tf.decode_csv() 'op, aby przekonwertować plik tekstowy na tensor, ale może to być kosztowne (w szczególności wymaga to utworzenia jednego' Tensora' na kolumnę, a następnie połączenia tych liczbowych razem). Być może łatwiejszą alternatywą byłoby użycie ['pandas.read_csv()'] (http://pandas.pydata.org/pandas-docs/stable/generated/pandas.read_csv.html) i ['pandas.DataFrame.as_matrix() '] (http://pandas.pydata.org/pandas-docs/stable/generated/pandas.DataFrame.as_matrix.html), aby uzyskać dane wejściowe jako tablicę NumPy. – mrry

+0

Korzystając z opcji 2, czy istnieje sposób na wyrzucenie tablicy NumPy i zapisanie pamięci? – morphe

23

użyć tej metody, aby załadować i osadzenie akcji.

W = tf.get_variable(name="W", shape=embedding.shape, initializer=tf.constant_initializer(embedding), trainable=False) 
6

Odpowiedź @mrry nie jest w porządku, ponieważ provoques nadpisaniu z zanurzeń ciężarami każda sieć jest uruchamiany, więc jeśli są następujące podejście minibatch trenować swoją sieć, została zastąpiona ciężarów embeddings. Tak, na mojego punktu widzenia właściwy sposób wstępnie przeszkoleni zanurzeń jest:

embeddings = tf.get_variable("embeddings", shape=[dim1, dim2], initializer=tf.constant_initializer(np.array(embeddings_matrix)) 
+0

Dokładny duplikat odpowiedzi Liuji. – TimZaman

+3

@TimZaman .. W rzeczywistości brakuje mu dającego się trenować = fałszywego argumentu, a tym samym skończy się dostrajaniem jego osadzania w procesie. – Shatu

+3

Sądzę też, że rozumowanie Eugenio jest nieprawidłowe. Po prostu nie musisz uruchamiać polecenia "embedding_init" przy każdej mini-partii, a wszystko będzie dobrze. Oznacza to, że wystarczy uruchomić inicjowanie osadzania tylko raz na początku szkolenia. – Shatu

Powiązane problemy