参考资料:
时间序列预测-LSTNet模型
LSTNet详解
LSTNet时间序列预测
多元时间序列预测之(二)LSTNet模型
LSTNet学习
源码
数据集
导读

LSTnet文章提出该模型针对多元时间序列预测问题,在文章中,主要应用在太阳能发电厂能量输出,电力消耗和交通堵塞等情况的预测。
提供的源码项目里就是对这些内容的实战例子。
直接引用参考文章里的解释:LSTNet有啥特点呢?它利用卷积层的优势发现多维输入变量之间的局部依赖模式,并循环层捕获复杂的长期依赖模式(It leverages the strengths of both the convolutional layer to discover the local dependency patterns among multi-dimensional input variables and the recurrent layer to captures complex long-term dependencies)。还要啥其他的创新吗?有,循环跳跃(Recurrent-skip):其被设计用来捕获特别长期依赖的模式,并利用了输入时间序列信号的周期性使优化变得更容易(designed for capturing very long-term dependence patterns and making the optimization easier as it utilizes the periodic property of the input time series signals)。
创新点就是将时序数据通过卷积层进行特征提取,用于捕捉短期局部信息,使用LSTM捕捉长期宏观信息。
整个模型的思想其实很简单,正如上图所示,先将多维时序数据通过CNN进行提取,然后通过RNN网络进行常规的LSTM模型训练,最后将最初的CNN提取内容跟经过LSTM的结果进行合并输出预测结果。
项目配置
在参考文章LSTNet详解中,介绍了基于不同框架的LSTnet的项目,这里的源码用的是pytorch框架的。
下载完源码后,在安装配置完pytorch环境后,打开项目,如下图:

其中,画圈的是作者提示的项目运行指令,如solar.sh中的内容如下:
python main.py --gpu 0 --data data/solar_AL.txt --save save/solar_AL.pt --hidSkip 10 --output_fun Linear
直接在终端输入这条指令即可运行整个项目。
这里要做Debug,所以换一个方式运行,打开main.py文件,在空白处右键,然后打开修改运行配置
将作者提示的形参传入下图红框部分--gpu 0 --data data/solar_AL.txt --save save/solar_AL.pt --hidSkip 10 --output_fun Linear
源代码里--gpu 4,这里的电脑只用1给gpu,所以设置为0。不用多卡训练的花,这个部分可以删了,不传入形参。系统调用cpu训练。

然后开始运行,在运行前需要创建save文件夹,用来保存权重的,将数据集放到项目里,创建data文件夹,然后将数据集对应的丢进来:
如果出行以下错误:
原因是torch的版本跟项目的版本不一样导致的,将data[0]改为data.item()即可。

参数配置
每个形参后都有英文介绍
parser = argparse.ArgumentParser(description='PyTorch Time series forecasting')
parser.add_argument('--data', type=str, required=True,
help='location of the data file')
parser.add_argument('--model', type=str, default='LSTNet',
help='')
parser.add_argument('--hidCNN', type=int, default=100,
help='number of CNN hidden units')
parser.add_argument('--hidRNN', type=int, default=100,
help='number of RNN hidden units')
parser.add_argument('--window', type=int, default=24 * 7,
help='window size')
parser.add_argument('--CNN_kernel', type=int, default=6,
help='the kernel size of the CNN layers')
parser.add_argument('--highway_window', type=int, default=24,
help='The window size of the highway component')
parser.add_argument('--clip', type=float, default=10.,
help='gradient clipping')
parser.add_argument('--epochs', type=int, default=100,
help='upper epoch limit')
parser.add_argument('--batch_size', type=int, default=128, metavar='N',
help='batch size')
parser.add_argument('--dropout', type=float, default=0.2,
help='dropout applied to layers (0 = no dropout)')
parser.add_argument('--seed', type=int, default=54321,
help='random seed')
parser.add_argument('--gpu', type=int, default=None)
parser.add_argument('--log_interval', type=int, default=2000, metavar='N',
help='report interval')
parser.add_argument('--save', type=str, default='model/model.pt',
help='path to save the final model')
parser.add_argument('--cuda', type=str, default=True)
parser.add_argument('--optim', type=str, default='adam')
parser.add_argument('--lr', type=float, default=0.001)
parser.add_argument('--horizon', type=int, default=12)
parser.add_argument('--skip', type=float, default=24)
parser.add_argument('--hidSkip', type=int, default=5)
parser.add_argument('--L1Loss', type=bool, default=True)
parser.add_argument('--normalize', type=int, default=2)
parser.add_argument('--output_fun', type=str, default='sigmoid')
args = parser.parse_args()
args.cuda = args.gpu is not None
if args.cuda:
torch.cuda.set_device(args.gpu)
# Set the random seed manually for reproducibility.
#希望结果复现,通过设置随机数种子的方法来实现。
torch.manual_seed(args.seed)
if torch.cuda.is_available():
if not args.cuda:
print("WARNING: You have a CUDA device, so you should probably run with --cuda")
else:
torch.cuda.manual_seed(args.seed)
读取数据
Data = Data_utility(args.data, 0.6, 0.2, args.cuda, args.horizon, args.window, args.normalize);
Data_utility类的行参:
def init(self, file_name, train, valid, cuda, horizon, window, normalize = 2):
- file_name 文件的路径
- train 训练集的占比
- valid 验证集占比
- cuda 是否使用GPU训练
- horizon 时间戳的理想界限
- window 滑动窗口
- normalize 使用标准化的模式供3种标准化模式,normalize = 2是按行方向的最大值归一化。
引用LSTNet时间序列预测的解释:
在这篇文章中,我们关注多变量时间预测的任务。正式的说,给定一系列观察到的时间序列信号Y = {y(1),y(2),…,y(T)},其中,yt∈Rn, n为变量维数,我们的目标是以滚动预测的方式预测一系列未来信号。为了预测y(T+h),我们需要提供{y(1),y(2),…,y(T)}的数据,其中h是当前时间戳的理想界限(horizon我不知道该如何翻译,暂且认为是一个极限值)。同样的,为了预测下一个时间戳的值y(T+h+1),需要提供{y(1),y(2),…,y(T),y(T+1)}。因此我们把时间戳T的输入矩阵表示为X(T)={y1,y2,…,yT},这个矩阵的维度是R(n*T)。
class Data_utility(object):
# train and valid is the ratio of training set and validation set. test = 1 - train - valid
def __init__(self, file_name, train, valid, cuda, horizon, window, normalize = 2):
self.cuda = cuda;
self.P = window;
self.h = horizon
#打开数据
fin = open(file_name);
#读取数据
self.rawdat = np.loadtxt(fin,delimiter=',');
self.dat = np.zeros(self.rawdat.shape);
self.n, self.m = self.dat.shape;
self.normalize = 2
self.scale = np.ones(self.m);
#数据标准化
self._normalized(normalize);
#训练集跟验证集分割
self._split(int(train * self.n), int((train+valid) * self.n), self.n);
#浮点型便于运算
#时序数据每个维度上的所有数,例如100组时序数据,1个时序数据有10维,self.scale获得的是这10个维度上所有的数。
self.scale = torch.from_numpy(self.scale).float();
tmp = self.test[1] * self.scale.expand(self.test[1].size(0), self.m);
if self.cuda:
self.scale = self.scale.cuda();
self.scale = Variable(self.scale);
#标准化
self.rse = normal_std(tmp

本文详细介绍了LSTNet模型在时间序列预测任务中的应用,包括模型的配置参数、数据读取与标准化、模型搭建、训练与验证过程。LSTNet结合卷积层和循环层,捕捉短期和长期依赖,通过PyTorch框架实现并提供源码示例。

8916

被折叠的 条评论
为什么被折叠?



