如何在Keras中使用return_sequences选项和TimeDistributed层?

时间:2017-03-13 02:35:03

标签: deep-learning keras lstm recurrent-neural-network

我有一个如下的对话框。我想实现一个预测系统动作的LSTM模型。系统动作被描述为位向量。并且用户输入被计算为字嵌入,其也是位向量。

t1: user: "Do you know an apple?", system: "no"(action=2)
t2: user: "xxxxxx", system: "yyyy" (action=0)
t3: user: "aaaaaa", system: "bbbb" (action=5)

所以我想要实现的是"很多很多(2)"模型。当我的模型收到用户输入时,它必须输出系统操作。 enter image description here 但是我在LSTM之后无法理解return_sequences选项和TimeDistributed图层。要实现"多对多(2)",return_sequences==True并在需要LSTM后添加TimeDistributed?如果你能更多地描述它们,我感激不尽。

  

return_sequences :布尔值。是返回输出序列中的最后一个输出,还是返回完整序列。

     

TimeDistributed :此包装器允许将图层应用于输入的每个时间片。

更新2017/03/13 17:40

我想我可以理解return_sequence选项。但我仍然不确定TimeDistributed。如果我在LSTM之后添加TimeDistributed,模型是否与"我的多对多(2)"下面?所以我认为Dense图层适用于每个输出。 enter image description here

2 个答案:

答案 0 :(得分:36)

LSTM层和TimeDistributed包装器是获得所需“多对多”关系的两种不同方式。

  1. LSTM将逐句吃掉你的句子中的单词,你可以通过“return_sequence”选择在每一步(每个单词处理后)输出一些东西(状态),或者只输出最后一个单词被吃掉后的东西。因此,使用return_sequence = TRUE,输出将是一个相同长度的序列,return_sequence = FALSE,输出将只是一个向量。
  2. TimeDistributed。这个包装器允许您将一个层(例如Dense)应用于序列的每个元素独立。该层对于每个元素具有完全相同的权重,它与将应用于每个单词的权重相同,当然,它将返回独立处理的单词序列。
  3. 正如你所看到的,两者之间的区别在于LSTM“通过序列传播信息,它会吃掉一个单词,更新它的状态并返回它。然后它会继续下一个单词而仍然从前面的信息中携带信息....就像在TimeDistributed中一样,单词将以相同的方式自行处理,就像它们处于孤岛中一样,并且同一层适用于它们中的每一个。

    所以你不必连续使用LSTM和TimeDistributed,你可以做任何你想做的事情,只要记住他们每个人做的事情。

    我希望它更清楚?

    修改

    在您的情况下,分配的时间将密集层应用于LSTM输出的每个元素。

    我们举一个例子:

    您有一系列嵌入在emb_size维度中的n_words字词。因此,您的输入是形状@PropertySource(value = "file:${app.conf}") @SpringBootApplication public class Application {

    的2D张量

    首先应用输出维度为(n_words, emb_size)lstm_output的LSTM。输出仍然是一个序列,因此它将是形状return_sequence = True的2D张量。 所以你有长度为lstm_output的n_words向量。

    现在,您应用TimeDistributed密集图层,将3维输出作为Dense的参数。所以TimeDistributed(Dense(3))。 这将将Dense(3)n_words次应用于序列中每个大小为lstm_output的向量...它们将全部变为长度为3的向量。您的输出仍然是一个序列,所以2D张量,现在形状{{1 }}。

    更清楚吗? : - )

答案 1 :(得分:5)

    return_sequences=True parameter:

如果我们想要输出序列,而不是像普通神经网络那样只有一个矢量,那么我们必须将return_sequences设置为True。具体来说,假设我们有一个带形状的输入(num_seq,seq_len,num_feature)。如果我们没有设置return_sequences = True,我们的输出将具有形状(num_seq,num_feature),但是如果我们这样做,我们将获得具有形状的输出(num_seq,seq_len,num_feature)。

    TimeDistributed wrapper layer:

由于我们在LSTM图层中设置了return_sequences = True,因此输出现在是一个三维向量。如果我们将其输入到Dense图层中,则会引发错误,因为Dense图层只接受二维输入。为了输入三维向量,我们需要使用一个名为TimeDistributed的包装层。这一层将帮助我们保持输出的形状,这样我们就可以在最后实现一个序列作为输出。