做网站策划薪酬,网站设计O2O平台,网页设计改版,在手机上做网站是什么软件论文地址-Informer论文地址PDF点击即可阅读
代码地址- 论文官方代码地址点击即可跳转下载GIthub链接
个人魔改版本地址- 文章末尾 一、本文介绍
在之前的文章中我们已经讲过Informer模型了#xff0c;但是呢官方的预测功能开发的很简陋只能设定固定长度去预测未…
论文地址-Informer论文地址PDF点击即可阅读
代码地址- 论文官方代码地址点击即可跳转下载GIthub链接
个人魔改版本地址- 文章末尾 一、本文介绍
在之前的文章中我们已经讲过Informer模型了但是呢官方的预测功能开发的很简陋只能设定固定长度去预测未来固定范围的值当我们想要发表论文的时候往往这个预测功能是并不能满足的所以我在官方代码的基础上增添了一个滚动长期预测的功能这个功能就是指我们可以第一次预测未来24个时间段的值然后我们像模型中填补 24个值再次去预测未来24个时间段的值(填补功能我设置成自动的了无需大家手动填补)这个功能可以说是很实用的这样我们可以准确的评估固定时间段的值当我们实际使用时可以设置自动爬取数据从而产生实际效用。本文修改内容完全为本人个人开发创作不易所以如果能够帮助到大家希望大家给我的文章点点赞同时可以关注本专栏(免费阅读)本专栏持续复现各种的顶会内容无论你想发顶会还是其它水平的论文都能够对你有所帮助。 专栏回顾 时间序列预测专栏——持续复习各种顶会内容——科研必备 Informer讲解回顾时间序列预测模型实战案例(八)(Informer)个人数据集、详细参数、代码实战讲解 连续滚动预测结果评估: 同时我将滚动预测结果生成了csv文件方便大家对比和评估以下是我生成的csv文件可以说是非常的直观。 我们可以利用其进行画图从而评估结果- 目录
一、本文介绍
二、Informer论文笔记
2.1、论文首先提出了Transformer模型的问题
2.2、LSTM技术的缺陷
2.3、Informer模型的提出
2.4、图解Informer的机制原理
2.5、结果分析
三、数据集介绍
四、项目结构和详细参数讲解
4.1、项目结构
4.2、模型参数讲解以及Bug修复
4.2.1、参数讲解
4.2.2、Bug修复
五、模型训练
六、结果预测
七、如何训练你自己的数据集
八、全文总结 二、Informer论文笔记
2.1、论文首先提出了Transformer模型的问题
时间序列预测在许多领域都是关键要素在这些场景中我们可以利用大量的时间序列历史数据来进行长期预测即长序列时间序列预测LSTF。然而现有方法大多设计用于短期问题如预测48点或更少的数据。随着序列长度的增加模型的预测能力受到挑战。例如当预测长度超过48点时LSTM网络的预测效果开始变得不满意推理速度急剧下降。LSTF的主要挑战是提升预测能力以满足日益增长的长序列需求这需要a超常的长距离对齐能力和b在长序列输入输出上的高效操作。最近Transformer模型在捕捉长距离依赖性方面表现优于RNN模型。然而自注意力机制由于其二次方的计算和内存消耗违反了b的要求。一些大型Transformer模型在NLP任务上取得了令人印象深刻的结果但训练和部署成本高昂。因此本文试图回答这个问题我们是否可以改进Transformer模型使其在计算、内存和架构上更高效同时保持更高的预测能力
2.2、LSTM技术的缺陷 上图展示了一个真实数据集上的预测结果其中LSTM网络从短期12个点0.5天预测电力变压器站的小时温度到长期480个点20天。当预测长度大于48个点时图1b中的实心星号整体性能差距显著均方误差升高推理速度急剧下降LSTM模型开始失效。 总结:这里说明了传统的时间序列预测对于长期预测效果不是很好大家如果想看LSTM的预测效果可以看我的往期博客里面有各种类型的LSTM讲解 2.3、Informer模型的提出
Informer是一种用于长序列时间序列预测的Transformer模型,但是它与传统的Transformer模型又有些不同点与传统的Transformer模型相比Informer具有以下几个独特的特点
1. ProbSparse自注意力机制Informer引入了ProbSparse自注意力机制该机制在时间复杂度和内存使用方面达到了O(Llog L)的水平能够有效地捕捉序列之间的长期依赖关系。
2. 自注意力蒸馏通过减少级联层的输入自注意力蒸馏技术可以有效处理极长的输入序列提高了模型处理长序列的能力。
3. 生成式解码器Informer采用生成式解码器可以一次性预测整个长时间序列而不是逐步进行预测。这种方式大大提高了长序列预测的推理速度。 2.4、图解Informer的机制原理 上图为Informer模型概述:左侧编码器接收大规模的长序列输入绿色序列。我们使用提出的ProbSparse自注意力替代传统的自注意力。蓝色梯形表示自注意力蒸馏操作用于提取主导的注意力大幅减小网络大小。层堆叠的副本增加了模型的稳健性。右侧解码器接收长序列输入将目标元素填充为零测量特征图的加权注意力组合并以生成式风格即时预测输出元素橙色序列 上图是Informer模型编码器结构的视觉表示下面是对其内容的解释 编码器堆栈图像中的水平堆栈代表Informer编码器结构中的一个编码器副本。每个堆栈都是一个独立单元处理部分或全部输入序列。 主堆栈图中显示的主堆栈处理整个输入序列。主堆栈之后第二个堆栈处理输入序列的一半以此类推每个后续的堆栈都处理上一个堆栈输入的一半。 点积矩阵堆栈内的红色层是点积矩阵它们是自注意力机制的一部分。通过在每一层应用自注意力蒸馏这些矩阵的大小逐层递减可能降低了计算复杂度并集中于序列中最相关的信息。 输出的拼接通过自注意力机制处理后所有堆栈的特征图被拼接起来形成编码器的最终输出。然后模型的后续部分如解码器通常使用这个输出基于输入序列中学习到的特征和关系生成预测。 这张图片可能用于说明Informer模型如何通过注意力蒸馏和跨多个处理堆栈的输入序列的智能处理有效地处理长序列并减少计算负载。
2.5、结果分析 上面图片包含三个图表分别标记为(a)、(b)和(c)每个图表都展示了Informer模型性能的不同方面与均方误差MSE得分之间的关系
(a) 输入长度此图表比较了编码器不同输入长度和解码器token长度的MSE得分。它显示了两个预测范围48和168指示模型性能随输入序列长度增加的变化。
(b) 采样因子此图表展示了不同采样因子c3、c5、c8、c10对Informer MSE得分的影响。采样因子在Informer模型的上下文中可能与ProbSparse自注意力机制有关影响注意力机制如何采样输入序列。
(c) 堆叠组合这个图表说明了当应用不同的依赖度量尺度L尺度、L/2尺度、L/4尺度与Informer自身的依赖方法相比不同编码器输入长度的MSE得分。这些不同的尺度可能指的是Informer模型处理输入序列的方式可能表示模型内部的一种层次化处理或注意力机制。
这些图表有助于理解不同参数和配置如何影响Informer模型的性能特别是在预测准确性方面以MSE测量。每个图表都提供了洞察如何优化模型以在各种时间序列数据长度上获得更好的准确性。 总结Informer模型成功提高了在LSTF问题中的预测能力验证了类似Transformer的模型在捕捉长序列时间序列输出和输入之间的个体长期依赖关系方面的潜在价值。 提出了ProbSparse自注意力机制以高效地替代传统的自注意力机制,提出了自注意力蒸馏操作可优化J个堆叠层中主导的注意力得分并将总空间复杂度大幅降低。提出了生成式风格的解码器只需要一步前向传播即可获得长序列输出同时避免在推理阶段累积误差的传播。 三、数据集介绍
我们本文用到的数据集是官方的ETTh1.csv 该数据集是一个用于时间序列预测的电力负荷数据集它是 ETTh 数据集系列中的一个。ETTh 数据集系列通常用于测试和评估时间序列预测模型。以下是 ETTh1.csv 数据集的一些内容
数据内容该数据集通常包含有关电力系统的多种变量如电力负荷、价格、天气情况等。这些变量可以用于预测未来的电力需求或价格。
时间范围和分辨率数据通常按小时或天记录涵盖了数月或数年的时间跨度。具体的时间范围和分辨率可能会根据数据集的版本而异。
以下是该数据集的部分截图-
四、项目结构和详细参数讲解
4.1、项目结构
项目结构如下图所示其中main_informer.py文件为程序入口。 4.2、模型参数讲解以及Bug修复
main_informer.py的参数讲解如下-
4.2.1、参数讲解
参数名称参数类型参数讲解0modelstr这是一个用于实验的参数设置其中包含了三个选项: informer, informerstack, informerlight。根据实验需求可以选择其中之一来进行实验默认是使用informer模型。1datastr 数据,这个并不是你理解的你的数据集文件而是你想要用官方定义的方法还是你自己的数据集进行定义数据加载器如果是自己的数据集就输入custom 2root_pathstr这个才是你文件的路径不要到具体的文件到目录级别即可。3data_pathstr这个填写你文件的名称。4is_rolling_predictbool是否进行滚动预测的选项如果设置为False则是普通预测本文改进5rolling_data_pathstr如果你要进行滚动预测则需要一个额外的文件可以从你的数据集末尾中进行裁取。本文改进6featuresstr这个是特征有三个选项MMSS。分别是多元预测多元多元预测单元单元预测单元。7targetstr这个是你数据集中你想要预测那一列数据假设我预测的是油温OT列就输入OT即可。8freqstr时间的间隔你数据集每一条数据之间的时间间隔。9checkpointsstr训练出来的模型保存路径10seq_lenint用过去的多少条数据来预测未来的数据11label_lenint可以裂解为更高的权重占比的部分要小于seq_len12pred_lenint预测未来多少个时间点的数据13enc_inint你数据有多少列,要减去时间那一列这里我是输入8列数据但是有一列是时间所以就填写714dec_inint同上15c_outint这里有一些不同如果你的features填写的是M那么和上面就一样如果填写的MS那么这里要输入1因为你的输出只有一列数据。16d_modelint用于设置模型的维度默认值为512。可以根据需要调整该参数的数值来改变模型的维度17n_headsint用于设置模型中的注意力头数。默认值为8表示模型会使用8个注意力头我建议和的输入数据的总体保持一致列如我输入的是8列数据不用刨去时间的那一列就输入8即可。18e_layersint用于设置编码器的层数19d_layersint用于设置解码器的层数20s_layersstr用于设置堆叠编码器的层数21d_ffint模型中全连接网络FCN的维度默认值为204822factorint ProbSparse自注意力中的因子默认值为523paddingint填充类型默认值为0这个应该大家都理解如果不够数据就填写0.24distilbool是否在编码器中使用蒸馏操作。使用--distil参数表示不使用蒸馏操作默认为True也是我们的论文中比较重要的一个改进。25dropoutfloat这个应该都理解不说了丢弃的概率防止过拟合的。26attnstr编码器中使用的注意力类型默认为prob我们论文的主要改进点提出的注意力机制。27embedstr时间特征的编码方式默认为timeF28activationstr激活函数29output_attentionbool是否在编码器中输出注意力默认为False30do_predictbool是否进行预测这里模型中没有给添加算是一个小bug我们需要填写一个defaultTrue在其中。31mixbool在生成式解码器中是否使用混合注意力默认为True32colsstr从数据文件中选择特定的列作为输入特征应该用不到33num_workersint线程windows大家最好设置成0否则会报线程错误,linux系统随便设置。34itrint实验运行的次数默认为2我们这里改成数字1.35train_epochsint训练的次数36batch_sizeint一次往模型力输入多少条数据37patienceint早停机制如果损失多少个epochs没有改变就停止训练。38learning_ratefloat学习率。39desstr 实验描述默认为test40lossstr 损失函数默认为mse41lradjstr 学习率的调整方式默认为type142use_ampbool混合精度训练43inversebool我们的数据输入之前会被进行归一化处理这里默认为False算是一个小bug因为输出的数据模型没有给我们转化成我们的数据我们要改成True。44use_gpubool是否使用GPU训练根据自身来选择45gpuintGPU的编号46use_multi_gpubool是否使用多个GPU训练。47devicesstrGPU的编号 4.2.2、Bug修复
其中定义了许多参数,在其中存在一些bug有如下的-
main_informer.py: error: the following arguments are required: --model, --data 这个bug是因为头两行参数的中的requiredTrue导致的我们将其删除掉即可。
parser.add_argument(--model, typestr, requiredTrue, defaultinformer,helpmodel of experiment, options: [informer, informerstack, informerlight(TBD)])parser.add_argument(--data, typestr, requiredTrue, defaultETTh1, helpdata)
删除完以后如下-
parser.add_argument(--model, typestr, defaultinformer,helpmodel of experiment, options: [informer, informerstack, informerlight(TBD)])parser.add_argument(--data, typestr, defaultETTh1, helpdata)
过程中还有些bug在参数讲解的描述中我都讲述了该如何解决,希望能够帮助到大家。
五、模型训练
到这里参数已经完全讲解完了bug也解决了我们可以开始进行模型训练了。我修改完训练的main_informer.py内容如下。
import argparseimport torchfrom exp.exp_informer import Exp_Informerparser argparse.ArgumentParser(description[Informer] Long Sequences Forecasting)parser.add_argument(--model, typestr, defaultinformer,helpmodel of experiment, options: [informer, informerstack, informerlight(TBD)])parser.add_argument(--data, typestr, defaultcustom, helpdata)
parser.add_argument(--root_path, typestr, default./, helproot path of the data file)
parser.add_argument(--data_path, typestr, defaultETTh1.csv, helpdata file)
parser.add_argument(--is_rolling_predict, typebool, defaultFalse, helprolling predict)
parser.add_argument(--rolling_data_path, typestr, defaultETTh1-Test.csv, helpdata file)
parser.add_argument(--features, typestr, defaultMS, helpforecasting task, options:[M, S, MS]; M:multivariate predict multivariate, S:univariate predict univariate, MS:multivariate predict univariate)
parser.add_argument(--target, typestr, defaultOT, helptarget feature in S or MS task)
parser.add_argument(--freq, typestr, defaulth,helpfreq for time features encoding, options:[s:secondly, t:minutely, h:hourly, d:daily, b:business days, w:weekly, m:monthly], you can also use more detailed freq like 15min or 3h)
parser.add_argument(--checkpoints, typestr, default./checkpoints/, helplocation of model checkpoints)
parser.add_argument(--seq_len, typeint, default126, helpinput sequence length of Informer encoder)
parser.add_argument(--label_len, typeint, default64, helpstart token length of Informer decoder)
parser.add_argument(--pred_len, typeint, default4, helpprediction sequence length)
# parser.add_argument(--sum_pred_len, typeint, default42, helpsum_pred_len // pred_len 0)# Informer decoder input: concat[start token series(label_len), zero padding series(pred_len)]parser.add_argument(--enc_in, typeint, default7, helpencoder input size)
parser.add_argument(--dec_in, typeint, default7, helpdecoder input size)
parser.add_argument(--c_out, typeint, default1, helpoutput size)
parser.add_argument(--d_model, typeint, default512, helpdimension of model)
parser.add_argument(--n_heads, typeint, default8, helpnum of heads)
parser.add_argument(--e_layers, typeint, default2, helpnum of encoder layers)
parser.add_argument(--d_layers, typeint, default1, helpnum of decoder layers)
parser.add_argument(--s_layers, typestr, default3,2,1, helpnum of stack encoder layers)
parser.add_argument(--d_ff, typeint, default2048, helpdimension of fcn)
parser.add_argument(--factor, typeint, default5, helpprobsparse attn factor)
parser.add_argument(--padding, typeint, default0, helppadding type)
parser.add_argument(--distil, actionstore_false,helpwhether to use distilling in encoder, using this argument means not using distilling,defaultTrue)
parser.add_argument(--dropout, typefloat, default0.05, helpdropout)
parser.add_argument(--attn, typestr, defaultprob, helpattention used in encoder, optio---ns:[prob, full])
parser.add_argument(--embed, typestr, defaulttimeF,helptime features encoding, options:[timeF, fixed, learned])
parser.add_argument(--activation, typestr, defaultgelu, helpactivation)
parser.add_argument(--output_attention, actionstore_true, helpwhether to output attention in ecoder)
parser.add_argument(--do_predict, actionstore_true, defaultTrue, helpwhether to predict unseen future data)
parser.add_argument(--mix, actionstore_false, helpuse mix attention in generative decoder, defaultTrue)
parser.add_argument(--cols, typestr, nargs, helpcertain cols from the data files as the input features)
parser.add_argument(--num_workers, typeint, default0, helpdata loader num workers)
parser.add_argument(--itr, typeint, default1, helpexperiments times)
parser.add_argument(--train_epochs, typeint, default20, helptrain epochs)
parser.add_argument(--batch_size, typeint, default32, helpbatch size of train input data)
parser.add_argument(--patience, typeint, default5, helpearly stopping patience)
parser.add_argument(--learning_rate, typefloat, default0.0001, helpoptimizer learning rate)
parser.add_argument(--des, typestr, defaulttest, helpexp description)
parser.add_argument(--loss, typestr, defaultmse, helploss function)
parser.add_argument(--lradj, typestr, defaulttype1, helpadjust learning rate)
parser.add_argument(--use_amp, actionstore_true, helpuse automatic mixed precision training, defaultFalse)
parser.add_argument(--inverse, actionstore_true, helpinverse output data, defaultFalse)parser.add_argument(--use_gpu, typebool, defaultTrue, helpuse gpu)
parser.add_argument(--gpu, typeint, default0, helpgpu)
parser.add_argument(--use_multi_gpu, actionstore_true, helpuse multiple gpus, defaultFalse)
parser.add_argument(--devices, typestr, default0,1,2,3, helpdevice ids of multile gpus)args parser.parse_args()
args.use_gpu True if torch.cuda.is_available() and args.use_gpu else Falseif args.use_gpu and args.use_multi_gpu:args.devices args.devices.replace( , )device_ids args.devices.split(,)args.device_ids [int(id_) for id_ in device_ids]args.gpu args.device_ids[0]data_parser {ETTh1: {data: sum.csv, T: sl, B: [7, 7, 7], S: [350, 168, 4], MS: [7, 7, 1]},ETTh2: {data: ETTh2.csv, T: OT, M: [7, 7, 7], S: [1, 1, 1], MS: [7, 7, 1]},ETTm1: {data: sum.csv, T: sl, B: [7, 7, 7], S: [126, 42, 4], MS: [7, 7, 1]},ETTm2: {data: ETTm2.csv, T: OT, M: [7, 7, 7], S: [1, 1, 1], MS: [7, 7, 1]},WTH: {data: WTH.csv, T: WetBulbCelsius, M: [12, 12, 12], S: [1, 1, 1], MS: [12, 12, 1]},ECL: {data: ECL.csv, T: MT_320, M: [321, 321, 321], S: [1, 1, 1], MS: [321, 321, 1]},Solar: {data: solar_AL.csv, T: POWER_136, M: [137, 137, 137], S: [1, 1, 1], MS: [137, 137, 1]},custom: {data: {}.format(args.data_path), T: OT, M: [7, 7, 7], MS: [7, 7, 1], S: [1, 1, 1]},
}
if args.data in data_parser.keys():data_info data_parser[args.data]args.data_path data_info[data]args.target data_info[T]args.enc_in, args.dec_in, args.c_out data_info[args.features]args.s_layers [int(s_l) for s_l in args.s_layers.replace( , ).split(,)]
args.detail_freq args.freq
args.freq args.freq[-1:]print(Args in experiment:)
print(args)Exp Exp_Informerfor ii in range(args.itr):# setting record of experimentssetting group_id{}_{}_{}_ft{}_sl{}_ll{}_pl{}_dm{}_nh{}_el{}_dl{}_df{}_at{}_fc{}_eb{}_dt{}_mx{}_{}_{}.format(args.data_path, args.model, args.data, args.features,args.seq_len, args.label_len, args.pred_len,args.d_model, args.n_heads, args.e_layers, args.d_layers, args.d_ff, args.attn, args.factor,args.embed, args.distil, args.mix, args.des, ii)exp Exp(args) # set experimentsprint(start training : {}.format(setting))exp.train(setting)print(testing : {}.format(setting))exp.test(setting)if args.do_predict:print(predicting : {}.format(setting))exp.predict(args, setting, True)torch.cuda.empty_cache()我们运行该文件,控制台就会开始输出进行训练。 训练出来的模型会保存在该目录下-其中的pth文件就是保存下来的模型。 六、结果预测
训练完成之后我们就可以开始预测了我这里进行了修改将所有的结果都变成了CSV文件这样方便大家观测结果会保存在下面的文件当中。 我们可以打开该文件部分截图如下- 我们可以利用其进行画图从而评估结果- 七、如何训练你自己的数据集
上面介绍了用我的数据集训练模型那么大家在利用模型的时候如何训练自己的数据集呢这里给家介绍一下需要修改的几处地方。
parser.add_argument(--data, typestr, defaultcustom, helpdata)
parser.add_argument(--root_path, typestr, default./, helproot path of the data file)
parser.add_argument(--data_path, typestr, defaultETTh1.csv, helpdata file)
parser.add_argument(--is_rolling_predict, typebool, defaultFalse, helprolling predict)
parser.add_argument(--rolling_data_path, typestr, defaultETTh1.csv, helpdata file)
parser.add_argument(--features, typestr, defaultMS, helpforecasting task, options:[M, S, MS]; M:multivariate predict multivariate, S:univariate predict univariate, MS:multivariate predict univariate)
parser.add_argument(--target, typestr, defaultOT, helptarget feature in S or MS task)
parser.add_argument(--freq, typestr, defaulth,helpfreq for time features encoding, options:[s:secondly, t:minutely, h:hourly, d:daily, b:business days, w:weekly, m:monthly], you can also use more detailed freq like 15min or 3h)
首先需要修改的就是上面这几处
其中data必须填写customroot_path填写文件夹即可data_path填写具体的文件在你文件夹下面is_rolling_predict就是滚动预测的开关设置为True则进行滚动预测否则就是普通预测rolling_data_path如果你要进行滚动预测则需要一个额外的文件可以从你的数据集末尾中进行裁取。features前面有讲解具体是看你自己的数据集我这里MS就是7列结果综合分析输出想要的那一列结果的预测值target就是你数据集中你想要知道那列的预测值的列名freq就是你两条数据之间的时间间隔。
parser.add_argument(--seq_len, typeint, default96, helpinput sequence length of Informer encoder)
parser.add_argument(--label_len, typeint, default48, helpstart token length of Informer decoder)
parser.add_argument(--pred_len, typeint, default24, helpprediction sequence length)
然后这三个就是影响精度的地方seq_len和label_len需要根据数据的特性来设置要进行专业的数据分析我会在下一周出教程希望到时候能够帮助到大家。
parser.add_argument(--enc_in, typeint, default7, helpencoder input size)
parser.add_argument(--dec_in, typeint, default7, helpdecoder input size)
parser.add_argument(--c_out, typeint, default7, helpoutput size)
这三个参数要修改和你的数据集对应和前面features的设定来配合设置具体可以看我前面的参数讲解部分参数需要修改的就这些然后是代码部分如下。
data_parser {ETTh1: {data: ETTh1.csv, T: OT, M: [7, 7, 7], S: [1, 1, 1], MS: [7, 7, 1]},ETTh2: {data: ETTh2.csv, T: OT, M: [7, 7, 7], S: [1, 1, 1], MS: [7, 7, 1]},ETTm1: {data: ETTm1.csv, T: OT, M: [7, 7, 7], S: [1, 1, 1], MS: [7, 7, 1]},ETTm2: {data: ETTm2.csv, T: OT, M: [7, 7, 7], S: [1, 1, 1], MS: [7, 7, 1]},WTH: {data: WTH.csv, T: WetBulbCelsius, M: [12, 12, 12], S: [1, 1, 1], MS: [12, 12, 1]},ECL: {data: ECL.csv, T: MT_320, M: [321, 321, 321], S: [1, 1, 1], MS: [321, 321, 1]},Solar: {data: solar_AL.csv, T: POWER_136, M: [137, 137, 137], S: [1, 1, 1], MS: [137, 137, 1]},custom: {data: ETTh1.csv, T: OT, M: [7, 7, 7], S: [1, 1, 1], MS: [7, 7, 1]},
}main_informer.py文件有如上的结构这是我修改之后的你可以按照我的修改其中custom就是对应你前面设置参数data的名字然后data后面替换成你的数据集必须是csv格式的文件这里然后是T大家不用管OT修改成你自己数据集中预测的哪一列列名就是前面设置的target值然后是M,S,MS分别对应你数据中的列的给个数即可我这里输入是8列扣去时间一列在M中就全部填写7即可S的话我的数据集用不到MS就是7列输出一列。
最后呢大家如果需要我的数据集和修改完成之后的实战代码可以在评论区留言。
八、全文总结 到此本文的正式分享内容就结束了在这里给大家推荐我的时间序列专栏本专栏目前为新开的平均质量分98分后期我会根据各种最新的前沿顶会进行论文复现也会对一些老的模型进行补充目前本专栏免费阅读(暂时大家尽早关注不迷路~)如果大家觉得本文帮助到你了订阅本专栏关注后续更多的更新~ 专栏回顾 时间序列预测专栏——持续复习各种顶会内容——科研必备 如果大家有不懂的也可以评论区留言一些报错什么的大家可以讨论讨论看到我也会给大家解答如何解决最后希望大家工作顺利学业有成