Skip to content

DUET 总览

精读范围

完整 BFS 精读:DUET 是 Phase 4 中架构最复杂的模型,引入了两个全新组件(MoE 时序路由 + Mahalanobis 通道掩码),值得完整分层。


一、它解决什么问题

Phase 4 定位

Phase 3 确立了四条路线后,Phase 4 转向具体场景专攻:

PatchTST (路线A: 时间patch+CI) ──→ CycleNet (强周期数据)
iTransformer (路线B: 变量token+CD) ──→ DUET (分布漂移+通道异质)

iTransformer 的剩余问题:iTransformer 把每个变量作为 token,在变量维度做注意力,能建模跨变量依赖——但它假设所有变量用相同方式处理(静态、均匀的通道关系)。现实数据有两个麻烦:

  1. 分布漂移(Distribution Shift):不同时间窗口的时序分布可能不同,同一个线性层难以处理所有模式
  2. 通道异质性(Channel Heterogeneity):不同变量间的相关性强弱不一致,有些变量强相关,有些几乎独立;用同一个注意力权重矩阵建模所有关系会引入噪声

DUET 的解法

分布漂移 ──→ Mixture of Experts (MoE)
              每个样本被路由到最合适的专家(不同线性变换)
              让不同分布的输入走不同的计算路径

通道异质性 ──→ Mahalanobis 距离掩码
               在频域计算通道两两相似度
               相似度低的通道对在注意力中被掩码掉(置为 0)
               Attention 只在真正相关的通道间传播信息

二、核心创新

2.1 MoE 时序路径(分布漂移)

输入 (B, L, N)

  ├── RevIN 归一化

  ├── 门控网络(encoder): mean(x) → MLP → logits (B*N, num_experts)
  │   └── noisy top-k gating: 添加噪声 + softmax + top-1 → sparse gates

  ├── SparseDispatcher: 按 gate 把样本分发给各专家
  │   ├── Expert 0 (Linear_extractor): series_decomp → Linear_S + Linear_T
  │   ├── Expert 1 (Linear_extractor): 同上,不同权重
  │   └── ...

  └── SparseDispatcher.combine: 按 gate 权重聚合输出
      → temporal_feature (B, N, d_model)

每个专家是一个独立的 DLinear 骨架(seasonal + trend 两路线性)。路由机制决定当前输入的分布特征最适合哪个专家。

2.2 Mahalanobis 通道掩码(通道异质性)

输入 (B, N, L)

  ├── rfft → 频谱幅度 |XF| (B, N, freq_size)

  ├── 两两做差: diff[b,i,j,:] = |XF|[b,i,:] - |XF|[b,j,:]

  ├── Mahalanobis 距离: dist = einsum(A, diff)^2  (可学习矩阵 A)

  ├── 相似度: p = 1/(dist+ε),对角线置 0,归一化到 [0,1]

  └── Bernoulli+Gumbel softmax 采样 → 0/1 掩码 (B, 1, N, N)
      → 为每个通道对独立决定"是否参与注意力"

三、跨模型对比表

维度DLineariTransformerPatchTSTDUET
token 语义无 token变量时间 patch变量(同 iTransformer)
注意力轴变量轴(N×N)时间轴(P×P)变量轴(N×N)
多变量建模CI(独立)CD(全连接)CI(独立)动态稀疏 CD
分布漂移❌ 静态线性❌ 静态❌ 静态✅ MoE 路由
通道选择❌(所有通道全连接)✅ Mahalanobis 掩码
归一化RevIN(affine)
复杂度O(L)O(N2d)O(P2d)O(N2d)(通道)+ O(kEd)(MoE)
额外训练损失✅ MoE 负载均衡损失

四、论文架构图(原理层)


五、TFB 调用链

DUET._process 特殊点:返回 {"output": output, "additional_loss": loss_importance}(仅训练时),loss_importance 是 MoE 负载均衡损失,由框架自动叠加到主损失上。


六、文档 BFS 树形索引


七、论文组件 → 代码对应表

论文组件代码实现精读文档
Mixture of Experts(MoE)时序提取Linear_extractor_cluster[[03A-Layer2A-MoE时序路径]]
Noisy Top-k Gatingnoisy_top_k_gating() in Linear_extractor_cluster[[03A-Layer2A-MoE时序路径]]
Sparse DispatcherSparseDispatcher in linear_extractor_cluster.py[[03A1-Layer3-SparseDispatcher]]
单个线性专家(DLinear 骨架)Linear_extractor in linear_pattern_extractor.py[[03A2-Layer3-LinearExpert]]
分布感知门控(distributional router)encoder in distributional_router_encoder.py[[03A-Layer2A-MoE时序路径]] §5.3
Mahalanobis 通道相似度掩码Mahalanobis_mask in masked_attention.py[[03B-Layer2B-MahalanobisMask]]
Gumbel-Bernoulli 可微分采样bernoulli_gumbel_rsample()[[03B-Layer2B-MahalanobisMask]] §5.4
通道 Transformer(带掩码)Encoder + EncoderLayer + FullAttention in masked_attention.py[[03C-Layer2C-ChannelTransformer]]
RevIN 归一化RevIN in layers/RevIN.py[[03A-Layer2A-MoE时序路径]] §5.2

八、全局 Toy 参数

参数说明
B3batch size
seq_len16输入序列长度
pred_len5预测步数
enc_in (N)7变量数
d_model8隐层维度(= MoE expert 输出维度)
n_heads2注意力头数
d_ff32FFN 隐层
num_experts6MoE 专家数
k1top-k 激活专家数(超参,非形状维度)
hidden_size10门控 MLP 隐层
moving_avg3series_decomp 核大小(奇数)
freq_size9= seq_len//2+1 = 16//2+1
d_keys4= d_model//n_heads = 8//2
B×N21= 3×7(CI 模式下 batch 展开后的维度)
所有维度互不相同

{B=3, seq_len=16, pred_len=5, enc_in=7, d_model=8, n_heads=2, d_ff=32, num_experts=6, hidden_size=10, freq_size=9, d_keys=4, B×N=21} 全部不同,shape 追踪时任意 transpose/reshape 都可清晰识别。


九、推荐阅读路径

快速了解直觉(30 min)00-总览02-Layer1-DUETModel主链(看架构 SVG 和双路 forward 流程)

完整代码精读(3–4 h):按编号顺序 01 → 02 → 03A → 03A1 → 03A2 → 03B → 03C → 04

重点关注

  • 03A-MoE时序路径:SparseDispatcher 的 dispatch/combine 是稀疏 MoE 的经典实现,理解后可迁移到其他 MoE 架构
  • 03B-MahalanobisMask:Gumbel-Bernoulli 采样是可微分离散决策的标准技巧,值得深入

创建:2026-04-24 · 精读范围:DUET 完整 BFS(MoE + Mahalanobis)

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