我一直试图用https://www.tensorflow.org/tutorials/recurrent来理解示例代码 你可以在https://github.com/tensorflow/models/blob/master/tutorials/rnn/ptb/ptb_word_lm.py找到
(使用tensorflow 1.3.0.)
对于我的问题,我总结了(我认为是)关键部分,如下:
size = 200
vocab_size = 10000
layers = 2
# input_.input_data is a 2D tensor [batch_size, num_steps] of
# word ids, from 1 to 10000
cell = tf.contrib.rnn.MultiRNNCell(
[tf.contrib.rnn.BasicLSTMCell(size) for _ in range(2)]
)
embedding = tf.get_variable(
"embedding", [vocab_size, size], dtype=tf.float32)
inputs = tf.nn.embedding_lookup(embedding, input_.input_data)
inputs = tf.unstack(inputs, num=num_steps, axis=1)
outputs, state = tf.contrib.rnn.static_rnn(
cell, inputs, initial_state=self._initial_state)
output = tf.reshape(tf.stack(axis=1, values=outputs), [-1, size])
softmax_w = tf.get_variable(
"softmax_w", [size, vocab_size], dtype=data_type())
softmax_b = tf.get_variable("softmax_b", [vocab_size], dtype=data_type())
logits = tf.matmul(output, softmax_w) + softmax_b
# Then calculate loss, do gradient descent, etc.
我最大的问题是,考虑到句子的前几个单词,如何使用生成的模型实际生成下一个单词建议?具体地说,我认为流程是这样的,但是我无法理解注释行的代码是什么:
prefix = ["What", "is", "your"]
state = #Zeroes
# Call static_rnn(cell) once for each word in prefix to initialize state
# Use final output to set a string, next_word
print(next_word)
我的子问题是:
(我把他们都当作一个问题来问,因为我怀疑他们都是有联系的,而且都与我理解上的一些差距有关。)
我希望在这里看到的是加载一组现有的word2vec单词嵌入(例如,使用gensim的KeyedVectors.load_word2vec_format()
),在每个句子中加载时将输入语料库中的每个单词转换为该表示,然后LSTM将吐出一个相同维度的向量,我们会尝试找到最相似的单词(例如,使用gensim的similar_by_vector(y, topn=1)
)。
使用softmax是不是让我们免于相对缓慢的similar_by_vector(y, topn=1)
调用?
顺便说一下,我的问题Using pre-trained word2vec with LSTM for word generation中预先存在的word2vec部分是类似的。不过,目前的答案并不是我想要的。我所希望的是一个简单的英文解释,它能帮我打开灯,堵住我理解上的任何缺口。Use pre-trained word2vec in lstm language model?是另一个类似的问题。
更新:Predicting next word using the language model tensorflow example和Predicting the next word using the LSTM ptb model tensorflow example是类似的问题。然而,这两种方法都没有显示代码实际读取一个句子的前几个单词,并打印出它对下一个单词的预测。我试着粘贴第二个问题和https://stackoverflow.com/a/39282697/841830(带有github分支)中的代码,但无法在没有错误的情况下运行这两个问题。我想它们可能是为了TensorFlow的早期版本?
另一个更新:又一个问题问了基本相同的问题:Predicting Next Word of LSTM Model from Tensorflow Example 它链接到 Predicting next word using the language model tensorflow example(而且,这里的答案并不完全是我想要的)。
如果还不清楚,我试图编写一个名为getNextWord(model, sentencePrefix)
的高级函数,其中model
是我从磁盘加载的先前构建的LSTM,而sentencePrefix
是一个字符串,例如“Open the”,它可能返回“pod”。然后我可以用“打开豆荚”来称呼它,它会返回“bay”,以此类推。
一个例子(带有一个字符RNN,并使用mxnet)是sample()
函数,显示在https://github.com/zackchase/mxnet-the-straight-dope/blob/master/chapter05_recurrent-neural-networks/simple-rnn.ipynb的末尾
你可以在训练过程中调用sample()
,但也可以在训练结束后调用,并且可以使用任何你想要的句子。
有很多问题,我想澄清其中的一些。
这里的关键是,下一代词汇实际上是词汇中的词汇分类。所以你需要一个分类器,这就是为什么在输出中有一个softmax。
其原理是,在每一个时间步,模型将根据最后一个单词的嵌入和前一个单词的内部记忆输出下一个单词。
tf.contrib.rnn.static_rnn
自动将输入合并到内存中,但我们需要提供最后一个单词的嵌入并对下一个单词进行分类。我们可以使用一个预先训练的word2vec模型,只需将
embedding
矩阵与预先训练的矩阵初始化。为了简单起见,我认为本教程使用了随机矩阵。内存大小与嵌入大小无关,可以使用较大的内存大小来保留更多信息。这些教程是高级的。如果您想深入了解细节,我建议您查看纯python/numpy的源代码。
在我解释我的答案之前,先说说你对
# Call static_rnn(cell) once for each word in prefix to initialize state
的建议:请记住static_rnn
返回的不是像numpy数组那样的值,而是一个张量。当张量在会话中运行时(1)(会话保持计算图的状态,包括模型参数的值)和(2)(使用计算张量值所需的输入),可以将其计算为一个值。可以使用输入阅读器(本教程中的方法)或占位符(我将在下面使用)提供输入。下面是实际答案: 本教程中的模型旨在从文件中读取输入数据。@user3080953的答案已经展示了如何使用您自己的文本文件,但据我所知,您需要更多地控制如何将数据输入模型。为此,您需要定义自己的占位符,并在调用
session.run()
时将数据馈送给这些占位符。在下面的代码中,我对
PTBModel
进行了子类化,并使其负责显式地向模型提供数据。我介绍了一个特殊的PTBInteractiveInput
,它有一个类似于PTBInput
的接口,因此您可以重用PTBModel
中的功能。为了训练你的模型,你仍然需要PTBModel
。在
PTBModel
函数的__init__
中,需要添加以下行:首先要注意,虽然嵌入在开始时是随机的,但是它们将与网络的其他部分一起接受训练。训练后获得的嵌入与word2vec模型获得的嵌入具有相似的特性,例如,能够用向量运算(king-man+woman=queen,在任务中,如果你有大量的训练数据,比如语言建模(不需要注释的训练数据)或者神经机器翻译,从头开始训练嵌入就更为常见。
Softmax是一个函数,它将相似度得分向量(logits)规范化为概率分布。您需要一个概率分布来训练具有交叉熵损失的模型,并能够从模型中取样。请注意,如果您只对训练模型中最可能出现的单词感兴趣,则不需要softmax,您可以直接使用logits。
不,原则上可以是任何价值。但是,使用维度低于嵌入维度的隐藏状态并没有多大意义。
下面是使用给定的numpy数组初始化嵌入的自包含示例。如果希望嵌入在训练期间保持固定/不变,请将
trainable
设置为False
。主要问题
加载单词
加载自定义数据而不是使用测试集:
test_data
应该包含单词id(对于映射,打印出word_to_id
)。举个例子,它应该看起来像:[152562246]。。。显示预测
我们需要在调用
sess.run
时返回FC层的输出(logits
)在函数的后面,
vals['top_word_id']
将有一个整数数组,其ID为最上面的单词。在word_to_id
中查找此项以确定预测的单词。我刚才用这个小模型做了这个,前1名的准确率很低(20-30%iirc),尽管困惑是在头球预测的。子问题
你得问问作者,但在我看来,训练嵌入使这更像是一个独立的教程:它不是把嵌入当作一个黑匣子,而是展示了它是如何工作的。
最后的预测是由隐藏层输出的余弦相似性决定的。在LSTM之后有一个FC层,它将嵌入的状态转换为最后一个单词的一个热编码。
下面是神经网络的操作和尺寸示意图:
从技术上讲,不是。如果你看LSTM方程,你会注意到x(输入)可以是任何大小,只要适当调整权重矩阵。
我不知道,对不起。
相关问题 更多 >
编程相关推荐