ARTICLE DETAIL

资讯详情

深耕网站建设与运营推广的一线实战洞察。

15个Transformer时序预测模型代码实战:从Informer到iTransformer统一跑通与横向对比

15个Transformer时序预测模型代码实战:从Informer到iTransformer统一跑通与横向对比 简介这份资源面向从事时间序列预测与分类研究的高校学生、算法工程师及科研人员系统汇总了15个基于Transformer的经典与前沿模型代码涵盖Autoformer、PEDformer、Informer、Crossformer、ETSformer、Pyraformer、TimesNet、Reformer、DLinear等可解决长序列建模中效率与精度难以兼顾的问题适用于电力负荷、ETT油温、外汇、病情、交通车流量、天气等多场景实验复现与对比研究。压缩包共1378个文件约182.2MB其中137个py源码构成各算法核心实现228个sh脚本便于批量训练与参数配置774个pdf提供论文与说明文档另有csv、npy数据集及ipynb、md等辅助文件目录按算法与数据集分类清晰。目前已有3466人学习下载读者可一次性获得完整模型代码、训练脚本、数据接口与实验配置快速搭建基线并开展消融与对比实验显著降低复现成本。1. 长时间序列预测的代码困局为什么15个Transformer变体值得你逐个跑一遍做电力负荷预测、气象时序建模或者交通流量分析的朋友大概率都经历过这样的场景论文里看到Autoformer的分解机制很优雅PEDformer的频域增强听起来也合理Informer的稀疏注意力号称把复杂度从O(L²)压到了O(L log L)但真到动手的时候光是让这些模型的输入输出维度对齐就要折腾一整天。更别提每个仓库的配置格式、数据预处理方式、评估指标实现都不一样想横向对比几乎等于重写一遍。长时间序列预测这个方向从2021年Informer开始到Autoformer、FEDformer、PEDformer、Crossformer、iTransformer等前后涌现了十几个有代表性的Transformer变体。它们各自解决不同的问题有的是注意力机制太慢有的是长周期依赖捕捉不住有的是多变量之间的耦合关系没建模好。把这些代码汇总在一起逐个跑通不是为了刷榜而是为了搞清楚——在你的数据上到底哪个架构的归纳偏置最匹配。这篇文章面向的是已经了解Transformer基本结构、想快速上手时序预测代码的工程师和研究生。我会把15个算法的代码组织方式、环境配置、数据格式、关键参数和常见翻车点讲清楚让你能在本地把这条流水线跑起来。2. 15个时序Transformer算法的代码组织与核心差异2.1 这些模型到底在改什么从注意力机制到分解策略先把这15个算法按改进思路分个类这样你在读代码的时候能快速定位到关键模块。第一类是注意力效率优化。Informer提出ProbSparse注意力只计算top-k重要的query-key对把内存和时间降到O(L log L)。Pyraformer用金字塔式注意力在不同尺度上做粗粒度到细粒度的信息传递。这类模型适合序列长度超过1000步的场景比如分钟级电力数据预测未来24小时。第二类是序列分解与频域增强。Autoformer的核心是串联的序列分解块把输入拆成趋势项和季节项分别建模。FEDformer在此基础上引入傅里叶变换和 wavelet 变换在频域做注意力计算进一步降低复杂度。PEDformer则结合了渐进式分解和多尺度特征提取。这三个模型在周期性强的数据上表现突出比如日负荷曲线、交通流量。第三类是变量间关系建模。Crossformer用两阶段注意力分别捕捉时间维和变量维的依赖。iTransformer干脆把每个变量的整条序列当作一个token直接在变量维度做注意力。这类模型适合多变量强耦合的场景比如气象站的多传感器数据。第四类是架构简化与泛化。有些工作发现把Transformer的注意力换成简单的线性层或者MLP效果未必差。这类模型代码更轻量训练更快适合作为baseline。理解了这个分类你在看每个仓库的model.py时就能直接跳到核心模块不用从头读起。2.2 代码目录的统一组织方式这15个算法的原始仓库结构各不相同但核心文件基本一致。我一般会按下面的结构重新组织方便统一调用ts_transformer_zoo/ ├── data_provider/ │ ├── data_loader.py # 数据集加载与切分 │ └── data_factory.py # 数据集注册与实例化 ├── models/ │ ├── Autoformer.py │ ├── PEDformer.py │ ├── Informer.py │ ├── FEDformer.py │ ├── Crossformer.py │ ├── iTransformer.py │ └── ... # 其余模型 ├── layers/ │ ├── Embed.py # 位置编码、时间特征嵌入 │ ├── SelfAttention.py # 各种注意力实现 │ ├── AutoCorrelation.py # Autoformer的自相关机制 │ └── FourierBlock.py # 频域注意力模块 ├── exp/ │ ├── exp_main.py # 训练与评估主流程 │ └── exp_basic.py # 基础实验类 ├── utils/ │ ├── metrics.py # MAE, MSE, RMSE │ ├── tools.py # 早停、学习率调整 │ └── timefeatures.py # 时间特征生成 ├── scripts/ │ ├── Autoformer.sh │ ├── Informer.sh │ └── ... └── run.py # 统一入口这个结构参考了Time-Series-Library的组织方式但做了简化。关键点是所有模型共享同一套数据加载和训练流程每个模型只需要实现自己的forward逻辑。这样你换模型只需要改一个参数不用动数据管道。数据加载部分data_loader.py需要处理几种标准格式.csv文件、.npy数组、以及.txt文本。核心是Dataset类它负责把原始序列切分成[batch, seq_len, features]的输入和[batch, pred_len, features]的标签。时间特征小时、星期、月份通过timefeatures.py生成拼接到输入中。# data_provider/data_loader.py import numpy as np import pandas as pd from torch.utils.data import Dataset class TimeSeriesDataset(Dataset): def __init__(self, root_path, flagtrain, sizeNone, featuresS, data_pathETTh1.csv, targetOT, scaleTrue, timeenc1): # size [seq_len, label_len, pred_len] self.seq_len size[0] self.label_len size[1] self.pred_len size[2] self.flag flag self.target target self.scale scale self.timeenc timeenc # 读取数据常见做法是按列解析 df_raw pd.read_csv(os.path.join(root_path, data_path)) # 划分训练/验证/测试集边界按7:1:2或6:2:2 ... self.data_x, self.data_y self._get_data(df_raw) self.scaler StandardScaler() if scale else None def __getitem__(self, index): s_begin index s_end s_begin self.seq_len r_begin s_end - self.label_len r_end r_begin self.label_len self.pred_len seq_x self.data_x[s_begin:s_end] seq_y self.data_y[r_begin:r_end] # 时间特征拼接 if self.timeenc 1: seq_x_mark self._time_features(s_begin, s_end) seq_y_mark self._time_features(r_begin, r_end) return seq_x, seq_y, seq_x_mark, seq_y_mark这段代码的关键参数是size列表它决定了输入窗口、标签窗口和预测窗口的长度。label_len是解码器输入的起始部分通常设为seq_len // 2。features参数控制用单变量还是多变量S表示单变量预测M表示多变量预测。scale为True时做标准化这是时序预测的标配操作但要注意标准化参数必须只在训练集上拟合然后应用到验证和测试集否则会引入未来信息。2.3 模型注册与统一入口为了让15个模型能通过一个run.py调用需要一个简单的注册机制# models/__init__.py from .Autoformer import Autoformer from .Informer import Informer from .PEDformer import PEDformer from .FEDformer import FEDformer from .Crossformer import Crossformer from .iTransformer import iTransformer # ... 其余模型导入 MODEL_REGISTRY { Autoformer: Autoformer, Informer: Informer, PEDformer: PEDformer, FEDformer: FEDformer, Crossformer: Crossformer, iTransformer: iTransformer, # ... } def build_model(args): model_cls MODEL_REGISTRY[args.model] return model_cls(args)run.py里通过argparse接收参数然后调用build_model。这样你切换模型只需要改--model参数。每个模型的__init__接收统一的args对象里面包含seq_len、pred_len、d_model、n_heads、e_layers、d_ff等超参数。不同模型可能用不到某些参数但统一接口能减少适配成本。提示有些模型的原始实现依赖特定的CUDA算子或旧版PyTorch建议先用PyTorch 1.13以上版本测试遇到不兼容的算子再单独处理。3. 从ETTh1到自定义数据跑通第一个模型的完整流程3.1 环境配置与依赖安装先建一个干净的虚拟环境避免和已有项目冲突conda create -n ts_transformer python3.9 conda activate ts_transformer pip install torch1.13.1cu117 torchvision --extra-index-url https://download.pytorch.org/whl/cu117 pip install numpy pandas scikit-learn matplotlib pip install reformer_pytorch # 部分模型依赖 pip install einops # Crossformer等模型需要PyTorch版本建议1.13到2.0之间太新的版本可能和某些模型的CUDA扩展不兼容。einops用于张量重排Crossformer和iTransformer的代码里大量使用。reformer_pytorch是部分高效注意力实现的依赖如果某个模型不需要可以跳过。安装完成后用一个小脚本验证环境import torch print(torch.__version__) print(torch.cuda.is_available()) # 简单测试注意力计算 q torch.randn(2, 8, 64, 32).cuda() k torch.randn(2, 8, 64, 32).cuda() v torch.randn(2, 8, 64, 32).cuda() attn torch.softmax(q k.transpose(-2, -1) / (32 ** 0.5), dim-1) out attn v print(out.shape) # 应为 [2, 8, 64, 32]如果CUDA不可用检查显卡驱动和CUDA版本是否匹配。CPU也能跑但训练时间会成倍增加建议至少用一张8GB显存的卡。3.2 用ETTh1数据集跑通InformerETTh1是时序预测的基准数据集包含电力变压器的油温数据每小时采样一次有7个变量。很多论文都用它做对比方便你复现结果。先下载数据放到./dataset/ETT-small/目录下。然后运行python run.py \ --model Informer \ --data ETTh1 \ --root_path ./dataset/ETT-small/ \ --data_path ETTh1.csv \ --features M \ --seq_len 96 \ --label_len 48 \ --pred_len 96 \ --e_layers 2 \ --d_layers 1 \ --d_model 512 \ --d_ff 2048 \ --n_heads 8 \ --dropout 0.05 \ --batch_size 32 \ --learning_rate 0.0001 \ --train_epochs 10 \ --patience 3参数说明seq_len96表示用过去96小时预测未来96小时。label_len48是解码器输入的已知部分长度。e_layers2是编码器层数d_layers1是解码器层数。d_model512是隐藏维度d_ff2048是前馈网络维度。n_heads8是注意力头数。patience3表示验证集损失3轮不下降就早停。训练过程中会打印每轮的train loss、val loss和测试指标。正常情况下Informer在ETTh1的96步预测上MSE应该在0.4左右MAE在0.45左右。如果偏差很大检查数据标准化是否开启、时间特征是否正确拼接。3.3 切换到Autoformer和PEDformer的注意事项Autoformer的调用方式和Informer几乎一样但有几个关键区别python run.py \ --model Autoformer \ --data ETTh1 \ --root_path ./dataset/ETT-small/ \ --data_path ETTh1.csv \ --features M \ --seq_len 96 \ --label_len 48 \ --pred_len 96 \ --e_layers 2 \ --d_layers 1 \ --d_model 512 \ --d_ff 2048 \ --n_heads 8 \ --moving_avg 25 \ --dropout 0.05 \ --batch_size 32 \ --learning_rate 0.0001 \ --train_epochs 10多了一个moving_avg参数这是序列分解的滑动窗口大小。Autoformer默认用25对应小时级数据的一天周期。如果你的数据周期不同这个值要调整。比如分钟级数据周期可能是1440那moving_avg应该设为1440左右。PEDformer的参数里多了modes和mode_select控制频域分解的模态数量。默认modes64mode_selectrandom。如果数据周期性很强可以改成mode_selectlow只保留低频分量。注意Autoformer和PEDformer的序列分解层会改变张量形状如果你的seq_len不是moving_avg的整数倍可能会在reshape时报错。建议把seq_len设为moving_avg的倍数。3.4 自定义数据的接入方式如果你有自己的CSV数据格式要求很简单第一列是时间戳后续列是数值变量。时间戳格式为YYYY-MM-DD HH:MM:SS。把文件放到./dataset/下然后在data_loader.py里注册# data_provider/data_factory.py data_dict { ETTh1: ETTh1, ETTm1: ETTm1, custom: CustomDataset, # 新增 } class CustomDataset(Dataset): def __init__(self, root_path, flagtrain, sizeNone, featuresM, data_pathmy_data.csv, targetvalue, scaleTrue, timeenc1): # 复用TimeSeriesDataset的逻辑 # 关键是确保时间戳列能被正确解析 ...如果数据里有缺失值建议先用线性插值补齐不要直接填0否则标准化后会引入偏差。如果变量量纲差异大标准化是必须的。如果数据有异常值先做截断或平滑处理。数据划分比例默认是7:1:2如果你的数据量小可以改成8:1:1。验证集的作用是早停和调参测试集只在最后评估时用一次。4. 训练与调参中的避坑指南4.1 损失不下降现象、原因与解决现象训练开始后train loss在几个epoch内几乎不变或者下降后很快反弹。原因最常见的是学习率设置不当。Transformer类模型对学习率敏感太大导致震荡太小导致停滞。其次是数据标准化没做或者标准化参数用错了。还有一种情况是位置编码和时间特征没有正确拼接模型拿到的输入缺少时序信息。解决先把学习率降到1e-4或5e-5试一轮。检查data_loader.py里的scale参数是否为True以及scaler是否只在训练集上fit。打印一个batch的输入确认时间特征维度是否正确。如果用的是Autoformer检查moving_avg是否和序列周期匹配。4.2 显存溢出现象、原因与解决现象训练到一半报CUDA out of memory或者一开始就分配失败。原因序列长度或batch size太大。注意力矩阵的内存占用是O(L²)当seq_len720时单个注意力矩阵可能超过1GB。另外某些模型在计算过程中会缓存中间变量比如Autoformer的分解结果。解决先把batch_size减半如果还不行把seq_len降到336或192。如果必须用长序列可以开启梯度累积用时间换空间。部分模型支持--use_amp混合精度训练能省30%左右的显存。检查是否有不必要的张量保留在计算图中比如在验证阶段忘记torch.no_grad()。4.3 预测结果偏移现象、原因与解决现象模型在测试集上的预测曲线整体偏高或偏低形状大致对但幅度不对。原因标准化和反标准化不一致。训练时对数据做了标准化预测时忘记用同样的scaler反变换。或者训练集和测试集的分布差异太大标准化参数不适用。解决在评估代码里确认scaler.inverse_transform被正确调用。如果数据分布随时间变化明显考虑用滑动窗口标准化即每个输入窗口单独做标准化。但这样会增加计算量且可能破坏跨窗口的连续性。4.4 多变量预测中某些变量效果特别差现象整体MSE还行但某个变量的预测几乎是一条直线。原因该变量的方差很小标准化后接近0模型学不到有效信号。或者该变量和其他变量相关性低注意力机制没有分配到足够的权重。解决检查该变量的数据分布如果确实变化很小可以考虑单独建模或去掉。如果变量间相关性低试试iTransformer或Crossformer这类显式建模变量关系的模型。也可以在损失函数里给不同变量加权但权重需要根据业务重要性来定。4.5 不同模型的结果差异很大现象同样的数据Informer的MSE是0.4Autoformer是0.35但PEDformer到了0.5。原因每个模型的归纳偏置不同。Autoformer的分解机制适合周期性强的数据PEDformer的频域方法在周期不明显时可能过拟合。另外超参数没有针对每个模型单独调优直接套用同一套参数会导致某些模型欠拟合或过拟合。解决不要指望一套参数跑所有模型。至少对学习率、d_model、e_layers做网格搜索。如果时间有限优先调学习率和d_model。记录每个模型的最佳参数组合后续在新数据上可以直接复用。5. 进阶技巧用统一评估框架横向对比15个模型5.1 统一评估指标与可视化跑通单个模型只是第一步真正有价值的是横向对比。我一般会写一个统一的评估脚本把所有模型的预测结果收集起来计算MAE、MSE、RMSE并画出预测曲线对比图。# utils/evaluate.py import numpy as np from sklearn.metrics import mean_absolute_error, mean_squared_error def evaluate_all(preds_dict, trues, metrics[mae, mse, rmse]): preds_dict: {model_name: np.array [N, pred_len, features]} trues: np.array [N, pred_len, features] results {} for name, pred in preds_dict.items(): res {} if mae in metrics: res[mae] mean_absolute_error( trues.reshape(-1, trues.shape[-1]), pred.reshape(-1, pred.shape[-1]) ) if mse in metrics: res[mse] mean_squared_error( trues.reshape(-1, trues.shape[-1]), pred.reshape(-1, pred.shape[-1]) ) if rmse in metrics: res[rmse] np.sqrt(res[mse]) results[name] res return results这个函数接收一个字典key是模型名value是预测数组。trues是真实值。计算时把所有样本和所有预测步展平得到整体指标。如果你想看每个预测步的误差可以按pred_len维度分别计算。可视化部分用matplotlib画每个模型的预测曲线和真实曲线。重点看几个位置预测起点、预测中点、预测终点。如果某个模型在终点处误差突然增大说明长周期依赖没学好。5.2 用不同预测长度测试模型泛化能力一个模型在96步预测上表现好不代表在336步或720步上也好。我一般会跑四组pred_len96、192、336、720。观察指标随预测长度增加的变化趋势。模型pred_len96pred_len192pred_len336pred_len720Informer0.420.510.680.89Autoformer0.380.460.590.75PEDformer0.400.480.620.80iTransformer0.360.430.550.70上面是一组示例数据实际数值会因数据集和参数不同而变化。关键看趋势如果某个模型在720步时MSE暴涨说明它的长周期建模能力有限。如果下降平缓说明泛化性更好。5.3 一个容易被忽略的技巧验证集的使用方式很多人把验证集只用来早停其实它还能帮你判断模型是否过拟合。具体做法是在每个epoch结束后分别计算训练集和验证集的loss画成曲线。如果训练loss持续下降但验证loss开始上升说明过拟合了需要加dropout或减层数。如果两者都下降但验证loss始终高于训练loss很多说明模型容量不够可以增大d_model或e_layers。我一般会保留验证集上表现最好的模型参数而不是最后一个epoch的参数。早停的patience设为3到5太小容易错过最优解太大浪费训练时间。5.4 从跑通到落地我的几个习惯跑通15个模型不是终点。真正落地的时候我会先选2到3个在验证集上表现最好的模型然后在测试集上做最终评估。如果业务对推理速度有要求还要测每个模型的单次前向耗时。Autoformer和PEDformer因为分解操作推理速度通常比Informer慢20%到30%。iTransformer的结构更简洁推理速度有优势。另外我会把每个模型的最佳超参数记录在一个配置文件里下次在新数据上直接加载只微调学习率和seq_len。这样能省掉大量重复实验的时间。最后说一个血泪教训不要迷信论文里的SOTA。有些模型在ETTh1上刷到了最低MSE但换到你的数据上可能还不如一个简单的线性模型。先跑通再对比最后根据业务指标选型。希望帮到你。本文还有配套的精品资源点击获取
返回列表