md_files/科研/动态图神经网络.md

681 lines
25 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 动态图神经网络
## 如何对GAT的权重$W$)和注意力参数($a$)进行增量更新(邻居偶尔变化)
#### 1. 核心思想
- **局部更新**:邻居变化的节点及其直接邻域的权重和注意力参数需要调整,其他部分冻结。
- **梯度隔离**:反向传播时,仅计算受影响节点的梯度,避免全局参数震荡。
---
#### 2. 数学实现步骤
#### **(1) 识别受影响的节点**
设邻居变化后的新邻接矩阵为 $\tilde{A}$,原邻接矩阵为 $A$,受影响节点集合 $\mathcal{V}_{\text{affected}}$ 包括:
- 新增或删除边的两端节点(直接受影响)。
- 这些节点的1-hop邻居间接受影响根据GAT层数决定
#### **(2) 损失函数局部化**
仅对 $\mathcal{V}_{\text{affected}}$ 中的节点计算损失:
$$
\mathcal{L}_{\text{incremental}} = \sum_{i \in \mathcal{V}_{\text{affected}}} \ell(y_i, \hat{y}_i)
$$
其中 $\ell$ 为交叉熵损失,$y_i$ 为标签,$\hat{y}_i$ 为模型输出。
#### **(3) 梯度计算与参数更新**
- **梯度掩码**
反向传播时,非受影响节点的梯度强制置零:
$$
\nabla_{W,a} \mathcal{L}_{\text{incremental}} = \left\{
\begin{array}{ll}
\nabla_{W,a} \ell(y_i, \hat{y}_i) & \text{if } i \in \mathcal{V}_{\text{affected}} \\
0 & \text{otherwise}
\end{array} \right.
$$
- **参数更新**
使用优化器如Adam仅更新有梯度的参数
$$
W \leftarrow W - \eta \nabla_W \mathcal{L}_{\text{incremental}}, \quad a \leftarrow a - \eta \nabla_a \mathcal{L}_{\text{incremental}}
$$
其中 $\eta$ 为较小的学习率(防止过拟合)。
#### **(4) 注意力权重的动态适应**
GAT的注意力机制会自动适应新邻居
$$
\alpha_{ij} = \text{softmax}\left(\text{LeakyReLU}\left(a^T [W h_i \| W h_j]\right)\right)
$$
由于 $W$ 和 $a$ 已局部更新,新邻居 $j \in \tilde{\mathcal{N}}(i)$ 的权重 $\alpha_{ij}$ 会重新计算。
#### 3. 适用场景
- **低频变化**:如社交网络每天新增少量边、论文引用网络月度更新。
- **局部变化**:每次变化仅影响图中少量节点(<10%)。
若邻居**高频变化**如秒级更新需改用动态GNN如TGAT或时间序列建模
## EvolveGCN
### EvolveGCN-H
#### **1. EvolveGCN-H核心思想**
EvolveGCN-H 通过 **GRU门控循环单元** 动态更新 GCN 每一层的权重矩阵 $W_t^{(l)}$将权重矩阵视为 GRU **隐藏状态**并利用当前时间步的 **节点嵌入(特征)** 作为输入来驱动演化
**关键特点**
- **输入依赖**利用节点嵌入 $H_t^{(l)}$ 指导权重更新
- **时序建模**通过 GRU 隐式捕捉参数演化的长期依赖
---
#### **2. 动态更新流程(以第 $l$ 层为例)**
**输入**
1. 当前节点嵌入矩阵 $H_t^{(l)} \in \mathbb{R}^{n \times d}$
2. 上一时间步的权重矩阵 $W_{t-1}^{(l)} \in \mathbb{R}^{d \times d'}$
3. 邻接矩阵 $A_t \in \mathbb{R}^{n \times n}$
**输出**
1. 更新后的权重矩阵 $W_t^{(l)} \in \mathbb{R}^{d \times d'}$。
2. 下一层节点嵌入 $H_t^{(l+1)} \in \mathbb{R}^{n \times d'}$。
---
#### **3. 动态更新示意图**
```plaintext
Time Step t-1 Time Step t
+-------------------+ +-------------------+
| Weight Matrix | | Weight Matrix |
| W_{t-1}^{(l)} | --(GRU更新)--> | W_t^{(l)} |
+-------------------+ +-------------------+
^ ^
| |
+-------------------+ +-------------------+
| Node Embeddings | | Node Embeddings |
| H_t^{(l)} | --(GCN计算)--> | H_t^{(l+1)} |
+-------------------+ +-------------------+
^ ^
| |
+-------------------+ +-------------------+
| 邻接矩阵 A_t | | 邻接矩阵 A_{t+1} |
| (显式输入) | | (下一时间步输入) |
+-------------------+ +-------------------+
```
$$
\begin{align*}
W_t^{(l)} &<= H_t^{(l)} + W_{t-1}^{(l)} \\
H_t^{(l+1)} &<= A_t + H_t^{(l)} + W_t^{(l)}
\end{align*}
$$
#### **4. 具体步骤分解**
##### **步骤 1节点嵌入聚合Summarize**
由于 GRU 的输入需与隐藏状态 $W_{t-1}^{(l)}$ 的列维度匹配 $d'$需将 $H_t^{(l)}$ $n \times d$ 压缩为 $d' \times d$
$$
Z_t = \text{Summarize}(H_t^{(l)}, d')
$$
将会舍弃部分节点
**实现方式**论文方案
1. 计算得分
$$
y_t = H_t^{(l)} p / \|p\| \quad (p \in \mathbb{R}^d \text{为可学习参数})
$$
学一个打分器参数 $p$$H_t^{(l)} p$相当于对每个节点的嵌入向量和 $p$做点积得到一个分数比如在社交网络中$p$ 可能代表活跃度”,得分高的用户更活跃
2. 选取 Top-$d'$ 个节点 $y_t$ 排序加权求和
$$
Z_t = [H_t^{(l)} \circ \tanh(y_t)]_{\text{top-}d'} \quad (\circ \text{为逐元素乘})
$$
- 输出 $Z_t \in \mathbb{R}^{d' \times d}$。
**举个例子**
假设
- 有3个节点$n=3$),嵌入维度 $d=2$选Top-2个节点$d'=2$)。
- 节点嵌入
$$
H_t^{(l)} = \begin{bmatrix} 1 & 0.5 \\ 0.3 & 2 \\ -1 & 1 \end{bmatrix}, \quad p = [1, 0]
$$
$p$ 只关注嵌入的第一维比如用户发帖数量”)
1. **计算分数**
$$
y_t = H_t^{(l)} p = [1 \cdot 1 + 0.5 \cdot 0, \ 0.3 \cdot 1 + 2 \cdot 0, \ -1 \cdot 1 + 1 \cdot 0] = [1, 0.3, -1]
$$
Top-2节点是第1第2个节点分数1和0.3)。
2. **加权聚合**
$$
Z_t = \begin{bmatrix} [1, 0.5] \circ \tanh(1) \\ [0.3, 2] \circ \tanh(0.3) \end{bmatrix} = \begin{bmatrix} 0.76 & 0.38 \\ 0.09 & 0.58 \end{bmatrix}
$$
假设 $\tanh(1) \approx 0.76$, $\tanh(0.3) \approx 0.29$
3. **输出**$Z_t$ $2 \times 2$ 矩阵可以直接喂给GRU
##### **步骤 2GRU 更新权重矩阵**
$$
W_t^{(l)} = \text{GRU}(Z_t^T, W_{t-1}^{(l)})
$$
标准GRU的输入隐藏输出都是向量但这里都是矩阵
当前时间步的输入$Z_t^T$
上一时间步的隐藏状态$W_{t-1}^{(l)}$
更新隐藏状态 $W_t^{(l)}$
| **标准GRU** | **论文中的矩阵GRU** | **作用** |
| ------------------------ | ------------------- | ------------------------------------------------------------ |
| $W_{xz}$ (输入更新门) | $W_Z$ | 将当前输入 $Z_t^T$ 映射到更新门 |
| $W_{hz}$ (隐藏更新门) | $U_Z$ | 将上一隐藏状态 $W_{t-1}^{(l)}$ 映射到更新门 |
| $b_z$ (更新门偏置) | $B_Z$ | 更新门的偏置项 |
| $W_{xh}$ (输入候选状态) | $W_H$ | 将当前输入 $Z_t^T$ 映射到候选状态 |
| $W_{hh}$ (隐藏候选状态) | $U_H$ | 将调制后的隐藏状态 $(R_t \circ W_{t-1}^{(l)})$ 映射到候选状态 |
| $b_h$ (候选状态偏置) | $B_H$ | 候选状态的偏置项 |
**GRU 的矩阵形式计算**
1. **重置门** $R_t$控制历史信息的遗忘程度
$$
R_t = \sigma(Z_t^T W_Z + W_{t-1}^{(l)} U_Z + B_Z)
$$
2. **更新门** $Z_t$控制新旧状态混合比例
$$
U_t = \sigma(Z_t^T W_U + W_{t-1}^{(l)} U_U + B_U)
$$
3. **候选状态** $\widetilde{W}_t$
$$
\widetilde{W}_t = \tanh(Z_t^T W_H + (R_t \circ W_{t-1}^{(l)}) U_H + B_H)
$$
4. **最终权重更新**
$$
W_t^{(l)} = (1 - U_t) \circ W_{t-1}^{(l)} + U_t \circ \widetilde{W}_t
$$
- 输出 $W_t^{(l)} \in \mathbb{R}^{d \times d'}$。
##### **步骤 3GCN 生成下一层嵌入**
使用更新的 $W_t^{(l)}$ 执行标准 GCN 操作
$$
H_t^{(l+1)} = \sigma\left(\widehat{A}_t H_t^{(l)} W_t^{(l)}\right)
$$
- $\widehat{A}_t$ 为归一化邻接矩阵含自环)。
---
#### **5. 关键设计细节**
1. **权重共享**
- 所有时间步共享同一 GRU 的参数$W_*, U_*, B_*$确保模型尺寸不随时间增长
2. **层独立性**
- 每一层 GCN 的权重矩阵独立演化不同层有各自的 GRU)。
3. **特征与结构的协同**
- 节点嵌入 $H_t^{(l)}$ 既包含特征信息也隐含历史结构信息通过多层 GCN 传播因此 GRU 能间接感知结构变化
#### 6. 所需提前训练的权重
| **参数类型** | **符号** | **维度** | **作用** |
| ---------------- | --------------- | --------------------------- | ------------------------------- |
| GCN 初始权重 | $W_0^{(l)}$ | $\mathbb{R}^{d \times d'}$ | 初始时刻各层 GCN 的初始参数 |
| GRU 输入变换矩阵 | $W_Z, W_R, W_H$ | $\mathbb{R}^{d \times d'}$ | 将输入 $Z_t^T$ 映射到门控 |
| GRU 隐藏变换矩阵 | $U_Z, U_R, U_H$ | $\mathbb{R}^{d' \times d'}$ | $W_{t-1}^{(l)}$ 映射到门控 |
| GRU 偏置项 | $B_Z, B_R, B_H$ | $\mathbb{R}^{d'}$ | 门控和候选状态的偏置 |
| Summarize 参数 | $p$ | $\mathbb{R}^d$ | 对特征进行打分不同层$p$不一样 |
| 任务相关参数 | 例如 MLP 权重 | 任务相关 | 链接预测节点分类等输出层 |
### **EvolveGCN-O**
#### **1. 核心思想**
EvolveGCN-O 通过 **LSTM** 直接演化 GCN 的权重矩阵 $W_t^{(l)}$将权重矩阵视为 **LSTM的输出**下一时间步的输入**不依赖节点嵌入**。
**关键特点**
- **结构驱动**仅通过历史权重 $W_{t-1}^{(l)}$ 预测当前权重完全基于图结构的动态变化
- **轻量化**无需处理节点嵌入计算效率更高
---
#### **2. 动态更新流程(第$l$层)**
**输入**
1. 上一时间步权重 $W_{t-1}^{(l)} \in \mathbb{R}^{d \times d'}$
2. 邻接矩阵 $A_t \in \mathbb{R}^{n \times n}$仅用于GCN计算
**输出**
1. 更新后权重 $W_t^{(l)} \in \mathbb{R}^{d \times d'}$
2. 下一层节点嵌入 $H_t^{(l+1)} \in \mathbb{R}^{n \times d'}$
#### 3.具体步骤分解
##### **步骤1LSTM更新权重矩阵**
**矩阵版LSTM计算**
1. 遗忘门
$F_t = \sigma(W_F W_{t-1}^{(l)} + U_F C_{t-1} + B_F)$
2. 输入门
$I_t = \sigma(W_I W_{t-1}^{(l)} + U_I C_{t-1} + B_I)$
3. 候选状态
$\widetilde{C}_t = \tanh(W_C W_{t-1}^{(l)} + U_C C_{t-1} + B_C)$
4. 细胞状态更新
$C_t = F_t \circ C_{t-1} + I_t \circ \widetilde{C}_t$
5. 输出门
$O_t = \sigma(W_O W_{t-1}^{(l)} + U_O C_{t-1} + B_O)$
6. 最终权重输出
$W_t^{(l)} = O_t \circ \tanh(C_t)$
##### **步骤2GCN生成下一层嵌入**
$H_t^{(l+1)} = \sigma(\widehat{A}_t H_t^{(l)} W_t^{(l)})$
#### **4. 与EvolveGCN-H对比**
| **特性** | **EvolveGCN-H** | **EvolveGCN-O** |
| -------------- | -------------------------- | ---------------------------- |
| **RNN类型** | GRU | LSTM |
| **演化依据** | 节点嵌入+历史权重 | 仅历史权重 |
| **计算复杂度** | 需Summarize | |
| **适用场景** | 特征动态性强如社交网络 | 结构变化主导如路由器拓扑 |
## TGAT
### Bochner定理
Bochner定理为TGAT的**连续时间编码**提供了理论基础使其能够将任意时间差映射为可学习的向量表示从而在动态图中有效捕捉时序依赖这一方法超越了传统离散编码的局限性是TGAT的核心创新之一
#### 时间编码的构造
**1Bochner 定理的数学形式**
根据Bochner定理任意正定时间核函数 $ f(\Delta t) $ 可表示为
$$
f(\Delta t) = \mathbb{E}_{\omega \sim \mu} \left[ e^{i \omega \Delta t} \right],
$$
其中 $e^{i \omega \Delta t} = \cos(\omega \Delta t) + i \sin(\omega \Delta t)$ 是复指数函数
**2蒙特卡洛近似 & 实值化**
由于直接计算期望复杂TGAT 用蒙特卡洛采样近似
1. 从分布 $\mu$ 中采样 $d$ 个频率 $\omega_1, \omega_2, \ldots, \omega_k$。
2. 用这些频率构造实值编码取复指数的实部和虚部 $\cos$ $\sin$
$$
\Phi_d(\Delta t) = \frac{1}{\sqrt d}\bigl[\cos(\omega_1 \Delta t),\sin(\omega_1 \Delta t),\dots,\cos(\omega_d \Delta t),\sin(\omega_d \Delta t)\bigr]
$$
这样就把时间差转成了一个长度为 $2d$ 的实值向量
#### 例子
$d=1$(此时时间编码向量就是二维的),有
$$
\Phi_1(\Delta t)\;=\;\frac{1}{\sqrt1}\bigl[\cos(\omega_1\Delta t),\;\sin(\omega_1\Delta t)\bigr]
=\bigl[\cos(\omega_1\Delta t),\;\sin(\omega_1\Delta t)\bigr].
$$
例如若我们令 $\omega_1=1$ $\Delta t = \pi/3$,那么
$$
\Phi_1\bigl(\pi/3\bigr)
=\bigl[\cos(\pi/3),\;\sin(\pi/3)\bigr]
=\bigl[0.5,\;0.866\!\dots\bigr].
$$
所以在这个例子里二维时间编码就是 $\bigl[0.5,\;0.866]$。
#### **为什么这样设计?**
- 普通的图神经网络即使有时间戳也只能把它当作一个离散特征很难推广到模型没见过的时刻TGAT通过把相对时间差 $\Delta t$ 映射成一组连续周期性的函数值 $(\cos(\omega_1 \Delta t),\sin(\omega_1 \Delta t))$,让模型天然具备处理任意实数时间差的能力
- 用一堆正余弦函数来编码时间使得时间特征是平滑连续的
- 节点对邻居信息的关注度不仅由节点特征决定也由时间编码决定模型可以自动学出距离现在越近的交互越重要”“一周前的活动强度要比一个月前的活动强度高之类的规律
- **可学习性**频率参数`{ωᵢ}`可以通过训练优化例如让模型自动学习短期交互长期交互的不同时间尺度)。
### 需要维护的数据:
1. **全量事件日志(事件流)**
整个动态图被表示成一条事件流”──每一条事件是一个三元组
$$
(u, v, t)
$$
表示节点 $u$ 和节点 $v$ 在时刻 $t$ 上发生了一次交互训练推断时TGAT 会遍历这条有时间戳的边列表按时间顺序对每个目标节点做消息聚合
2. **每个节点的历史邻居列表**
为了快速地找到截止当前时刻 $t$某节点 $v$ 最近接触过哪些节点”,TGAT 通常会为每个节点维护一个按时间排序的邻居列表
$$
\mathit{Nbrs}(v) \;=\; [(u_1,t_1),\,(u_2,t_2),\,\dots]
$$
其中每个 $(u_i, t_i)$ 表示节点 $u_i$ 在时间 $t_i$ $v$ 交互过这样给定当前时间 $t$就可以高效地检索出所有满足 $t_i < t$ 的历史交互
3. **每层的节点隐藏状态**
TGAT 是一个多层multi-layer注意力网络在第 $l$ 层它会产生每个节点在各个时间点的隐藏表示
$$
\tilde h_v^{(l)}(t)\,.
$$
为了在更高层次继续聚合这些中间表示需要被缓存下来至少要保存上一次前一层计算出的向量才能和后续的时间编码一起拼接送入下一层注意力
4. **时间编码的频率参数**
TGAT 中的 $\{\omega_k\}_{k=1}^d$(映射 $\Delta t\mapsto [\cos(\omega_k\Delta t),\sin(\omega_k\Delta t)]$ 用的频率向量是模型的可学习参数也需要存储
### 工作原理
#### 1.检索时间邻居
从事件流中取出所有在 $t$ 之前与 $v_0$ 有过交互的节点集合以及交互的时间 $t_i$。
$$
\mathcal{N}(v_0; t) = \{ v_i \mid \exists (v_0, v_i, t_i) \in \mathcal{E}, t_i < t \}
$$
实际实现中TGAT通过以下两种策略避免邻居集合无限膨胀
1**时间窗口截断**
- 仅保留目标时间 $t$ 的最近 $\Delta T$ 时间内的交互节点例如过去7天的邻居)。
- **数学表达**
$$
\mathcal{N}(v_0; t) = \{ v_i \mid (v_0, v_i, t_i) \in \mathcal{E}, t - \Delta T \leq t_i < t \}
$$
2**邻居采样Neighborhood Sampling**
- 即使在一个时间窗口内如果邻居数量过多例如社交网络中的活跃用户TGAT会随机采样固定数量的邻居如最多20个)。
#### 2.准备输入特征+时间编码
TGAT 模型中每一层都需要计算隐藏表示
在第 $l$ 层里既要计算目标节点 $v_0$ 在当前时刻 $t$ 的隐藏表示 $\tilde{h}_0^{(l-1)}(t)$也要计算它的每个邻居 $v_i$ 在各自交互时刻 $t_i$ 的隐藏表示 $\tilde{h}_i^{(l-1)}(t_i)$。
- $l=1$,则将原始静态特征 $x_i$ 作为第 0 层隐藏表示 $\tilde h_i^{(0)}(t_i)$
- $l>1$,则使用第 $(l-1)$ 层计算出的隐藏表示 $\tilde h_i^{(l-1)}(t_i)$。
对每个邻居 $v_i$ 计算相对时间差 $\Delta t_i = t - t_i$,再通过
$$
\Phi_d(\Delta t_i) = \tfrac1{\sqrt d}\bigl[\cos(\omega_1\Delta t_i),\sin(\omega_1\Delta t_i),\dots\bigr]
$$
得到长度为 $2d$ 的时间编码向量。对目标节点自身,使用 $\Delta t=0$ 的时间编码。
#### 3.拼接构建"实体—时间"矩阵
$$
Z(t) =
\begin{bmatrix}
\tilde h_0^{(l-1)}(t)\,\|\,\Phi_d(0)\\
\tilde h_1^{(l-1)}(t_1)\,\|\,\Phi_d(\Delta t_1)\\
\;\;\vdots\\
\tilde h_N^{(l-1)}(t_N)\,\|\,\Phi_d(\Delta t_N)
\end{bmatrix}
$$
其中 $\Delta t_i=t-t_i$ ,这里 $v_0$ 一共有 $N$ 个节点。可能存在同一时间有多个交互的节点。
#### 4. 线性映射到 Query/Key/Value
分别用三组可学习的线性变换把 $Z(t)$ 投影出
$$
Q = Z(t)W^Q,\quad
K = Z(t)W^K,\quad
V = Z(t)W^V
$$
其中 $Q$ 取第一行(目标节点),$K,V$ 取其余行。
#### 5.计算注意力权重
对每个邻居 $i$ 计算
$$
\alpha_i \;=\;\frac{\exp\bigl(Q^\top K_i\bigr)}{\sum_j\exp\bigl(Q^\top K_j\bigr)}\,,
$$
这样就能在同一时刻、同一节点间对「谁更重要」自动打分。
#### 6.加权求和生成聚合向量
$$
h^{(l)}(t)\;=\;\sum_{i\in N(v_0;t)}\alpha_i\,V_i\quad\in\mathbb{R}^{d_h}.
$$
#### 7.与目标节点静态特征融合并通过 FFN
把聚合向量 $h^{(l)}(t)$ 和目标节点的原始特征 $x_0$ 拼接,送入两层前馈网络:
$$
\tilde h_0^{(l)}(t)
= \mathrm{FFN}\bigl(h^{(l)}(t)\,\|\,x_0\bigr)
= \mathrm{ReLU}\Bigl(\bigl[h^{(l)}(t)\parallel x_0\bigr] W_0^{(l)} + b_0^{(l)}\Bigr) W_1^{(l)} + b_1^{(l)}
$$
这样就得到了第 $l$ 层节点 $v_0$ 在时刻 $t$ 的最终输出表示。
FFN 并不是只在最后一层使用,而是在**每一层**注意力聚合后都要执行,以产生该层的节点时刻表示。
#### 8.**多头与多层堆叠**
- 如果使用多头注意力,则在步骤 46 中并行做 $k$ 组不同投影,得出 $\{h^{(l,i)}(t)\}_{i=1}^k$,再将它们拼接后送入 FFN
- 堆叠 $L$ 层上述流程,就能把多跳($L$ 跳)邻居信息聚合进来。
总结:每个节点,动态融合节点自身及其邻居在不同时间点的嵌入,其中这些嵌入都显式编码了时间信息。
不同层之间的嵌入维度可以不同,但同一层内所有时间步的嵌入维度必须保持一致。
#### **举例**
假设目标节点 $v_0$ 在时间 $t=10$ 需要聚合历史邻居,其中:
$t=10$时$v_0$的特征:$\tilde{h}_0(t=10)=[0.1, 0.2, 0.3, 0.4, 0.5]$
- 在时间 $t_1=8$$v_0$ 与邻居 $\{v_{1}, v_{2}\}$ 交互。
- $v_1$ 的特征:$\tilde{h}_1(t=8) = [0.6, 0.7, 0.8, 0.9, 1.0]$
- $v_2$ 的特征:$\tilde{h}_2(t=8) = [0.2, 0.3, 0.4, 0.5, 0.6]$
- 在时间 $t_2=5$$v_0$ 与邻居 $\{v_{3}\}$ 交互。
- $v_3$ 的特征:$\tilde{h}_3(t=5) = [1.1, 1.2, 1.3, 1.4, 1.5]$
**时间编码**$d_T=2$, $\omega_1=1$
- $\Phi_{d_T}(10-8=2) = [\cos(2), \sin(2)] \approx [-0.42, 0.91]$
- $\Phi_{d_T}(10-5=5) = [\cos(5), \sin(5)] \approx [0.28, -0.96]$
- $\Phi_{d_T}(0) = [1, 0]$
**将每个邻居的特征与对应时间编码拼接:**
$$
Z(10) = \begin{bmatrix}
\tilde{h}_0(10) \| \Phi_{d_T}(0) \\
\tilde{h}_1(8) \| \Phi_{d_T}(2) \\
\tilde{h}_2(8) \| \Phi_{d_T}(2) \\
\tilde{h}_3(5) \| \Phi_{d_T}(5)
\end{bmatrix} = \begin{bmatrix}
0.1, 0.2, 0.3, 0.4, 0.5, 1, 0 \\
0.6, 0.7, 0.8, 0.9, 1.0, -0.42, 0.91 \\
0.2, 0.3, 0.4, 0.5, 0.6, -0.42, 0.91 \\
1.1, 1.2, 1.3, 1.4, 1.5, 0.28, -0.96
\end{bmatrix}_{4 \times 7}
$$
**注意力权重计算:**
**1.投影矩阵参数**(简化示例,设 $d_h = 3$,真实情况由训-练得来):
$$
W_Q = W_K = \begin{bmatrix}
0.1 & 0.2 & 0.3 \\
0.4 & 0.5 & 0.6 \\
0.7 & 0.8 & 0.9 \\
1.0 & 1.1 & 1.2 \\
1.3 & 1.4 & 1.5 \\
0.2 & 0.3 & 0.4 \\
0.5 & 0.6 & 0.7
\end{bmatrix}_{7 \times 3}, \quad
W_V = \begin{bmatrix}
0.3 & 0.4 & 0.5 \\
0.6 & 0.7 & 0.8 \\
0.9 & 1.0 & 1.1 \\
1.2 & 1.3 & 1.4 \\
1.5 & 1.6 & 1.7 \\
0.1 & 0.2 & 0.3 \\
0.4 & 0.5 & 0.6
\end{bmatrix}_{7 \times 3}
$$
**2.计算 Query/Key/Value**
- **Query**(目标节点 $v_0$
$$
q(10) = [Z(10)]_0 W_Q = [0.1, 0.2, 0.3, 0.4, 0.5, 1, 0] \cdot W_Q = [2.38, 2.76, 3.14]
$$
- **Keys**(邻居节点):
$$
K(10) = [Z(10)]_{1:3} W_K = \begin{bmatrix}
0.6 & 0.7 & 0.8 & 0.9 & 1.0 & -0.42 & 0.91 \\
0.2 & 0.3 & 0.4 & 0.5 & 0.6 & -0.42 & 0.91 \\
1.1 & 1.2 & 1.3 & 1.4 & 1.5 & 0.28 & -0.96
\end{bmatrix} \cdot W_K = \begin{bmatrix}
3.22 & 3.68 & 4.14 \\
1.82 & 2.18 & 2.54 \\
4.18 & 4.64 & 5.10
\end{bmatrix}
$$
- **Values**(邻居节点):
$$
V(10) = [Z(10)]_{1:3} W_V = \begin{bmatrix}
3.52 & 3.92 & 4.32 \\
2.12 & 2.42 & 2.72 \\
4.48 & 4.88 & 5.28
\end{bmatrix}
$$
**3.计算注意力权重**
- 计算未归一化分数(缩放因子 $\sqrt{d_h} = \sqrt{3} \approx 1.732$
$$
\text{scores} = \frac{q(10) K(10)^\top}{\sqrt{3}} = \frac{[2.38, 2.76, 3.14] \cdot \begin{bmatrix}3.22 & 1.82 & 4.18 \\ 3.68 & 2.18 & 4.64 \\ 4.14 & 2.54 & 5.10\end{bmatrix}}{1.732}\approx [18.46, 10.56, 21.40]
$$
- Softmax 归一化:
$$
\alpha = \text{softmax}([18.46, 10.56, 21.40]) = [2.4 \times 10^{-2}, 1.6 \times 10^{-5}, 0.976]
$$
**4.加权求和生成聚合向量**
$$
h(10) = \sum_{i=1}^3 \alpha_i V_i = 0.024 \cdot \begin{bmatrix}3.52 \\ 3.92 \\ 4.32\end{bmatrix} + 1.6 \times 10^{-5} \cdot \begin{bmatrix}2.12 \\ 2.42 \\ 2.72\end{bmatrix} + 0.976 \cdot \begin{bmatrix}4.48 \\ 4.88 \\ 5.28\end{bmatrix}\approx [4.48, 4.88, 5.28]
$$
**5.节点嵌入更新**
**1.拼接操作**
$$
z=[h(10) \| x_0] = [4.48, 4.88, 5.28, 0.1, 0.2, 0.3, 0.4, 0.5]
$$
**2. FFN参数设置**
FFN 包含两层:
$$
\tilde{h}_0^{(l)}(10)=\text{FFN}(z) = \text{ReLU}(z W_0 + b_0) W_1 + b_1
$$
### 需提前训练的参数
| 参数名称 | 符号 | 维度 | 来源层 | 作用 |
| ---------------- | ----------------------------- | ----------------------- | ------------- | --------------------------------------------------------- |
| 时间编码频率参数 | $\omega_1,\dots,\omega_{d_T}$ | $d_T\times1$ | 全模型 | 控制功能性时间编码基频率,用于生成 $\Phi_{d_T}(\Delta t)$ |
| Query 投影矩阵 | $W_Q^{(l)}$ | $(d_h + d_T)\times d_h$ | 第 $l$ 层 | 将拼接后的"隐藏表示+时间编码"映射为 Query 向量 |
| Key 投影矩阵 | $W_K^{(l)}$ | $(d_h + d_T)\times d_h$ | 第 $l$ 层 | 将拼接后的"隐藏表示+时间编码"映射为 Key 向量 |
| Value 投影矩阵 | $W_V^{(l)}$ | $(d_h + d_T)\times d_h$ | 第 $l$ 层 | 将拼接后的"隐藏表示+时间编码"映射为 Value 向量 |
| FFN 第一层权重 | $W_0^{(l)}$ | $(d_h + d_0)\times d_f$ | 第 $l$ 层 FFN | 拼接向量 $[\,h^{(l)}(t)\,\|\,x_0\,]$ 的第一层线性变换 |
| FFN 第一层偏置 | $b_0^{(l)}$ | $d_f$ | 第 $l$ 层 FFN | 第一层线性偏置 |
| FFN 第二层权重 | $W_1^{(l)}$ | $d_f\times d$ | 第 $l$ 层 FFN | 第二层线性变换,生成本层最终节点表示 |
| FFN 第二层偏置 | $b_1^{(l)}$ | $d$ | 第 $l$ 层 FFN | 第二层线性偏置 |
每个节点运行的模型是一样的QKV这些参数都是一样的。
运行过程中这些训练好的参数不会变化,模型的动态性体现在:
- 维护**全局事件流**;当新的边 $(u, v, t)$ 加入或旧的边变得不再被采样时,下一次你对某个节点做推理时,检索到的邻居集合就不一样;
- 时间编码会根据新的 $\Delta t$ 动态计算;
- 注意力权重 $\alpha_i$ 会重新分配FFN 也会基于新的聚合结果给出新的输出。
节点是否需要交互(是否需要全局信息)
- 如果节点仅关注自己的特征更新以及任务,仅需维护:
从事件流中取出所有在 $t$ 之前与 $v_0$ 有过交互的节点集合以及交互的时间 $t_i$。
$$
\mathcal{N}(v_0; t) = \{ v_i \mid \exists (v_0, v_i, t_i) \in \mathcal{E}, t_i < t \}
$$
- 如果节点还关注其他节点的特征更新及任务需要知道**全局事件流** (若干时刻邻接矩阵转化而来)