如何使用固定长度数据的 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)
。如果您想要不同的最终形状,请在模型外重新塑造它。
我想做的事情看起来很简单,但我在网上找不到任何例子。首先,我不是在用语言工作,所以所有 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)
。如果您想要不同的最终形状,请在模型外重新塑造它。