Appearance
TimesNet 深度学习笔记
Temporal 2D-Variation Modeling for General Time Series Analysis(ICLR 2023)
一句话定位
TimesNet = FFT 周期发现 + 1D→2D 折叠变形 + Inception 多尺度 Conv2d + Softmax 自适应聚合 → 把时间序列"铺展"成二维图像,用图像识别中成熟的卷积骨干同时建模"周期内变化"和"周期间变化",一个统一架构完成 5 种分析任务。
零、前置知识
0.1 必须了解(缺少就看不懂正文)
| 概念 | 关键内容 | 推荐入口 |
|---|---|---|
| 离散傅里叶变换 (DFT/FFT) | rfft 把实值序列变成复数频谱;频率 | [[11-PyTorch-Tensor基础操作-切片变形拼接注意力]] §6 |
| 2D 卷积 (Conv2d) | kernel 在行列两个方向滑动;多 kernel 并行抽取不同尺度特征 | PyTorch 官方文档 |
| 残差连接 (ResNet) | y = F(x) + x,保证梯度流通,允许深度堆叠 | He et al. 2016 |
| Inception Block | 同时跑多种 kernel size 的 Conv,结果 mean-merge;用少量参数覆盖多尺度 | Szegedy et al. 2015 |
| 时序任务 setup | 输入历史 x_enc (B, seq_len, C),预测未来 pred_len 步 | [[00-总览]] |
0.2 推荐了解
| 概念 | 为什么推荐 |
|---|---|
| Autoformer | 同组工作,FFT 用于 AutoCorrelation;TimesNet 的自适应聚合受其启发 |
| PatchTST | 同期对比基线;把时间序列分段建模,与 TimesNet 的"分周期"思路可以对比 |
| DLinear | SOTA 线性基线;TimesNet 论文中是重要对比对象 |
0.3 背景:前作留下了什么问题
传统模型把时序看成一根 1D 线段:t0, t1, t2, ..., tT,要么对相邻点建模(RNN、TCN),要么对所有点做 attention(Transformer 系列)。
这个视角有两个盲区:
- 多周期叠加:现实时序(电力、交通、气象)往往是日周期、周周期、年周期的叠加。在 1D 轴上,这些周期彼此交织,很难同时捕获。
- 局部结构:同一周期内相邻时刻的"周期内变化",与不同周期块之间的"周期间变化",在 1D 表达里没有结构区分。
TimesNet 的突破口:把 1D 时序按主要周期"折叠"成 2D 网格,周期内位置 → 列,不同周期块 → 行,两类变化立刻成为 2D 图像的列方向和行方向,天然适合 Conv2d。
一、问题定义
输入:历史观测
任务:TimesNet 以统一的架构支持 5 种分析任务:
- 长期预测(Long-term Forecasting)
- 短期预测(Short-term Forecasting)
- 插值/填补(Imputation)
- 分类(Classification)
- 异常检测(Anomaly Detection)
核心符号:
| 符号 | 含义 |
|---|---|
| 超参数,选 top-k 频率(实验中预测=5,其他=3) | |
| 第 | |
| 对应周期 | |
| 幅值向量, | |
| 第 |
二、整体架构鸟瞰
![[assets/TimesNet/figure3-timesnet-overall-architecture.png]]
论文 Figure 3:TimesNet 整体架构。左侧:多个 TimesBlock 以残差方式堆叠,输入和输出均为 1D 特征
。右侧:单个 TimesBlock 内部的 1D→2D→1D 流程——从底部 1D 序列出发,折叠成 个不同尺度的 2D 张量,经共享 Inception Block 处理后折回 1D,最终通过 Softmax 幅值权重加权聚合成输出 1D 特征。
![[assets/TimesNet/arch_dataflow.svg]]
颜色说明:蓝=输入,青=时间编码,橙=线性投影,紫=FFT 周期检测,深灰=1D↔2D 变形,黄棕=Inception Conv2d,红=自适应聚合,绿=输出。
前向流程(以 TFB 预测任务为例):
x_enc (B, seq_len, C)
↓ 实例归一化(减 mean,除 stdev)
DataEmbedding: value + time_mark + position
↓ → (B, seq_len, d_model)
predict_linear: 时间轴从 seq_len 扩展到 seq_len+pred_len
↓ → (B, T, d_model) T = seq_len + pred_len
TimesBlock × L(残差堆叠):
每层: FFT发现 k 个周期 → k 路 1D→2D→Inception→2D→1D → Softmax聚合 → 残差加
↓ → (B, T, d_model)
Projection: Linear(d_model → C) + 反归一化
↓ → (B, T, C)
取最后 pred_len 步 → dec_out (B, pred_len, C)三、核心变换:发现周期 & 1D→2D 折叠
![[assets/TimesNet/figure1-multi-periodicity-concept.png]]
论文 Figure 1:多周期性与时序 2D-variation 示意。上方 1D 时序同时包含多个周期(Period 1、Period 2、Period 3);将同一周期内的时间点(蓝色,intraperiod-variation)和不同周期块之间的位置(红色,interperiod-variation)可视化后,可以发现两类结构各自对应 2D 网格的列方向和行方向。
![[assets/TimesNet/figure2-fft-period-to-2d-tensors.png]]
论文 Figure 2:单变量示例。左侧:原始 1D 序列 → rfft → 频谱中选择最大的 3 个频率;中间:对每个频率
把序列折叠成一个矩形 2D 张量(每列是周期内位置,每行是相邻周期块);右侧:2D 张量可直接被 2D kernel 同时沿列方向(intraperiod-variation)和行方向(interperiod-variation)建模。
3.1 FFT 周期发现(Eq. 1–2)
具体步骤:
- 对长度
的序列做 rfft,得个复数频率系数 - 幅值
;多变量时在 维度上平均 → topk(A, k)取幅值最大的个频率 - 对应周期
,只考虑 (避免直流分量)
数值示例:FFT_for_Period(T=13, k=2, D=1)
输入:x = [2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2](交替序列,主周期=2)
Step 1:rfft
rfft(x, n=13) → 7 个复数(频率 bin 0–6)
频率 bin 对应的真实频率:
| 频率 bin | 幅值(约) | 含义 |
|---|---|---|
| 0 | ~19.5 | 直流分量(均值)→ 被忽略 |
| 1 | ~0.1 | 弱 |
| 2 | ~0.1 | 弱 |
| 3 | ~0.1 | 弱 |
| 4 | ~0.1 | 弱 |
| 5 | ~0.1 | 弱 |
| 6 | ~6.0 | 强(对应2步周期) |
Step 2:排除 bin 0,topk(k=2)
选 bin 6(幅值最大)和 bin 5(次大)→
Step 3:换算周期
(主周期 ✓) (凑巧相同,实际数据通常不同)
真实数据更直观
电力消耗序列 FFT 后幅值会在 bin=24(对应日周期=24小时)和 bin=168(周周期=168小时)处有明显峰值。
3.2 Padding + Reshape:1D→2D(Eq. 3)
原则:将长度
实现中实际的 permute 顺序(多变量场景):
python
# X_1D: (B, T, D)
# 对周期 p,f = ceil(T/p)
X_pad = F.pad(X_1D, (0, 0, 0, p*f - T)) # pad 到 p*f
# → (B, p*f, D)
X_2D = X_pad.reshape(B, f, p, D).permute(0, 3, 1, 2)
# → (B, D, f, p) 即 (batch, channel, rows=周期块数, cols=周期内位置)数值示例:Padding + Reshape(T=13, p=4, f=4, D=1)
原始 1D: [a, b, c, d, e, f, g, h, i, j, k, l, m] 长度 13
Pad 到 16: [a, b, c, d, e, f, g, h, i, j, k, l, m, 0, 0, 0]
Reshape 成 (4行 × 4列):
row0 (周期块 0): [a, b, c, d] ← intraperiod: a→b→c→d
row1 (周期块 1): [e, f, g, h]
row2 (周期块 2): [i, j, k, l]
row3 (周期块 3): [m, 0, 0, 0] ← padding 行
列方向 = 周期内位置 (intraperiod-variation)
行方向 = 周期块序号 (interperiod-variation)验证
p=4→ 每列 4 个元素,对应 1 个完整周期f=4→ 4 行 = 4 个周期块- Conv2d 在此 4×4 矩阵上滑动:
看单点, 同时看 3 个相邻时刻 + 3 个相邻周期块
四、TimesBlock:核心计算单元
TimesBlock 的完整前向公式(Eq. 4–5):
内部:
4.1 Inception_Block_V1:多尺度 2D 卷积
输入:(B, D, f, p)(2D 张量)
三路并行 Conv2d,kernel size 分别为 padding='same' 保持尺寸),输出 mean 合并:
python
# 伪代码
out_1 = Conv2d(in_ch, out_ch, kernel_size=1)(x)
out_3 = Conv2d(in_ch, out_ch, kernel_size=3, padding=1)(x)
out_5 = Conv2d(in_ch, out_ch, kernel_size=5, padding=2)(x)
out = mean([out_1, out_3, out_5]) # 三路平均为什么 3 个 kernel?
| Kernel | 捕获的结构 |
|---|---|
| 单时刻单周期块的点特征 | |
| 3 个相邻时刻 × 3 个相邻周期块的局部结构 | |
| 更大范围的周期内变化 + 趋势变化 |
关键设计:同一个 Inception Block 的参数在
4.2 Adaptive Aggregation:幅值加权融合(Eq. 6)
直觉:FFT 幅值代表各频率的"信号强度",强周期对应的 2D 特征应获得更高的聚合权重。Softmax 保证权重和为 1。
数值示例:Adaptive Aggregation(k=2, T=13, D=1)
输入 FFT 幅值(对应 k=2 个被选频率):
Softmax:
加权聚合(假设两路 1D 结果):
验证
- 权重和 = 0.80 + 0.20 = 1.0 ✓
- 主周期(幅值更大)贡献 80% 权重,次周期贡献 20% ✓
- 如果 k=1,退化为直接使用单路结果 ✓
五、训练细节
优化器:Adam(
损失函数:
- 预测/插值:MSE
- 短期预测:SMAPE(对称平均绝对百分比误差)
- 分类:Cross Entropy
- 异常检测:MSE(无监督重建误差)
关键工程细节:
- 归一化:Series Stationarization(减均值、除标准差),来自 Non-stationary Transformer
d_model随变量数自适应: ,保证参数量不随 爆炸 - 预测任务:用一个额外的
predict_linear(Linear 层,对时间轴操作)把 hidden 从seq_len扩展到seq_len+pred_len,再截取最后pred_len步
六、实验结果
![[assets/TimesNet/figure4-model-performance-comparison.png]]
论文 Figure 4:左侧雷达图展示 TimesNet(红色实线)在 5 种任务上均优于所有对比方法(ETSformer、LightTS、DLinear、FEDformer、Autoformer、Informer);右侧散点图展示用更强大的 2D 视觉骨干(ResNeXt、SwinBlock 等)替换 Inception 后性能进一步提升,证明 TimesNet 可直接受益于计算机视觉领域的最新进展。
![[assets/TimesNet/figure5-classification-accuracy.png]]
论文 Figure 5:UEA 10 个子集上的平均分类精度。TimesNet(绿柱,73.6%)超过 Classical 方法 Rocket(72.5%)和 Transformer-based 方法 Flowformer(73.0%)。MLP 方法 DLinear 在分类任务上失败(67.5%),因为固定权重的线性层无法学到层级表示;而 TimesNet 的 2D 特征天然支持层级化表征学习。
长期预测关键数字(Table 2,MSE):
| 数据集 | TimesNet | Autoformer | DLinear | 改进 |
|---|---|---|---|---|
| ETTm1 | 0.400 | 0.588 | 0.299 | Autoformer −32% |
| Electricity | 0.192 | 0.227 | 0.212 | 最优 |
| Weather | 0.259 | 0.338 | 0.265 | 接近 DLinear |
5 任务综合排名(Table 11):TimesNet 所有任务排名均为 1,平均排名 1.0,是唯一在 5 个任务全部第一的模型。
七、消融实验
来自附录 C(Table 8, 9, 10)的关键结论:
| 消融点 | 结论 |
|---|---|
| 替换 Inception → ResNet/ResNeXt/SwinTransformer | F1-score 提升(更强骨干=更好性能),但参数量增大 |
| 用独立参数代替共享 Inception(Ind vs Shared) | 独立参数略好但参数量随 k 线性增长;共享参数以极小代价换来参数效率 |
| 加入 Autoformer 的趋势分解(+ decomposition) | 反而轻微下降(85.49→85.29),说明 2D-variation 已足够捕获趋势/季节信号 |
| 仅在原始输入上做 1D→2D 变换(Transform raw data) | Avg F1 从 85.49 降到 84.85,证明在每个 TimesBlock 内部做变换(对深层特征)更有效 |
| 去掉 Softmax 直接求和(Directly-sum) | 从 85.49 降到 84.57 |
| 去掉 Softmax 用原始幅值加权(Removing-Softmax) | 从 85.49 降到 85.25 |
八、与同类模型横向对比
![[assets/TimesNet/figure7-temporal-2d-variations-case.png]]
论文 Figure 7:电力数据集的 2D-variation 可视化案例。左侧 Value Bar 显示序列的频率分布(Frequency=5, 9, 15 三个主要周期),右侧对应 3 个折叠出的 2D 矩阵(Period=72, 40, 24 小时)。可以看出列方向(周期内)呈现连续变化,行方向(周期间)呈现相邻行高度相似,体现了 2D 局部性假设的合理性。
| 维度 | DLinear | PatchTST | Autoformer | TimesNet |
|---|---|---|---|---|
| 核心 token 视角 | 变量级线性序列 | patch 局部片段 | 时间 token | 周期折叠后的 2D 网格 |
| 主要归纳偏置 | 趋势/季节线性外推 | patch 局部时间依赖 | 分解 + lag 相关 | FFT 周期 + Conv2d |
| 频域作用 | 无 | 无 | FFT 做自相关 | FFT 选主周期 |
| 是否用 attention | 否 | 是 | AutoCorrelation | 否 |
| 核心张量变形 | (B,T,C)→(B,C,T) | unfold patch | Q/K/V lag 聚合 | (B,T,D)→(B,D,f,p) |
| 支持多任务 | 否(预测专用) | 否 | 否 | 是(5 种任务统一) |
| 参数效率 | 极高 | 中 | 中 | 高(Shared Inception) |
| 连接视觉骨干 | 否 | 否 | 否 | 是(2D Kernel 直接替换) |
九、局限性与未来方向
| 局限 | 描述 | 可能方向 |
|---|---|---|
| 周期假设 | 对无明显周期的时序(如金融汇率),FFT 选出的"周期"意义弱 | 学习动态的非周期分解方式 |
| Padding 边界效应 | 末尾用 0 padding 到 | 循环 padding 或可学习 padding |
| 预测架构略重 | 需要额外的 predict_linear 先扩展时间轴 | 直接 decoder 输出,类似 Autoformer |
| 大规模预训练 | 论文最后提出但未实现;参数固定不依赖 C,天然适合跨数据集预训练 | 基于 TimesNet 构建时序 Foundation Model |
思考问题
- [ ] FFT 的幅值能反映"哪个周期更重要",但幅值会因归一化方式不同而改变。如果对序列做了 Instance Normalization,FFT 幅值的含义是否还准确?
- [ ] TimesNet 对每个周期用同一个 Inception Block(共享权重)。是否可以为每个频率分配不同的轻量 adapter(类似 LoRA)来提升区分度?
- [ ] 论文中说"2D 局部性"是 Conv2d 有效的基础:相邻列(intraperiod)和相邻行(interperiod)的值应该接近。但对于 exchange 数据(无明显周期),这个局部性假设是否成立?
- [ ] 论文使用 mean 合并 3 路 Conv2d 输出。如果改为 attention 加权合并(每个 kernel size 一个 weight),对性能有什么影响?
- [ ] TimesNet 的 predict_linear 在预测任务中先把时间轴从 seq_len 扩展到 T=seq_len+pred_len,这等价于对未来做了线性外推初始化。这个设计和 Autoformer 的 decoder 有何本质异同?
关联笔记
- [[Autoformer/00-总览]] — Autoformer 用 FFT 做自相关(AutoCorrelation),TimesNet 用 FFT 找周期;两者都受频域分析启发,但目标不同
- [[TimesNet/00-总览]] — 代码精读系列,对应本笔记的实现细节
- ![[zdocs/modelread/TimesNet/TimesNet.pdf#page=1|TimesNet 原论文]]