【问题标题】:How to Feed in the output of one LSTM along with Text into another LSTM in Tensorflow?如何将一个 LSTM 的输出连同文本一起输入到 Tensorflow 中的另一个 LSTM?
【发布时间】:2018-02-02 23:06:19
【问题描述】:

我正在尝试将一个 LSTM 层的输出连同该层包含的文本一起输入另一个 LSTM 层。提供给两个 LSTM 的文本是不同的,我的目标是第二个 LSTM 在第一个 LSTM 理解的基础上提高对文本的理解。

我可以尝试像这样在 Tensorflow 中实现它:

# text inputs to the two LSTM's
rnn_inputs = tf.nn.embedding_lookup(embeddings, text_data)
rnn_inputs_2 = tf.nn.embedding_lookup(embeddings, text_data)
# first LSTM
lstm1Output, lstm1State = tf.nn.dynamic_rnn(cell=lstm1, 
        inputs=rnn_inputs, 
        sequence_length=input_lengths, 
        dtype=tf.float32, 
        time_major=False)
# second LSTM
lstm2Output, lstm2State = tf.nn.dynamic_rnn(cell=lstm2, 
        # use the input of the second LSTM and the first LSTM here
        inputs=rnn_inputs_2 + lstm1State, 
        sequence_length=input_lengths_2, 
        dtype=tf.float32, 
        time_major=False)

这有一个问题,因为rnn_inputs_2 的大小是(batch_size, _, hidden_layer_size),而lstm1State 的大小是(batch_size, hidden_layer_size)。有谁知道我可以如何改变形状来完成这项工作,或者是否有更好的方法?

谢谢

【问题讨论】:

  • rnn_inputs_2形状中的_的解释是什么?
  • @DavidParks 是输入句子/序列的最大长度。所以它是一个固定的数量,例如 100。
  • 也许我很困惑,如果这样纠正我。但是根据您上面所说的,我认为您并不是要将隐藏状态添加到rnn_inputs_2。我怀疑您的意思是将lstm1Outputrnn_inputs_2 连接起来,它们都应该具有时间步长维度。如果你想将第一个 RNN 的状态提供给第二个 RNN,你应该通过指定第二个 RNN 的初始状态来做到这一点(如果你不指定这个,第二个 RNN 将从默认状态 0 开始)。我在这里步入正轨吗?您正在尝试做的事情的图表可能有助于理解和解释。
  • 我可以将lstm1Outputrnn_inputs_2 连接起来,但我不确定这是否能达到我想要的效果。给 LSTM1 一个句子,假设它正确理解它,将帮助 LSTM2 理解它的句子。我试图根据 LSTM1 的理解找到一种提供 LSTM2 信息的方法。如果我将 LSTM1 的输出与 LSTM2 的输入连接起来,这会让 LSTM2 了解 LSTM1 吗?在 LSTM2 中使用 LSTM1 的隐藏状态会提供一种理解吗?我不太确定如何处理这个问题,如果你能多解释一下你的想法背后的直觉,那就太好了。
  • 我明白了,您将 LSTM1 的隐藏状态解释为一个句子嵌入(理所当然)。现在,您希望将该句子嵌入作为先验知识传递到 LSTM2 中,它可以根据它做出决策。我描述对了吗?如果是这样,那么您似乎正在描述一个编码器/解码器模型,并向 LSTM2 添加了新输入。如果那是准确的,那么我的第一种方法是将 LSTM1 的隐藏状态作为 LSTM2 的初始状态传入。这比将其添加到每个 LSTM2 时间步的输入中要合乎逻辑。

标签: tensorflow nlp deep-learning lstm


【解决方案1】:

您将 LSTM1 的隐藏状态解释为一个句子嵌入(理所当然)。现在,您希望将该句子嵌入作为先验知识传递到 LSTM2 中,它可以根据它做出决策。

如果我描述正确,那么您似乎是在描述编码器/解码器模型,并在 LSTM2 中添加了新输入。如果那是准确的,那么我的第一种方法是将 LSTM1 的隐藏状态作为 LSTM2 的初始状态传入。这比将其添加到每个 LSTM2 时间步的输入中要合乎逻辑。

您将获得从 LSTM2 通过 LSTM1 的状态返回到 LSTM1 的额外梯度路径的进一步好处,因此您不仅要训练 LSTM1 的 LSTM1 的损失函数,还要训练它提供某些东西的能力LSTM2 可以用来改进其损失函数(假设您在相同的 sess.run 迭代中同时训练 LSTM 1 和 2)。

关于问题:

另一个问题,如果我想引入一个 LSTM3 的输出怎么办 也应该影响 LSTM2。在这种情况下,我是否可以将 LSTM3 和 LSTM1隐藏状态并将其设置为LSTM2的初始状态?

求和听起来很糟糕,串联听起来不错。你控制 LSTM2 的隐藏状态大小,它应该有更大的隐藏状态大小。

关于这个问题:

我没有提到的一件事 之前是有时 LSTM1 不会收到输入,显然 因为它的输入是一个句子,LSTM1 会收到不同的输入 每次。这会影响 LSTM1 和 LSTM2 的错误更新吗? 另外,这意味着我不能使用编码器-解码器系统, 对?否则你说的有道理,我现在正在运行它 看看它是否有助于我的表现

在这种情况下,如果 LSTM1 没有输入(因此没有输出状态),我认为逻辑解决方案是用全零的标准隐藏状态向量初始化 LSTM2。如果你不给它一个初始隐藏状态,这就是 dynamic_rnn 在幕后所做的事情,所以如果你明确地传递一个 0 的向量,它是等价的。

【讨论】:

  • 如果我将 0 传递给 LSTM1,那么 LSTM2 将具有全 0 的初始化状态,对吗?因此,对于不使用 LSTM1 的情况,我不需要做任何特别的事情,只需为该训练/测试示例传入所有 0 即可?感谢您的回答,我会尽快接受。
  • 没错。与给定某些嵌入句子表示的初始状态相比,全 0 的初始状态与 LSTM 有意义地不同。网络可以学习在它认为合适的时候使用它。只要确保在同一个更新步骤中同时训练所有 LSTM,这样梯度就可以从后面的 LSTM 传递到前面的 LSTM。如果没有为 LSTM1 传入任何内容,您可能需要一个 tf.cond 语句来生成零向量。
  • 我有点困惑,为什么我需要 tf.cond 语句,因为如果我为批处理中的所有示例传入 0,LSTM 状态应该自动为 0,对吗?还是没有?
  • 如果您同时处理两个 LSTM,并且 LSTM1 正在处理输入,您将获取 LSTM1 的最终隐藏状态并将其传递给 LSTM2。如果您没有 LSTM1 的输入,因此不要为 LSTM1 运行优化器 OP,您将不会计算 LSTM1 状态并且需要使用 0 常数。这就是我看到的情况。
  • 在这种情况下,LSTM1隐藏状态是不是不存在或者全是0,因为0被传入了?我能够在没有特殊 tf.cond 条件的情况下运行这个实验。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-12-19
  • 1970-01-01
  • 2016-06-22
  • 1970-01-01
  • 2017-04-13
相关资源
最近更新 更多