在 Keras 中实现 Causal CNN 以进行多变量时间序列预测
Posted
技术标签:
【中文标题】在 Keras 中实现 Causal CNN 以进行多变量时间序列预测【英文标题】:Implement Causal CNN in Keras for multivariate time-series prediction 【发布时间】:2019-11-05 18:35:27 【问题描述】:这个问题是我之前的问题的后续问题:Multi-feature causal CNN - Keras implementation,但是,我认为有很多事情不清楚,我认为需要提出一个新问题。这里有问题的模型是根据上面提到的帖子中接受的答案构建的。
我正在尝试对具有 5 个特征的 10 个序列的多元时间序列数据应用因果 CNN 模型。
lookback, features = 10, 5
过滤器和内核应该设置成什么?
过滤器和内核对网络有什么影响? 这些只是一个任意数字 - 即 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)))
根据前面提到的答案,输入需要按照以下逻辑进行reshape:
在Reshape
之后,现在将 5 个输入要素视为 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')))
根据上面提到的答案,模型需要重塑,按照以下逻辑:
将特征图堆叠在一起,这样每个时间步都可以查看之前生成的所有特征 -(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 的回溯?
为什么最初独立应用因果层?
reshape 后为什么要依赖应用? 为什么不从一开始就独立应用它们?================================================ ==============================
完整代码
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 的原因,它非常擅长预测单个时间序列数组,但是,我的问题需要我使用多个多个特征。
【问题讨论】:
【参考方案1】:对给定答案的评论
问题:
为什么因果层最初是独立应用的? 为什么它们在 reshape 后依赖应用? 为什么不从一开始就独立应用它们?
这个答案有点奇怪。我不是专家,但我认为没有必要使用TimeDistributed
层来保留独立功能。但我也不能说它是否给出了更好的结果。起初我会说这只是不必要的。但它可能会带来额外的智能,因为它可能会看到涉及两个特征之间的遥远步骤的关系,而不是仅仅查看“相同的步骤”。 (这个应该测试一下)
不过,这种方法有一个错误。
旨在交换回溯和特征大小的重塑没有达到预期的效果。答案的作者显然想swap axes(保持对什么是特征,什么是lookback的解释),这与reshape不同(混合一切,数据失去意义) )
正确的方法需要实际的轴交换,例如 model.add(Permute((2,1)))
而不是重塑。
所以,我不知道这些答案,但似乎没有什么能产生这种需求。 一件可以肯定的事情是:你肯定会想要依赖的部分。如果一个模型不考虑特征之间的关系,它就不会接近原始模型的智能。 (除非你有幸拥有完全独立的数据)
现在,解释一下 LSTM 和 Conv1D 之间的关系
LSTM
可以直接与Conv1D
进行比较,并且使用的形状完全相同,它们的含义几乎相同,只要您使用的是channels_last
。
也就是说,(samples, input_length, features_or_channels)
的形状对于LSTM
和Conv1D
都是正确的。事实上,在这种情况下,特征和渠道是完全一样的。变化的是每一层在输入长度和计算方面的工作方式。
过滤器和内核的概念
内核是卷积层内的整个张量,它将与输入相乘以获得结果。内核包括其空间大小 (kernel_size
) 和 filters
的数量(输出特征)。还有自动输入过滤器。
没有多少内核,但是有一个kernel_size
。内核大小是每个输出步骤将连接到长度中的步骤数。 (这个tutorial 非常适合理解 2D 卷积关于它的作用和内核大小是什么——想象一下 1D 图像——尽管本教程没有显示“过滤器”的数量,它就像 1 过滤器动画)
filters
的数量与features
的数量直接相关,它们是一回事。
过滤器和内核应该设置成什么?
所以,如果你的LSTM
层使用units=256
,这意味着它将输出 256 个特征,你应该使用filters=256
,这意味着你的卷积将输出 256 个通道/特征。
这不是一个规则,虽然,您可能会发现使用更多或更少的过滤器可以带来更好的结果,因为这些层毕竟做不同的事情。没有必要让所有层都具有相同数量的过滤器!!在这里,您应该进行参数调整。 测试看看哪些数字最适合您的目标和数据。
现在,内核大小是无法与 LSTM 相比的。这是模型中添加的新事物。
数字 3 是一种非常常见的选择。这意味着卷积需要三个时间步才能产生一个时间步。然后滑动一个步骤以采取另一组三个步骤来生成下一步,依此类推。
扩张
Dilations 表示卷积滤波器在步骤之间有多少空间。
卷积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 步我的问题
如果您能“准确”解释您是如何构建数据的、原始数据是什么以及如何将其转换为输入形状、是否有独立序列、是否正在创建滑动窗口等. 可以更好地理解这个过程。
【讨论】:
以上是关于在 Keras 中实现 Causal CNN 以进行多变量时间序列预测的主要内容,如果未能解决你的问题,请参考以下文章