// Step definitions — the narrative backbone of the playground. // Each step knows which pipeline elements are "active" (highlighted), // which formula block to highlight, and what's shown on the graph. const STEPS = [ { id: "input", title: "输入", subtitle: "带属性图 G = (V, E, X)", active: ["input-x", "input-a"], formula: "input", desc: "论文 Sec. 3.1 — DGAC 处理带属性的图 G = (V, E, X),其中 V 是 n 个节点的集合,E 是 m 条边,X ∈ ℝⁿˣᶠ 是属性矩阵(第 i 行 Xᵢ 是节点 vᵢ 的属性)。邻接矩阵 A 从 E 导出(Aᵢⱼ = 1 当且仅当 (vᵢ, vⱼ) ∈ E)。不同于传统 GNN,DGAC 不需要标签就能聚类,并在同质(Cora)与异质(Texas / Wisconsin)图上都稳定工作。", }, { id: "encode", title: "输入编码", subtitle: "交叉模态初值:U = SVD_d(X̄),B = eig_d(Â)", active: ["input-x", "input-a", "s-enc", "a-enc"], formula: "encode", desc: "论文 Eq.12-13 / Lemma 3 — DGAC 的交叉模态设计:拓扑分支的初值 H₀ᵗ = U 来自属性侧(X̄ = diag(d)⁻¹ᐟ²·X 的 SVD),属性分支的初值 H₀ᵃ = B 来自拓扑侧(Â 的前 d 个特征向量)。两个初值把对侧的结构信息注入本分支,再各自扩散。", }, { id: "topology", title: "拓扑分支扩散", subtitle: "Hᵗ ← α · Â · Hᵗ + H₀ᵗ (迭代 L 次)", active: ["s-enc", "top-diff"], formula: "topology", desc: "论文 Eq.12 — 拓扑分支沿归一化邻接 Â 做 L 步 APPNP 风格扩散:每一步把当前表示在邻居上做加权平均,再加一个与初值 H₀ᵗ = U 的残差项。展开得闭式 Hᵗ = Σ αℓ Âℓ U。", }, { id: "attribute", title: "属性分支扩散", subtitle: "Hᵃ ← α · Ŝ · Hᵃ + H₀ᵃ (迭代 L 次)", active: ["a-enc", "attr-diff"], formula: "attribute", desc: "论文 Eq.13 — 属性分支沿属性相似图 Ŝ 做同形式的扩散,初值是来自拓扑侧的 B。Ŝ = X̂·X̂ᵀ 把特征接近的节点视作「虚拟邻居」,哪怕它们在原图 A 中无边 —— 这是对异质图友好的关键。", }, { id: "fusion", title: "双分支融合", subtitle: "Z = H·W (线性变换) → H = β·Zᵗ + (1-β)·Zᵃ → L2 归一化", active: ["top-diff", "attr-diff", "fusion"], formula: "fusion", desc: "论文 Eq.14 — 先分别做线性变换 Zᵗ=Hᵗ·Wᵗ、Zᵃ=Hᵃ·Wᵃ(Wᵗ/Wᵃ 可学习),再用可调权重 β 线性融合,最后每行 L2 归一化 ‖H_i‖=1。β 靠近 1 更信任拓扑,靠近 0 更信任属性;异质图通常需要更小的 β。", }, { id: "kmeans", title: "K-means 初分配", subtitle: "在 H 上做余弦 k-means 得 C₀", active: ["fusion", "kmeans"], formula: "kmeans", desc: "论文 Sec. 5.2 — 对融合表示 H 做一次余弦 k-means,得到硬分配矩阵 C₀ ∈ {0,1}ᴺˣᴷ。这是一次「粗糙」的分配,可能有不少节点被分错 —— 下一步的 C-prop 会用邻居投票纠错。 想看代码真实跑什么?点 K-MEANS 公式块的 k-means chip → popover 底部「Impl Note · 代码真相」(CPU sklearn / 双重角色 / cosine 参数失效)。", }, { id: "cprop", title: "簇分配扩散 (C-prop)", subtitle: "C ← γ · Â · C + C₀ (迭代 Lc 次,论文 Eq.16)", active: ["kmeans", "cprop"], formula: "cprop", desc: "DGAC 的点睛之笔:把硬分配 C₀ 也放回图上扩散 —— 错误分配的节点被邻居「纠正」,形成软分配 C。不需要梯度,靠扩散本身平滑。系数是 γ,与分支扩散的 α 区分开(playground toy 实现共用一个滑块)。剧场里的微妙之处:protagonist 被 km 错分的根本原因通常不是邻居们 km 也错了,而是它有跨簇邻居(异质边)—— 这些邻居本身 km 是对的,但在特征扩散时把 k-means 的簇心往自己那边拉偏了。cprop 能把它纠回来,靠的是同簇邻居数 > 跨簇邻居数(论文的 homophily 假设);异质图上这条件破坏,DGAC 就用属性分支 Ŝ 补救。", }, { id: "loss", title: "自监督目标", subtitle: "L = L_cont + L_cluster + L_recons", active: ["fusion", "cprop", "loss"], formula: "loss", desc: "论文 Section 5.3 的三项顶层损失:(1) L_cont — 分层对比,三粒度(节点/邻居/簇)一致性 + 去相关 L_dec;(2) L_cluster — InfoNCE 式簇心对比;(3) L_recons — Scaled Cosine Error,H 与 X̂ 对齐。无需标签。", }, { id: "output", title: "输出聚类", subtitle: "argmax(C)", active: ["cprop", "output"], formula: "output", desc: "训练收敛后,argmax(C) 就是最终聚类结果。在 Cora / Citeseer / Texas / Wisc 等 12 个图数据集上,DGAC 在 ACC / NMI / ARI / F1 四项指标上都达到 SOTA。", }, ]; window.STEPS = STEPS;