2017-06-04 61 views
3

嘗試使用100昏暗的預訓練的word2vec的嵌入了訓練LSTMTensorflow tf.constant_initializer很慢

@staticmethod 
def load_embeddings(pre_trained_embeddings_path, word_embed_size): 
    embd = [] 
    import time 
    start_time = time.time() 
    cnt = 4 
    with codecs.open(pre_trained_embeddings_path, mode="r", encoding='utf-8') as f: 
     for line in f.readlines(): 
      values = line.strip().split(' ') 
      embd.append(values[1:]) 
      cnt += 1 
      if cnt % 100000 == 0: 
       print("word-vectors loaded: %d" % cnt) 

    embedding, vocab_size, embed_dim = embd, len(embd), len(embd[0]) 

    load_end_time = time.time() 
    print("word vectors loaded from and start initialising, cnt: %d, time taken: %d secs " % (vocab_size, load_end_time - start_time)) 

    embedding_init = tf.constant_initializer(embedding, dtype=tf.float16) 
    src_word_embedding = tf.get_variable(shape=[vocab_size, embed_dim], initializer=embedding_init, trainable=False, name='word_embedding', dtype=tf.float16) 

    print("word-vectors loaded and initialised, cnt: %d, time taken: %d secs" % (vocab_size, time.time() - load_end_time)) 

    return src_word_embedding 

並在此輸出運行時,這種方法是這樣的:

word vectors loaded from and start initialising, cnt: 2419080, time taken: 74 secs 
word-vectors loaded and initialised, cnt: 2419080, time taken: 1647 secs 

系統信息:tensorflow 1.1.0, tcmalloc, python 3.6, ubuntu 14.04

半小時初始化似乎很慢,或者它是一個正常的行爲?任何想法可能是這個問題或有一個?

UPDATE:使用@sirfz供給的嵌入的方法使得它非常快加載的嵌入Initialization Done in 85 secs

+0

它在float32中慢嗎? – user1735003

+0

是與float32類似的時間 – jknair

+0

這似乎是一個公開的問題。參考[GPU上的布爾運算非常緩慢](https://github.com/tensorflow/tensorflow/issues/3649)。 – frankyjuang

回答

0

載入大常數成圖形不僅慢,它也泄漏大量內存。我也有類似的問題,它I reported not long ago和對我來說最好的解決方法是:

# placeholder for loading your saved embeddings 
embedding_init = tf.placeholder(tf.float16, shape=[vocab_size, embed_dim]) 
src_word_embedding = tf.get_variable(initializer=embedding_init, trainable=False, name='word_embedding', dtype=tf.float16) 

# run initialization with the value of embeddings placeholder 
session.run(tf.global_variables_initializer(), feed_dict={embedding_init: embedding}) 
+0

當保存檢查點時這會保存嵌入,並且這會在還原時加載原始嵌入嗎? – jknair

+0

DAMN這減少了瘋狂的數量 初始化在85秒完成 – jknair

+0

我也有同樣的反應,當我第一次嘗試它);至於檢查點,我相信它會正常工作,因爲它將會按原樣序列化變量。我個人更喜歡使用'numpy.save'而不是檢查點來拋棄變量,因爲它更快。 – sirfz

0

我不知道這是否是一個預期的行爲,但我可以解釋爲什麼它可以在一個小例子放緩:

import tensorflow as tf 

x = [[0, 1], [2, 3]] 
a = tf.constant(x, name='a') 
b = tf.Variable(x, name='b') 
c = a + b 

with tf.Session() as sess: 
    writer = tf.summary.FileWriter('logs', sess.graph) 
    writer.close() 

初始化常量時,此常量的值將添加到圖形中。如果你打開圖表,你可以通過點擊a值來看到它。

enter image description here

在我來說,這是一個2×2矩陣,但它看起來像你的情況是2米x?矩陣,這是巨大的。所以我認爲這是執行速度緩慢的原因。

嘗試將其初始化爲一個變量並將其嵌入到此處。

+0

準確地說,它將大張量序列化到圖形中的一個節點中,該節點是慢度的主要來源(並最終導致更大的內存佔用)。在我的答案中使用解決方法避免了這個昂貴的序列化步驟。 – sirfz