使用2D卷积技术进行时间序列预测(下)

简介: 使用2D卷积技术进行时间序列预测

1D卷积预测方法

另一种预测时间序列的方法是使用一维卷积模型。1D卷积使用一个过滤窗口并在数据上循环该窗口以产生新的输出。根据所学的卷积窗参数,它们可以像移动平均线、方向指示器或模式探测器一样随时间变化。

640.png

step 1

这里有一个包含8个元素的数据集,过滤器大小为4。过滤器中的四个数字是Conv1D层学习的参数。在第一步中,我们将过滤器的元素乘以输入数据,并将结果相加以产生卷积输出。640.png


step 2

在卷积的第二步中,窗口向前移动一个,重复相同的过程以产生第二个输出。

640.png

Last step

这个过程一直持续到窗口到达输入数据的末尾。在我们的例子中,一个输入数据序列是我们之前设置的72小时的数据。如果我们添加padding=“same”选项,我们的输入数据将在开始和结束处用零进行填充,以保持输出长度等于输入长度。上面的演示使用线性激活,这意味着最后一个多色数组是我们的输出。但是,我们可以在这里使用一整套激活函数,这些函数将通过一个额外的步骤来运行这个数字。因此,在下面的例子中,将有一个ReLU激活函数应用于最后的输出,以产生最终的输出。

下面展示了建立1D卷积模型的相关代码:

defbasic_conv1D(n_filters=10, fsize=5, window_size=5, n_features=2):
new_model=keras.Sequential()
new_model.add(tf.keras.layers.Conv1D(n_filters, fsize, padding=”same”, activation=”relu”, input_shape=(window_size, n_features)))
#Flattenwilltakeourconvolutionfiltersandlaythemoutendtoendsoourdenselayercanpredictbasedontheoutcomesofeachnew_model.add(tf.keras.layers.Flatten())
new_model.add(tf.keras.layers.Dense(1800, activation=’relu’))
new_model.add(tf.keras.layers.Dense(100))
new_model.add(tf.keras.layers.Dense(1))
new_model.compile(optimizer=”adam”, loss=”mean_squared_error”)
returnnew_model

模型情况如下:

univar_model=basic_conv1D(n_filters=24, fsize=8, window_size=window_size, n_features=X_train.shape[2])
univar_model.summary()
Model: "sequential_1"_________________________________________________________________Layer (type)                 OutputShapeParam#=================================================================conv1d (Conv1D)             (None, 72, 24)            216_________________________________________________________________flatten_1 (Flatten)         (None, 1728)              0_________________________________________________________________dense_3 (Dense)             (None, 1800)              3112200_________________________________________________________________dense_4 (Dense)             (None, 100)               180100_________________________________________________________________dense_5 (Dense)             (None, 1)                 101=================================================================Totalparams: 3,292,617Trainableparams: 3,292,617Non-trainableparams: 0

注意,这里有24个卷积窗口,过滤器大小是8。因此,在我们的例子中,输入数据将是72小时,这将创建一个大小为8的窗口,其中将有24个过滤器。因为我使用padding=“same”,每个过滤器的输出宽度将是72,就像我们的输入数据一样,并且输出的数量将是24个卷积数组。最后通过Flatten生成72*24=1728长度的数组。Flatten的工作过程如下图所示:

640.png

Flatten工作示意图

对比1D卷积模型、LSTM、基线模型的预测损失如下:

640.png

显然1D卷积方法比LSTM更好一些,但是它仍然没有达到最初的基准模型更好的效果。当我们看预测效果曲线时,我们可以看到这个模型有明显的偏差:

640.png

1D卷积预测效果

添加数据维度

在上面的例子中,我们只使用我们想要预测的特性作为我们的输入变量。然而,我们的数据集有12个可能的输入变量。我们可以将所有的输入变量叠加起来,然后一起使用它们来进行预测。由于许多输入变量与我们的输出变量具有中等/较强的相关性,因此使用更多的数据进行更好的预测应该是可能的。

640.png

多输入1D卷积

如果我想把一个不同的数据序列叠加到模型中,首先要通过相同的窗口处理过程来生成一组观测值,每个观测值都包含变量的最后72个读数。例如,如果我想在第1列中添加变量DADemand(日前需求,当前前一天的需求),将对其执行以下操作:

(DADemand, _) =window_data(gc_df, window_size, 1, 1)
scaler=StandardScaler()
DADemand=scaler.fit_transform(DADemand)
split=int(0.8*len(X))
DADemand_train=DADemand[: split1]
DADemand_test=DADemand[split:]
DADemand_test.shape(61875, 72, 1)

然后,可以对所有的12个变量重复这个过程,并将它们堆积成一个单独的集合,如下所示:

data_train=np.concatenate((X_train, db_train, dew_train, DADemand_train, DALMP_train, DAEC_train, DACC_train, DAMLC_train, RTLMP_train, RTEC_train, RTCC_train, RTMLC_train), axis=2)
data_test=np.concatenate((X_test, db_test, dew_test, DADemand_test, DALMP_test, DAEC_test, DACC_test, DAMLC_test, RTLMP_test, RTEC_test, RTCC_test, RTMLC_test), axis=2)
data_train.shape(61875, 72, 12)

至此生成了包含61875个样本、每一个都包含12个不同时间序列的72小时单独读数的数据集。我们现在通过一个Conv1D网络来运行它,看看我们得到了什么结果。如果回顾一下我们用于创建这些模型的函数,会注意到其中一个变量是特征feature的数量,因此运行这个新模型的代码同样十分简单。预测误差结果如下:

640.png

模型的性能实际上随着其他变量的增加而降低。分析其原因,可能是“模糊”效应(添加更多的数据集往往会“模糊”任何一个特定输入变化的影响,反而会产生一个不太精确的模型。)。

2D卷积

我们实际需要的是一个卷积窗口,它可以查看我们的模型特征并找出哪些特征是有益的。2D卷积可以实现我们想要的效果。

640.png

在做了一些尝试之后,本文将使用(1,filter_size)大小的2D卷积窗口,在上图中,filter_size=3。回到我们的能源预测问题,我们有12个特点。为了让它进入二维卷积窗口,我们实际上需要它有4个维度。我们可以通过以下方法得到另一个维度:

data_train_wide=data_train.reshape((data_train.shape[0], data_train.shape[1], data_train.shape[2], 1))
data_test_wide=data_test.reshape((data_test.shape[0], data_test.shape[1], data_test.shape[2], 1))
data_train_wide.shape(61875, 72, 12, 1)

测试了不同的窗口尺寸过后,我们发现一次考虑两个特征效果最好:

defbasic_conv2D(n_filters=10, fsize=5, window_size=5, n_features=2):
new_model=keras.Sequential()
new_model.add(tf.keras.layers.Conv2D(n_filters, (1,fsize), padding=”same”, activation=”relu”, input_shape=(window_size, n_features, 1)))
new_model.add(tf.keras.layers.Flatten())
new_model.add(tf.keras.layers.Dense(1000, activation=’relu’))
new_model.add(tf.keras.layers.Dense(100))
new_model.add(tf.keras.layers.Dense(1))
new_model.compile(optimizer=”adam”, loss=”mean_squared_error”)
returnnew_modelm2=basic_conv2D(n_filters=24, fsize=2, window_size=window_size, n_features=data_train_wide.shape[2])
m2.summary()
Model: "sequential_4"_________________________________________________________________Layer (type)                 OutputShapeParam#=================================================================conv2d (Conv2D)             (None, 72, 12, 24)        72_________________________________________________________________flatten_4 (Flatten)         (None, 20736)             0_________________________________________________________________dense_12 (Dense)             (None, 1000)              20737000_________________________________________________________________dense_13 (Dense)             (None, 100)               100100_________________________________________________________________dense_14 (Dense)             (None, 1)                 101=================================================================Totalparams: 20,837,273Trainableparams: 20,837,273Non-trainableparams: 0

这个模型相当大。在普通CPU上训练每一个epoch大约需要4分钟。不过,当它完成后,预测效果如下图:

640.png

与其他模型对比预测误差:

640.png

可以看到,2D卷积的效果优于其它所有的预测模型。

补充

如果我们使用类似的想法,但同时用尺寸为(8,1)的滤波器进行卷积运算呢?相关代码如下:

defdeeper_conv2D(n_filters=10, fsize=5, window_size=5, n_features=2, hour_filter=8):
new_model=keras.Sequential()
new_model.add(tf.keras.layers.Conv2D(n_filters, (1,fsize), padding=”same”, activation=”linear”, input_shape=(window_size, n_features, 1)))
new_model.add(tf.keras.layers.Conv2D(n_filters, (hour_filter, 1), padding=”same”, activation=”relu”))
new_model.add(tf.keras.layers.Flatten())
new_model.add(tf.keras.layers.Dense(1000, activation=’relu’))
new_model.add(tf.keras.layers.Dense(100))
new_model.add(tf.keras.layers.Dense(1))
new_model.compile(optimizer=”adam”, loss=”mean_squared_error”)
returnnew_model

模型预测性能表现很好:

640.png

模型预测误差也进一步降低:

640.png

本文所有代码和数据可以在这里直接下载:

https://github.com/walesdata/2Dconv_pub

作者:Johnny Wales

目录
相关文章
|
机器学习/深度学习 算法
【基础回顾】在回归任务中常见的损失函数比较(mse、mae、huber)
【基础回顾】在回归任务中常见的损失函数比较(mse、mae、huber)
1518 0
【基础回顾】在回归任务中常见的损失函数比较(mse、mae、huber)
|
缓存 监控 算法
jvm性能调优实战 - 39一次大促导致的内存泄漏和Full GC优化
jvm性能调优实战 - 39一次大促导致的内存泄漏和Full GC优化
420 0
|
12月前
|
传感器
【VOFA+速成】半小时入门VOFA+简明教程之进阶用法(二)
【VOFA+速成】半小时入门VOFA+简明教程之进阶用法(二)
1305 1
|
7月前
|
资源调度 算法 数据可视化
基于IEKF迭代扩展卡尔曼滤波算法的数据跟踪matlab仿真,对比EKF和UKF
本项目基于MATLAB2022A实现IEKF迭代扩展卡尔曼滤波算法的数据跟踪仿真,对比EKF和UKF的性能。通过仿真输出误差收敛曲线和误差协方差收敛曲线,展示三种滤波器的精度差异。核心程序包括数据处理、误差计算及可视化展示。IEKF通过多次迭代线性化过程,增强非线性处理能力;UKF避免线性化,使用sigma点直接处理非线性问题;EKF则通过一次线性化简化处理。
222 14
|
7月前
|
机器学习/深度学习 人工智能 算法
基于Python深度学习的【害虫识别】系统~卷积神经网络+TensorFlow+图像识别+人工智能
害虫识别系统,本系统使用Python作为主要开发语言,基于TensorFlow搭建卷积神经网络算法,并收集了12种常见的害虫种类数据集【"蚂蚁(ants)", "蜜蜂(bees)", "甲虫(beetle)", "毛虫(catterpillar)", "蚯蚓(earthworms)", "蜚蠊(earwig)", "蚱蜢(grasshopper)", "飞蛾(moth)", "鼻涕虫(slug)", "蜗牛(snail)", "黄蜂(wasp)", "象鼻虫(weevil)"】 再使用通过搭建的算法模型对数据集进行训练得到一个识别精度较高的模型,然后保存为为本地h5格式文件。最后使用Djan
395 1
基于Python深度学习的【害虫识别】系统~卷积神经网络+TensorFlow+图像识别+人工智能
|
机器学习/深度学习 人工智能 算法
鸟类识别系统Python+卷积神经网络算法+深度学习+人工智能+TensorFlow+ResNet50算法模型+图像识别
鸟类识别系统。本系统采用Python作为主要开发语言,通过使用加利福利亚大学开源的200种鸟类图像作为数据集。使用TensorFlow搭建ResNet50卷积神经网络算法模型,然后进行模型的迭代训练,得到一个识别精度较高的模型,然后在保存为本地的H5格式文件。在使用Django开发Web网页端操作界面,实现用户上传一张鸟类图像,识别其名称。
432 12
鸟类识别系统Python+卷积神经网络算法+深度学习+人工智能+TensorFlow+ResNet50算法模型+图像识别
|
Python
时间序列去趋势化和傅里叶变换
在计算傅里叶变换之前对信号去趋势是一种常见的做法,特别是在处理时间序列时。在这篇文章中,我将从数学和视觉上展示信号去趋势是如何影响傅里叶变换的。
833 0
|
XML 数据可视化 算法
目标检测YOLO数据集的三种格式及转换
目标检测YOLO数据集的三种格式及转换
|
机器学习/深度学习 人工智能 算法
【机器学习】平均绝对误差 (MAE) 与均方误差 (MSE) 有什么区别?
【5月更文挑战第17天】【机器学习】平均绝对误差 (MAE) 与均方误差 (MSE) 有什么区别?
|
NoSQL 关系型数据库 MongoDB
非关系型数据库(NoSQL)的语法
【4月更文挑战第11天】NoSQL数据库语法各异,无统一标准。Redis以其多样数据类型(如字符串、散列)和命令式操作(如`SET`、`GET`)为特点,而MongoDB采用类似JavaScript的查询语言,支持复杂操作。适应不同NoSQL数据库需学习相应语法,参考官方文档是最佳实践。
222 3