Appearance
DUET · 收束
§1 端到端完整流程
§2 Tensor 变化汇总表
| 步骤 | 操作 | 输入 shape | 输出 shape | 说明 |
|---|---|---|---|---|
| 0 | 框架输入 | — | (3, 16, 7) | B, seq_len, N |
| 1 | CI rearrange | (3, 16, 7) | (21, 16, 1) | B×N 展开,单变量格式 |
| 2 | RevIN norm(CI 技巧) | (21,16,1) → 临时 (3,16,7) → 还原 | (21, 16, 1) | 存储 μ/σ 供 denorm 用 |
| 3 | 门控网络(mean→MLP) | (21, 16, 1) → mean → (21, 16) → ... | (21, 6) gates | 稀疏,每行 1 个非零 |
| 4 | SparseDispatcher init | (21, 6) | 索引结构 | _batch_index/_part_sizes |
| 5 | dispatch | (21, 16, 1) | 6×(n_i, 16, 1) | |
| 6 | 6 个 Linear_extractor | 各 (n_i, 16, 1) | 各 (n_i, 8, 1) | series_decomp+Linear(16→8) |
| 7 | combine | 6×(n_i, 8, 1) | (21, 8, 1) | × gate weight + index_add |
| 8 | rearrange 恢复 | (21, 8, 1) | (3, 8, 7) | B×d_model×N |
| 9 | rearrange 转置 | (3, 8, 7) | (3, 7, 8) | B×N×d_model,变量 token |
| 10 | 通道路径 rearrange | (3, 16, 7) | (3, 7, 16) | B×N×L,计算通道距离用 |
| 11 | Mahalanobis_mask | (3, 7, 16) | (3, 1, 7, 7) | rfft→距离→Gumbel采样 |
| 12 | Channel_transformer | (3,7,8) + (3,1,7,7) | (3, 7, 8) | 带掩码变量注意力 × 2 层 |
| 13 | linear_head | (3, 7, 8) | (3, 7, 5) | Linear(8→5) |
| 14 | rearrange 输出 | (3, 7, 5) | (3, 5, 7) | B×pred_len×N |
| 15 | RevIN denorm | (3, 5, 7) | (3, 5, 7) | 还原量纲 |
| 16 | MoE 损失 | gates (21,6) | scalar | cv_squared(importance+load) |
§3 核心设计决策回顾
3.1 为什么分两条路径?
| 问题 | 路径 | 解法 |
|---|---|---|
| 分布漂移:不同样本的时序统计特征不同,单一线性层无法适应 | MoE 时序路径 | 多个专家各有特化的权重,门控网络决定当前样本用哪个专家 |
| 通道异质:不同变量间的相关性强弱不一,全连接注意力引入噪声 | Mahalanobis 通道路径 | 频域相似度 → 稀疏掩码,只允许真正相关的通道对互相传递信息 |
两条路径在 Channel_transformer 处汇合:MoE 提供"每个变量的特征向量"(token),Mahalanobis 掩码控制"哪些 token 对之间允许注意力"。
3.2 为什么 RevIN 放在 MoE 路径里(而不是最外层)?
RevIN 需要知道变量轴(N 维)才能计算各变量的 μ/σ。在 CI 模式下,进入 MoE 之前数据已被展开为 (B*N, L, 1),"变量轴"消失了。解决方案:在 Linear_extractor_cluster.forward() 内部做临时 rearrange:(B*N, L, 1) → (B, L, N) → RevIN → 还原。这样 RevIN 仍能对 N 个变量分别归一化,且整个过程对外不可见。
3.3 Gumbel Bernoulli 采样的梯度如何传回 A?
掩码 mask 是离散的(0/1),不可直接求导。Gumbel Softmax(hard=True)的 straight-through estimator:前向传播用 argmax 得到 0/1 掩码,反向传播用 softmax 的梯度代替。这样梯度可以通过 softmax → logit = log(p/(1-p)) → p → exp_dist → dist → temp = A @ diff → A,训练 A 去学习哪些频率分量的差异对预测最重要。
§4 跨模型对比表
| 维度 | DLinear | iTransformer | PatchTST | DUET |
|---|---|---|---|---|
| token 语义 | 无 token | 变量(整条序列) | 时间 patch | 变量(MoE 特征) |
| 注意力轴 | 无 | 变量轴(N×N) | 时间轴(P×P) | 变量轴(N×N),稀疏掩码 |
| 多变量建模 | CI(完全独立) | CD(全连接) | CI | 动态稀疏 CD |
| 分布漂移处理 | ❌ 静态权重 | ❌ | ❌ | ✅ MoE(多专家路由) |
| 通道选择 | ❌ | ❌ 所有通道全连接 | ❌ | ✅ Mahalanobis 掩码 |
| 归一化 | 无 | 无 | 无 | ✅ RevIN(affine=True,CI 特殊技巧) |
| 注意力复杂度 | — | |||
| 额外训练损失 | ❌ | ❌ | ❌ | ✅ MoE 负载均衡(cv_squared) |
| 主任务损失 | MSE | MSE | MSE | Huber Loss |
| 专家数量 | — | — | — | 4(默认),top-k=1 激活 |
§5 文档完整性确认
| 文档 | 覆盖组件 | 状态 |
|---|---|---|
| [[00-总览]] | 全局动机、BFS 树、toy 参数 | ✅ |
| [[01-Layer0-接入界面]] | DUET adapter、config 组装、_process | ✅ |
| [[02-Layer1-DUETModel主链]] | DUETModel forward、rearrange 链 | ✅ |
| [[03A-Layer2A-MoE时序路径]] | Linear_extractor_cluster、noisy gating、RevIN CI 技巧 | ✅ |
| [[03A1-Layer3-SparseDispatcher]] | dispatch/combine 稀疏索引机制 | ✅ |
| [[03A2-Layer3-LinearExpert]] | Linear_extractor、series_decomp、DLinear 骨架 | ✅ |
| [[03B-Layer2B-MahalanobisMask]] | rfft 距离、Gumbel Bernoulli 采样 | ✅ |
| [[03C-Layer2C-ChannelTransformer]] | 带掩码 Encoder、AttentionLayer、FullAttention、FFN | ✅ |
| [[04-收束]] | 端到端流程、tensor 汇总、设计回顾 | ✅ |
SVG 资产:
| 文件 | 引用文档 | 状态 |
|---|---|---|
duet_architecture.svg | 02-Layer1 | ✅ |
duet_moe_dispatch.svg | 03A-Layer2A | ✅ |
duet_mahalanobis_mask.svg | 03B-Layer2B | ✅ |
duet_channel_attention.svg | 03C-Layer2C | ✅ |
创建:2026-04-24 · DUET BFS 精读完结