2017-10-12 80 views
4

当我使用预先训练的单词向量做LSTM分类时,我想知道如何处理tensorflow中大于2gb的嵌入查找表。如何在张量流中处理大型(> 2GB)嵌入式查找表?

要做到这一点,我试图让嵌入查找表像下面的代码,

data = tf.nn.embedding_lookup(vector_array, input_data)

得到这个值误差。上的代码

ValueError: Cannot create a tensor proto whose content is larger than 2GB

可变vector_array是numpy的阵列,它包含约14万个独特的标记和对每个字100个尺寸字向量。

感谢您的帮助

回答

2

对我来说,接受的答案似乎并不奏效。虽然没有错误,但结果是糟糕的(与通过直接初始化的较小嵌入相比),并且我怀疑嵌入是tf.Variable()初始化的常量。

使用只是一个占位符没有额外的变量

self.Wembed = tf.placeholder(
    tf.float32, self.embeddings.shape, 
    name='Wembed') 

,然后在每session.run()图的喂养嵌入但似乎工作。

+0

对不起,听到它不适合你。当我尝试时,我使用交互式会话检查了个人权重,他们绝对不是全0。此外,我仅仅在Stackoverflow上引用了超过93个upvotes的回答,这是由Google员工提供的,所以不确定哪里出了问题 - 也许在我的代码或你的代码中存在一些错字。你当然可以做你所建议的,而不是使用变量,但我认为你不能使张量持续这种方式。我保存我的变量,以便将来不必运行这个耗费内存的进程 - 我只是恢复已保存的变量。 – ltt

6

您需要将其复制到tf变量。有一个伟大的回答这个问题在StackOverflow的: Using a pre-trained word embedding (word2vec or Glove) in TensorFlow

这是我做的:

embedding_weights = tf.Variable(tf.constant(0.0, shape=[embedding_vocab_size, EMBEDDING_DIM]),trainable=False, name="embedding_weights") 
embedding_placeholder = tf.placeholder(tf.float32, [embedding_vocab_size, EMBEDDING_DIM]) 
embedding_init = embedding_weights.assign(embedding_placeholder) 
sess = tf.Session(config=tf.ConfigProto(log_device_placement=True)) 
sess.run(embedding_init, feed_dict={embedding_placeholder: embedding_matrix}) 

然后,您可以使用embedding_weights变量进行查找(记得把存储字索引映射)

更新:使用该变量不是必需的,但它允许您将其保存以供将来使用,以便您不必再重新执行整个操作(加载非常大时需要一段时间在我的笔记本电脑上嵌入物)。如果这不重要,你可以简单地使用像Niklas Schnelle建议的占位符