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

jef*_*jef 34 deep-learning lstm keras 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)
Run Code Online (Sandbox Code Playgroud)

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

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

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

更新2017/03/13 17:40

我想我能理解这个return_sequence选项.但我还不确定TimeDistributed.如果我添加一个TimeDistributedLSTM之后,模型是否与下面的"我的多对多(2)"相同?所以我认为Dense图层适用于每个输出. 在此输入图像描述

Nas*_*Ben 41

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

  1. LSTM将逐句吃掉你的句子中的单词,你可以通过"return_sequence"选择在每一步(每个单词处理后)输出一些东西(状态),或者只输出最后一个单词被吃掉后的东西.因此,使用return_sequence = TRUE,输出将是一个相同长度的序列,return_sequence = FALSE,输出将只是一个向量.
  2. TimeDistributed.此包装可以让你一层(说密集例如)适用于您的序列中的每个元素独立.该层对于每个元素具有完全相同的权重,它将与应用于每个单词的相同,当然,它将返回独立处理的单词序列.

正如您所看到的,两者之间的区别在于LSTM"通过序列传播信息,它将吃掉一个单词,更新其状态并返回它.然后它将继续下一个单词,同时仍然携带信息从之前的那些......如在TimeDistributed中,单词将以相同的方式自行处理,就好像它们处于孤岛中并且同一层适用于它们中的每一个.

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

我希望它更清楚?

编辑:

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

我们来举个例子:

您有一系列嵌入在emb_size维度中的n_words单词.所以你的输入是2D张量的形状(n_words, emb_size)

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

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

它更清楚吗?:-)

  • 谢谢.如果我只使用Dense(3)而不是TimeDistributed(Dense(3)),有什么区别? (4认同)

naa*_*iii 5

    return_sequences=True parameter:
Run Code Online (Sandbox Code Playgroud)

如果我们要有一个输出序列,而不仅仅是像普通神经网络那样有一个向量,那么有必要将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:
Run Code Online (Sandbox Code Playgroud)

由于我们在LSTM层中设置了return_sequences = True,因此输出现在是三维矢量。如果我们将其输入到Dense层,则将引发错误,因为Dense层仅接受二维输入。为了输入三维矢量,我们需要使用一个称为TimeDistributed的包装层。该层将帮助我们保持输出的形状,以便最终获得输出序列。