找回密码
 会员注册
查看: 34|回复: 0

Time-LLM:为时间序列预测重新编程LLM探索Time-LLM的架构,并在Python中将其应用于预测项目

[复制链接]

5

主题

0

回帖

16

积分

新手上路

积分
16
发表于 2024-9-10 11:06:30 | 显示全部楼层 |阅读模式
参考资料:Time-LLM/ReprogramanLLMforTimeSeriesForecasting.md文章目录探索Time-LLM输入补丁化重新编程层使用提示前缀增强输入输出投影使用Time-LLM进行预测在neuralforecast中扩展Time-LLM使用Time-LLM进行预测使用N-BEATS和MLP进行预测我对Time-LLM的看法结论参考文献研究人员尝试将自然语言处理(NLP)技术应用于时间序列领域并非首次。例如,Transformer架构在NLP领域是一个重要的里程碑,但其在时间序列预测方面的表现一直平平,直到PatchTST的提出。正如您所知,大型语言模型(LLMs)正在积极开发,并在NLP领域展示出令人印象深刻的泛化和推理能力。因此,值得探索将LLM重新用于时间序列预测的想法,以便我们可以从这些大型预训练模型的能力中受益。为此,Time-LLM被提出。在原始论文中,研究人员提出了一个框架,重新编程现有的LLM以执行时间序列预测。在本文中,我们将探讨Time-LLM的架构以及它如何有效地使LLM能够预测时间序列数据。然后,我们将实现该模型并将其应用于一个小型预测项目。要了解更多详情,请务必阅读原始论文。让我们开始吧!探索Time-LLMTime-LLM更应被视为一个框架,而不是一个具有特定架构的实际模型。Time-LLM的一般结构如下所示。Time-LLM的一般结构。图片由M.Jin,S.Wang,L.Ma,Z.Chu,J.Zhang,X.Shi,P.Chen,Y.Liang,Y.Li,S.Pan,Q.Wen提供,来源为Time-LLM:TimeSeriesForecastingbyReprogrammingLargeLanguageModelsTime-LLM的整个理念是重新编程一个嵌入可见的语言基础模型,如LLaMA或GPT-2。请注意,这与微调LLM是不同的。相反,我们教导LLM接受一系列时间步的输入,并在一定的时间范围内输出预测。这意味着LLM本身保持不变。在高层次上,Time-LLM首先通过自定义的补丁嵌入层对输入时间序列序列进行标记化。然后,这些补丁通过一个重新编程层,将预测任务本质上转化为语言任务。请注意,我们还可以传递一个提示前缀以增强模型的推理能力。最后,输出的补丁通过投影层,最终得到预测。这里有很多内容需要深入探讨,让我们更详细地探讨每个步骤。输入补丁化第一步是对输入序列进行补丁化,就像在PatchTST中一样。补丁化的可视化。这里,我们有一个包含15个时间步的序列,补丁长度为5,步长也为5,因此得到三个补丁。图片由作者提供。通过补丁化,我们的目标是通过查看一组时间步而不是单个时间步来保留局部语义信息。这样做的附加好处是大大减少了要馈送到重新编程层的标记数量。在这里,每个补丁都变成一个输入标记,因此将标记数量从L减少到大约L/S,其中L是输入序列的长度,S是步长。补丁化完成后,输入序列被发送到重新编程层。重新编程层在Time-LLM中,语言模型保持不变。现在,语言模型可以执行许多NLP任务,如情感分析、摘要和文本生成,但不能进行时间序列预测。这就是重新编程层的作用。它本质上将输入时间序列映射到一个语言任务,使我们能够利用语言模型的能力。为此,它使用受限词汇来描述每个输入补丁,如下所示。将输入补丁转换为语言任务。图片由M.Jin,S.Wang,L.Ma,Z.Chu,J.Zhang,X.Shi,P.Chen,Y.Liang,Y.Li,S.Pan,Q.Wen提供,来源为Time-LLM:TimeSeriesForecastingbyReprogrammingLargeLanguageModels在上图中,我们可以看到每个时间序列补丁是如何描述的。例如,一个补丁可以被翻译为“短期上涨然后稳步下降”。通过这种方式,我们有效地将时间序列的行为编码为自然语言输入,这正是LLM所期望的。完成此操作后,翻译后的补丁被发送到多头注意力机制,然后进行线性投影,以将重新编程的补丁的维度与LLM骨干的维度对齐。重新编程层的整体架构。图片由M.Jin,S.Wang,L.Ma,Z.Chu,J.Zhang,X.Shi,P.Chen,Y.Liang,Y.Li,S.Pan,Q.Wen提供,来源为Time-LLM:TimeSeriesForecastingbyReprogrammingLargeLanguageModels请注意,重新编程层是一个经过训练的层。我们可以决定为特定数据集对其进行训练,或者预先训练它并将Time-LLM用作零-shot预测器。现在,在翻译后的补丁实际发送到LLM之前,可以使用提示前缀来增强输入。使用提示前缀增强输入为了激活LLM的能力,我们使用一个提示,即指定LLM任务的自然语言输入。现在,即使我们传递了被翻译为自然语言的时间序列补丁,对LLM来说仍然是一个挑战进行预测。因此,研究人员建议使用提示前缀来补充补丁重新编程。提示前缀的示例。图片由M.Jin,S.Wang,L.Ma,Z.Chu,J.Zhang,X.Shi,P.Chen,Y.Liang,Y.Li,S.Pan,Q.Wen提供,来源为Time-LLM:TimeSeriesForecastingbyReprogrammingLargeLanguageModels在上图中,我们看到了一个在基准数据集ETT上的提示前缀示例。提示包含三个不同部分:数据集的一般背景任务说明输入统计信息第一个组件完全由用户定义。在这里,我们可以指定关于数据集的信息,解释其背景并写出观察结果。然后,任务说明根据预测的时间范围和系列的输入大小进行程序化设置。最后,输入统计信息也是根据输入系列自动计算的。请注意,使用快速傅里叶变换计算出了前五个滞后。简而言之,它将输入系列转换为幅度和频率的函数,并认为具有最高幅度的频率更重要。因此,在这一点上,我们有一个包含LLM上下文和说明的提示前缀,以及被发送到LLM的重新编程补丁序列,如下所示。提示前缀和重新编程补丁被发送到LLM。最后一步是线性投影以获得最终预测。图片由M.Jin,S.Wang,L.Ma,Z.Chu,J.Zhang,X.Shi,P.Chen,Y.Liang,Y.Li,S.Pan,Q.Wen提供,来源为Time-LLM:TimeSeriesForecastingbyReprogrammingLargeLanguageModels该框架的最后一步是将输出补丁嵌入通过线性投影层以获得最终预测。输出投影一旦提示前缀和重新编程补丁被发送到LLM,它将输出补丁嵌入。然后,必须将此输出展平并进行线性投影以得出最终预测,如下所示。LLM的输出补丁嵌入被展平并线性投影以获得最终预测。图片由M.Jin,S.Wang,L.Ma,Z.Chu,J.Zhang,X.Shi,P.Chen,Y.Liang,Y.Li,S.Pan,Q.Wen提供,来源为Time-LLM:TimeSeriesForecastingbyReprogrammingLargeLanguageModels总结一下通过Time-LLM的流程:首先对输入系列进行补丁化并重新编程为语言任务。我们附加一个提示前缀,指定数据的上下文,LLM的说明以及输入统计信息。将组合输入发送到LLM。输出嵌入被展平并投影以生成预测。现在我们了解了Time-LLM的内部工作原理,让我们在Python中进行一个小实验。使用Time-LLM进行预测在这个小实验中,我们将使用Time-LLM进行时间序列预测,并将其性能与其他模型(如N-HiTS和简单的多层感知器(MLP))进行比较。在开始之前,我必须提到以下几点:我将使用neuralforecast库扩展Time-LLM,因为我认为Time-LLM的原始代码库很难使用。我不是最好的提示工程师,由于Time-LLM依赖于LLM,您可能会通过更好的上下文提示获得比我更好的结果。我的时间和计算资源有限。我在单个GPU上对Time-LLM进行了100个epochs的训练。如果你有更多时间和更好的GPU,你可以训练模型更长时间,可能会获得更好的结果。这个实验的代码可以在GitHub上找到。让我们开始吧!在neuralforecast中扩展Time-LLM在这个实验中,我将在neuralforecast库中实现Time-LLM,使其比论文中的实现更易于使用和更灵活。遵循neuralforecast的贡献指南,我们首先创建一个继承自BaseWindows的TimeLLM类,该类负责解析输入时间序列的批次。然后,在__init__函数中,我们指定与Time-LLM相关的参数,然后是继承自BaseWindows的参数。classTimeLLM(BaseWindows):def__init__(self,h,input_size,patch_len:int=16,stride:int=8,d_ff:int=128,top_k:int=5,d_llm:int=768,d_model:int=32,n_heads:int=8,enc_in:int=7,dec_in:int=7,llm=None,llm_config=None,llm_tokenizer=None,llm_num_hidden_layers=32,llm_output_attention:bool=True,llm_output_hidden_states:bool=True,prompt_prefix:str=None,dropout:float=0.1,#继承自BaseWindows的参数12345678910111213141516171819202122在上面的代码块中,我们看到了用于分块的参数,以及我们希望使用的LLM的参数。与原始实现使用LLaMA不同,这个实现允许用户使用transformers库选择任何他们喜欢的LLM。然后,我们重用了原始实现的相同逻辑,但修改了forward方法以遵循neuralforecast的指导原则。defforward(self,windows_batch):insample_y=windows_batch['insample_y']x=insample_y.unsqueeze(-1)y_pred=self.forecast(x)y_pred=y_pred[:,-self.h:,:]y_pred=self.loss.domain_map(y_pred)returny_pred12345678910'运行运行在上面的代码块中,我们使用windows_batch访问输入批次并通过Time-LLM运行它。然后,我们使用self.loss.domain_map(y_pred)将输出映射到所选损失函数的域和形状。这对于模型实际训练是必要的。要查看详细的实现,可以在这里查看(该实现仍在积极开发中,因此在您阅读此内容时可能会发生变化)。然后,我们只需将模型添加到适当的init文件中,然后运行pipinstall.即可访问新模型。就这样,我们现在可以在neuralforecast中使用Time-LLM了。使用Time-LLM进行预测现在我们准备使用Time-LLM进行预测。在这里,我们使用简单的航空乘客数据集。首先,让我们导入所需的库。importtimeimportnumpyasnpimportpandasaspdimportpytorch_lightningasplimportmatplotlib.pyplotaspltfromneuralforecastimportNeuralForecastfromneuralforecast.modelsimportTimeLLMfromneuralforecast.losses.pytorchimportMAEfromneuralforecast.tsdatasetimportTimeSeriesDatasetfromneuralforecast.utilsimportAirPassengers,AirPassengersPanel,AirPassengersStatic,augment_calendar_dffromtransformersimportGPT2Config,GPT2Model,GPT2Tokenizer12345678910111213然后,我们加载数据集,这个数据集方便地包含在neuralforecast中。AirPassengersPanel,calendar_cols=augment_calendar_df(df=AirPassengersPanel,freq='M')Y_train_df=AirPassengersPanel[AirPassengersPanel.ds
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 会员注册

本版积分规则

QQ|手机版|心飞设计-版权所有:微度网络信息技术服务中心 ( 鲁ICP备17032091号-12 )|网站地图

GMT+8, 2025-1-5 09:25 , Processed in 0.703874 second(s), 34 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

快速回复 返回顶部 返回列表