当前位置: 首页 > 科技观察

DeepTime-AMeta-LearningModelinTimeSeriesForecasting

时间:2023-03-13 12:52:06 科技观察

DeepTime,是一种结合元学习的深度时间指数模型。通过对时间序列中的常见问题(协变量偏移和条件分布偏移-非平稳)使用元学习公式来预测未来。该模型是时间序列预测的元学习公式协同作用的一个很好的例子。DeepTimeArchitectureDeepTimeComponentsDeepTime中一共有三种层:岭回归多层感知器(MLP)随机傅里叶特征让我们看看这些层在做什么:岭回归多层感知器(MLP)这些是在神经网络中使用的线性回归公式(nn)。然后使用ReLU函数进行激活。这些层非常适合将时间索引映射到该时间索引的时间序列值。公式如下:StochasticFourierLayerStochasticFourier允许mlp学习高频模式。尽管随机傅立叶层需要为每个任务和数据集找到不同的超参数(只是为了不过度拟合或欠拟合),作者通过将各种傅立叶基函数与各种尺度参数相结合来限制这种计算来实现这一点。DeepTIMEArchitecture在每个任务中,选择一个时间序列,然后将其分为两部分,骨干窗口(绿色)和预测窗口(蓝色)。然后,他们通过两个相互共享信息并与元参数相关联的元模型。在上述架构上训练模型后,计算损失函数并尝试使其最小化。与其他时间序列预测模型的区别DeepTIME是一个时间指标模型,就像Prophet、Gaussian过程等,而最近比较突出的模型如N-HiTS、Autoformer、DeepAR、Informer等都是历史价值模型。当我们说时间序列的时间指数模型时,我们的确切意思是预测绝对随时间变化(它考虑了当前的时间指数特征)。另一方面,历史价值模型使用以前的事件来预测未来。这个公式会让你更清楚。:)它包括元学习公式,这意味着模型可以学习如何学习。由于它是一个时间指数模型,它可以在元学习中表现出更好的样本效率。它使用直接多步估计(DMS)的方法(DMS模型一次直接预测几个数据点)。还有多步迭代(IMS),它只预测下一个值,然后用它来预测下一个数据点,这和ARIMA、DeepAR等是一样的。元学习给时间序列预测带来了什么?更好的任务泛化与附近时间步遵循局部平稳分布的假设一致。还包括一个假设,即相似的时间点将具有相似的特征。模型如何预测在每次训练过程中,数据被分成两个窗口(通过使用第一个窗口来预测第二个窗口)。这里,为简单起见,使用PyTorchLightning来简化训练过程。导入numpy作为np导入gin导入pytorch_lightning作为pl从模型导入get_model导入随机导入火炬导入torch.nn.functionalasF从火炬导入optim从utils导入数学从utils导入检查点,default_device,to_tensor@gin.configurable类DeepTimeTrainer(pl.LightningModule):def__init__(self,lr,lambda_lr,weight_decay,warmup_epochs,random_seed,T_max,eta_min,dim_size,datetime_feats,):gin.parse_config_file('/home/reza/Projects/PL_DeepTime/DeepTime/config/config.gin')super(DeepTimeTrainer,self).__init__()self.lr=lrself.lambda_lr=lambda_lrself.weight_decay=weight_decayself.warmup_epochs=warmup_epochsself.random_seed=random_seedself.lr=lrself.lambda_lr=lambda_lrself.weight_decay=weight_decayself.T_max=T_maxself.warmup_epochs=warmup_epochsself.eta_min=eta_minself.model=get_model(model_type='deeptime',dim_size=dim_size,datetime_feats=datetime_feats)defon_fit_start(self):火炬.manual_seed(self.random_seed)np.random.seed(self.random_seed)random.seed(self.random_seed)deftraining_step(self,batch,batch_idx):x,y,x_time,y_time=map(to_tensor,batch)预测=self.model(x,x_time,y_time)ifisinstance(forecast,tuple):#对于需要重建的模型+预测损失loss=F.mse_loss(forecast[0],x)+\F.mse_loss(forecast[1],y)else:loss=F.mse_loss(forecast,y)self.log('train_loss',loss,prog_bar=True,on_epoch=True)return{'loss':loss,'train_loss':loss,}deftraining_epoch_end(self,outputs):avg_train_loss=torch.stack([x["train_loss"]forxinoutputs]).mean()self.log('avg_train_loss',avg_train_loss,on_epoch=True,sync_dist=True)defvalidation_step(self,batch,batch_idx):x,y,x_time,y_time=map(to_tensor,batch)forecast=self.model(x,x_time,y_time)如果是实例(forecast,tuple):#对于需要重建的模型+预测损失loss=F.mse_loss(forecast[0],x)+\F.mse_loss(forecast[1],y)else:loss=F.mse_loss(forecast,y)self.log('val_loss',loss,prog_bar=True,on_epoch=True)return{'val_loss':loss}defvalidation_epoch_end(self,outputs):返回输出deftest_step(self,batch,batch_idx):x,y,x_time,y_time=map(to_tensor,batch)forecast=self.model(x,x_time,y_time)ifisinstance(forecast,tuple):#对于需要重建的模型+预测损失loss=F.mse_loss(forecast[0],x)+\F.mse_loss(forecast[1],y)else:loss=F.mse_loss(forecast,y)self.log('test_loss',loss,prog_bar=True,on_epoch=True)return{'test_loss':loss}deftest_epoch_end(self,outputs):返回输出@gin.configurabledefconfigure_optimizers(self):group1=[]#lambdagroup2=[]#nodecaygroup3=[]#decayno_decay_list=('bias','norm',)forparam_name,paraminself.model.named_pa??rameters():ifparam_name中的“_lambda”:group1.append(param)elifany([modinparam_nameformodinno_decay_list]):group2.append(param)else:group3.append(param)optimizer=optim.Adam([{'params':group1,'weight_decay':0,'lr':self.lambda_lr,'scheduler':'cosine_annealing'},{'params':group2,'weight_decay':0,'scheduler':'cosine_annealing_with_linear_warmup'},{'params':group3,'scheduler':'cosine_annealing_with_linear_warmup'}],lr=self.lr,weight_decay=self.weight_decay)scheduler_fns=[]forparam_groupinoptimizer.param_groups:scheduler=param_group['scheduler']ifscheduler=='none':fn=lambdaT_cur:1elifscheduler=='cosine_annealing':lr=eta_max=param_group['lr']fn=lambdaT_cur:(self.eta_min+0.5*(eta_max-self.eta_min)*(1.0+math.cos((T_cur-self.warmup_epochs)/(self.T_max-self.warmup_epochs)*math.pi)))/lrelifscheduler=='cosine_annealing_with_linear_warmup':lr=eta_max=param_group['lr']fn=lambdaT_cur:T_cur/self.warmup_epochsifT_cur0:forecasting_mask[:,0,-self.n_time_out:]=0Y,Y_hat,z=self.model(Y=Y,mask=forecasting_mask,idxs=None,z_0=z_0)如果self.n_time_out>0:Y=Y[:,:,-self.n_time_out:]Y_hat=Y_hat[:,:,-self.n_time_out:]sample_mask=sample_mask[:,:,-self.n_time_out:]返回Y,Y_hat,sample_mask,z合成作者在数据集和真实世界数据集上进行的大量实验表明,DeepTime具有非常有竞争力的性能,在基于MSE的多变量预测基准上进行的24次实验中有20次取得了最先进的结果。看看源代码:https://github.com/salesforce/DeepTime