Использование предварительно обученного вложения слов (word2vec или Glove) в TensorFlow

Недавно я рассмотрел интересную реализацию для сверточного текстового классификации. Однако все рассмотренные мной коды 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)

Кто-нибудь знает, как использовать результаты Word2vec или встроенного в GloVe встраивания слов вместо случайного?

Ответ 1

Есть несколько способов, которыми вы можете использовать предварительно обученное вложение в TensorFlow. Скажем, что у вас есть вложение в массив NumPy, называемый embedding, со строками vocab_size и embedding_dim и вы хотите создать тензор W который можно использовать при вызове tf.nn.embedding_lookup().

  1. Просто создайте W как tf.constant() который принимает embedding как его значение:

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

    Это самый простой подход, но он не эффективен с точки зрения памяти, поскольку значение tf.constant() хранится несколько раз в памяти. Поскольку embedding может быть очень большим, вы должны использовать этот подход только для игрушечных примеров.

  2. Создайте W как tf.Variable и инициализируйте его из массива NumPy через 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})
    

    Это позволяет не хранить копию embedding в графике, но для этого требуется достаточно памяти для одновременного хранения двух копий матрицы в памяти (один для массива NumPy и один для tf.Variable). Обратите внимание, что я предположил, что вы хотите удерживать константу матрицы вставки во время обучения, поэтому W создается с trainable=False.

  3. Если встраивание было обучено как часть другой модели tf.train.Saver, вы можете использовать tf.train.Saver для загрузки значения из файла контрольной точки другой модели. Это означает, что матрица внедрения может вообще обойти Python. Создайте W как в варианте 2, затем выполните следующие действия:

    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")
    

Ответ 2

Я использую этот метод для загрузки и совместного использования вложений.

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

Ответ 3

Ответ @mrry неверен, поскольку он провоцирует перезапись весов вложений, каждый из которых запущен в сети, поэтому, если вы выполняете подход мини-маршрута для обучения своей сети, вы переписываете веса вложений. Итак, с моей точки зрения, правильный путь к предварительно обученным вложениям:

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

Ответ 4

Я также столкнулся с проблемой внедрения, поэтому я написал подробный учебник с набором данных. Здесь я хотел бы добавить то, что я пробовал. Вы также можете попробовать этот метод,

import tensorflow as tf

tf.reset_default_graph()

input_x=tf.placeholder(tf.int32,shape=[None,None])

#you have to edit shape according to your embedding size


Word_embedding = tf.get_variable(name="W", shape=[400000,100], initializer=tf.constant_initializer(np.array(word_embedding)), trainable=False)
embedding_loopup= tf.nn.embedding_lookup(Word_embedding,input_x)

with tf.Session() as sess:
        sess.run(tf.global_variables_initializer())
        for ii in final_:
            print(sess.run(embedding_loopup,feed_dict={input_x:[ii]}))

Здесь приведен пример подробного учебного примера Ipython, если вы хотите понять с нуля, посмотрите.