在我的原始设置下,我得到了
X1 = (1200,40,1)
y1 = (1200,10)
然后,我可以完美地使用我的代码:
model = Sequential()
model.add(LSTM(12, input_shape=(40, 1), return_sequences=True))
model.add(LSTM(12, return_sequences=True))
model.add(LSTM(6, return_sequences=False))
model.add((Dense(10)))
现在,我进一步得到了另一个与X1
和y1
相同大小的时间序列数据。即
X2 = (1200,40,1)
y2 = (1200,10)
现在,我将X1
,X2
和y1
,y2
堆叠为3D阵列:
X_stack = (1200,40,2)
y_stack = (1200,10,2)
然后,我尝试修改keras
代码,例如:
model = Sequential()
model.add(LSTM(12, input_shape=(40, 2), return_sequences=True))
model.add(LSTM(12, return_sequences=True))
model.add(LSTM(6, return_sequences=False))
model.add((Dense((10,2))))
我希望我的代码直接与3D数组X_stack
和y_stack
一起使用,而不必将它们重塑为2D数组。您能帮我修改设置吗?谢谢。
答案 0 :(得分:0)
您可以使用X_stack.shape()
的输出元组:
model = Sequential()
model.add(LSTM(12, input_shape=(X_stack.shape[1], X_stack.shape[2]),return_sequences=True))
model.add(LSTM(12, return_sequences=True))
model.add(LSTM(6, return_sequences=False))
model.add((Dense((10,2))))
答案 1 :(得分:0)
我假设为数组报告的形状中某处有错误。我猜y_stack.shape == (1200, 10, 2)
,对吗?
但是,这里有一种可能性可以做您描述的事情:
model = Sequential()
model.add(LSTM(12, input_shape=(40, 2), return_sequences=True))
model.add(LSTM(12, return_sequences=True))
model.add(LSTM(6, return_sequences=False))
model.add(Dense(10 * 2))
model.add(Reshape((10, 2)))
通过Dense
层将网络的输出创建为2D张量,然后通过Reshape
将其输出重塑为3D张量。
从输入输出的角度来看,这应该像您指定的那样。
答案 2 :(得分:0)
我假设您需要为堆栈中的每个数组共享参数。
如果要堆叠全新的功能,则每个功能都不会有关联的目标。
如果要堆叠完全不同的示例,则不会使用3D数组,而只是像正常情况一样将它们附加到末尾。
解决方案
要解决此问题,我将利用TimeDistributed wrapper from Keras。
LSTM层的形状为(j, k)
,其中j
是时间步数,k
是要素数。由于您希望将数组保持为输入和输出的3D形式,因此您希望将其堆叠在与要素维度不同的维度上。
简要说明:
我认为重要的是要注意这两种方法之间的差异。在要素维上堆叠可为您提供相同时间步长的多个要素。在那种情况下,您可能希望使用相同的LSTM层而不走这条路线。因为您需要3D输入和3D输出,所以我建议您创建一个要堆叠的新尺寸,以便您可以独立应用相同的LSTM层。
时间分配:
此包装器在1
索引处将一个层应用于每个数组。
通过将X1
和X2
数组堆叠在1
索引上,并使用TimeDistributed包装器,可以将LSTM层分别应用于所堆叠的每个数组。下面请注意,原始和更新的模型摘要具有完全相同的参数数量。
实施步骤:
第一步是将(40, 2)
的输入重塑为(2, 40, 1)
。这相当于 2 x (40, 1)
个数组输入。您可以像我一样在模型中进行此操作,也可以在构建数据集并更新输入形状时进行
(..., 1)
,我们将数据保持为LSTM能够理解的格式(如果它只是查看一次堆叠的数组之一)。请注意您的原始input_shape例如是(40, 1)
。然后将每个图层包装在TimeDistributed包装器中。
最后,通过将(2, 10)
交换为(10, 2)
,调整y输出的形状以匹配您的数据。
代码
from tensorflow.python.keras import Sequential
from tensorflow.python.keras.layers import LSTM, Dense, TimeDistributed, InputLayer, Reshape
from tensorflow.python.keras import backend
import numpy as np
# Original Model
model = Sequential()
model.add(LSTM(12, input_shape=(40, 1), return_sequences=True))
model.add(LSTM(12, return_sequences=True))
model.add(LSTM(6, return_sequences=False))
model.add((Dense(10)))
model.summary()
原始模型摘要
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
lstm (LSTM) (None, 40, 12) 672
_________________________________________________________________
lstm_1 (LSTM) (None, 40, 12) 1200
_________________________________________________________________
lstm_2 (LSTM) (None, 6) 456
_________________________________________________________________
dense (Dense) (None, 10) 70
=================================================================
Total params: 2,398
Trainable params: 2,398
Non-trainable params: 0
_________________________________________________________________
应用时间分布的包装器
model = Sequential()
model.add(InputLayer(input_shape=(40, 2)))
model.add(Reshape(target_shape=(2, 40, 1)))
model.add(TimeDistributed(LSTM(12, return_sequences=True)))
model.add(TimeDistributed(LSTM(12, return_sequences=True)))
model.add(TimeDistributed(LSTM(6, return_sequences=False)))
model.add(TimeDistributed(Dense(10)))
model.add(Reshape(target_shape=(10, 2)))
model.summary()
更新的模型摘要
_________________________________________________________________
Layer (type) Output Shape Param #
=================================================================
reshape (Reshape) (None, 2, 40, 1) 0
_________________________________________________________________
time_distributed (TimeDistri (None, 2, 40, 12) 672
_________________________________________________________________
time_distributed_1 (TimeDist (None, 2, 40, 12) 1200
_________________________________________________________________
time_distributed_2 (TimeDist (None, 2, 6) 456
_________________________________________________________________
time_distributed_3 (TimeDist (None, 2, 10) 70
_________________________________________________________________
reshape_1 (Reshape) (None, 10, 2) 0
=================================================================
Total params: 2,398
Trainable params: 2,398
Non-trainable params: 0
_________________________________________________________________
答案 3 :(得分:0)
我不能简短地回答这个问题,但是我认为需要对LSTM的一些基本概念进行澄清(一对一,一对多,... )
由于超结构RNN(包括LSTM)是顺序的,所以它们被构造为找到类似时间的相关性,而CNN是空间的,它们被构造为找到类似空间的相关性。相关性
然后,LSTM在一对一,一对多,多对一和多对多中有进一步的区别,如 {{ 3}}
此处所需的网络类型是Many to one and many to many LSTM examples in Keras中的第5点,它表示:
步数与输入/输出长度不同时,很多对很多:这在Keras中很难实现。没有简单的代码片段可以对此进行编码。
因为输入形状为X_stack = (1200,40,2)
,所以它是类型5
并且输出形状为y_stack = (1200,10,2)
,因此时间步数不同({40
输入和10
输出)
如果您可以设法使输入和输出时间步数相等,则可以像 Many to one and many to many LSTM examples in Keras 中那样调整输入和输出数据(numpy.reshape
)的形状(请注意数组中的 [和] )。这并不意味着要重塑为2D(即展平)。
在keras LSTM feeding input with the right shape中,是使用TimeDistributed
层
仅出于完整性考虑,对于时空数据,还存在 CNN-LSTM ,但这不适用于此处,因为两个堆叠的时间序列没有明确的空间相关性:>
如果您拥有3D数量(即,随时间变化的体积分布)并想了解这一点,则必须使用 CNN-LSTM网络。在这种方法中,将同时保留3D信息和时间信息。保留3D信息意味着不丢弃空间信息。通常,在像LSTM这样的类似时间的学习者中,通常会通过在空间图像中使用展平来丢弃该空间信息,然后再在LSTM中对其进行处理。 https://machinelearningmastery.com/timedistributed-layer-for-long-short-term-memory-networks-in-python/
中有一个完整的教程,介绍如何在keras中构建(时空的)CNN-LSTM。