在Keras中实现因果CNN在多元时间序列预测中的应用

2024-06-06 07:36:44 发布

您现在位置:Python中文网/ 问答频道 /正文

这个问题是我上一个问题的后续问题:Multi-feature causal CNN - Keras implementation,然而,有许多事情我不清楚,我认为它值得一个新的问题。这里所讨论的模型是根据上述帖子中的公认答案构建的。

我试图应用一个因果CNN模型对10个序列和5个特征的多元时间序列数据。

lookback, features = 10, 5
  • 过滤器和内核应该设置为什么?

    • 过滤器和内核对网络的影响是什么?在
    • 这些仅仅是一个任意的数目-即神经网络层中神经元的数量?在
    • 或者它们会对网络如何解释时间步长产生影响?在
  • 扩张应该设置为什么?

    • 这是一个任意的数字还是代表了模型的lookback?在
^{pr2}$

根据前面提到的答案,需要根据以下逻辑对输入进行整形:

  • Reshape5之后,输入特性现在被视为时间分布层的时间层
  • 当Conv1D应用于每个输入特征时,它认为层的形状是(10,1)

  • 使用默认的“channels_last”,因此。。。

  • 10个时间步是时间维度
  • 1是“通道”,即特征地图的新位置
# 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')))

根据上述答案,需要根据以下逻辑重塑模型:

  • 将特性映射堆叠在一起,以便每个时间步可以查看之前生成的所有特性(10个时间点,5个特性*32个过滤器)

接下来,因果层现在独立地应用于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()

====================================================================================

编辑:

丹尼尔,谢谢你的回答。

问题:

如果你能“准确地”解释你是如何组织数据的,什么是原始数据,以及你如何将其转换成输入形状,如果你有独立的序列,如果你正在创建滑动窗口等等,那么就可以更好地理解这个过程。

回答:

我希望我能正确地理解你的问题。

每个特征都是时间序列数据的序列数组。它们是独立的,因为它们不是一个图像,但是它们之间有某种关联。

这就是为什么我尝试使用Wavenet,它非常擅长预测单个时间序列数组,但是,我的问题需要我使用多个多个特性。


Tags: inaddformodelrate时间序列activation
1条回答
网友
1楼 · 发布于 2024-06-06 07:36:44

对给定答案的评论

问题:

  • Why are causal layers initially applied independently?
  • Why are they applied dependently after reshape?
    • Why not apply them dependently from the beginning?

这个答案有点奇怪。我不是专家,但我不认为有必要用TimeDistributed层保持独立的特性。但我也不能说它是否能带来更好的结果。一开始我会说这是不必要的。但它可能会带来额外的智能,因为它可能会看到两个特征之间的距离,而不仅仅是看“相同的步骤”。(应进行测试)

然而,这种方法有一个错误。在

用于交换回溯和特征大小的整形没有达到预期的效果。答案的作者显然想交换轴(保持对什么是特征的解释,什么是回溯),这不同于重塑(混合所有东西,数据失去意义)

正确的方法需要实际的轴交换,比如model.add(Permute((2,1)))而不是整形。在

所以,我不知道这些答案,但似乎没有什么能创造这种需求。 有一件事是肯定的:你肯定会想要依赖的部分。如果一个模型不考虑特征之间的关系,它将无法获得接近原始模型的智能。(除非您幸运地拥有完全独立的数据)

现在,解释LSTM和Conv1D

一个LSTM可以直接与一个Conv1D相比较,使用的形状是完全相同的,而且它们的意思实际上是相同的,只要你使用channels_last。在

也就是说,形状(samples, input_length, features_or_channels)LSTM和{}的正确形状。事实上,在这种情况下,功能和频道是完全相同的。改变的是每个层在输入长度和计算方面的工作方式。在

过滤器和内核的概念

Kernel是conv层中的整个张量,它将被乘以输入以得到结果。内核包括它的空间大小(kernel_size)和filters的数量(输出特性)。以及自动输入过滤器。在

内核不多,但有一个kernel_size。内核大小是每个输出步骤将连接在一起的长度中的步骤数。(这个tutorial对于关于它做什么和内核大小的不确定的二维卷积来说是很好的-想象一下1D图像,但是本教程没有显示“过滤器”的数量,就像1个过滤器动画)

filters的数目与features的数目直接相关,它们是完全相同的。在

What should filters and kernel be set to?

因此,如果您的LSTM层使用units=256,这意味着它将输出256个特征,那么您应该使用filters=256,这意味着您的卷积将输出256个通道/特征。在

这不是一个规则,尽管,您可能会发现使用更多或更少的过滤器可以带来更好的结果,因为层毕竟做了不同的事情。没有必要有相同数量的过滤器,以及所有层!!这里您应该进行参数调整。测试哪些数字最适合您的目标和数据。

现在,内核大小是无法与LSTM相比的。这是模型中增加的新东西。在

数字3是一个很常见的选择。这意味着卷积需要三个时间步才能产生一个时间步。然后滑动一个步骤,采取另一组三个步骤来生成下一个步骤,依此类推。在

扩张

膨胀意味着卷积滤波器将有多少步间距。在

  • 卷积dilation_rate=1需要kernel_size连续的步骤来产生一个步骤。在
  • 例如,使用dilation_rate = 2的卷积需要步骤0、2和4来生成一个步骤。然后采取步骤1、3、5生成下一步,依此类推。在

What should dilations be set to to represent lookback of 10?

range = 1 + (kernel_size - 1) * dilation_rate

因此,在内核大小为3时:

  • 膨胀率=0(膨胀率=1):核大小的范围为3步
  • 膨胀率=1(膨胀率=2):内核大小的范围为5步
  • 膨胀率=2(膨胀率=4):内核大小为9步
  • 膨胀=3(膨胀率=8):内核大小的范围是17步

我的问题是

如果你能“准确地”解释你是如何组织数据的,什么是原始数据,你是如何将它转换成输入形状的,如果你有独立的序列,如果你正在创建滑动窗口等等,那么就可以更好地理解这个过程。在

相关问题 更多 >