Keras 中的多对一和多对多 LSTM 示例
Many to one and many to many LSTM examples in Keras
我尝试了解 LSTM 以及如何使用 Keras 构建它们。我发现,运行 RNN 主要有 4 种模式(图中右边的 4 种)
图片来源:Andrej Karpathy
现在我想知道他们每个人的简约代码片段在 Keras 中会是什么样子。
所以像
model = Sequential()
model.add(LSTM(128, input_shape=(timesteps, data_dim)))
model.add(Dense(1))
对于这 4 个任务中的每一个,可能都需要一些解释。
所以:
一对一:您可以使用 Dense
层,因为您不处理序列:
model.add(Dense(output_size, input_shape=input_shape))
一对多:这个选项不支持很好,因为链接模型在Keras
中不是很容易,所以下面的版本是最简单的:
model.add(RepeatVector(number_of_times, input_shape=input_shape))
model.add(LSTM(output_size, return_sequences=True))
多对一:实际上,您的代码片段(几乎)是这种方法的一个示例:
model = Sequential()
model.add(LSTM(1, input_shape=(timesteps, data_dim)))
多对多:当输入和输出的长度与循环步骤数匹配时,这是最简单的片段:
model = Sequential()
model.add(LSTM(1, input_shape=(timesteps, data_dim), return_sequences=True))
当步数不同于 input/output 长度时的多对多:这在 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
与长度为 N
的人工填充序列一样简单,例如使用使用 0
个向量,以便将其调整到合适的大小。
@Marcin Możejko 的精彩回答
我会将以下内容添加到 NR.5(具有不同 in/out 长度的多对多):
A) 作为香草 LSTM
model = Sequential()
model.add(LSTM(N_BLOCKS, input_shape=(N_INPUTS, N_FEATURES)))
model.add(Dense(N_OUTPUTS))
B) 作为 Encoder-Decoder 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'))
我尝试了解 LSTM 以及如何使用 Keras 构建它们。我发现,运行 RNN 主要有 4 种模式(图中右边的 4 种)
现在我想知道他们每个人的简约代码片段在 Keras 中会是什么样子。 所以像
model = Sequential()
model.add(LSTM(128, input_shape=(timesteps, data_dim)))
model.add(Dense(1))
对于这 4 个任务中的每一个,可能都需要一些解释。
所以:
一对一:您可以使用
Dense
层,因为您不处理序列:model.add(Dense(output_size, input_shape=input_shape))
一对多:这个选项不支持很好,因为链接模型在
Keras
中不是很容易,所以下面的版本是最简单的:model.add(RepeatVector(number_of_times, input_shape=input_shape)) model.add(LSTM(output_size, return_sequences=True))
多对一:实际上,您的代码片段(几乎)是这种方法的一个示例:
model = Sequential() model.add(LSTM(1, input_shape=(timesteps, data_dim)))
多对多:当输入和输出的长度与循环步骤数匹配时,这是最简单的片段:
model = Sequential() model.add(LSTM(1, input_shape=(timesteps, data_dim), return_sequences=True))
当步数不同于 input/output 长度时的多对多:这在 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
与长度为 N
的人工填充序列一样简单,例如使用使用 0
个向量,以便将其调整到合适的大小。
@Marcin Możejko 的精彩回答
我会将以下内容添加到 NR.5(具有不同 in/out 长度的多对多):
A) 作为香草 LSTM
model = Sequential()
model.add(LSTM(N_BLOCKS, input_shape=(N_INPUTS, N_FEATURES)))
model.add(Dense(N_OUTPUTS))
B) 作为 Encoder-Decoder 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'))