使用 LSTM ptb 模型 tensorflow 示例预测下一个单词
Predicting the next word using the LSTM ptb model tensorflow example
我正在尝试使用 tensorflow LSTM model 进行下一个单词预测。
如本 related question 中所述(没有公认的答案)该示例包含用于提取下一个单词概率的伪代码:
lstm = rnn_cell.BasicLSTMCell(lstm_size)
# Initial state of the LSTM memory.
state = tf.zeros([batch_size, lstm.state_size])
loss = 0.0
for current_batch_of_words in words_in_dataset:
# The value of state is updated after processing each batch of words.
output, state = lstm(current_batch_of_words, state)
# The LSTM output can be used to make next word predictions
logits = tf.matmul(output, softmax_w) + softmax_b
probabilities = tf.nn.softmax(logits)
loss += loss_function(probabilities, target_words)
我对如何解释概率向量感到困惑。我修改了ptb_word_lm.py中PTBModel
的__init__
函数来存储概率和logits:
class PTBModel(object):
"""The PTB model."""
def __init__(self, is_training, config):
# General definition of LSTM (unrolled)
# identical to tensorflow example ...
# omitted for brevity ...
# computing the logits (also from example code)
logits = tf.nn.xw_plus_b(output,
tf.get_variable("softmax_w", [size, vocab_size]),
tf.get_variable("softmax_b", [vocab_size]))
loss = seq2seq.sequence_loss_by_example([logits],
[tf.reshape(self._targets, [-1])],
[tf.ones([batch_size * num_steps])],
vocab_size)
self._cost = cost = tf.reduce_sum(loss) / batch_size
self._final_state = states[-1]
# my addition: storing the probabilities and logits
self.probabilities = tf.nn.softmax(logits)
self.logits = logits
# more model definition ...
然后在 run_epoch
函数中打印了一些关于它们的信息:
def run_epoch(session, m, data, eval_op, verbose=True):
"""Runs the model on the given data."""
# first part of function unchanged from example
for step, (x, y) in enumerate(reader.ptb_iterator(data, m.batch_size,
m.num_steps)):
# evaluate proobability and logit tensors too:
cost, state, probs, logits, _ = session.run([m.cost, m.final_state, m.probabilities, m.logits, eval_op],
{m.input_data: x,
m.targets: y,
m.initial_state: state})
costs += cost
iters += m.num_steps
if verbose and step % (epoch_size // 10) == 10:
print("%.3f perplexity: %.3f speed: %.0f wps, n_iters: %s" %
(step * 1.0 / epoch_size, np.exp(costs / iters),
iters * m.batch_size / (time.time() - start_time), iters))
chosen_word = np.argmax(probs, 1)
print("Probabilities shape: %s, Logits shape: %s" %
(probs.shape, logits.shape) )
print(chosen_word)
print("Batch size: %s, Num steps: %s" % (m.batch_size, m.num_steps))
return np.exp(costs / iters)
这会产生如下输出:
0.000 perplexity: 741.577 speed: 230 wps, n_iters: 220
(20, 10000) (20, 10000)
[ 14 1 6 589 1 5 0 87 6 5 3 5 2 2 2 2 6 2 6 1]
Batch size: 1, Num steps: 20
我期望 probs
向量是一个概率数组,词汇表中的每个单词都有一个概率(例如形状 (1, vocab_size)
),这意味着我可以使用np.argmax(probs, 1)
如另一个问题中所建议的。
但是,向量的第一维实际上等于展开的 LSTM 中的步数(如果使用小配置设置,则为 20),我不确定该怎么做。要访问预测词,我是否只需要使用最后一个值(因为它是最后一步的输出)?还是我还缺少其他东西?
我试图通过查看 seq2seq.sequence_loss_by_example 的实现来理解预测是如何进行和评估的,它必须执行此评估,但这最终会调用 gen_nn_ops._sparse_softmax_cross_entropy_with_logits
,这似乎不是将包含在 github 存储库中,所以我不确定还能去哪里查看。
我对 tensorflow 和 LSTM 都很陌生,非常感谢您的帮助!
output
张量包含每个时间步的 LSTM 单元输出的串联(参见其定义 here)。因此,您可以通过采用 chosen_word[-1]
(或 chosen_word[sequence_length - 1]
如果序列已被填充以匹配展开的 LSTM)来找到下一个单词的预测。
tf.nn.sparse_softmax_cross_entropy_with_logits()
op is documented in the public API under a different name. For technical reasons, it calls a generated wrapper function that does not appear in the GitHub repository. The implementation of the op is in C++, here.
我也在实现seq2seq模型。
所以让我试着用我的理解来解释一下:
您的 LSTM 模型的 输出 是一个列表(长度为 num_steps),其大小为 [batch_size,尺寸]。
代码行:
output = tf.reshape(tf.concat(1, outputs), [-1, size])
将产生一个新的 输出 ,这是一个大小为 [batch_size x [ 的二维张量=101=], 尺寸]。
对于您的情况,batch_size = 1 和 num_steps = 20 --> 输出形状为 [20,size]。
代码行:
logits = tf.nn.xw_plus_b(output, tf.get_variable("softmax_w", [size, vocab_size]), tf.get_variable("softmax_b", [vocab_size]))
<=> 输出[batch_size x num_steps, 大小] x softmax_w [size, vocab_size] 将输出 logits 大小 [batch_size x num_steps,vocab_size].
对于您的情况,大小为 [20、vocab_size] 的 logits
--> probs 张量与 logits 大小相同 [20, vocab_size]。
代码行:
chosen_word = np.argmax(probs, 1)
将输出 chosen_word 张量 [20, 1]每个值是当前词的下一个预测词索引。
代码行:
loss = seq2seq.sequence_loss_by_example([logits], [tf.reshape(self._targets, [-1])], [tf.ones([batch_size * num_steps])])
是计算batch_size个序列的softmax交叉熵损失。
我正在尝试使用 tensorflow LSTM model 进行下一个单词预测。
如本 related question 中所述(没有公认的答案)该示例包含用于提取下一个单词概率的伪代码:
lstm = rnn_cell.BasicLSTMCell(lstm_size)
# Initial state of the LSTM memory.
state = tf.zeros([batch_size, lstm.state_size])
loss = 0.0
for current_batch_of_words in words_in_dataset:
# The value of state is updated after processing each batch of words.
output, state = lstm(current_batch_of_words, state)
# The LSTM output can be used to make next word predictions
logits = tf.matmul(output, softmax_w) + softmax_b
probabilities = tf.nn.softmax(logits)
loss += loss_function(probabilities, target_words)
我对如何解释概率向量感到困惑。我修改了ptb_word_lm.py中PTBModel
的__init__
函数来存储概率和logits:
class PTBModel(object):
"""The PTB model."""
def __init__(self, is_training, config):
# General definition of LSTM (unrolled)
# identical to tensorflow example ...
# omitted for brevity ...
# computing the logits (also from example code)
logits = tf.nn.xw_plus_b(output,
tf.get_variable("softmax_w", [size, vocab_size]),
tf.get_variable("softmax_b", [vocab_size]))
loss = seq2seq.sequence_loss_by_example([logits],
[tf.reshape(self._targets, [-1])],
[tf.ones([batch_size * num_steps])],
vocab_size)
self._cost = cost = tf.reduce_sum(loss) / batch_size
self._final_state = states[-1]
# my addition: storing the probabilities and logits
self.probabilities = tf.nn.softmax(logits)
self.logits = logits
# more model definition ...
然后在 run_epoch
函数中打印了一些关于它们的信息:
def run_epoch(session, m, data, eval_op, verbose=True):
"""Runs the model on the given data."""
# first part of function unchanged from example
for step, (x, y) in enumerate(reader.ptb_iterator(data, m.batch_size,
m.num_steps)):
# evaluate proobability and logit tensors too:
cost, state, probs, logits, _ = session.run([m.cost, m.final_state, m.probabilities, m.logits, eval_op],
{m.input_data: x,
m.targets: y,
m.initial_state: state})
costs += cost
iters += m.num_steps
if verbose and step % (epoch_size // 10) == 10:
print("%.3f perplexity: %.3f speed: %.0f wps, n_iters: %s" %
(step * 1.0 / epoch_size, np.exp(costs / iters),
iters * m.batch_size / (time.time() - start_time), iters))
chosen_word = np.argmax(probs, 1)
print("Probabilities shape: %s, Logits shape: %s" %
(probs.shape, logits.shape) )
print(chosen_word)
print("Batch size: %s, Num steps: %s" % (m.batch_size, m.num_steps))
return np.exp(costs / iters)
这会产生如下输出:
0.000 perplexity: 741.577 speed: 230 wps, n_iters: 220
(20, 10000) (20, 10000)
[ 14 1 6 589 1 5 0 87 6 5 3 5 2 2 2 2 6 2 6 1]
Batch size: 1, Num steps: 20
我期望 probs
向量是一个概率数组,词汇表中的每个单词都有一个概率(例如形状 (1, vocab_size)
),这意味着我可以使用np.argmax(probs, 1)
如另一个问题中所建议的。
但是,向量的第一维实际上等于展开的 LSTM 中的步数(如果使用小配置设置,则为 20),我不确定该怎么做。要访问预测词,我是否只需要使用最后一个值(因为它是最后一步的输出)?还是我还缺少其他东西?
我试图通过查看 seq2seq.sequence_loss_by_example 的实现来理解预测是如何进行和评估的,它必须执行此评估,但这最终会调用 gen_nn_ops._sparse_softmax_cross_entropy_with_logits
,这似乎不是将包含在 github 存储库中,所以我不确定还能去哪里查看。
我对 tensorflow 和 LSTM 都很陌生,非常感谢您的帮助!
output
张量包含每个时间步的 LSTM 单元输出的串联(参见其定义 here)。因此,您可以通过采用 chosen_word[-1]
(或 chosen_word[sequence_length - 1]
如果序列已被填充以匹配展开的 LSTM)来找到下一个单词的预测。
tf.nn.sparse_softmax_cross_entropy_with_logits()
op is documented in the public API under a different name. For technical reasons, it calls a generated wrapper function that does not appear in the GitHub repository. The implementation of the op is in C++, here.
我也在实现seq2seq模型。
所以让我试着用我的理解来解释一下:
您的 LSTM 模型的 输出 是一个列表(长度为 num_steps),其大小为 [batch_size,尺寸]。
代码行:
output = tf.reshape(tf.concat(1, outputs), [-1, size])
将产生一个新的 输出 ,这是一个大小为 [batch_size x [ 的二维张量=101=], 尺寸]。
对于您的情况,batch_size = 1 和 num_steps = 20 --> 输出形状为 [20,size]。
代码行:
logits = tf.nn.xw_plus_b(output, tf.get_variable("softmax_w", [size, vocab_size]), tf.get_variable("softmax_b", [vocab_size]))
<=> 输出[batch_size x num_steps, 大小] x softmax_w [size, vocab_size] 将输出 logits 大小 [batch_size x num_steps,vocab_size].
对于您的情况,大小为 [20、vocab_size] 的 logits
--> probs 张量与 logits 大小相同 [20, vocab_size]。
代码行:
chosen_word = np.argmax(probs, 1)
将输出 chosen_word 张量 [20, 1]每个值是当前词的下一个预测词索引。
代码行:
loss = seq2seq.sequence_loss_by_example([logits], [tf.reshape(self._targets, [-1])], [tf.ones([batch_size * num_steps])])
是计算batch_size个序列的softmax交叉熵损失。