Использование предварительно обученного вложения слов (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()
.
-
Просто создайте W
как tf.constant()
который принимает embedding
как его значение:
W = tf.constant(embedding, name="W")
Это самый простой подход, но он не эффективен с точки зрения памяти, поскольку значение tf.constant()
хранится несколько раз в памяти. Поскольку embedding
может быть очень большим, вы должны использовать этот подход только для игрушечных примеров.
-
Создайте 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
.
-
Если встраивание было обучено как часть другой модели 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, если вы хотите понять с нуля, посмотрите.