在 Keras 中实现因果 CNN 以进行多变量时间序列预测

mic*_*196 5 python time-series conv-neural-network keras tensorflow

这个问题是我上一个问题的后续问题:Multi-feature causal CNN-Keras implementation,但是,有很多事情我不清楚,我认为这值得一个新问题。这里有问题的模型是根据上述帖子中接受的答案构建的。

我正在尝试将因果 CNN 模型应用于具有 5 个特征的 10 个序列的多元时间序列数据。

lookback, features = 10, 5
Run Code Online (Sandbox Code Playgroud)
  • 过滤器和内核应该设置为什么?

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

    • 这只是一个任意数字还是代表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)))

Run Code Online (Sandbox Code Playgroud)

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

  • Reshape5个输入特征现在都被视为对于TimeDistributed层的时间层
  • 当 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')))
Run Code Online (Sandbox Code Playgroud)

根据提到的答案,模型需要根据以下逻辑进行重塑:

  • 将特征图堆叠在一起,以便每个时间步都可以查看之前生成的所有特征 -(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()

Run Code Online (Sandbox Code Playgroud)

概括

  • 过滤器和内核应该设置为什么?
    • 它们会影响网络如何解释时间步长吗?
  • 应该设置什么膨胀来表示 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()

Run Code Online (Sandbox Code Playgroud)

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

编辑:

丹尼尔,谢谢你的回答。

题:

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

回答:

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

每个特征都是一个时间序列数据的序列数组。它们是独立的,因为它们不是图像,但是,它们在某种程度上相互关联。

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

Dan*_*ler 6

对给定答案的评论

问题:

  • 为什么因果层最初是独立应用的?
  • 为什么它们在重塑后依赖应用?
    • 为什么不从一开始就独立应用它们?

这个答案有点奇怪。我不是专家,但我认为没有必要在TimeDistributed图层中保留独立的特征。但我也不能说它是否给出了更好的结果。起初我会说这只是不必要的。但它可能会带来额外的智能,因为它可能会看到涉及两个特征之间远距离的关系,而不仅仅是查看“相同的步骤”。(这个应该测试)

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

旨在交换回溯和特征大小的重塑并没有达到预期的效果。答案的作者显然想交换轴(保留对什么是特征,什么是回顾的解释),这与reshape不同(混合所有内容,数据失去意义)

正确的方法需要实际的轴交换,model.add(Permute((2,1)))而不是重塑。

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

现在,解释 LSTM 和 Conv1D 之间的关系

AnLSTM可以直接与 a 进行比较,Conv1D并且使用的形状完全相同,并且它们的含义几乎相同,只要您使用channels_last.

这就是说,形状(samples, input_length, features_or_channels)是两个正确的形状LSTMConv1D。事实上,在这种情况下,特征和渠道是完全一样的。改变的是每一层关于输入长度和计算的工作方式。

过滤器和内核的概念

Kernel 是 conv 层内的整个张量,它将与输入相乘以获得结果。内核包括其空间大小 ( kernel_size) 和filters(输出特征)的数量。还有自动输入过滤器。

没有许多内核,但有一个kernel_size. 内核大小是为每个输出步骤将长度中的多少步连接在一起。(本教程非常适合了解 2D 卷积关于它的作用和内核大小 - 想象一下 1D 图像 - 不过本教程没有显示“过滤器”的数量,它就像 1 过滤器动画)

的数量与 的数量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 时:

  • Dilation = 0 (dilation_rate=1):内核大小范围为 3 步
  • Dilation = 1 (dilation_rate=2):内核大小范围为 5 步
  • Dilation = 2 (dilation_rate=4):内核大小范围为 9 步
  • Dilation = 3 (dilation_rate=8):内核大小范围为 17 步

我对你的问题

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