时间序列预测模型实战案例(八)(Informer)个人数据集、详细参数、代码实战讲解

news2024/11/29 23:37:08

论文地址->Informer论文地址PDF点击即可阅读

代码地址-> 论文官方代码地址点击即可跳转下载GIthub链接

本文介绍

本篇博客带大家看的是Informer模型进行时间序列预测的实战案例,它是在2019年被提出并在ICLR 2020上被评为Best Paper,可以说Informer模型在当今的时间序列预测方面还是十分可靠的,Informer模型的实质是注意力机制+Transformer模型,Informer模型的核心思想是将输入序列进行自注意力机制的处理,以捕捉序列中的长期依赖关系,并利用Transformer的编码器-解码器结构进行预测,通过阅读本文你可以学会利用个人数据集训练模型,在这次实战案例的讲解中我们的流程如下->

Informer模型的机制原理

Informer是一种用于长序列时间序列预测的Transformer模型,但是它与传统的Transformer模型又有些不同点,与传统的Transformer模型相比,Informer具有以下几个独特的特点:

1. ProbSparse自注意力机制:Informer引入了ProbSparse自注意力机制,该机制在时间复杂度和内存使用方面达到了O(Llog L)的水平,能够有效地捕捉序列之间的长期依赖关系。

2. 自注意力蒸馏:通过减少级联层的输入,自注意力蒸馏技术可以有效处理极长的输入序列,提高了模型处理长序列的能力。

3. 生成式解码器:Informer采用生成式解码器,可以一次性预测整个长时间序列,而不是逐步进行预测。这种方式大大提高了长序列预测的推理速度。

与LSTM技术的对比

上图展示了一个真实数据集上的预测结果,其中LSTM网络从短期(12个点,0.5天)预测电力变压器站的小时温度到长期(480个点,20天)。当预测长度大于48个点时(图1b中的实心星号),整体性能差距显著,均方误差升高,推理速度急剧下降,LSTM模型开始失效。

总结:这里说明了传统的时间序列预测对于长期预测效果不是很好大家如果想看LSTM的预测效果可以看我的往期博客里面有各种类型的LSTM讲解

图解LSTM的机制原理

 

上图为Informer模型概述:左侧:编码器接收大规模的长序列输入(绿色序列)。我们使用提出的ProbSparse自注意力替代传统的自注意力。蓝色梯形表示自注意力蒸馏操作,用于提取主导的注意力,大幅减小网络大小。层堆叠的副本增加了模型的稳健性。右侧:解码器接收长序列输入,将目标元素填充为零,测量特征图的加权注意力组合,并以生成式风格即时预测输出元素(橙色序列)

总结:Informer模型,成功提高了在LSTF问题中的预测能力,验证了类似Transformer的模型在捕捉长序列时间序列输出和输入之间的个体长期依赖关系方面的潜在价值。

  • 提出了ProbSparse自注意力机制,以高效地替代传统的自注意力机制,
  • 提出了自注意力蒸馏操作,可优化J个堆叠层中主导的注意力得分,并将总空间复杂度大幅降低。
  • 提出了生成式风格的解码器,只需要一步前向传播即可获得长序列输出,同时避免在推理阶段累积误差的传播。

数据集介绍

本文我们用到的数据集是一个油温数监控数据集,其以小时为单位,具有八列数据,其中第一个列为时间,其余七列数据为特征,我们主要预测的是其中油温OT列,数据集部分截图如下->

项目结构

项目结构如下图所示,其中main_informer.py文件为程序入口。

模型参数讲解以及Bug修复

main_informer.py的参数讲解如下->

参数讲解

参数名称参数类型参数讲解
0modelstr这是一个用于实验的参数设置,其中包含了三个选项: informer, informerstack, informerlight。根据实验需求,可以选择其中之一来进行实验,默认是使用informer模型。
1datastr数据,这个并不是你理解的你的数据集文件,而是你想要用官方定义的方法还是你自己的数据集进行定义数据加载器,如果是自己的数据集就输入custom
2root_pathstr这个才是你文件的路径,不要到具体的文件,到目录级别即可。
3data_pathstr这个填写你文件的名称。
4featuresstr这个是特征有三个选项M,MS,S。分别是多元预测多元,多元预测单元,单元预测单元。
5targetstr这个是你数据集中你想要预测那一列数据,假设我预测的是油温OT列就输入OT即可。
6freqstr时间的间隔,你数据集每一条数据之间的时间间隔。
7checkpointsstr训练出来的模型保存路径
8seq_lenint用过去的多少条数据来预测未来的数据
9label_lenint可以裂解为更高的权重占比的部分要小于seq_len
10pred_lenint预测未来多少个时间点的数据
11enc_inint你数据有多少列,要减去时间那一列,这里我是输入8列数据但是有一列是时间所以就填写7
12dec_inint同上
13c_outint这里有一些不同如果你的features填写的是M那么和上面就一样,如果填写的MS那么这里要输入1因为你的输出只有一列数据。
14d_modelint用于设置模型的维度,默认值为512。可以根据需要调整该参数的数值来改变模型的维度
15n_headsint用于设置模型中的注意力头数。默认值为8,表示模型会使用8个注意力头,我建议和的输入数据的总体保持一致,列如我输入的是8列数据不用刨去时间的那一列就输入8即可。
16e_layersint用于设置编码器的层数
17d_layersint用于设置解码器的层数
18s_layersstr用于设置堆叠编码器的层数
19d_ffint模型中全连接网络(FCN)的维度,默认值为2048
20factorint ProbSparse自注意力中的因子,默认值为5
21paddingint填充类型,默认值为0,这个应该大家都理解,如果不够数据就填写0.
22distilbool是否在编码器中使用蒸馏操作。使用--distil参数表示不使用蒸馏操作,默认为True也是我们的论文中比较重要的一个改进。
23dropoutfloat这个应该都理解不说了,丢弃的概率,防止过拟合的。
24attnstr编码器中使用的注意力类型,默认为"prob"我们论文的主要改进点,提出的注意力机制。
25embedstr时间特征的编码方式,默认为"timeF"
26activationstr激活函数
27output_attentionbool是否在编码器中输出注意力,默认为False
28do_predictbool是否进行预测,这里模型中没有给添加算是一个小bug我们需要填写一个default=True在其中。
29mixbool在生成式解码器中是否使用混合注意力,默认为True
30colsstr从数据文件中选择特定的列作为输入特征,应该用不到
31num_workersint线程windows大家最好设置成0否则会报线程错误,linux系统随便设置。
32itrint实验运行的次数,默认为2,我们这里改成数字1.
33train_epochsint训练的次数
34batch_sizeint一次往模型力输入多少条数据
35patienceint早停机制,如果损失多少个epochs没有改变就停止训练。
36learning_ratefloat学习率。
37desstr        实验描述,默认为"test"
38lossstr     损失函数,默认为"mse"
39lradjstr     学习率的调整方式,默认为"type1"
40use_ampbool混合精度训练,
41inversebool我们的数据输入之前会被进行归一化处理,这里默认为False,算是一个小bug因为输出的数据模型没有给我们转化成我们的数据,我们要改成True。
42use_gpubool是否使用GPU训练,根据自身来选择
43gpuintGPU的编号
44use_multi_gpubool是否使用多个GPU训练。
45devicesstrGPU的编号

Bug修复 

其中定义了许多参数,在其中存在一些bug有如下的->

main_informer.py: error: the following arguments are required: --model, --data

这个bug是因为头两行参数的,中的required=True导致的,我们将其删除掉即可。

parser.add_argument('--model', type=str, required=True, default='informer',help='model of experiment, options: [informer, informerstack, informerlight(TBD)]')

parser.add_argument('--data', type=str, required=True, default='ETTh1', help='data')

删除完以后如下-> 

parser.add_argument('--model', type=str, default='informer',help='model of experiment, options: [informer, informerstack, informerlight(TBD)]')

parser.add_argument('--data', type=str, default='ETTh1', help='data')

过程中还有些bug在参数讲解的描述中我都讲述了该如何解决,希望能够帮助到大家。

模型训练

到这里参数已经完全讲解完了,bug也解决了我们可以开始进行模型训练了。我修改完训练的main_informer.py内容如下。

import argparse

import torch

from exp.exp_informer import Exp_Informer

parser = argparse.ArgumentParser(description='[Informer] Long Sequences Forecasting')

parser.add_argument('--model', type=str, default='informer',
                    help='model of experiment, options: [informer, informerstack, informerlight(TBD)]')

parser.add_argument('--data', type=str, default='custom', help='data')
parser.add_argument('--root_path', type=str, default='', help='root path of the data file')
parser.add_argument('--data_path', type=str, default='ETTh1.csv', help='data file')
parser.add_argument('--features', type=str, default='M',
                    help='forecasting task, options:[M, S, MS]; M:multivariate predict multivariate, S:univariate predict univariate, MS:multivariate predict univariate')
parser.add_argument('--target', type=str, default='OT', help='target feature in S or MS task')
parser.add_argument('--freq', type=str, default='h',
                    help='freq 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', type=str, default='./checkpoints/', help='location of model checkpoints')

parser.add_argument('--seq_len', type=int, default=96, help='input sequence length of Informer encoder')
parser.add_argument('--label_len', type=int, default=48, help='start token length of Informer decoder')
parser.add_argument('--pred_len', type=int, default=24, help='prediction sequence length')
# Informer decoder input: concat[start token series(label_len), zero padding series(pred_len)]

parser.add_argument('--enc_in', type=int, default=7, help='encoder input size')
parser.add_argument('--dec_in', type=int, default=7, help='decoder input size')
parser.add_argument('--c_out', type=int, default=7, help='output size')
parser.add_argument('--d_model', type=int, default=512, help='dimension of model')
parser.add_argument('--n_heads', type=int, default=8, help='num of heads')
parser.add_argument('--e_layers', type=int, default=2, help='num of encoder layers')
parser.add_argument('--d_layers', type=int, default=1, help='num of decoder layers')
parser.add_argument('--s_layers', type=str, default='3,2,1', help='num of stack encoder layers')
parser.add_argument('--d_ff', type=int, default=2048, help='dimension of fcn')
parser.add_argument('--factor', type=int, default=5, help='probsparse attn factor')
parser.add_argument('--padding', type=int, default=0, help='padding type')
parser.add_argument('--distil', action='store_false',
                    help='whether to use distilling in encoder, using this argument means not using distilling',
                    default=True)
parser.add_argument('--dropout', type=float, default=0.05, help='dropout')
parser.add_argument('--attn', type=str, default='prob', help='attention used in encoder, options:[prob, full]')
parser.add_argument('--embed', type=str, default='timeF',
                    help='time features encoding, options:[timeF, fixed, learned]')
parser.add_argument('--activation', type=str, default='gelu', help='activation')
parser.add_argument('--output_attention', action='store_true', help='whether to output attention in ecoder')
parser.add_argument('--do_predict', action='store_true', help='whether to predict unseen future data', default=True)
parser.add_argument('--mix', action='store_false', help='use mix attention in generative decoder', default=True)
parser.add_argument('--cols', type=str, nargs='+', help='certain cols from the data files as the input features')
parser.add_argument('--num_workers', type=int, default=0, help='data loader num workers')
parser.add_argument('--itr', type=int, default=1, help='experiments times')
parser.add_argument('--train_epochs', type=int, default=6, help='train epochs')
parser.add_argument('--batch_size', type=int, default=32, help='batch size of train input data')
parser.add_argument('--patience', type=int, default=3, help='early stopping patience')
parser.add_argument('--learning_rate', type=float, default=0.0001, help='optimizer learning rate')
parser.add_argument('--des', type=str, default='test', help='exp description')
parser.add_argument('--loss', type=str, default='mse', help='loss function')
parser.add_argument('--lradj', type=str, default='type1', help='adjust learning rate')
parser.add_argument('--use_amp', action='store_true', help='use automatic mixed precision training', default=False)
parser.add_argument('--inverse', action='store_true', help='inverse output data', default=True)

parser.add_argument('--use_gpu', type=bool, default=True, help='use gpu')
parser.add_argument('--gpu', type=int, default=0, help='gpu')
parser.add_argument('--use_multi_gpu', action='store_true', help='use multiple gpus', default=False)
parser.add_argument('--devices', type=str, default='0,1,2,3', help='device ids of multile gpus')

args = parser.parse_args()

args.use_gpu = True if torch.cuda.is_available() and args.use_gpu else False

if 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': '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]},
}

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_Informer

for ii in range(args.itr):
    # setting record of experiments
    setting = '{}_{}_ft{}_sl{}_ll{}_pl{}_dm{}_nh{}_el{}_dl{}_df{}_at{}_fc{}_eb{}_dt{}_mx{}_{}_{}'.format(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 experiments
    print('>>>>>>>start training : {}>>>>>>>>>>>>>>>>>>>>>>>>>>'.format(setting))
    exp.train(setting)

    print('>>>>>>>testing : {}<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<'.format(setting))
    exp.test(setting)

    if args.do_predict:
        print('>>>>>>>predicting : {}<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<'.format(setting))
        exp.predict(setting, True)

    torch.cuda.empty_cache()

我们运行该文件,控制台就会开始输出进行训练。

训练出来的模型会保存在该目录下->其中的pth文件就是保存下来的模型。

结果预测

训练完成之后,我们就可以开始预测了,这里的官方Informer模型的预测结果会自动保存成npy文件,他需要输入np库才能查看,代码如下->

import numpy as np

# 指定.npy文件路径
file_path = "results/informer_custom_ftM_sl96_ll48_pl24_dm512_nh8_el2_dl1_df2048_atprob_fc5_ebtimeF_dtTrue_mxTrue_test_0/real_prediction.npy"

# 使用NumPy加载.npy文件
data = np.load(file_path)

# 打印文件内容
print(data)

真实值保存的结果会在该文件下->

我这里进行了一个修改版,把你生成的真实值和预测值生成一个csv文件方便我们观察。

import numpy as np
import pandas as pd
# 指定.npy文件路径
file_path1 = "results/informer_custom_ftM_sl96_ll48_pl24_dm512_nh8_el2_dl1_df2048_atprob_fc5_ebtimeF_dtTrue_mxTrue_test_0/real_prediction.npy"
file_path2 = "results/informer_custom_ftM_sl96_ll48_pl24_dm512_nh8_el2_dl1_df2048_atprob_fc5_ebtimeF_dtTrue_mxTrue_test_0/pred.npy"

# 使用NumPy加载.npy文件
true_value = []
pred_value = []

data1 = np.load(file_path1)
data2 = np.load(file_path2)
print(data2)
for i in range(24):
    true_value.append(data2[0][i][6])
    pred_value.append(data1[0][i][6])

# 打印内容
print(true_value)
print(pred_value)

df = pd.DataFrame({'real': true_value, 'pred': pred_value})

df.to_csv('results.csv', index=False)

我们生成了results.csv文件以后就可以利用绘图工具进行结果展示,当然你也可以用matplotlib绘图出来我这里因为习惯性的要给上级汇报所以一般就用绘图软件画,下面是预测值和真实值之间的对比。 

如何训练你自己的数据集

上面介绍了用我的数据集训练模型,那么大家在利用模型的时候如何训练自己的数据集呢这里给家介绍一下需要修改的几处地方。

parser.add_argument('--data', type=str, default='custom', help='data')
parser.add_argument('--root_path', type=str, default='', help='root path of the data file')
parser.add_argument('--data_path', type=str, default='ETTh1.csv', help='data file')
parser.add_argument('--features', type=str, default='MS',
                    help='forecasting task, options:[M, S, MS]; M:multivariate predict multivariate, S:univariate predict univariate, MS:multivariate predict univariate')
parser.add_argument('--target', type=str, default='OT', help='target feature in S or MS task')
parser.add_argument('--freq', type=str, default='h',

首先需要修改的就是上面这几处,

  • 其中data必须填写custom,
  • root_path填写文件夹即可,
  • data_path填写具体的文件在你文件夹下面,
  • features前面有讲解,具体是看你自己的数据集,我这里MS就是7列结果综合分析输出想要的那一列结果的预测值,
  • target就是你数据集中你想要知道那列的预测值的列名,
  • freq就是你两条数据之间的时间间隔。
parser.add_argument('--seq_len', type=int, default=96, help='input sequence length of Informer encoder')
parser.add_argument('--label_len', type=int, default=48, help='start token length of Informer decoder')
parser.add_argument('--pred_len', type=int, default=24, help='prediction sequence length')

然后这三个就是影响精度的地方,seq_len和label_len需要根据数据的特性来设置,要进行专业的数据分析,我会在下一周出教程希望到时候能够帮助到大家。

parser.add_argument('--enc_in', type=int, default=7, help='encoder input size')
parser.add_argument('--dec_in', type=int, default=7, help='decoder input size')
parser.add_argument('--c_out', type=int, default=7, help='output 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列输出一列。 

最后呢大家如果需要我的数据集和修改完成之后的实战代码可以在评论区留言。

总结 

到此本文的实战案例讲解部分就全部完成了,希望能够帮助到大家,在这里也给大家推荐一些我其它的博客的时间序列实战案例讲解。

时间序列预测模型实战案例(七)(TPA-LSTM)结合TPA注意力机制的LSTM实现多元预测

时间序列预测模型实战案例(六)深入理解机器学习ARIMA包括差分和相关性分析

时间序列预测模型实战案例(五)基于双向LSTM横向搭配单向LSTM进行回归问题解决

时间序列预测模型实战案例(四)(Xgboost)(Python)(机器学习)图解机制原理实现时间序列预测和分类(附一键运行代码资源下载和代码讲解)

时间序列预测模型实战案例(三)(LSTM)(Python)(深度学习)时间序列预测(包括运行代码以及代码讲解)

【全网首发】(MTS-Mixers)(Python)(Pytorch)最新由华为发布的时间序列预测模型实战案例(一)(包括代码讲解)实现企业级预测精度包括官方代码BUG修复Transform模型

时间序列预测模型实战案例(二)(Holt-Winter)(Python)结合K-折交叉验证进行时间序列预测实现企业级预测精度(包括运行代码以及代码讲解)

如果大家有不懂的也可以评论区留言一些报错什么的大家可以讨论讨论看到我也会给大家解答如何解决!

最后希望大家工作顺利学业有成!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1176518.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

麒麟操作系统登录双因素认证方案 安当加密

麒麟操作系统安全登录方案可以采取以下几种方式&#xff1a; 账户密码认证&#xff1a;用户登录时需要输入正确的账户和密码&#xff0c;账户和密码是用户登录系统的必要条件。为了保证账户和密码的安全性&#xff0c;可以采用加密算法对密码进行加密存储&#xff0c;并且限制…

CTF工具音频隐写神器MP3stego安装和详细使用方法

音频隐写MP3stego安装和详细使用方法 1.MP3stego介绍&#xff1a;2.MP3stego下载安装&#xff1a;3.MP3stego使用教程&#xff1a;4.MP3stego使用案例&#xff1a;5.MP3stego总结&#xff1a; 1.MP3stego介绍&#xff1a; MP3stego是一个在通用的MP3音频文件中隐写的软件&…

1. Collection,List, Map, Queue

1. java集合框架体系结构图 2. Collection派生的子接口 其中最重要的子接口是&#xff1a; 1&#xff09;List 表示有序可重复列表&#xff0c;重要的实现类有&#xff1a;ArrayList, LinkedList ArrayList特点&#xff1a;底层数组实现&#xff0c;随机查找快&#xff0c;增删…

【FastCAE源码阅读4】VTK OrientationMarkerWidget方向标记组件的使用

FastCAE前处理窗口有个方向指示的组件&#xff0c;会跟踪场景进行旋转&#xff0c;这种设计在很多三维软件都有类似的设计&#xff0c;效果如下图&#xff1a; FastCAE采用的是VTK自带的vtkOrientationMarkerWidget实现的&#xff0c;具体代码如下&#xff1a; void Graph3D…

Springboot在线考试系统 毕业设计-附源码82626

Springboot在线考试系统 摘 要 信息化社会内需要与之针对性的信息获取途径&#xff0c;但是途径的扩展基本上为人们所努力的方向&#xff0c;由于站在的角度存在偏差&#xff0c;人们经常能够获得不同类型信息&#xff0c;这也是技术最为难以攻克的课题。针对在线考试等问题&am…

基于Pytorch框架的LSTM算法(一)——单维度单步滚动预测(2)

#项目说明&#xff1a; 说明&#xff1a;1time_steps滚动预测代码 y_norm scaler.fit_transform(y.reshape(-1, 1)) y_norm torch.FloatTensor(y_norm).view(-1)# 重新预测 window_size 12 future 12 L len(y)首先对模型进行训练&#xff1b; 然后选择所有数据的后wind…

“利用义乌购API揭秘跨境贸易商机:一键获取海量优质商品列表!“

义乌购API可以根据关键词取商品列表。通过调用义乌购API的item_search接口&#xff0c;传入关键词参数&#xff0c;可以获取到符合该关键词的商品列表。 以下是使用义乌购API根据关键词取商品列表的步骤&#xff1a; 注册义乌购开发者账号并获取授权码和密钥。在代码中导入义…

SAP-MM-定义计量单位组

业务场景&#xff1a; 有些物料的计量单位是相同的&#xff0c;为了快速维护物料的计量单位的转换关系&#xff0c;可以创建计量单位组&#xff0c;输入转换关系时&#xff0c;输入组就可以直接转换&#xff0c;不需要单个维护 SPRO-后勤常规-物料主数据-设置关键字段-定义计…

享搭低代码平台:快速构建符合需求的进销存管理系统应用

本文介绍了享搭低代码平台如何赋予用户快速构建进销存管理系统应用的能力。通过在应用商店安装费用进销存管理模板&#xff0c;并通过拖拽方式对模板进行自定义扩充&#xff0c;用户可以快速搭建符合自身需求的进销存管理系统&#xff0c;从而提高管理效率和优化运营。 介绍低代…

shopee、亚马逊卖家如何安全给自己店铺测评?稳定测评环境是关键

大家都知道通过测评可以提升产品的转化率&#xff0c;提升产品的销量&#xff0c;那么做跨境平台的卖家如何安全的给自己店铺测评呢&#xff1f; 无论是亚马逊、拼多多Temu、shopee、Lazada、wish、速卖通、敦煌网、Wayfair、雅虎、eBay、Newegg、乐天、美客多、阿里国际、沃尔…

进销存管理系统如何提高供应链效率?

供应链和进销存系统之间有着密切的联系。进销存系统是供应链管理的一部分&#xff0c;用于跟踪和管理产品的采购、库存和销售。进销存管理是供应链管理的核心流程之一&#xff0c;它有助于提高效率、降低成本、增加盈利&#xff0c;同时确保客户满意度&#xff0c;这对于企业的…

HackTheBox-Starting Point--Tier 1---Ignition

文章目录 一 题目二 实验过程 一 题目 Tags Web、Common Applications、Magento、Reconnaissance、Web Site Structure Discovery、Weak Credentials译文&#xff1a;Web、常见应用、Magento、侦察、网站结构发现、凭证薄弱Connect To attack the target machine, you must …

Docker安装Minio(稳定版)

1、安装 docker pull minio/minio:RELEASE.2021-06-17T00-10-46Z docker run -p 9000:9000 minio/minio:RELEASE.2021-06-17T00-10-46Z server /data 2、访问测试 3、MinIO自定义Access和Secret密钥 要覆盖MinIO的自动生成的密钥&#xff0c;您可以将Access和Secret密钥设为…

干货分享 | 3D WEB轻量化引擎HOOPS Communicator如何读取复杂大模型文件?

HOOPS Communicator是一款简单而强大的工业级高性能3D Web可视化开发包&#xff0c;其主要应用于Web领域&#xff0c;主要加载其专有的SCS、SC、SCZ格式文件&#xff1b;HOOPS还拥有另一个桌面端开发包HOOPS Visualize&#xff0c;主要加载HSF、HMF轻量化格式文件。 两者虽然同…

面向有连接型和面向无连接型

文章目录 面向有连接型和面向无连接型面向有连接型面向无连接型 面向有连接型和面向无连接型 通过网络发送数据&#xff0c;大致可以分为面向有连接与面向无连接两种类型&#xff0c;如下图&#xff1a; 面向有连接型 面向有连接型中&#xff0c;在发送数据之前&#xff0c…

Python Slice函数:数据处理利器详解

引言&#xff1a; 在Python编程中&#xff0c;处理数据是一个非常常见且重要的任务。为了更高效地处理数据&#xff0c;Python提供了许多内置函数和方法。其中&#xff0c;slice()函数是一个非常强大且常用的工具&#xff0c;它可以帮助我们轻松地提取、操作和处理数据。无论是…

无效的标记: --release

一、错误提示&#xff1a; 无效的标记: --release 二、原因 使用的 jdk 版本与所需 jdk 版本不符 三、解决&#xff1a; 1、先排除是否是JDK与SpringBoot的版本不一致导致的&#xff1a;如JDK1.8和SpringBoot3.1.5冲突&#xff1b; 2、检查调整Java编译版本 3、检查Maven环…

MTK 拨打紧急电话接通时间过长问题分析

1、问题分析 从Log视频来看&#xff0c;通话接通时间过长&#xff0c;但是Modem Log来看&#xff0c;进行多两次拨号。 查看AP代码确实进行了两次拨号 AP界面查看确实只有一路通话 查看MTK原始代码&#xff0c;发现当紧急拨号失败后&#xff0c;上层换卡重试&#xff0c;界面不…

yolov8模型训练、目标跟踪

一、准备条件 1.下载yolov8 https://github.com/ultralytics/ultralytics2.安装python https://www.python.org/ftp/python/3.8.0/python-3.8.0-amd64.exe3.安装依赖 进入ultralytics-main&#xff0c;执行&#xff1a; pip install -r requirements.txt pip install -U ul…

chrome 防止http自动转https的方法

1. 左上角&#xff0c;单击地址栏左边 2. 然后点击网站设置 3. 不安全内容改为【允许】 4. 然后以后访问此网站时&#xff0c;就不会再自动跳转为https了