
简介本资源是面向时间序列预测与分析领域的研究者、算法工程师及高校研究生的Transformer架构实践代码合集聚焦长时间序列建模这一核心挑战覆盖Autoformer、Informer、TimesNet、DLinear、Crossformer、ETSformer等15种主流改进模型。资源包共1378个文件含137个核心Python训练/推理脚本、228个环境配置与运行脚本.sh、774份论文与技术文档.pdf以及CSV、NPY等格式的电力负荷、ETT油温、交通流量、外汇汇率、气象与疾病监测等多源真实数据集整体压缩包大小为182.2MB。已有3448人学习下载目录结构按模型分仓组织每个算法均包含完整训练流程、超参配置、数据预处理模块及多数据集适配接口支持开箱即用与对比实验设计。读者可直接复现SOTA结果、开展消融研究或迁移至自有时序任务显著降低Transformer时序建模的工程门槛。1. 项目概述为什么我们需要一个长时间序列Transformer代码库如果你正在做时间序列预测尤其是那种需要预测未来几十甚至上百个点的长时间序列任务那你一定绕不开Transformer。但当你兴冲冲地打开一篇论文比如《Informer: Beyond Efficient Transformer for Long Sequence Time-Series Forecasting》想复现一下结果时大概率会陷入一种困境作者提供的官方代码可能只适配特定的数据集环境依赖复杂或者不同论文的代码风格迥异你想对比一下Autoformer和FEDformer的效果得在两个完全不同的项目里折腾半天。更别提还有PatchTST、TimesNet、DLinear等一众新秀每个都声称自己效果拔群你该信谁怎么快速验证这就是我动手整理这个“基于Transformer的长时间序列代码汇总”项目的初衷。它不是一个简单的代码打包而是一个统一、模块化、开箱即用的代码框架集成了包括Autoformer, FEDformer, Informer, PatchTST, TimesNet, DLinear, LightTS, Non-stationary Transformer等在内的15个主流算法。我的目标很简单让你能在一个统一的实验管道下用同一份数据、同一个评估标准公平、快速地对比不同模型把精力从“折腾环境和对齐代码”真正转移到“理解模型和调优业务”上。这个项目覆盖了从经典到SOTA的多种长时间序列预测思路。比如Informer用ProbSparse自注意力解决传统Transformer的平方复杂度问题Autoformer引入了序列分解和自相关机制来捕捉长期依赖FEDformer则利用傅里叶变换和小波变换在频域进行高效建模而像DLinear这样简单的线性模型在某些数据集上反而能“大力出奇迹”挑战复杂的深度学习模型。把这些模型放在一起你不仅能直接用更能通过对比它们的结构差异深刻理解每种设计背后的动机与优劣。2. 核心模型架构与设计思想深度解析长时间序列预测的核心挑战在于如何高效地建模长程依赖关系同时避免计算爆炸。传统的Transformer在序列长度L很大时其自注意力机制O(L²)的复杂度是难以承受的。下面我将深入拆解本项目集成的几类代表性模型的核心思想。2.1 效率优先派Informer与ProbSparse自注意力Informer的出发点直指Transformer的效率瓶颈。其核心创新是ProbSparse Self-attention。传统自注意力计算Query和所有Key的点积但作者认为注意力权重分布往往是长尾的只有少数“关键”的Query-Key对贡献了主要注意力。因此Informer设计了一种近似方法只为每个Query采样Top-u个Keyu c * log Lc为常数将复杂度从O(L²)降至O(L log L)。注意在代码实现中ProbSparse注意力的有效性高度依赖于对“稀疏性”的度量。原论文使用基于熵的估计方法但在实际编码时需要对随机采样的稳定性进行处理否则可能引入较大方差影响训练收敛。我通常在实现中会加入一个可选的“均值”回退机制当采样结果过于极端时使用平均注意力作为补充。除了注意力机制Informer的Distilling操作也值得一说。它通过卷积和最大池化对序列进行下采样逐步压缩中间层的维度进一步减少参数量和计算量。这种设计使得模型能够处理更长的历史序列比如720个时间点为预测更长的未来如480个点提供了信息基础。2.2 分解与周期挖掘派Autoformer与自相关机制Autoformer认为时间序列通常由趋势Trend、周期Seasonality和残差组成。它创新性地将序列分解Series Decomposition作为一个内部算子嵌入到Transformer块中而不是传统的事前预处理。每个Autoformer层内部都进行一次分解让模型在每一层都能渐进式地分离并提炼出趋势和周期成分。其另一大亮点是自相关注意力Auto-Correlation。它不再计算点与点之间的注意力而是计算序列在不同时间延迟lag上的自相关性。通过快速傅里叶变换FFT计算自相关函数找出最显著的几个周期如每天、每周然后基于这些周期进行信息聚合。例如如果发现序列有24小时的强周期那么今天下午3点的值会更关注昨天下午3点、前天下午3点的值。这种方法将复杂度降至O(L log L)并且具有明确的时序可解释性。实操心得实现自相关注意力时FFT的计算效率很高但如何选择top-k个延迟周期是个关键超参数。在代码中我通常会提供一个基于自相关系数阈值如选取超过均值标准差的部分的动态选择方式并允许用户固定k值方便在不同数据集上对比。2.3 频域变换派FEDformer与傅里叶/小波基底FEDformer另辟蹊径在频域Fourier域或时频域Wavelet域进行建模。其基本思想是许多时间序列模式在频域中表示更为紧凑。FEDformer在注意力机制中使用一组可学习的参数在频域与随机选择的傅里叶基底或小波基底进行交互从而用远少于L的参数如固定为M个模式来捕获全局依赖。具体来说它使用傅里叶变换FFT将序列转换到频域在频域进行低秩的注意力操作选择固定的低频分量然后再逆变换回时域。这种操作相当于一个全局的、高效的滤波器。小波变换版本则能同时提供时间和频率的局部信息对非平稳序列可能更有优势。模型核心思想对比表模型核心创新点解决的核心问题计算复杂度适用场景特点InformerProbSparse注意力蒸馏机制传统Transformer的O(L²)计算与内存瓶颈O(L log L)超长序列1000需极致压缩内存Autoformer序列分解内嵌自相关注意力长期周期性依赖的显式建模与效率O(L log L)具有强周期、季节性的序列如电力、交通FEDformer频域傅里叶/小波注意力在全局依赖建模上寻求参数效率O(L)序列整体平滑或包含多尺度周期模式PatchTST将序列分割为局部Patch进行独立建模关注局部语义降低跨Patch依赖建模难度O(Patch数量²)高维多元序列局部模式比全局依赖更重要DLinear简单的线性层分别对趋势和周期建模挑战“深度学习一定比线性模型好”的假设O(L)作为强大的基准或序列本身线性可分性强2.4 另类思路PatchTST、TimesNet与DLinearPatchTST受Vision Transformer启发将时间序列划分为不重叠的“Patch”如将16个时间点作为一个Patch。每个Patch经过线性投影后成为一个“词向量”然后送入标准的Transformer编码器。关键在于这里的Transformer只处理Patch级别的序列长度大大缩短且每个Patch内部的信息被压缩迫使模型学习更有意义的局部表示。对于多元预测它对每个变量独立处理Channel-Independent共享同一个Transformer大大减少了参数。TimesNet将一维时间序列通过多周期变换转化为二维张量类似图像然后使用标准的2D卷积网络进行处理。其核心是周期挖掘将不同周期下的序列堆叠成二维矩阵的行从而将时间变化周期内和周期变化周期间两种模式同时暴露给2D卷积核学习构思非常巧妙。DLinear则是一个“简单到令人发指”但效果惊人的基线。它就是一个简单的线性层。其设计是先用移动平均从原始序列中分解出趋势成分然后用一个线性层预测趋势另一个线性层预测残差周期噪声最后相加得到预测。它的强大提醒我们在评估任何复杂模型前必须先过一个强线性基线的关。3. 项目代码结构设计与统一实验管道为了让15个模型能在一起愉快地“同台竞技”一个清晰、可扩展的代码结构至关重要。我的设计原则是高内聚、低耦合、配置驱动。3.1 核心目录结构long_ts_forecasting/ ├── core/ # 核心抽象与基础模块 │ ├── base_model.py # 所有模型的抽象基类 │ ├── base_dataset.py # 数据加载的抽象基类 │ └── base_trainer.py # 训练循环的抽象基类 ├── models/ # 所有模型实现 │ ├── __init__.py │ ├── informer.py │ ├── autoformer.py │ ├── fedformer.py │ ├── patchtst.py │ ├── timesnet.py │ ├── dlinear.py │ └── ... (其他模型) ├── data_loader/ # 数据集处理 │ ├── datasets.py # 具体数据集类ETTh1, ETTm2, Electricity等 │ └── data_factory.py # 统一数据工厂根据名称返回数据集 ├── exp/ # 实验管理与配置 │ ├── exp_basic.py # 实验基础类 │ └── exp_main.py # 主实验脚本负责训练、验证、测试全流程 ├── utils/ # 工具函数 │ ├── metrics.py # 评估指标MSE, MAE, RMSE, MAPE等 │ ├── tools.py # 日志、绘图、早期停止等工具 │ └── timefeatures.py # 时间特征编码如星期、月份、节假日 ├── configs/ # 配置文件YAML或JSON │ ├── ETTh1.yaml │ ├── Electricity.yaml │ └── ... ├── scripts/ # 启动脚本 │ ├── train.sh │ └── test.sh ├── results/ # 实验结果日志、模型权重、预测图 └── requirements.txt # 项目依赖3.2 统一接口设计的关键所有模型都必须继承自BaseModel并实现几个关键方法class BaseModel(nn.Module): def __init__(self, config): super().__init__() self.task_name config.task_name self.seq_len config.seq_len self.pred_len config.pred_len # ... 其他公共参数 def forward(self, x_enc, x_mark_enc, x_dec, x_mark_dec, enc_self_maskNone, dec_self_maskNone, dec_enc_maskNone): 统一的前向传播接口。 x_enc: 编码器输入序列 [Batch, Seq_len, Channel] x_mark_enc: 编码器时间特征 [Batch, Seq_len, Mark_dim] x_dec: 解码器输入序列通常是目标序列的零填充或部分已知[Batch, Pred_len, Channel] x_mark_dec: 解码器时间特征 [Batch, Pred_len, Mark_dim] raise NotImplementedError def predict(self, batch_data): 封装forward用于推理阶段 # ... 通用预处理和后处理 return self.forward(...)这种设计保证了无论模型内部多复杂对外的调用方式都是一致的。Exp_Basic实验类会调用model.forward()而不需要关心具体是哪个模型。3.3 配置驱动的实验流程我使用YAML文件来管理所有实验配置。一个典型的ETTh1.yaml配置如下# data config data: ETTh1 features: M # 预测类型: M-多元预测多变量输出, S-多元预测单变量输出, MS-多对多 target: OT # 目标变量列名 freq: h # 数据频率: h-小时, t-分钟 seq_len: 720 # 输入序列长度历史窗口 label_len: 360 # 解码器输入中与编码器重叠的长度Informer等使用 pred_len: 720 # 预测序列长度未来窗口 # model config model: autoformer # 模型名称对应models/下的文件名 embed: timeF # 编码方式: timeF-时间特征, fixed-固定位置编码 d_model: 512 # Transformer隐层维度 n_heads: 8 # 注意力头数 e_layers: 2 # 编码器层数 d_layers: 1 # 解码器层数 d_ff: 2048 # 前馈网络维度 factor: 5 # ProbSparse注意力因子Informer或自相关top-k因子Autoformer distil: True # 是否使用蒸馏Informer output_attention: False # 是否输出注意力权重用于可视化 # training config train_epochs: 10 batch_size: 32 learning_rate: 0.0001 loss: mse # 损失函数 lradj: type1 # 学习率调整策略 use_amp: True # 是否使用混合精度训练通过修改配置文件中的model字段即可在同一个数据集上切换不同模型进行实验确保了对比的公平性。4. 关键模块实现细节与避坑指南在这一部分我将深入几个关键模型的实现细节并分享一些官方代码中可能未提及但在实际整合中必须处理的“坑”。4.1 Informer的ProbSparse注意力高效实现原论文的ProbSparse注意力实现涉及对Query的采样如果直接按论文公式实现在PyTorch中容易写出低效的循环代码。我的实现采用了向量化操作来提升效率。核心是计算Query的“稀疏度量”M。一种高效的实现方式是def get_sparse_measure(self, Q, K): Q: [batch_size, n_heads, seq_len, d_k] K: [batch_size, n_heads, seq_len, d_k] 返回: 稀疏性分数 [batch_size, n_heads, seq_len] # 计算Q和K的L2范数避免数值问题 Q_norm torch.norm(Q, dim-1, keepdimTrue) # [B, H, L, 1] K_norm torch.norm(K, dim-1, keepdimTrue) # [B, H, L, 1] Q_normalized Q / (Q_norm 1e-8) K_normalized K / (K_norm 1e-8) # 计算所有Query和所有Key的余弦相似度矩阵 # 使用矩阵乘法实现效率远高于循环 similarity_matrix torch.matmul(Q_normalized, K_normalized.transpose(-2, -1)) # [B, H, L, L] # 稀疏度量M(q_i) max_j(q_i * k_j^T) - mean_j(q_i * k_j^T) # 即每行每个Query的最大值减去均值 max_values, _ torch.max(similarity_matrix, dim-1) # [B, H, L] mean_values torch.mean(similarity_matrix, dim-1) # [B, H, L] M max_values - mean_values # [B, H, L] return M得到M后我们为每个注意力头选择 top-u 个 Queryu factor * ln(seq_len)。这里有一个关键技巧不要直接对每个batch、每个头独立采样这会导致每次前向传播采样的Query索引不同带来训练不稳定。我采用的是在模型初始化时根据最大序列长度预计算一个参考的采样索引然后在每次前向传播时根据当前序列长度进行缩放适配。虽然是一种近似但能极大稳定训练过程。避坑指南1ProbSparse的稳定性。直接按论文实现训练损失可能震荡剧烈。除了上述预计算索引法还可以引入一个“稀疏度温度”参数软化Top-u的采样或者设置一个最小采样比例如至少采样10%的Query防止在序列较短时采样数过少。4.2 Autoformer的序列分解与自相关注意力序列分解的内嵌实现相对直观。对于一个输入序列X我们通过滑动平均来提取趋势项T然后用X - T得到季节项S。class SeriesDecomposition(nn.Module): def __init__(self, kernel_size): super().__init__() self.kernel_size kernel_size # 使用平均池化模拟移动平均 self.avg_pool nn.AvgPool1d(kernel_sizekernel_size, stride1, paddingkernel_size//2) def forward(self, x): # x: [Batch, Channel, Length] # 注意输入维度需要调整通常时间序列在最后一维这里假设已调整 trend self.avg_pool(x) seasonal x - trend return trend, seasonal在Autoformer块中先对输入做分解然后趋势部分通过一个线性层季节部分通过自相关注意力层最后再相加。这里内核大小kernel_size是一个重要超参数它控制了趋势的平滑程度。对于不同频率的数据小时、天、周需要调整。我的经验是将其设置为预测长度pred_len的1/4到1/2通常能取得不错的效果。自相关注意力的实现其核心是快速计算时间序列的自相关函数通过FFT并找到最显著的延迟lags。def auto_correlation(self, queries, keys, values): 简化的自相关计算流程。 queries, keys, values: [Batch, Head, Length, d_k] B, H, L, E queries.shape q_fft torch.fft.rfft(queries, dim2) # 实值FFT k_fft torch.fft.rfft(keys, dim2) # 计算互相关在频域是共轭相乘 corr torch.fft.irfft(q_fft * torch.conj(k_fft), dim2) # [B, H, L] # 取绝对值得到自相关系数 corr torch.abs(corr) # [B, H, L] # 找到top-k个延迟 top_k int(self.factor * math.log(L)) # factor是超参数 top_values, top_indices torch.topk(corr, top_k, dim-1) # [B, H, top_k] # 根据top_indices从values中聚合信息 # 这里需要复杂的索引和聚合操作略去细节 output aggregation(values, top_indices, top_values) return output避坑指南2自相关Top-k选择。factor参数控制选取的延迟数量。太小可能丢失重要周期太大会增加计算量并引入噪声。建议从3开始尝试并根据验证集效果调整。另外对于没有明显周期的序列如一些金融数据自相关机制可能收益不大此时可能需要调小factor或考虑其他模型。4.3 FEDformer的频域注意力实现FEDformer在频域操作其关键是如何在PyTorch中高效、正确地实现傅里叶变换下的可学习权重交互。class FourierAttention(nn.Module): def __init__(self, d_model, n_heads, dropout0.1, modefourier, num_freqsNone): super().__init__() self.mode mode self.d_model d_model self.n_heads n_heads self.d_k d_model // n_heads self.num_freqs num_freqs or d_model // 2 # 默认选择一半的频率分量 # 可学习的频域投影参数 self.W_q nn.Linear(self.d_k, self.num_freqs, biasFalse) self.W_k nn.Linear(self.d_k, self.num_freqs, biasFalse) self.W_v nn.Linear(self.d_k, self.num_freqs, biasFalse) self.W_o nn.Linear(self.num_freqs, self.d_k, biasFalse) def forward(self, x): # x: [Batch, Length, d_model] B, L, _ x.shape x x.view(B, L, self.n_heads, self.d_k).transpose(1, 2) # [B, H, L, d_k] # 1. 转换到时域 x_freq torch.fft.rfft(x, dim2) # [B, H, Freq, d_k] Freq L//21 # 2. 在频域进行“注意力”操作实际上是线性变换 # 我们只取低频部分假设前num_freqs个分量最重要 low_freq_component x_freq[:, :, :self.num_freqs, :] # [B, H, num_freqs, d_k] Q_freq self.W_q(low_freq_component) # 投影变换 K_freq self.W_k(low_freq_component) V_freq self.W_v(low_freq_component) # 3. 频域的“注意力权重”计算简化版原文有更复杂的交互 # 这里使用简单的线性交互模拟注意力 attn_weights torch.softmax(torch.matmul(Q_freq, K_freq.transpose(-2, -1)) / math.sqrt(self.num_freqs), dim-1) freq_output torch.matmul(attn_weights, V_freq) # [B, H, num_freqs, d_k] # 4. 逆变换回时域 # 先将处理过的低频部分放回高频部分保持不变或置零 full_freq_output torch.zeros_like(x_freq) full_freq_output[:, :, :self.num_freqs, :] freq_output # 可以选择保留原始高频full_freq_output[:, :, self.num_freqs:, :] x_freq[:, :, self.num_freqs:, :] output torch.fft.irfft(full_freq_output, nL, dim2) # [B, H, L, d_k] output output.transpose(1, 2).contiguous().view(B, L, self.d_model) return output避坑指南3频域分量的选择与混叠。num_freqs决定了保留多少低频分量。保留太少会丢失信息保留太多则效率提升有限。一个经验法则是保留序列长度的1/4到1/2。另外在进行逆傅里叶变换IFFT时要确保点数n参数与原始序列长度L一致否则会导致时域信号长度错误引发后续维度不匹配的问题。这是一个非常隐蔽的Bug。4.4 数据加载与时间特征工程统一的数据处理管道是公平对比的基石。我设计了DataFactory类根据配置自动加载ETT、Electricity、Traffic等常用数据集。关键点在于如何构建适用于自回归解码或直接多步预测的样本。对于大多数Transformer模型如Informer, Autoformer它们采用一种“生成式”的解码策略解码器输入一部分是目标序列的前几位label_len其余用0填充。因此在构建数据样本时需要生成三部分编码器输入enc_in、解码器输入dec_in、解码器真实目标dec_out。def __getitem__(self, index): # 计算序列的起始和结束位置 s_begin index s_end s_begin self.seq_len r_begin s_end - self.label_len # 解码器输入与编码器末尾重叠label_len长度 r_end r_begin self.label_len self.pred_len # 序列数据 seq_x self.data[s_begin:s_end] # 编码器输入 [seq_len, C] seq_y self.data[r_begin:r_end] # 解码器输入输出 [label_lenpred_len, C] # 时间戳特征 seq_x_mark self.stamp[s_begin:s_end] seq_y_mark self.stamp[r_begin:r_end] # 构建解码器输入前label_len是真实值后pred_len用0填充或均值填充 dec_inp torch.zeros([self.pred_len self.label_len, self.data.shape[1]]) dec_inp[:self.label_len, :] seq_y[:self.label_len, :] # 如果模型需要也可以将目标变量的历史值复制到dec_inp的对应位置 # ... return seq_x, seq_x_mark, dec_inp, seq_y_mark, seq_y # seq_y是完整的真实目标避坑指南4数据标准化与逆变换。必须使用fit在训练集transform在全部数据的标准流程。即用训练集的均值和标准差去标准化整个数据集训练、验证、测试。在模型预测后需要将输出逆标准化回原始量纲才能计算正确的指标如MAPE。忘记逆变换是新手常犯的错误会导致指标好得“离谱”因为预测值和真实值都在0附近。5. 训练、调优与模型对比实战有了统一的框架我们就可以系统地训练和评估各个模型。本节将分享训练过程中的关键技巧并展示一个完整的对比实验流程。5.1 训练超参数设置与学习率调度不同模型对超参数的敏感度不同。以下是我通过大量实验总结的通用起手式配置可以作为调优的起点优化器AdamW。比Adam有更好的权重衰减处理泛化性能通常更优。betas(0.9, 0.999)eps1e-8。初始学习率这是一个关键参数。对于Transformer类模型建议从1e-4开始尝试。对于DLinear这种简单模型可以稍大如1e-3。学习率调度我强烈推荐使用余弦退火热重启CosineAnnealingWarmRestarts。它能周期性地重置学习率帮助模型跳出局部最优。设置T_0第一次重启的周期epoch数为总训练epoch的1/3到1/2。批大小Batch Size在GPU内存允许下尽可能大。长时间序列模型通常比较吃内存32或64是常见选择。如果遇到OOM内存溢出可以尝试梯度累积模拟更大的批大小。损失函数默认使用MSE均方误差。对于存在异常值的数据可以尝试Huber Loss或MAEL1 Loss它们对异常值更不敏感。早停Early Stopping耐心patience设置为10-20个epoch。监控验证集损失如果连续patience个epoch没有下降则停止训练并恢复最佳模型。在我的BaseTrainer中实现了混合精度训练AMP这对于Transformer模型可以显著减少显存占用并加速训练尤其是pred_len很长的时候。5.2 多模型对比实验流程假设我们想在ETTh1数据集上对比Informer,Autoformer,FEDformer,DLinear四个模型在pred_len720长时预测下的效果。准备配置文件复制四份ETTh1.yaml分别修改model字段为informer,autoformer,fedformer,dlinear。其他超参数如d_model,n_heads,e_layers等可以先保持论文推荐值或我的默认值。启动训练使用脚本批量启动。# scripts/train_all.sh for model in informer autoformer fedformer dlinear do python -u run.py \ --config_path ./configs/ETTh1_${model}.yaml \ --model_id ETTh1_${model}_720 \ --train_epochs 20 \ --batch_size 32 \ --gpu 0 \ ./logs/ETTh1_${model}_720.log 21 done监控与记录训练日志会输出到./logs/。我使用TensorBoard或Weights Biases来实时监控训练损失和验证损失曲线。同时代码会在./results/下为每个实验创建独立文件夹保存最佳模型权重.pth文件和配置。测试与评估训练完成后运行测试脚本计算在测试集上的指标MSE, MAE, RMSE, MAPE。python -u run.py \ --config_path ./configs/ETTh1_informer.yaml \ --model_id ETTh1_informer_720 \ --test_only True \ --checkpoint ./results/ETTh1_informer_720/checkpoint.pth结果汇总与分析将所有模型的测试结果汇总到一个表格中。更重要的是可视化预测曲线。将测试集上某一段的真实序列和各个模型的预测序列画在一起直观对比谁的趋势捕捉更准谁在突变点表现更好。一个典型的对比结果可能如下表所示ETTh1, pred_len720:模型MSEMAERMSEMAPE (%)训练时间 (小时)参数量 (M)DLinear0.3850.4210.6213.120.50.05Informer0.4210.4450.6493.452.114.3Autoformer0.3720.4080.6102.982.821.7FEDformer0.3960.4280.6293.211.918.5注以上为示例数据非真实结果从这个假设结果可以看出DLinear再次证明了其作为强基线的实力它以极少的参数和极短的训练时间取得了非常有竞争力的指标。Autoformer在长时预测上表现最佳其内嵌分解和自相关机制对电力数据的周期性捕捉得很好。Informer和FEDformer效果接近但可能因为ETTh1数据的特性其优势没有完全发挥。实操心得如何看待对比结果不要只看平均指标。一定要看预测曲线图有些模型可能MSE略高但在关键转折点的预测上更准这在业务中可能价值更大。此外要分析误差分布是系统性偏高/偏低还是方差大这有助于下一步的模型改进。5.3 模型选择与业务落地建议经过系统的对比实验后如何为你的具体任务选型我总结了一个决策流第一步跑通DLinear。把它作为你的第一个基线。如果它的效果已经足够好或者与复杂模型相差无几那么恭喜你可能不需要更复杂的模型。优先考虑部署和维护的简便性。第二步分析数据特性。强周期、趋势明显如电力、客流优先尝试Autoformer和FEDformer (Wavelet)。Autoformer的分解和自相关对周期敏感FEDformer的小波变换擅长处理多尺度周期。序列极长内存是瓶颈如传感器高频数据优先尝试Informer和LightTS。它们的ProbSparse注意力内存效率高。高维多元序列变量相对独立如多指标监控优先尝试PatchTST。其Channel-Independent设计能有效防止过拟合并提升训练效率。序列包含复杂局部模式和非平稳性尝试TimesNet将时间序列视为二维图像来处理可能捕捉到意想不到的模式。第三步考虑推理延迟和资源。对于需要实时预测的场景模型大小和推理速度至关重要。DLinear, LightTS, PatchTST 通常是轻量级的选择。Transformer类模型可以通过知识蒸馏或模型剪枝进行压缩。第四步集成与后处理。如果单一模型表现不稳定可以考虑简单的模型集成例如对Autoformer、FEDformer、PatchTST的预测结果进行加权平均。对于业务指标可能需要对模型的原始输出进行后处理校准例如确保预测值非负或者符合某些业务规则。6. 常见问题排查与实战技巧实录在实际整合和实验过程中我遇到了无数大大小小的问题。这里把最具代表性的几个整理出来希望能帮你节省大量调试时间。6.1 训练不收敛或损失为NaN这是最常见的问题之一。检查数据首先确认输入数据没有NaN或Inf值。检查标准化过程防止除零错误例如某个通道方差为0。检查学习率过大的学习率是导致NaN的元凶。尝试将学习率降低一个数量级例如从1e-3降到1e-4并使用学习率预热Warmup。在训练前几个epoch线性地将学习率从0增加到设定值能极大提升稳定性。检查梯度使用torch.nn.utils.clip_grad_norm_(model.parameters(), max_norm1.0)进行梯度裁剪防止梯度爆炸。检查损失函数对于MSE确保预测值和真实值在同一个量级。如果使用MAPE作为损失要防止真实值接近零导致除零可以加一个很小的平滑项epsilon。检查模型初始化Transformer的层初始化很重要。确保线性层、LayerNorm层使用默认初始化即可注意力层的投影矩阵可以使用Xavier初始化。6.2 验证集损失震荡早停过早触发降低早停耐心如果数据噪声大验证损失小幅震荡是正常的。可以适当增加早停的patience如从10调到20。检查验证集划分确保验证集和训练集来自同一分布没有数据泄露例如未来信息混入了训练集。时间序列必须按时间顺序划分。使用更平滑的评估指标不要每个epoch都验证。可以每2个或3个epoch验证一次或者使用验证集损失的移动平均来判断是否早停。调整学习率调度余弦退火热重启本身就会导致损失周期性震荡这是正常的。确保你监控的是每个周期内的最低损失而不是瞬时值。6.3 预测结果滞后Lagging或过于平滑这是时间序列预测的经典问题模型倾向于预测一个“均值”导致在趋势转折点反应迟钝。增加解码器输入的真实信息适当增加label_len解码器与编码器重叠的长度让解码器在开始时拥有更多真实的上下文。对于Informer这类模型这很关键。在损失函数中加入一阶差分约束除了预测点的误差还可以加入预测序列变化趋势一阶差分与真实序列变化趋势的误差迫使模型学习变化规律。def loss_fn(pred, true): mse_loss F.mse_loss(pred, true) # 趋势一致性损失 pred_diff pred[:, 1:, :] - pred[:, :-1, :] true_diff true[:, 1:, :] - true[:, :-1, :] trend_loss F.mse_loss(pred_diff, true_diff) return mse_loss 0.1 * trend_loss # 加权求和使用多任务学习同时预测未来多个时间窗口如短期、中期、长期共享编码器让模型学习不同尺度的模式。尝试直接多步预测策略有些工作如DLinear、PatchTST采用直接输出所有未来点的“直接多步预测”而非自回归有时能缓解滞后问题。6.4 显存不足OOM的解决方案处理长序列时显存是硬约束。减小批大小最直接的方法。可以尝试batch_size16或8。使用梯度累积如果希望保持较大的有效批大小可以使用梯度累积。每accumulation_steps个小批次才更新一次参数。optimizer.zero_grad() for i, batch in enumerate(data_loader): loss model(batch) loss loss / accumulation_steps # 损失标准化 loss.backward() if (i1) % accumulation_steps 0: optimizer.step() optimizer.zero_grad()启用混合精度训练AMP如前所述能有效减少显存并加速。检查注意力计算确保ProbSparseInformer或自相关Autoformer等优化注意力机制已正确启用而不是回退到标准注意力。减少模型尺寸降低d_model如从512降到256、d_ff如从2048降到1024或层数e_layers,d_layers。缩短输入序列如果业务允许尝试减少seq_len。但要注意历史窗口太短可能影响长时预测能力。6.5 如何为自己的数据集定制模型当你有一个新的业务数据集时可以按以下步骤快速适配数据格式转换实现一个新的Dataset类继承BaseDataset。确保返回(seq_x, seq_x_mark, dec_inp, dec_mark, seq_y)这五元组。时间特征*_mark至少包含绝对时间信息如小时、星期可以加入节假日等业务特征。探索性数据分析EDA绘制序列图、自相关图ACF、偏自相关图PACF了解数据的周期性、趋势和平稳性。超参数扫描最重要的几个超参数是seq_len历史窗口、pred_len预测窗口、d_model模型容量、learning_rate。可以使用网格搜索或贝叶斯优化工具如Optuna进行小范围搜索。特征工程除了时间戳可以考虑加入滞后特征lag features、滚动统计量如过去24小时的均值、方差、甚至外部特征如天气、促销活动。这些特征可以作为额外的通道Channel输入模型。模型微调选择一个在公开数据集上表现良好的模型作为基础在其结构上进行微调。例如对于有明显周期但周期长度未知的数据可以尝试让Autoformer的factor自相关top-k参数可学习或者让移动平均的kernel_size自适应。这个代码库的价值就在于它提供了一个坚实的起点和公平的擂台。你可以快速地将这些前沿算法应用到你的数据上通过科学的对比找到最适合的那一个或者从中获得灵感去设计属于你自己的、更强大的时间序列预测模型。本文还有配套的精品资源点击获取