PyTorch-LSTM时间序列预测中如何预测真正的未来值_lstm训练好的模型怎么预测-程序员宅基地

技术标签: 未来值  lstm  PyTorch  时间序列预测  深度学习  DL  pytorch  

I. 前言

之前写过几篇有关PyTorch搭建LSTM实现时间序列预测的文章,具体链接如下:

系列文章:

  1. 深入理解PyTorch中LSTM的输入和输出(从input输入到Linear输出)
  2. PyTorch搭建LSTM实现时间序列预测(负荷预测)
  3. PyTorch中利用LSTMCell搭建多层LSTM实现时间序列预测
  4. PyTorch搭建LSTM实现多变量时间序列预测(负荷预测)
  5. PyTorch搭建双向LSTM实现时间序列预测(负荷预测)
  6. PyTorch搭建LSTM实现多变量多步长时间序列预测(一):直接多输出
  7. PyTorch搭建LSTM实现多变量多步长时间序列预测(二):单步滚动预测
  8. PyTorch搭建LSTM实现多变量多步长时间序列预测(三):多模型单步预测
  9. PyTorch搭建LSTM实现多变量多步长时间序列预测(四):多模型滚动预测
  10. PyTorch搭建LSTM实现多变量多步长时间序列预测(五):seq2seq
  11. PyTorch中实现LSTM多步长时间序列预测的几种方法总结(负荷预测)
  12. PyTorch-LSTM时间序列预测中如何预测真正的未来值
  13. PyTorch搭建LSTM实现多变量输入多变量输出时间序列预测(多任务学习)
  14. PyTorch搭建ANN实现时间序列预测(风速预测)
  15. PyTorch搭建CNN实现时间序列预测(风速预测)
  16. PyTorch搭建CNN-LSTM混合模型实现多变量多步长时间序列预测(负荷预测)
  17. PyTorch搭建Transformer实现多变量多步长时间序列预测(负荷预测)
  18. PyTorch时间序列预测系列文章总结(代码使用方法)
  19. TensorFlow搭建LSTM实现时间序列预测(负荷预测)
  20. TensorFlow搭建LSTM实现多变量时间序列预测(负荷预测)
  21. TensorFlow搭建双向LSTM实现时间序列预测(负荷预测)
  22. TensorFlow搭建LSTM实现多变量多步长时间序列预测(一):直接多输出
  23. TensorFlow搭建LSTM实现多变量多步长时间序列预测(二):单步滚动预测
  24. TensorFlow搭建LSTM实现多变量多步长时间序列预测(三):多模型单步预测
  25. TensorFlow搭建LSTM实现多变量多步长时间序列预测(四):多模型滚动预测
  26. TensorFlow搭建LSTM实现多变量多步长时间序列预测(五):seq2seq
  27. TensorFlow搭建LSTM实现多变量输入多变量输出时间序列预测(多任务学习)
  28. TensorFlow搭建ANN实现时间序列预测(风速预测)
  29. TensorFlow搭建CNN实现时间序列预测(风速预测)
  30. TensorFlow搭建CNN-LSTM混合模型实现多变量多步长时间序列预测(负荷预测)
  31. PyG搭建图神经网络实现多变量输入多变量输出时间序列预测
  32. PyTorch搭建GNN-LSTM和LSTM-GNN模型实现多变量输入多变量输出时间序列预测
  33. PyG Temporal搭建STGCN实现多变量输入多变量输出时间序列预测
  34. 时序预测中Attention机制是否真的有效?盘点LSTM/RNN中24种Attention机制+效果对比
  35. 详解Transformer在时序预测中的Encoder和Decoder过程:以负荷预测为例
  36. (PyTorch)TCN和RNN/LSTM/GRU结合实现时间序列预测
  37. PyTorch搭建Informer实现长序列时间序列预测
  38. PyTorch搭建Autoformer实现长序列时间序列预测

文章写出后有不少人加了我的微信,也探讨了不少问题。这其中大家问得最多的问题是:到底怎么预测真正的未来值呢?而不是简单预测测试集里面的数据。这个问题其实很好解决,但貌似很多人不知道怎么写代码,也不知道怎么在原有代码的基础上改代码。所以,这篇文章我详细讲一下如何预测真正的未来值。

II. 分析

模型训练自不必说。

在对测试集进行预测时,我们已经提前处理好了数据,具体测试代码如下:

def test(args, Dte, lis, path):
    # Dtr, Dte, lis1, lis2 = load_data(args, flag, args.batch_size)
    pred = []
    y = []
    print('loading models...')
    input_size, hidden_size, num_layers = args.input_size, args.hidden_size, args.num_layers
    output_size = args.output_size
    if args.bidirectional:
        model = BiLSTM(input_size, hidden_size, num_layers, output_size, batch_size=args.batch_size).to(device)
    else:
        model = LSTM(input_size, hidden_size, num_layers, output_size, batch_size=args.batch_size).to(device)
    # models = LSTM(input_size, hidden_size, num_layers, output_size, batch_size=args.batch_size).to(device)
    model.load_state_dict(torch.load(path)['models'])
    model.eval()
    print('predicting...')
    for (seq, target) in tqdm(Dte):
        target = list(chain.from_iterable(target.data.tolist()))
        y.extend(target)
        seq = seq.to(device)
        with torch.no_grad():
            y_pred = model(seq)
            y_pred = list(chain.from_iterable(y_pred.data.tolist()))
            pred.extend(y_pred)

    y, pred = np.array(y), np.array(pred)
    m, n = lis[0], lis[1]
    y = (m - n) * y + n
    pred = (m - n) * pred + n
    print('mape:', get_mape(y, pred))
    # plot
    plot(y, pred)

核心代码:

for (seq, target) in tqdm(Dte):
    target = list(chain.from_iterable(target.data.tolist()))
    y.extend(target)
    seq = seq.to(device)
    with torch.no_grad():
        y_pred = model(seq)
        y_pred = list(chain.from_iterable(y_pred.data.tolist()))
        pred.extend(y_pred)

Dte为测试集,对于Dte中的每一个seq我们都知道了其标签target,但在预测未来值时我们只能得到seq,并不知道label。

当前时间为2022/6/6的21:00,我们用前24个小时的负荷值预测未来12个小时的负荷值。现在假设测试集的截止时间就为6/6的21:00,现在我们需要预测22:00到6/7 9:00的负荷值。根据模型的需求,我们需要构造一个seq,seq里面包含了6/6 21:00往前24个时刻的负荷值,这个是真实存在的。

具体代码:

def predict_one_step(model):
    data = data_process.load_data()

    train = data[:int(len(data) * 0.7)]
    test = data[int(len(data) * 0.7):len(data)]
    # 取test的最后24个负荷值
    load = test[test.columns[1]]
    load = load.tolist()
    m, n = np.max(load), np.min(load)
    load = (load - n) / (m - n)
    test = test.values.tolist()
    seq = []
    for i in range(len(test) - 24, len(test)):
        seq.append([load[i]])
    seq = [seq]
    seq = torch.FloatTensor(seq)
    seq = MyDataset(seq)
    seq = DataLoader(dataset=seq, batch_size=1, shuffle=False, num_workers=0)
    # print(new_seq)
    seq = [x for x in iter(seq)][0]
    print(seq.shape)  # (1, 24, 1) batch_size=1, seq_len=24, input_size=1
    # 开始预测
    seq = seq.to(device)
    with torch.no_grad():
        y_pred = model(seq)
        y_pred = list(chain.from_iterable(y_pred.data.tolist()))
    # y_pred为一个列表,长度为12
    return y_pred * (m - n) + n

上述代码的作用是利用测试集中最后24个时刻的值预测未来12个时刻的负荷值,这12值还没被观测到,是真正意义上的未来值。值得注意的是,为了满足模型的需要,即使只预测一个样本,我们也需要将其处理成如下格式的Tensor:

(batch_size=1, seq_len=24, input_size=1)

这里input_size=1,即我们在预测未来值时只考虑负荷值,不考虑其他诸如温度、湿度以及压强等环境因素。

现在我们已经预测完了今晚22:00到6/7 9:00的负荷值,如果我们想接着预测6/7 10:00~21:00的负荷值又该如何操作呢?一般来讲,有以下三种可能:

(1)假设电网有能力实时收集到真实用电负荷值,到明天9:00时,我们已经观测到了今晚22:00到明天9:00的真实值,且这些真实值保存在了数据库中,假设保存在了数组true_list中。那么我们完全可以利用今晚22:00到明天9:00的真实值预测未来12小时的负荷值,具体代码如下:

def predict_1(model, true_list, MAX, MIN):
    # 取真实值中最后24个负荷值
    true_list = true_list[-24:]
    # 构造seq
    true_list = (true_list- MIN) / (MAX - MIN)
    seq = [[x] for x in true_list]
    seq = [seq]
    seq = torch.FloatTensor(seq)
    seq = MyDataset(seq)
    seq = DataLoader(dataset=seq, batch_size=1, shuffle=False, num_workers=0)
    # print(new_seq)
    seq = [x for x in iter(seq)][0]
    print(seq.shape)  # (1, 24, 1) batch_size=1, seq_len=24, input_size=1
    # 开始预测
    seq = seq.to(device)
    with torch.no_grad():
        y_pred = model(seq)
        y_pred = list(chain.from_iterable(y_pred.data.tolist()))
    # y_pred为一个列表,长度为12
    return y_pred * (MAX - MIN) + MIN

简单来说就是利用真实值列表true_list中最后24个值进行预测。需要注意的是,我们是利用训练集中的最大最小值来对新数据进行归一化与反归一化的。此时,我们是可以计算MAPE的,因为真实值和预测值都存在。

(2)在现实生活中,往往很难及时收集到用电负荷信息,比如我们预测到了明天9:00,在明天9:00时,我们收集不到今晚22:00到明天9:00间的真实负荷值,此时我们就需要利用预测值来进行预测。也就是用一开始得到的今晚22:00到明天9:00间的预测值来预测未来12小时的负荷值,我们假设预测值保存在pred_list中,那么将上面代码中的true_list换成pred_list就可以得到未来12小时的负荷预测值。值得注意的是,此时是不能计算MAPE的,因为真实值尚未观测到。

(3)在明天9:00时,我们也不是一点真实值都没收集到,比如我们收集到了今晚22:00到明早3:00的负荷值,4:00到9:00的真实负荷值虽然已经产生,但电网还没有收集到数据库中。此时我们拥有6个真实值以及6个预测值,那么此时我们就可以用6个真实值加6个预测值,以及今晚9:00之前的12个真实值组成1个seq进行预测。一个大的前提:尽量使用真实值进行预测。

III. 多变量预测

上面的例子都是单变量预测,如果是多变量预测,情况将变得复杂一点。假设我们利用负荷值、温度、湿度以及压强四个变量来预测负荷。在我们预测今晚22:00到明早9:00的负荷值时,我们可以利用测试集中的数据进行预测。但当我们需要预测明早9:00之后的负荷值时,我们需要同时考虑是否收集到了真实的温度、湿度以及压强值。一般来讲,这些环境变量的收集比负荷数据的收集更加容易,也就是上述第二节中的第一种情况。

如果我们无法及时收集到负荷值,我们可以利用预测值进行预测;如果我们无法及时收集到温度、湿度以及压强值,我们也只能利用预测值进行预测。这就意味着,我们需要额外训练三个模型来分别预测温度、湿度以及压强,由于这三个变量和负荷一一对应,也属于时序数据,我们也可以采用LSTM进行预测,如果其变化幅度不大也可以采用传统的机器学习算法进行预测。

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/Cyril_KI/article/details/125154016

智能推荐

Java笔记5.0-程序员宅基地

文章浏览阅读75次。if条件结构基本if条件结构if(条件){}注意:当if关键词后的一对大括号里只有一个语句时,可以省略大括号。2.多重复if条件结构if(条件1){}else if(条件2){}else{}应用于只有一个if条件不能解决的问题,可以将问题的条件更详细地表示。3.嵌套if条件结构嵌套if选择结构就是在if里嵌入if选择结构,如下if(条件){if(条件){代码...

Paul Graham:未来的互联网创业(上)-程序员宅基地

文章浏览阅读63次。根据Paul Graham的简历,他是一个计算机博士,一个程序员,一个风险投资家。 ...

C#入门5.7——迭代语句之foreach语句_c# 中迭代变量 与集合变量-程序员宅基地

文章浏览阅读372次。foreach提供了一个for语句的捷径,而且还促进了集合类更为一致。格式foreach(类型 变量 in 集合) //注意集合二字。{代码体}补充:string类型可以看成是char类型的一个集合新语句char.IsWhiteSpace(c) //判断c是否为空格例子:将语句识别为单词并逐行输出using System;using Syst_c# 中迭代变量 与集合变量

django 中路由的使用 path 和 re_path的区别 url_django re_path 使用方法-程序员宅基地

文章浏览阅读719次。django 中路由的使用_django re_path 使用方法

uni-app中uni-table的uni-tr无点击事件_uniapp uni-table 点击事件-程序员宅基地

文章浏览阅读1.4k次,点赞3次,收藏8次。增加点击行点击事件(很多事件都没有),这个问题很久就有人在其官方论坛提出,但官方一直没有解决。有时开发就是那么“山重水复疑无路”,等方法二觉得是自己最后的无奈的选择时。笔者在写这篇文章时,为了信息的准确和完整,再去。标签里面,绑定相同的事件(如果想实现点击单元格触发不同的事件就可以定义不同的方法)。,但这样样式会改变,如下图所示。(后来在uni-app的论坛的回答也看到类似的。相比于方法一,优点是表格的样式不变,缺点是代码凌乱复杂。总之,最优的解决方法应该是方法三,期望有人去改善。本文记录用于记录使用。_uniapp uni-table 点击事件

做后端开发需要学什么?标梵看到了一条小白的发展之路_学后端需要什么基础-程序员宅基地

文章浏览阅读7.5k次,点赞53次,收藏304次。在去年结束的秋季招聘中,后台开发或者服务器开发的岗位需求一度火爆,甚至超过了算法的岗位。很多同学在诸神黄昏从算法岗战场退下来,转到了更偏向工程能力的后台开发岗,导致后台开发岗竞争大爆发。后台开发工程师使用的主流编程语言是C++、Java、PHP、Golang,目前慢慢流行起来。本文将从C++的角度谈谈如何学习和准备后台开发的岗位。第一,语言基础。无论是C++开发还是Java开发,对于一个代码农民来说,最重要的是熟悉编程语言。同样,无论从事什么样的岗位,首先要做的就是掌握语言基础。C++是一种深奥的编_学后端需要什么基础

随便推点

Visio首要事项闪退-程序员宅基地

文章浏览阅读2.5w次,点赞36次,收藏25次。网上有很多首要事项三个选项无论怎么选都直接闪退的情况,我自己遇到后瞎捣鼓解决了,把方法发出来给后来者借鉴。1、在设置-应用中找到Visio,应该叫“Microsoft Visio Professional 2013”。2、单击右边三个小点,选择“修改”。3、选“输入产品密钥”。4、复制这个失效密钥 27W4Q-T9N3J-JWX46-M7K96-GMQ73 并输入。5、因为已经安装过了就不需要自定义,所以选择继续、继续就行。6、提示重启系统,直接叉掉,没有修改安装文件没必要重启。.._首要事项

Java 设计模式 - Builder_java builder设计模式-程序员宅基地

文章浏览阅读137次。Java Design Partterns - Builder_java builder设计模式

[源码和文档分享]基于C++实现的LZW压缩算法-程序员宅基地

文章浏览阅读53次。1 特点 基于C++实现的LZW压缩算法,特点如下所示: 使用stl::map键值对作为字典存储 感觉算是简单的文件操作 字典无限长,字典自生长。但是字典只能解析存储ascii编码之类存在,中文符号之类的碰到就挂 2 逻辑设计 2.1 总体思路 ..._c++基于字典的无压缩算法lzw和lz77

自己动手编程实现“电子地图下载器_地图下载器实现原理-程序员宅基地

文章浏览阅读2.1k次,点赞3次,收藏3次。自己动手编程实现“电子地图下载器”请联系本文作者(QQ:442134556)获取源码电子地图对于国土规划、交通运输、水利设计、农林地质等部门的测绘、测量专业设计人员至关重要。国内已有一些公司提供下载软件,如迈高图(megomap)地图下载器、水经注(rivermap)万能地图下载器、BIGEMAP地图下载器、全能电子地图下载器等。这些软件的使用费从几百元到几千元不等。其实,绝大部分地理信息图..._地图下载器实现原理

HN8145X6/HS8145X6安装虚拟机OpenWRT-程序员宅基地

文章浏览阅读927次。(5)21.02.2版本和电信插件管理平台不兼容,电信平台起不来,所有的库都在原来的地方,但是ldd appmgr会报告一堆relocation。(1)125版以上固件的tar是残废的,不能正确解析跨目录的软链接,需要自行另外找版本;(2)默认network服务是关闭的,不要随意乱配和启动,可能会挂掉,特别是CPU口eth0,挂了用上面的软链接方法恢复,要拼手速。(3)默认防火墙firewall服务也是关闭的,,不要随意乱配和启动,可能网络会挂掉连不上,挂了用上面的软链接方法恢复,要拼手速。_hn8145x6

大屏大概是怎么个开发法(前端)_大屏开发-程序员宅基地

文章浏览阅读3.7k次,点赞16次,收藏36次。关于项目的维护与新增需求过程中值得一提的事_大屏开发