Keras中的多对一和多对多LSTM示例

159
我会尝试理解LSTMs以及如何使用Keras构建它们。我发现,原则上有4种模式可以运行RNN(图片中的右侧4种)。 enter image description here 图片来源:Andrej Karpathy 现在我想知道每个模式在Keras中的最简代码片段是什么样的,类似于:
model = Sequential()
model.add(LSTM(128, input_shape=(timesteps, data_dim)))
model.add(Dense(1))

针对这4个任务,可能需要稍微解释一下。

对于一对多架构的图表,位于第一个X输入右侧的RNN单元也需要输入。它们通常可以设置为前一个单元的输出(o或y)或默认零向量。 - Vass
2个回答

178

所以:

  1. 一对一:由于您不处理序列,因此可以使用 Dense 层:

    model.add(Dense(output_size, input_shape=input_shape))
    
  2. 一对多:由于在Keras中连接模型不太容易,因此不支持这个选项。因此,以下版本是最简单的:

  3. model.add(RepeatVector(number_of_times, input_shape=input_shape))
    model.add(LSTM(output_size, return_sequences=True))
    
  4. 多对一: 实际上,你的代码片段(几乎)是这种方法的一个例子:

  5. model = Sequential()
    model.add(LSTM(1, input_shape=(timesteps, data_dim)))
    
  6. 多对多:当输入和输出的长度与循环步数相同时,这是最简单的片段:

  7. model = Sequential()
    model.add(LSTM(1, input_shape=(timesteps, data_dim), return_sequences=True))
    
  8. 当步数与输入/输出长度不同时的多对多情况:在Keras中这非常困难。没有简单的代码片段可以处理它。

编辑:广告5

在我的最近一些应用程序中,我们实现了类似于第4张图中的多对多的东西。如果你想要一个具有以下架构的网络(当输入比输出更长时):

                                        O O O
                                        | | |
                                  O O O O O O
                                  | | | | | | 
                                  O O O O O O

您可以通过以下方式实现此目标:

model = Sequential()
model.add(LSTM(1, input_shape=(timesteps, data_dim), return_sequences=True))
model.add(Lambda(lambda x: x[:, -N:, :])) #Select last N from output

其中N是您想覆盖的最后几个步骤的数量(在图像中N = 3)。

从这一点出发到达:

                                        O O O
                                        | | |
                                  O O O O O O
                                  | | | 
                                  O O O 

通过使用例如0向量对长度为N的人工填充序列进行调整,使其适应所需的大小,这就是简单的方法。


14
一个澄清:例如对于多对一的情况,您可以使用LSTM(1,input_shape=(timesteps,data_dim))) 我原本以为1代表LSTM单元数/隐藏节点数,但显然不是这样 如果要编写一个具有512个节点的多对一模型,您将如何编码? (因为我读到了类似的内容,所以我认为可以使用以下代码: model.add(LSTM(512,input_shape=...)) model.add(Dense(1)) 那么这是用来做什么的?) - Luca Thiede
1
在这种情况下,你的代码——在更正了一个打字错误之后应该没问题了。 - Marcin Możejko
2
如果你仔细思考一下这张图片,它只是一个关于“一对多”概念呈现的概念图。所有这些隐藏单元必须接受某些输入。因此,它们可以接受相同的输入,也可以接受第一个输入等于 x 而另一个等于 0 的输入。但是,另一方面,它们也可以接受多次重复的相同的 x。不同的方法是链接模型,这在 Keras 中很难实现。我提供的选项是在 Keras 中实现“一对多”架构最简单的情况。 - Marcin Możejko
@MarcinMożejko 在您的“一对多”场景中,您是如何将repeatvector与LSTM层连接起来的?我应该如何设置repeatetvector中的“number_of_times”值?Keras本身不会找到构建模型所需的时间步数,然后重复输入向量那么多次吗? - ajaysinghnegi
@MarcinMożejko 所以你不需要明确地告诉模型输出序列的长度吗?你只需要使用return_sequence=True,它就可以推断出其余部分了吗? - user1893354
显示剩余7条评论

17

来自@Marcin Możejko的优秀回答。

我想在第5点中补充以下内容(具有不同输入/输出长度的多对多):

A)与香草LSTM一样

model = Sequential()
model.add(LSTM(N_BLOCKS, input_shape=(N_INPUTS, N_FEATURES)))
model.add(Dense(N_OUTPUTS))

作为编码器-解码器LSTM

model.add(LSTM(N_BLOCKS, input_shape=(N_INPUTS, N_FEATURES))  
model.add(RepeatVector(N_OUTPUTS))
model.add(LSTM(N_BLOCKS, return_sequences=True))  
model.add(TimeDistributed(Dense(1)))
model.add(Activation('linear')) 

7
请问你能否解释一下B)编码器-解码器LSTM结构的细节?我对"RepeatVector"和"TimeDistributed"步骤的作用还不是很理解。 - Marsellus Wallace
请问您能否帮忙解决如何正确地为多对多或编码器-解码器模型提供多维数据的问题?我主要是在处理形状方面遇到了困难。假设我们有一个存储在数组中的完整数据集,其形状为(45000,100,6)=(Nsample,Ntimesteps,Nfeatures),即我们有45000个样本,每个样本有100个时间步长和6个特征。 - Djordje Savic

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接