这个问题是我先前在这里提出的问题的后续问题:Multi-feature causal CNN - Keras implementation,但是,有很多事情我不清楚,我认为这值得提出一个新问题。这里讨论的模型是根据上面提到的帖子中公认的答案建立的。
我正在尝试对10个具有5个特征的序列的多元时间序列数据应用因果CNN模型。
lookback, features = 10, 5
应该将过滤器和内核设置为什么?
应将膨胀设置为什么?
lookback
?filters = 32
kernel = 5
dilations = 5
dilation_rates = [2 ** i for i in range(dilations)]
model = Sequential()
model.add(InputLayer(input_shape=(lookback, features)))
model.add(Reshape(target_shape=(features, lookback, 1), input_shape=(lookback, features)))
根据前面提到的答案,需要根据以下逻辑对输入进行重塑:
Reshape
之后,将5个输入要素视为TimeDistributed层的时间层将Conv1D应用于每个输入要素时,它认为层的形状为(10,1)
具有默认的“ channels_last”,因此...
# Add causal layers
for dilation_rate in dilation_rates:
model.add(TimeDistributed(Conv1D(filters=filters,
kernel_size=kernel,
padding='causal',
dilation_rate=dilation_rate,
activation='elu')))
根据上述答案,需要根据以下逻辑对模型进行重塑:
接下来,因果层现在将分别应用于5个输入要素。
model.add(Reshape(target_shape=(lookback, features * filters)))
next_dilations = 3
dilation_rates = [2 ** i for i in range(next_dilations)]
for dilation_rate in dilation_rates:
model.add(Conv1D(filters=filters,
kernel_size=kernel,
padding='causal',
dilation_rate=dilation_rate,
activation='elu'))
model.add(MaxPool1D())
model.add(Flatten())
model.add(Dense(units=1, activation='linear'))
model.summary()
应该设置哪些膨胀来表示回溯10?
为什么最初单独应用因果层?
================================================ ==========================
lookback, features = 10, 5
filters = 32
kernel = 5
dilations = 5
dilation_rates = [2 ** i for i in range(dilations)]
model = Sequential()
model.add(InputLayer(input_shape=(lookback, features)))
model.add(Reshape(target_shape=(features, lookback, 1), input_shape=(lookback, features)))
# Add causal layers
for dilation_rate in dilation_rates:
model.add(TimeDistributed(Conv1D(filters=filters,
kernel_size=kernel,
padding='causal',
dilation_rate=dilation_rate,
activation='elu')))
model.add(Reshape(target_shape=(lookback, features * filters)))
next_dilations = 3
dilation_rates = [2 ** i for i in range(next_dilations)]
for dilation_rate in dilation_rates:
model.add(Conv1D(filters=filters,
kernel_size=kernel,
padding='causal',
dilation_rate=dilation_rate,
activation='elu'))
model.add(MaxPool1D())
model.add(Flatten())
model.add(Dense(units=1, activation='linear'))
model.summary()
================================================ ==========================
丹尼尔,谢谢您的回答。
问题:
如果您可以“精确”地解释数据的结构方式,原始数据是什么以及如何将其转换为输入形状(如果您具有独立的序列)以及创建滑动Windows等。可以更好地了解此过程。
答案:
希望我能正确理解您的问题。
每个功能都是时间序列数据的序列数组。它们是独立的,例如它们不是图像,但是它们彼此之间有些相关。
这就是为什么我要使用Wavenet的原因,它非常擅长预测单个时间序列阵列,但是,我的问题要求我使用多个功能。
答案 0 :(得分:3)
问题:
- 为什么最初要单独应用因果层?
- 为什么它们在重塑后会被依赖地应用?
- 为什么不从一开始就依赖它们?
那个答案有点奇怪。我不是专家,但是我看不到需要使用TimeDistributed
层保留独立功能。但是我也不能说它是否能带来更好的结果。起初我会说这是不必要的。但是,它可能带来更多的智能,因为它可能看到关系涉及两个要素之间的遥远步骤,而不是仅仅关注“相同步骤”。 (应该对此进行测试)
尽管如此,该方法存在错误。
旨在交换回溯和特征尺寸的重塑未达到预期的效果。答案的作者显然想交换轴(保留对特征,回溯的解释),这与重塑不同(将所有内容混合在一起并且数据失去了意义) )
正确的方法将需要实际的轴交换,例如model.add(Permute((2,1)))
而不是整形。
所以,我不知道这些答案,但是似乎没有什么可以创造这种需求。 可以肯定的一件事是:您一定会想要依赖部分。如果模型不考虑要素之间的关系,则模型将无法获得原始模型的智能。 (除非您很幸运地拥有完全独立的数据)
可以将LSTM
与Conv1D
直接进行比较,并且所使用的形状完全相同,并且实际上意味着相同,只要您使用的是channels_last
。
也就是说,形状(samples, input_length, features_or_channels)
是LSTM
和Conv1D
的正确形状。实际上,在这种情况下,功能和渠道是完全一样的。变化的是每层在输入长度和计算方面的工作方式。
内核是conv层内的整个张量,将其与输入相乘以获得结果。内核包括其空间大小(kernel_size
)和filters
的数量(输出要素)。以及自动输入过滤器。
没有很多内核,但是有kernel_size
。内核大小是每个输出步骤将连接多少个长度的步骤。 (此tutorial非常适合于关于其功能和内核大小的未知2D卷积-想像一下1D图像-尽管本教程没有显示“过滤器”的数量,就像1-filter动画)
filters
的数量与features
的数量直接相关,它们是完全一样的。
应该将过滤器和内核设置为什么?
因此,如果您的LSTM
层正在使用units=256
,这意味着它将输出256个特征,那么您应该使用filters=256
,这意味着卷积将输出256个通道/特征。
但这不是规则,您可能会发现使用更多或更少的过滤器会带来更好的结果,因为这些图层毕竟会做不同的事情。不需要所有层都具有相同数量的过滤器!!在这里,您应该进行参数调整。 进行测试以查看最适合您的目标和数据的数字。
现在,内核大小是无法与LSTM相比的。这是模型中新增的内容。
数字3是很常见的选择。这意味着卷积将需要三个时间步才能产生一个时间步。然后滑动一个步骤,进行三个步骤的另一组操作,以产生下一个步骤,依此类推。
膨胀表示卷积滤波器在步骤之间将有多少间隔。
dilation_rate=1
连续执行kernel_size
步以产生一个步骤。 dilation_rate = 2
的卷积需要步骤0、2和4来产生一个步骤。然后执行步骤1、3、5以产生下一步,依此类推。 应该设置什么膨胀来表示回溯10?
range = 1 + (kernel_size - 1) * dilation_rate
因此,内核大小= 3:
如果您可以“精确地”解释数据的结构方式,原始数据是什么以及如何将其转换为输入形状,具有独立序列,创建滑动窗口等可以更好地了解此过程。