Appearance
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,在变量维度做注意力,能建模跨变量依赖——但它假设所有变量用相同方式处理(静态、均匀的通道关系)。现实数据有两个麻烦:
- 分布漂移(Distribution Shift):不同时间窗口的时序分布可能不同,同一个线性层难以处理所有模式
- 通道异质性(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)
→ 为每个通道对独立决定"是否参与注意力"三、跨模型对比表
| 维度 | DLinear | iTransformer | PatchTST | DUET |
|---|---|---|---|---|
| token 语义 | 无 token | 变量 | 时间 patch | 变量(同 iTransformer) |
| 注意力轴 | 无 | 变量轴(N×N) | 时间轴(P×P) | 变量轴(N×N) |
| 多变量建模 | CI(独立) | CD(全连接) | CI(独立) | 动态稀疏 CD |
| 分布漂移 | ❌ 静态线性 | ❌ 静态 | ❌ 静态 | ✅ MoE 路由 |
| 通道选择 | ❌ | ❌(所有通道全连接) | ❌ | ✅ Mahalanobis 掩码 |
| 归一化 | 无 | 无 | 无 | RevIN(affine) |
| 复杂度 | ||||
| 额外训练损失 | ❌ | ❌ | ❌ | ✅ 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 Gating | noisy_top_k_gating() in Linear_extractor_cluster | [[03A-Layer2A-MoE时序路径]] |
| Sparse Dispatcher | SparseDispatcher 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 参数
| 参数 | 值 | 说明 |
|---|---|---|
| B | 3 | batch size |
| seq_len | 16 | 输入序列长度 |
| pred_len | 5 | 预测步数 |
| enc_in (N) | 7 | 变量数 |
| d_model | 8 | 隐层维度(= MoE expert 输出维度) |
| n_heads | 2 | 注意力头数 |
| d_ff | 32 | FFN 隐层 |
| num_experts | 6 | MoE 专家数 |
| k | 1 | top-k 激活专家数(超参,非形状维度) |
| hidden_size | 10 | 门控 MLP 隐层 |
| moving_avg | 3 | series_decomp 核大小(奇数) |
| freq_size | 9 | = seq_len//2+1 = 16//2+1 |
| d_keys | 4 | = d_model//n_heads = 8//2 |
| B×N | 21 | = 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)