
简介这份资源是面向深度学习与时间序列预测学习者的Informer模型Python实战案例包适合具备一定PyTorch基础、希望掌握长序列预测方法的开发者与研究人员。案例围绕ProbSparse Self-Attention这一核心创新完整呈现Encoder-Decoder架构的搭建思路可应用于电力消耗、股票走势、气象预报等长期依赖场景。压缩包共65个文件约115.97MB以17个py源码文件为主体涵盖模型定义、注意力机制、数据加载与实验入口另有17个npy数据文件、2个pth权重文件、3个csv数据集及若干pyc、xml配置目录按data、models、exp、utils等模块清晰划分。目前已有330人学习下载。通过该案例读者可系统了解数据预处理、损失函数与优化器选择、训练验证流程及MAE、RMSE等指标评估并借助已保存的检查点与预测结果文件快速复现Informer在真实数据集上的建模与未来时间步预测全过程。1. Informer 长序列预测为什么它值得你花一个周末跑通如果你手上有电力负荷、交通流量、气象观测这类按小时甚至按分钟采样的数据想预测未来 96 步甚至 720 步Transformer 那套 O(L²) 的注意力机制会先把你的显存吃干净。Informer 就是冲着这个场景来的它把注意力做成 ProbSparse把编码器做成蒸馏式堆叠一次前向就能吐出整段长序列而不是像传统自回归那样一步步往外蹦。这个 Python 案例包的价值不在于又一个时序模型而在于它把长序列预测里最烦的三件事——显存、推理速度、多步输出——打包成了一份能直接改数据就能跑的工程骨架。适合谁适合已经会用 PyTorch 搭 LSTM、但被长序列预测的显存和速度卡住的算法工程师也适合做 python 量化交易策略代码、想把因子预测从日频推到分钟频的人。下面我按环境怎么搭 → 数据怎么进 → 模型怎么调 → 坑在哪的顺序把这份案例拆开讲透。2. 把环境搭起来从 python 安装到跑通第一个 epoch2.1 依赖清单与 python 环境配置Informer 官方实现基于 PyTorch对版本比较敏感。我一般用 python 3.8 到 3.10 之间的版本太新的 python 3.12 在装某些科学计算库时容易翻车。如果你还没装 python去 python 官网下载对应系统的安装包安装时记得勾选Add Python to PATH省得后面手动配 python 环境变量。装完先验证python --version pip --version接下来是核心依赖。Informer 需要 torch、numpy、pandas、scikit-learn、matplotlib做数据加载还会用到 scikit-learn 的 StandardScaler。一条命令搞定pip install torch numpy pandas scikit-learn matplotlib如果你用的是 GPU 版本torch 要单独按 CUDA 版本装别直接pip install torch装成 CPU 版否则训练时你会发现 GPU 利用率一直是 0这是最常见的玄学问题之一。装完跑一段验证脚本import torch import numpy as np import pandas as pd print(torch:, torch.__version__) print(cuda available:, torch.cuda.is_available()) print(device count:, torch.cuda.device_count())这段代码的作用是确认三件事torch 装没装对、CUDA 能不能用、有几张卡。如果cuda available是 False 但你明明有显卡八成是装成了 CPU 版 torch卸载重装对应 CUDA 版本的即可。参数上没什么可调的但torch.cuda.is_available()这个检查建议写进你所有训练脚本的开头比事后 debug 省事得多。2.2 数据格式Informer 到底吃什么形状的输入Informer 的数据加载器期望的是一张二维表行是时间步列是特征。第一列通常是时间戳date后面是各个变量比如 OT、HUFL、HULL 这些电力数据集的列名。它不像有些模型要求你手动做滑动窗口窗口是在 Dataset 里按seq_len和label_len、pred_len切出来的。关键参数有三个参数含义典型取值seq_len编码器输入的历史长度96 / 168 / 336label_len解码器的起始 token 长度48一般是 seq_len 的一半pred_len要预测的未来步数96 / 192 / 336 / 720我一般会先写个小脚本确认数据能被正确切分import pandas as pd df pd.read_csv(./data/ETTh1.csv) print(df.shape) print(df.columns.tolist()) print(df.head()) # 检查时间列是否连续 df[date] pd.to_datetime(df[date]) diff df[date].diff().dropna().unique() print(时间间隔种类:, diff)逻辑说明先看数据有多少行多少列确认列名和预期一致再把 date 列转成时间类型检查时间间隔是不是统一的。如果diff打印出来不止一种值说明数据里有缺失时间点或重复时间戳直接喂给模型会导致窗口错位预测结果会莫名其妙地偏移。这一步很多人跳过然后在训练时看到 loss 不降回头查半天才发现是数据本身有洞。2.3 跑通第一个 epoch 的最小命令假设你已经把案例包解压目录里有main_informer.py和data文件夹。最小启动命令长这样python main_informer.py \ --model informer \ --data ETTh1 \ --root_path ./data/ \ --data_path ETTh1.csv \ --features M \ --seq_len 96 \ --label_len 48 \ --pred_len 96 \ --e_layers 2 \ --d_layers 1 \ --batch_size 32 \ --train_epochs 3 \ --learning_rate 0.0001参数逐个说--features M表示多变量预测多变量如果你只想用多变量预测某一个目标列改成S--e_layers是编码器层数先设 2 跑通再说--d_layers解码器层数一般 1 就够--learning_rate 0.0001是 Informer 论文里的默认值别一上来就调大ProbSparse 注意力对学习率比较敏感。第一次跑建议--train_epochs 3目的不是训好是确认整条链路能通、显存不炸、loss 在动。如果这一步就 OOM先把--batch_size降到 16 或 8。3. Informer 调参ProbSparse 注意力和蒸馏堆叠怎么设才不白跑3.1 ProbSparse 注意力的采样因子Informer 的核心创新是 ProbSparse 注意力它不计算完整的 QK^T 矩阵而是只挑出活跃的 query 参与计算。这个挑选比例由采样因子控制代码里通常叫factor默认是 5。它的含义是从 L 个 query 里采样factor * ln(L)个来估计注意力分布。这个参数怎么影响结果factor 越大采样越多越接近完整注意力精度可能更高但速度优势变小factor 越小速度越快但可能漏掉重要的 query。我的经验是序列长度 96 到 336 时factor 保持 5 就行如果你把 pred_len 推到 720可以试着调到 3 或 7 对比一下。别把它当成必须精调的超参它更多是速度与精度的旋钮不是决定模型能不能用的关键。3.2 编码器蒸馏e_layers 和 distil 的配合Informer 编码器每一层后面有个蒸馏操作把序列长度砍半这样层数越多序列被压缩得越狠。--e_layers 2意味着经过两次蒸馏96 的长度会变成 24。如果你把 e_layers 设成 3 或 4序列会进一步缩短好处是显存占用下降坏处是太短的序列可能丢失局部细节。我一般这样定seq_len 96 配 e_layers 2seq_len 336 配 e_layers 3seq_len 720 配 e_layers 4。蒸馏开关在代码里是distilTrue如果你发现模型对短周期模式比如每天的峰谷捕捉不好可以试着关掉蒸馏但显存会涨。这是一个典型的显存换精度的取舍点。3.3 学习率与 batch_size 的联动Informer 论文用的学习率是 1e-4配合 batch_size 32。但实际数据千差万别我的做法是先固定 batch_size 32用 1e-4 跑 3 个 epoch 看 loss 曲线。如果 loss 在前 100 个 step 就剧烈震荡说明学习率偏大降到 5e-5如果 loss 几乎不动升到 2e-4 试试。batch_size 和 learning_rate 要联动调batch_size 翻倍时learning_rate 可以适当放大 1.5 倍左右但别超过 5e-4否则 ProbSparse 的稀疏估计会不稳定。# 训练循环里加一段 loss 监控方便判断学习率是否合适 for epoch in range(args.train_epochs): model.train() losses [] for i, (batch_x, batch_y, batch_x_mark, batch_y_mark) in enumerate(train_loader): optimizer.zero_grad() pred, true model(batch_x, batch_x_mark, batch_y, batch_y_mark) loss criterion(pred, true) loss.backward() optimizer.step() losses.append(loss.item()) if i % 100 0: print(fepoch {epoch} step {i} loss {loss.item():.6f}) print(fepoch {epoch} avg loss {sum(losses)/len(losses):.6f})这段代码的关键在于每 100 步打印一次 loss而不是等一个 epoch 结束。这样你能快速判断学习率是否合适如果前几个 100 步 loss 从 1.0 跳到 5.0 再跳回来就是学习率太大如果 1000 步了还在 0.9 附近磨就是太小。参数上criterion通常用 MSEInformer 论文也是 MSE别随便换成 MAE除非你的数据里异常值特别多。4. 避坑与排查Informer 实战里最容易翻车的 5 个点4.1 现象训练 loss 正常下降但验证集预测出来是一条直线原因数据归一化做错了。Informer 的 Dataset 默认对训练集 fit scaler然后 transform 验证集和测试集。如果你手动改了数据加载逻辑把整个数据集一起 fit就会造成信息泄漏模型学到的是未来信息验证时反而崩掉。另一种可能是 pred_len 设得比数据实际能提供的窗口还长最后几个 batch 的标签是填充的。解决检查data_loader.py里 scaler 的 fit 范围确保只在训练段 fit。然后打印一个 batch 的batch_y看看最后几行是不是全零或全 NaN。如果是把 pred_len 调小或者在 Dataset 里丢掉不完整的窗口。4.2 现象GPU 显存够但训练速度比 CPU 还慢原因数据加载成了瓶颈。Informer 的 Dataset 在__getitem__里做了不少索引和切片操作如果num_workers设成 0数据加载和模型计算串行GPU 大部分时间在等数据。另一个常见原因是 pin_memory 没开。解决在 DataLoader 里设num_workers4根据你机器的 CPU 核数调整pin_memoryTrue。如果用的是 Windowsnum_workers 设太大反而会报错先从 2 开始试。改完用nvidia-smi看 GPU 利用率能从 20% 提到 70% 以上。4.3 现象预测结果整体偏移形状对但数值差一个量级原因归一化方式不匹配。Informer 默认用 StandardScaler减均值除标准差如果你的数据里有明显的趋势或季节性StandardScaler 处理后的分布和模型假设不符。另外如果你在预测后忘了做 inverse_transform输出的就是归一化空间的值看起来会小很多。解决先确认预测后有没有调用scaler.inverse_transform。如果做了还是偏换成 MinMaxScaler 试试或者对数据做一阶差分去掉趋势再喂给模型。我一般会在验证脚本里同时打印归一化空间和原始空间的 MAE对比一下就知道问题出在哪。4.4 现象换了自己的数据模型完全不收敛原因特征列里混入了非数值列或者时间特征编码方式不对。Informer 对时间戳会做 hour、weekday、month 等编码如果你的 date 列格式不是它预期的%Y-%m-%d %H:%M:%S解析出来全是 NaT时间特征就废了。解决用 pandas 读进来后先df[date] pd.to_datetime(df[date])然后打印df[date].dt.hour.unique()看看是不是合理的 0 到 23。如果全是 0 或 NaN说明格式没解析对。另外确认所有特征列都是 float 类型object 类型的列会让 Dataset 在转 tensor 时直接报错。4.5 现象多变量预测里某个变量预测特别差其他都还行原因不同变量的量纲差异太大。比如电力数据里有的列是千瓦级有的是百分比StandardScaler 对每个列独立做归一化但如果某一列方差极小归一化后会被放大成噪声。解决先算每一列的标准差把标准差小于 1e-6 的列直接删掉。然后检查那一列的缺失值比例如果超过 30%考虑用插值补全或者干脆不用这一列。Informer 的注意力机制对噪声列比较敏感一列坏数据会拖累整个多变量预测。5. 进阶技巧用滚动预测和误差分解验证 Informer 到底值不值得上跑通一个 pred_len 96 的结果不难难的是判断这个模型在你的业务里到底能不能用。我一般会做两件事滚动预测验证和误差分解。滚动预测的做法是每次只预测 pred_len 步然后把预测值拼回输入序列滑动窗口往后推重复 N 次看误差会不会累积爆炸。Informer 的优势是一次输出多步但如果你直接拿它做几百步的滚动误差累积是不可避免的。代码大概长这样def rolling_forecast(model, initial_input, steps, pred_len, scaler): model.eval() history initial_input.clone() preds [] with torch.no_grad(): for _ in range(steps // pred_len): pred model(history, None, None, None) pred_denorm scaler.inverse_transform(pred.cpu().numpy()) preds.append(pred_denorm) # 把预测值接到历史后面丢掉最前面的 pred_len 步 history torch.cat([history[:, pred_len:, :], pred], dim1) return np.concatenate(preds, axis1)这段代码的逻辑是每次预测 pred_len 步然后把预测结果当作真实值接到输入后面形成新的窗口。参数上steps是你想预测的总步数必须是 pred_len 的整数倍。跑完之后把预测值和真实值画在同一张图上如果 200 步之后预测曲线明显发散说明这个模型不适合做超长滚动只能做单次多步预测。误差分解则是把 MAE 拆成趋势项、周期项和残差项。如果趋势项误差占大头说明模型没抓住长期走向可以试试加长 seq_len如果周期项误差大说明日周期或周周期没学好检查时间特征编码有没有问题如果残差项误差大那基本是数据噪声换模型也救不了。我自己的习惯是任何时序模型上线前先跑一遍滚动预测再跑一遍误差分解两个都过了才敢往生产环境推。Informer 在长序列上的优势是实打实的但它不是万能药数据质量差的时候再花哨的注意力机制也白搭。希望帮到你。本文还有配套的精品资源点击获取