2016-02-28 12 views
65

Ich habe vor kurzem eine interessante Implementierung für convolutional text classification überprüft. Jedoch sind alle TensorFlow Code, den ich überprüft habe verwendet eine zufällige (nicht vortrainiert) Einbetten von Vektoren wie folgt aus:Mit einer vortrainierten Worteinbettung (word2vec oder Glove) in 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) 

Weiß jemand, wie die Ergebnisse der Word2vec verwenden oder einer Glove-Wort vorge trainiert Einbettung statt ein zufälliger?

Antwort

97

Es gibt einige Möglichkeiten, wie Sie eine vortrainierte Einbettung in TensorFlow verwenden können. Nehmen wir an, Sie haben die Einbettung in ein NumPy-Array namens , mit vocab_size Zeilen und embedding_dim Spalten, und Sie möchten einen Tensor W erstellen, der in einem Aufruf an tf.nn.embedding_lookup() verwendet werden kann.

  1. einfach W als tf.constant() erstellen, die embedding als Wert nimmt:

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

    Dies ist der einfachste Ansatz, aber es ist nicht Speicher effizient, weil der Wert eines tf.constant() in mehrfach gespeichert wird Erinnerung. Da sehr groß sein kann, sollten Sie diesen Ansatz nur für Spielzeugbeispiele verwenden.

  2. erstellen W als tf.Variable und aus dem NumPy Array initialisieren über eine 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}) 
    

    dies zu vermeiden, eine Kopie embedding in dem Diagramm zu speichern, aber es ist genügend Speicher erfordert zwei Kopien zu halten die Matrix im Speicher auf einmal (eins für das NumPy-Array und eins für das tf.Variable). Beachten Sie, dass ich davon ausgegangen bin, dass Sie die Einbettungsmatrix während des Trainings konstant halten möchten. Daher wird W mit trainable=False erstellt.

  3. Wenn die Einbettung als Teil eines anderen TensorFlow-Modells trainiert wurde, können Sie den Wert mit tf.train.Saver aus der Prüfpunktdatei des anderen Modells laden. Dies bedeutet, dass die Einbettungsmatrix Python vollständig umgehen kann. Erstellen W wie in Option 2, dann gehen Sie wie folgt vor:

    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

I W wie folgt erstellen: W = np.loadtxt ("/ media/w2vTest.txt", dtype = 'string', delimiter = ''), das als Zeile erstellt: ['in' '0.070312 ......' - 0.0625 ']. Es gibt Probleme hier! soll ich dies als mein W betrachten, nachdem ich "in" entfernt und Zahlen von string in float32 umgewandelt habe? Wenn dies der Fall ist, wie kann man "in" mit seinem jeweiligen Vektor verbinden? ODER Ich muss Zahlen in float32 umwandeln und dann "in" lassen wie es ist; erwartet, dass Tensorflow alle erforderlichen Verarbeitungsschritte ausführt? Vielen Dank! – user3147590

+3

Ah, Sie haben hier ein paar Optionen. Sie könnten * den TensorFlow 'tf benutzen.decode_csv() 'op, um die Textdatei in einen Tensor zu konvertieren, aber dies kann teuer sein (insbesondere müssen Sie einen" Tensor "pro Spalte erstellen und dann die numerischen zusammen verketten). Vielleicht wäre eine einfachere Alternative, ['pandas.read_csv()'] (http://pandas.pydata.org/pandas-docs/stable/generated/pandas.read_csv.html) und ['pandas.DataFrame.as_matrix() '] (http://pandas.pydata.org/pandas-docs/stable/generated/pandas.DataFrame.as_matrix.html), um die Eingabe als NumPy-Array zu erhalten. – mrry

+0

Mit Option 2 gibt es eine Möglichkeit, das NumPy-Array wegzuwerfen und etwas Speicher zu sparen? – morphe

23

ich diese Methode verwenden zu laden und mit anderen teilen Einbettung.

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

Die Antwort von @mrry ist nicht richtig, weil es die Überschreibung der Einbettungen Gewichte jeweils das Netzwerk ausgeführt wird, provoques wenn Sie also ein mini Ansatz folgen Ihrem Netzwerk zu trainieren, überschreiben Sie die Gewichte der Einbettungen. Also, auf meiner Sicht der richtige Weg vortrainiert Einbettungen ist:

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

Genaues Duplikat von LiuJias Antwort. – TimZaman

+3

@TimZaman .. Tatsächlich fehlt ihm das Argument trainable = False und er wird damit seine Einbettungen verfeinern. – Shatu

+3

Auch denke ich, dass Eugenios Argumentation falsch ist. Sie müssen einfach nicht die Operation "embedding_init" mit jedem Minibatch ausführen, und alles wird gut. Führen Sie die Einbettungsinitialisierung nur einmal zu Beginn des Trainings aus. – Shatu

Verwandte Themen