Skip to content

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 把实值序列变成复数频谱;频率 f 对应周期 p=T/f;幅值 = 复数模[[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 的"分周期"思路可以对比
DLinearSOTA 线性基线;TimesNet 论文中是重要对比对象

0.3 背景:前作留下了什么问题

传统模型把时序看成一根 1D 线段:t0, t1, t2, ..., tT,要么对相邻点建模(RNN、TCN),要么对所有点做 attention(Transformer 系列)。

这个视角有两个盲区:

  1. 多周期叠加:现实时序(电力、交通、气象)往往是日周期、周周期、年周期的叠加。在 1D 轴上,这些周期彼此交织,很难同时捕获。
  2. 局部结构:同一周期内相邻时刻的"周期内变化",与不同周期块之间的"周期间变化",在 1D 表达里没有结构区分。

TimesNet 的突破口:把 1D 时序按主要周期"折叠"成 2D 网格,周期内位置 → 列,不同周期块 → 行,两类变化立刻成为 2D 图像的列方向和行方向,天然适合 Conv2d。


一、问题定义

输入:历史观测 X1DRT×CT 为序列长度,C 为变量数。

任务:TimesNet 以统一的架构支持 5 种分析任务:

  • 长期预测(Long-term Forecasting)
  • 短期预测(Short-term Forecasting)
  • 插值/填补(Imputation)
  • 分类(Classification)
  • 异常检测(Anomaly Detection)

核心符号

符号含义
k超参数,选 top-k 频率(实验中预测=5,其他=3)
pii 个频率对应的周期长度 pi=T/fi
fi对应周期 pi 的折叠后列数(行数) fi=T/pi
ART幅值向量,Aj = frequency-j 的强度(多变量平均)
X2Dl,il 层第 i 个周期折叠出的 2D 张量 Rpi×fi×C

二、整体架构鸟瞰

![[assets/TimesNet/figure3-timesnet-overall-architecture.png]]

论文 Figure 3:TimesNet 整体架构。左侧:多个 TimesBlock 以残差方式堆叠,输入和输出均为 1D 特征 X1Dl。右侧:单个 TimesBlock 内部的 1D→2D→1D 流程——从底部 1D 序列出发,折叠成 k 个不同尺度的 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 个频率;中间:对每个频率 fi 把序列折叠成一个矩形 2D 张量(每列是周期内位置,每行是相邻周期块);右侧:2D 张量可直接被 2D kernel 同时沿列方向(intraperiod-variation)和行方向(interperiod-variation)建模。

3.1 FFT 周期发现(Eq. 1–2)

A,{f1,,fk},{p1,,pk}=Period(X1D)

具体步骤

  1. 对长度 T 的序列做 rfft,得 T/2+1 个复数频率系数
  2. 幅值 =|FFT|;多变量时在 C 维度上平均 → ART/2
  3. topk(A, k) 取幅值最大的 k 个频率 {f1,,fk}
  4. 对应周期 pi=T/fi,只考虑 fi[1,T/2](避免直流分量)

数值示例: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 对应的真实频率:f=0,1,2,,6(单位:cycles/T)

频率 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(次大)→ f1=6,f2=5

Step 3:换算周期

  • p1=13/6=2(主周期 ✓)
  • p2=13/5=2(凑巧相同,实际数据通常不同)
真实数据更直观

电力消耗序列 FFT 后幅值会在 bin=24(对应日周期=24小时)和 bin=168(周周期=168小时)处有明显峰值。

3.2 Padding + Reshape:1D→2D(Eq. 3)

X2Di=Reshapepi,fi(Padding(X1D)),i{1,,k}

原则:将长度 T 的序列用 0 padding 到 pi×fi,然后 reshape 成 (fi,pi) 矩阵。

实现中实际的 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 矩阵上滑动:1×1 看单点,3×3 同时看 3 个相邻时刻 + 3 个相邻周期块

四、TimesBlock:核心计算单元

TimesBlock 的完整前向公式(Eq. 4–5):

X1Dl=TimesBlock(X1Dl1)+X1Dl1

内部:

Al1,{f1,,fk},{p1,,pk}=Period(X1Dl1)X2Dl,i=Reshapepi,fi(Padding(X1Dl1))X^2Dl,i=Inception(X2Dl,i)X^1Dl,i=Trunc(Reshape1,(pi×fi)(X^2Dl,i))

4.1 Inception_Block_V1:多尺度 2D 卷积

输入:(B, D, f, p)(2D 张量)

三路并行 Conv2d,kernel size 分别为 1×13×35×5(均用 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捕获的结构
1×1单时刻单周期块的点特征
3×33 个相邻时刻 × 3 个相邻周期块的局部结构
5×5更大范围的周期内变化 + 趋势变化

关键设计:同一个 Inception Block 的参数在 k 个不同周期分支间共享(Shared)——这使模型参数量不随 k 增大而增大。

4.2 Adaptive Aggregation:幅值加权融合(Eq. 6)

A^f1l1,,A^fkl1=Softmax(Af1l1,,Afkl1)X1Dl=i=1kA^fil1×X^1Dl,i

直觉:FFT 幅值代表各频率的"信号强度",强周期对应的 2D 特征应获得更高的聚合权重。Softmax 保证权重和为 1。

数值示例:Adaptive Aggregation(k=2, T=13, D=1)

输入 FFT 幅值(对应 k=2 个被选频率):

Af1=3.2,Af2=1.8

Softmax

A^1=e3.2e3.2+e1.8=24.5324.53+6.050.80A^2=e1.8e3.2+e1.80.20

加权聚合(假设两路 1D 结果):

X^1D1=[1.0,0.5,1.0,0.5,]X^1D2=[0.8,0.9,0.8,0.9,]X1Dl=0.80×[1.0,0.5,]+0.20×[0.8,0.9,]=[0.96,0.58,]
验证
  • 权重和 = 0.80 + 0.20 = 1.0 ✓
  • 主周期(幅值更大)贡献 80% 权重,次周期贡献 20% ✓
  • 如果 k=1,退化为直接使用单路结果 ✓

五、训练细节

优化器:Adam(β1=0.9,β2=0.999),学习率 104(预测/异常检测)到 103(分类)

损失函数

  • 预测/插值:MSE
  • 短期预测:SMAPE(对称平均绝对百分比误差)
  • 分类:Cross Entropy
  • 异常检测:MSE(无监督重建误差)

关键工程细节

  • 归一化:Series Stationarization(减均值、除标准差),来自 Non-stationary Transformer
  • d_model 随变量数 C 自适应:dmodel=min(max(2logC,dmin),dmax),保证参数量不随 C 爆炸
  • 预测任务:用一个额外的 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):

数据集TimesNetAutoformerDLinear改进
ETTm10.4000.5880.299Autoformer −32%
Electricity0.1920.2270.212最优
Weather0.2590.3380.265接近 DLinear

5 任务综合排名(Table 11):TimesNet 所有任务排名均为 1,平均排名 1.0,是唯一在 5 个任务全部第一的模型。


七、消融实验

来自附录 C(Table 8, 9, 10)的关键结论:

消融点结论
替换 Inception → ResNet/ResNeXt/SwinTransformerF1-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 局部性假设的合理性。

维度DLinearPatchTSTAutoformerTimesNet
核心 token 视角变量级线性序列patch 局部片段时间 token周期折叠后的 2D 网格
主要归纳偏置趋势/季节线性外推patch 局部时间依赖分解 + lag 相关FFT 周期 + Conv2d
频域作用FFT 做自相关FFT 选主周期
是否用 attentionAutoCorrelation
核心张量变形(B,T,C)→(B,C,T)unfold patchQ/K/V lag 聚合(B,T,D)→(B,D,f,p)
支持多任务否(预测专用)是(5 种任务统一)
参数效率极高高(Shared Inception)
连接视觉骨干是(2D Kernel 直接替换)

九、局限性与未来方向

局限描述可能方向
周期假设对无明显周期的时序(如金融汇率),FFT 选出的"周期"意义弱学习动态的非周期分解方式
Padding 边界效应末尾用 0 padding 到 p×f,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 原论文]]

*记录并在线阅读我的笔记*