如何使用固定长度数据的 Keras 构建序列到序列模型 (RNN / LSTM)?

How can I do a sequence-to-sequence model (RNN / LSTM) with Keras with fixed length data?

我想做的事情看起来很简单,但我在网上找不到任何例子。首先,我不是在用语言工作,所以所有 embedding 的东西都给我的任务增加了不必要的复杂性。

我以 (1, 1000) 向量的形式输入。它们是时间序列数据,所以我将按顺序收集其中的 10 个。如果我正确理解张量,它会给我一些形状 (10, 1, 1000),对吗?

我想通过 RNN/LSTM 传递它,输出也应该具有相同的形状 (10, 1, 1000)。即,10 个向量,每个向量 1000 个维度。

如果您只想要一个输入形状为 (nb_seq, 1, 1000) 的 LSTM 模型(nb_seq 是您的序列数,在您的情况下为 10)并输出相同的形状,这里是您可以适应的基本模型:

input_x = Input(shape=(1, 1000))
x = LSTM(64, return_sequences=True)(input_x)
x = LSTM(64, return_sequences=True)(x)
x = Dense(1000)(x)

Model(inputs=input_x, outputs=x)

return_sequence=True 的 LSTM 层将 return 形状为 (nb_seq, 1, 64) 的张量(64 表示 LSTM 层的神经元数量), 所以为了找到原始形状,你可以通过一个 Dense 层传递这个张量,这会给你一个形状 (nb_seq, 1, 1000) 或者你可以在你的最后一个 LSTM 层上直接有 1000 个神经元(我不推荐,因为它会产生很多参数)。

您可以随意修改。

精确后编辑

由于 keras LSTM 仅接受 3D 输入,您可以通过在开头传递一个 Timedistributed 展平层来欺骗它,如下所示:

input_x = Input(shape=(10, 1, 1000))
x = TimeDistributed(Flatten())(input_x)
x = LSTM(64, return_sequences=True)(x)
x = LSTM(64, return_sequences=True)(x)
x = Dense(1000)(x)
x = Reshape(target_shape=(10, 1, 1000))(x)

Model(inputs=input_x, outputs=x)

这给了你这个总结:

您需要做的第一件事是知道 "what" 您考虑的是那里的序列。

步骤是什么?它们是 10 个时间步长吗?或者它们是 1000 个时间步长?


我最初假设您有 1000 个时间步。

那么下一个问题是:这10件事是什么?它们是同一性质的 10 个不同的独立示例吗?或者它们是来自同一个例子的 10 个不同性质(特征)的平行事物?


这些问题是最重要的部分,你需要知道你是否有:

  • (10, 1000, 1):10 个独立示例,每个示例 1000 个时间步,测量单个 variable/feature
  • (1, 1000, 10):1 个长序列,1000 个时间步,测量 10 个独立 vars/veatures
    • 你需要在滑动中划分你的数据windows,因为上面两种情况的例子太少了(网上有很多关于如何做的例子)。如果不这样做,您的模型将过度拟合。
    • 滑动windows你会把数据变成(more_examples, shorter_length, same_features)
  • (1000, 10, 1):1000 个不同序列的 10 个时间步测量单个 var/feature
    • 良好的数据,你很高兴
  • (1, 10, 1000):1个单序列10个时间步长,独立测量1000个vars/features
    • 我不确定这个数据是否可以训练,你没有足够的例子,即使你尝试滑动 windows
  • (10, 1, 1000): 10 个单独的例子,1 个时间步,测量 1000 vars/features
  • (1000, 1, 10):1000 个不同序列的 1 个时间步测量 10 个变量。
    • 以上两种情况不是使用 LSTM 的序列。

一旦你决定了,就该开始工作了:

根据您的情况正确堆叠输入数据并启动模型。

我会认为你有形状为 (samples, timesteps, features) 的数据,那么你的模型可以像这样:

inputs = Input((timesteps, features)) #or (None,features) for variable length
outputs = LSTM(any_units, return_sequences=True)(inputs)
.... can add more LSTM layers with different units, and return_sequences=True
.... can add Conv1D layers with padding='same', any number of filters
outputs = Dense(desired_features, activation=some_useful_activation)(outputs)

请注意,您的输出必须是 (samples, timesteps, desired_features)。如果您想要不同的最终形状,请在模型外重新塑造它。