多彩编程 多彩编程MZPH · CODE BLOG
ARTICLE DETAIL

文章详情

深耕前端与后端开发技术的一线实战笔记与踩坑复盘。

时间序列预测实战(十三)利用FNet模型实现滚动长期预测并可视化结果

时间序列预测实战(十三)利用FNet模型实现滚动长期预测并可视化结果 论文地址-官方论文代码地址官方代码地址-官方下载地址Github个人修改代码地址- 个人修改版本下载地址CSDN一、本文介绍本博客将介绍一种新的时间序列预测模型——FNet它通过使用傅里叶变换代替自注意力机制旨在解决传统Transformer模型中的效率问题。FNet模型通过简单的线性变换包括非参数化的傅里叶变换来“混合”输入令牌从而实现了快速且高效的处理方式。这种创新的方法在保持了相对较高的准确性的同时显著提高了训练速度特别是在处理长序列数据时更显优势。本文的内容包括FNet的工作原理并通过一个实战案例展示如何实现基于FNet的可视化结果和滚动长期预测。预测类型-多元预测、单元预测、长期预测。适用对象-资源受限的环境例如生产服务器或边缘设备二、FNet的工作原理1.FNet的框架原理FNet是一种基于Transformer编码器架构的模型通过替换自注意力子层为简单的线性变换特别是傅里叶变换来加速处理过程。FNet架构中的每一层由一个傅里叶混合子层和一个前馈子层组成(下图中的白色框)。傅里叶子层应用2D离散傅里叶变换(DFT)到其输入一维DFT沿序列维度和隐藏维度。总结FNet相对于传统的Transformer的改进其实就一点就是将注意力机制替换为傅里叶变换,所以其精度并没有提升(我觉得反而有下降,但是论文内相等但是从我的实验角度结果分析精度是有下降的)其这么改进的主要效果就是训练速度的加快因为注意力机制一般都需要复杂计算傅里叶变化的计算很简单。2.FNet的主要优势FNet的改进主要优势可能就是其训练速度了这适合一些资源受限的环境例如生产服务器或边缘设备当我们在实际工作时候生产环境一般都不带有GPU的所以速度就很重要了下面我来分析其训练速度的提升。上面的这张图表展示了不同模型在掩码语言模型MLM任务中的准确性与训练步骤时间的关系。时间以毫秒(ms)为单位采用对数尺度表示可以看出随着训练时间的增加准确性有所提升图中展示了四种不同的模型BERT用蓝色圆点表示Linear用红色三角形表示FNet用黄色方块表示FNet-Hybrid用绿色星形表示从图中可以观察到以下几点BERT模型在相对较短的训练时间内提供了高准确性但随着时间的增加准确性提升的速度放缓。Linear模型在初始阶段准确性较低但随着训练时间的增加其准确性的提升速度似乎比BERT模型要快。FNet模型的表现介于BERT和Linear模型之间表明其在训练速度和准确性之间取得了一定的平衡。FNet-Hybrid模型与FNet相比似乎在较长的训练时间内达到了更高的准确性这表明在FNet中加入了一些自注意力机制可能会有所帮助。此图的一个关键信息是尽管BERT在开始时领先但随着时间的推移其他模型在准确性上逐渐接近BERT这表明对于有限的训练时间其他模型可能是更有效的选择。此外考虑到时间和准确性的平衡我们本文的模型FNet和FNet-Hybrid可能更适合在资源有限的情况下使用。三、数据集介绍本文所用到的数据集为某公司的业务水平评估和其它参数具体的内容我就介绍了估计大家都是想用自己的数据进行训练模型这里展示部分图片给大家提供参考-​四、参数讲解模型涉及到的参数全部如下-parser argparse.ArgumentParser(descriptionFNet Multivariate Time Series Forecasting) # basic config parser.add_argument(--train, typebool, defaultTrue, helpWhether to conduct training) parser.add_argument(--rollingforecast, typebool, defaultTrue, helprolling forecast True or False) parser.add_argument(--rolling_data_path, typestr, defaultETTh1-Test.csv, helprolling data file) parser.add_argument(--show_results, typebool, defaultTrue, helpWhether show forecast and real results graph) parser.add_argument(--model, typestr, defaultFNet,helpModel name) # data loader parser.add_argument(--root_path, typestr, default./data/, helproot path of the data file) parser.add_argument(--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) parser.add_argument(--checkpoints, typestr, default./models/, helplocation of model models) # forecasting task parser.add_argument(--seq_len, typeint, default126, helpinput sequence length) parser.add_argument(--label_len, typeint, default64, helpstart token length) parser.add_argument(--pred_len, typeint, default4, helpprediction sequence length) # model parser.add_argument(--norm, actionstore_false, defaultTrue, helpwhether to apply LayerNorm) parser.add_argument(--rev, actionstore_true, defaultTrue, helpwhether to apply RevIN) parser.add_argument(--d_model, typeint, default512, helpdimension of model) parser.add_argument(--n_heads, typeint, default1, 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(--d_ff, typeint, default2048, helpdimension of fcn) 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) parser.add_argument(--dropout, typefloat, default0.05, helpdropout) parser.add_argument(--embed, typestr, defaulttimeF, helptime features encoding, options:[timeF, fixed, learned]) parser.add_argument(--activation, typestr, defaultgelu, helpactivation) # optimization parser.add_argument(--num_workers, typeint, default0, helpdata loader num workers) parser.add_argument(--train_epochs, typeint, default10, helptrain epochs) parser.add_argument(--batch_size, typeint, default16, helpbatch size of train input data) parser.add_argument(--learning_rate, typefloat, default0.001, helpoptimizer learning rate) parser.add_argument(--loss, typestr, defaultmse, helploss function) parser.add_argument(--lradj, typestr, defaulttype1, helpadjust learning rate) # GPU parser.add_argument(--use_gpu, typebool, defaultTrue, helpuse gpu) parser.add_argument(--device, typeint, default0, helpgpu)参数的详细讲解如下-参数名称参数类型参数讲解0trainbool是否进行训练如果你单纯只想进行预测设置为False即可1rollingforecastbool是否进行滚动预测如果是则设置为True如果不进行滚动预测则进行正常的预测2rolling-data-pathstr如果进行滚动预测则需要添加新的和训练文件相同格式的数据3show_resultsbool是否保存预测值和真实值的滚动预测对比图4modelstr定义的模型名称5root_pathstr这个才是你文件的路径不要到具体的文件到目录级别即可。6data_pathstr这个填写你文件的具体名称。7featuresstr这个是特征有三个选项MMSS。分别是多元预测多元多元预测单元单元预测单元。8targetstr这个是你数据集中你想要预测那一列数据假设我预测的是油温OT列就输入OT即可。9freqstr时间的间隔你数据集每一条数据之间的时间间隔。10checkpointsstr训练出来的模型保存路径11seq_lenint用过去的多少条数据来预测未来的数据12label_lenint可以理解为更高的权重占比的部分要小于seq_len13pred_lenint预测未来多少个时间点的数据14normint这个参数控制是否应用层归一化15revint表明这个参数控制是否应用RevIN操作(推荐大家使用)16enc_inint你数据有多少列,要减去时间那一列这里我是输入8列数据但是有一列是时间所以就填写717dec_inint同上18c_outint这里有一些不同如果你的features填写的是M那么和上面就一样如果填写的MS那么这里要输入1因为你的输出只有一列数据。19d_modelint用于设置模型的维度默认值为512。可以根据需要调整该参数的数值来改变模型的维度20n_headsint用于设置模型中的注意力头数。默认值为8表示模型会使用8个注意力头我建议和的输入数据的总体保持一致列如我输入的是8列数据不用刨去时间的那一列就输入8即可。21e_layersint用于设置编码器的层数22d_layersint用于设置解码器的层数23s_layersstr用于设置堆叠编码器的层数24dropoutfloat这个应该都理解不说了丢弃的概率防止过拟合的。25embedstr时间特征的编码方式默认为timeF26activationstr激活函数27num_workersint线程windows大家最好设置成0否则会报线程错误,linux系统随便设置。28train_epochsint训练的次数29batch_sizeint一次往模型力输入多少条数据30learning_ratefloat学习率。31lossstr损失函数默认为mse32lradjstr学习率的调整方式默认为type133use_gpubool是否使用GPU训练根据自身来选择34gpuintGPU的编号五、项目结构项目的目录结构如下图-​其中的main.py文件为我们程序的主入口其中的配置如下-if __name__ __main__: parser argparse.ArgumentParser(descriptionFNet Multivariate Time Series Forecasting) # basic config parser.add_argument(--train, typebool, defaultTrue, helpWhether to conduct training) parser.add_argument(--rollingforecast, typebool, defaultTrue, helprolling forecast True or False) parser.add_argument(--rolling_data_path, typestr, defaultETTh1-Test.csv, helprolling data file) parser.add_argument(--show_results, typebool, defaultTrue, helpWhether show forecast and real results graph) parser.add_argument(--model, typestr, defaultFNet,helpModel name) # data loader parser.add_argument(--root_path, typestr, default./data/, helproot path of the data file) parser.add_argument(--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) parser.add_argument(--checkpoints, typestr, default./models/, helplocation of model models) # forecasting task parser.add_argument(--seq_len, typeint, default126, helpinput sequence length) parser.add_argument(--label_len, typeint, default64, helpstart token length) parser.add_argument(--pred_len, typeint, default4, helpprediction sequence length) # model parser.add_argument(--norm, actionstore_false, defaultTrue, helpwhether to apply LayerNorm) parser.add_argument(--rev, actionstore_true, defaultTrue, helpwhether to apply RevIN) parser.add_argument(--d_model, typeint, default512, helpdimension of model) parser.add_argument(--n_heads, typeint, default1, 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(--d_ff, typeint, default2048, helpdimension of fcn) 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) parser.add_argument(--dropout, typefloat, default0.05, helpdropout) parser.add_argument(--embed, typestr, defaulttimeF, helptime features encoding, options:[timeF, fixed, learned]) parser.add_argument(--activation, typestr, defaultgelu, helpactivation) # optimization parser.add_argument(--num_workers, typeint, default0, helpdata loader num workers) parser.add_argument(--train_epochs, typeint, default10, helptrain epochs) parser.add_argument(--batch_size, typeint, default16, helpbatch size of train input data) parser.add_argument(--learning_rate, typefloat, default0.001, helpoptimizer learning rate) parser.add_argument(--loss, typestr, defaultmse, helploss function) parser.add_argument(--lradj, typestr, defaulttype1, helpadjust learning rate) # GPU parser.add_argument(--use_gpu, typebool, defaultTrue, helpuse gpu) parser.add_argument(--device, typeint, default0, helpgpu) args parser.parse_args() Exp SCINetinitialization # setting record of experiments setting predict-{}-data-{}.format(args.model, args.data_path[:-4]) SCI SCINetinitialization(args) # 实例化模型 if args.train: print(start training : {}.format(args.model)) SCI.train(setting) print(predicting : {}.format(args.model)) SCI.predict(setting, True) plt.show()六、模型训练和预测1.模型训练当我们配置好所有的参数以后就可以开始训练了控制台的输出如下-​2.滚动预测我们进行滚动长期预测共预测未来的五百条数据每次预测四条数据控制台输入如下-​2.1结果展示下面的图片就是预测值和真实值的对比这个模型FNet和我前面用到的一些模型相比结果真的不是很好我也不知道模型本身就是这样还是该模型的效果有什么问题但是训练的速度和推理速度还是挺快的。​3.结果保存我们的滚动预测的输出结果和训练的模型和预测值和真实值的对比分别保存在下图的标注的路径上。七、如何定制化训练个人数据集这个模型我在写的过程中为了节省大家训练自己数据集我基本上把大部分的参数都写好了需要大家注意的就是如果要进行滚动预测下面的参数要设置为True。parser.add_argument(--rollingforecast, typebool, defaultTrue, helprolling forecast True or False)如果上面的参数设置为True那么下面就要提供一个进行滚动预测的数据集该数据集的格式要和你训练模型的数据集格式完全一致(重要)如果没有可以考虑在自己数据的尾部剪切一部分不要粘贴否则数据模型已经训练过了的话预测就没有效果了。parser.add_argument(--rolling_data_path, typestr, defaultETTh1-Test.csv, helprolling data file)其它的没什么可以讲的了大部分的修改操作在参数讲解的部分我都详细讲过了这里的滚动预测可能是大家想看的所以摘出来详细讲讲。全文总结到此本文已经全部讲解完成了希望能够帮助到大家在这里也给大家推荐一些我其它的博客的时间序列实战案例讲解其中有数据分析的讲解就是我前面提到的如何设置参数的分析博客最后希望大家订阅我的专栏本专栏均分文章均分98并且免费阅读。专栏目录时间序列预测目录深度学习、机器学习、融合模型、创新模型实战案例专栏时间序列预测专栏基础知识数据分析机器学习深度学习Transformer创新模型​​
返回列表