李振河 陈茂森 # 图神经网络 图表示学习的本质是把节点映射成低维连续稠密的向量。这些向量通常被称为 **嵌入(Embedding)**,它们能够捕捉节点在图中的结构信息和属性信息,从而用于下游任务(如节点分类、链接预测、图分类等)。 - **低维**:将高维的原始数据(如邻接矩阵或节点特征)压缩为低维向量,减少计算和存储开销。 - **连续**:将离散的节点或图结构映射为连续的向量空间,便于数学运算和捕捉相似性。 - **稠密**:将稀疏的原始数据转换为稠密的向量,每个维度都包含有意义的信息。 ## 对图数据进行深度学习的“朴素做法” 把图的邻接矩阵和节点特征“直接拼接”成固定维度的输入,然后将其送入一个深度神经网络(全连接层)进行学习。 ![image-20250316142412685](https://pic.bitday.top/i/2025/03/19/u8cfvq-2.png) 这种做法面临重大问题,导致其**并不可行**: 1. $O(|V|^2)$ 参数量 ,参数量庞大 2. 无法适应不同大小的图 ,需要固定输入维度 3. 对节点顺序敏感 ,节点编号顺序一变,输入就完全变样,但其实图的拓扑并没变(仅节点编号/排列方式不同)。 ```text A —— B | | D —— C ``` *矩阵 1*(顺序 $[A,B,C,D]$): $$ M_1 = \begin{pmatrix} 0 & 1 & 0 & 1\\ 1 & 0 & 1 & 0\\ 0 & 1 & 0 & 1\\ 1 & 0 & 1 & 0 \end{pmatrix}. $$ *矩阵 2*(顺序 $[C,A,D,B]$): $$ M_2 = \begin{pmatrix} 0 & 0 & 1 & 1 \\ 0 & 0 & 1 & 1 \\ 1 & 1 & 0 & 0 \\ 1 & 1 & 0 & 0 \end{pmatrix}. $$ ​ 两个矩阵完全不同,但**它们对应的图是相同的**(只不过节点的顺序改了)。 ## 计算图 在**图神经网络**里,通常每个节点$v$ 都有一个**局部计算图**,用来表示该节点在聚合信息时所需的所有邻居(及邻居的邻居……)的依赖关系。 直观理解 - 以节点 $v$ 为根; - 1-hop 邻居在第一层,2-hop 邻居在第二层…… - 逐层展开直到一定深度(例如 k 层)。 - 这样形成一棵“邻域树”或“展开图”,其中每个节点都需要从其子节点(邻居)获取特征进行聚合。 ![image-20250316152729679](https://pic.bitday.top/i/2025/03/19/u8d0gg-2.png) ![image-20250316152836156](https://pic.bitday.top/i/2025/03/19/u8cr12-2.png) ### 例子 在图神经网络中,每一层的计算通常包括以下步骤: 1. **聚合(Aggregation)**:将邻居节点的特征聚合起来(如求和、均值、最大值等)。 2. **变换(Transformation)**:将聚合后的特征通过一个神经网络(如 MLP)进行非线性变换。 ```text A | B / \ C D ``` 假设每个节点的特征是一个二维向量: - 节点 $ A $ 的特征:$ h_A = [1.0, 0.5] $ - 节点 $ B $ 的特征:$ h_B = [0.8, 1.2] $ - 节点 $ C $ 的特征:$ h_C = [0.3, 0.7] $ - 节点 $ D $ 的特征:$ h_D = [1.5, 0.9] $ **第 1 层更新:$A^{(0)} \to A^{(1)}$** 1. 节点 $A$ 的 1-hop 邻居:只有 $B$。 2. 聚合(示例:自+邻居取平均): $$ z_A^{(1)} = \frac{A^{(0)} + B^{(0)}}{2} = \frac{[1.0,\,0.5] + [0.8,\,1.2]}{2} = \frac{[1.8,\,1.7]}{2} = [0.9,\,0.85]. $$ 3. MLP 变换:用一个MLP映射 $z_A^{(1)}$ 到 2 维输出: $$ A^{(1)} \;=\; \mathrm{MLP_1}\bigl(z_A^{(1)}\bigr). $$ - (数值略,可想象 $\mathrm{MLP}([0.9,0.85]) \approx [1.0,0.6]$ 之类。) **结果**:$A^{(1)}$ 包含了 **A** 的初始特征 + **B** 的初始特征信息。 --- **第 2 层更新:$A^{(1)} \to A^{(2)}$** 为了让 **A** 获得 **2-hop** 范围($C, D$)的信息,需要先让 $B$ 在第 1 层就吸收了 $C, D$ 的特征,从而 **$B^{(1)}$** 蕴含 $C, D$ 信息。然后 **A** 在第 2 层再从 **$B^{(1)}$** 聚合。 1. **节点 B 在第 1 层**(简要说明) - 邻居:$\{A,C,D\}$ - 聚合:$z_B^{(1)} = \frac{B^{(0)} + A^{(0)} + C^{(0)} + D^{(0)}}{4} = \frac{[0.8,\,1.2] + [1.0,\,0.5] + [0.3,\,0.7] + [1.5,\,0.9]}{4} = \frac{[3.6,\,3.3]}{4} = [0.9,\,0.825].$ - MLP 变换:$B^{(1)} = \mathrm{MLP}\bigl(z_B^{(1)}\bigr)$。 - 此时 **$B^{(1)}$** 已经包含了 $C, D$ 的信息。 2. **节点 $A$ 的第 2 层聚合** - 邻居:$B$,但此时要用 **$B^{(1)}$**(它已吸收 C、D) - 聚合: $$ z_A^{(2)} = A^{(1)} + B^{(1)}. $$ - MLP 变换: $$ A^{(2)} = \mathrm{MLP_2}\bigl(z_A^{(2)}\bigr). $$ **结果**:$A^{(2)}$ 就包含了 **2-hop** 范围的信息,因为 **$B^{(1)}$** 中有 $C, D$ 的贡献。 **GNN 的层数**就是**节点聚合邻居信息的迭代次数**(也是计算图的层数)。 同一层里,**所有节点共享一组参数**(同一个 MLP 或全连接神经网络) ### **矩阵运算** $\tilde D^{-1}\,\tilde A\,\tilde D^{-1}H$ $H'=\tilde D^{-1}\,\tilde A\,H$ A | B / \ C D **1.构造矩阵** 含自环邻接矩阵 $\tilde A=A+I$ $$ \tilde A = \begin{bmatrix} 1 & 1 & 0 & 0\\ 1 & 1 & 1 & 1\\ 0 & 1 & 1 & 0\\ 0 & 1 & 0 & 1 \end{bmatrix} $$ 度矩阵 $\tilde D$(对角=自身+邻居数量) $$ \tilde D = \mathrm{diag}(2,\,4,\,2,\,2) $$ 特征矩阵 $H$(每行为一个节点的特征向量) $$ H = \begin{bmatrix} 1.0 & 0.5\\ 0.8 & 1.2\\ 0.3 & 0.7\\ 1.5 & 0.9 \end{bmatrix} $$ **2.计算** 求和: $\tilde A\,H$ $$ \tilde A H = \begin{bmatrix} 1.8 & 1.7\\ 3.6 & 3.3\\ 1.1 & 1.9\\ 2.3 & 2.1 \end{bmatrix} $$ 平均: $\tilde D^{-1}(\tilde A H)$ $$ \tilde D^{-1}\tilde A H = \begin{bmatrix} 0.90 & 0.85\\ 0.90 & 0.825\\ 0.55 & 0.95\\ 1.15 & 1.05 \end{bmatrix} $$ ## GCN 在 GCN 里,归一化(normalization)的核心目的就是 **平衡不同节点在信息传播(message‑passing)中的影响力**,避免「高连通度节点(high‑degree nodes)」主导了所有邻居的特征聚合。 $H' = \tilde D^{-1}\,\tilde A\,\tilde D^{-1}H$ - 对节点 $i$ 来说: $$ H'_i = \frac1{d_i}\sum_{j\in \mathcal N(i)}\frac1{d_j}\,H_j $$ - **先用源节点 $j$ 的度 $d_j$ 缩小它的特征贡献**,再用目标节点 $i$ 的度 $d_i$ 归一化总和。 ### **GCN中实际的公式:** $$ H^{(l+1)} = \sigma\Big(\tilde{D}^{-1/2}\tilde{A}\tilde{D}^{-1/2}H^{(l)}W^{(l)}\Big) $$ 其中: - $H^{(l)}$ 是第 $l$ 层的输入特征(对第 $0$ 层来说就是节点的初始特征), - $W^{(l)}$ 是第 $l$ 层的可训练权重矩阵,相当于一个简单的线性变换(类似于 MLP 中的全连接层), - $\sigma(\cdot)$ 是非线性激活函数(例如 ReLU), - $\tilde{A}$ 是包含自连接的邻接矩阵, - $\tilde{D}$ 是 $\tilde{A}$ 的度矩阵。 **$\tilde{D}^{-1/2}\tilde{A}\tilde{D}^{-1/2}$的优势** **1.对称归一化**:$\tilde D^{-\frac{1}{2}}\,\tilde A\,\tilde D^{-\frac{1}{2}}$ 是一个对称矩阵,这意味着信息在节点之间的传播是双向一致的。这种对称性特别适合无向图,因为无向图的邻接矩阵 $\tilde A$ 本身就是对称的。 **2.适度抑制高连通度节点**:对称平方根归一化通过 $\tilde D^{-\frac{1}{2}}$ 对源节点和目标节点同时进行归一化,能够适度抑制高连通度节点的特征贡献,而不会过度削弱其影响力。 **3.谱半径控制**:对称平方根归一化后的传播矩阵 $\tilde D^{-\frac{1}{2}}\,\tilde A\,\tilde D^{-\frac{1}{2}}$ 的谱半径(最大特征值)被控制在 $[0, 1]$ 范围内,这有助于保证模型的数值稳定性。 **4.归一化拉普拉斯矩阵**:对称平方根归一化的传播矩阵 $\tilde D^{-\frac{1}{2}}\,\tilde A\,\tilde D^{-\frac{1}{2}}$ 与归一化拉普拉斯矩阵 $L = I - \tilde D^{-\frac{1}{2}}\,\tilde A\,\tilde D^{-\frac{1}{2}}$ 有直接联系。归一化拉普拉斯矩阵在图信号处理中具有重要的理论意义,能够更好地描述图的频谱特性。 **GraphSAGE优化** $$ h_v^{(k+1)} = \sigma \Big( \mathbf{W}_{\text{self}}^{(k)} \cdot h_v^{(k)} \;+\; \mathbf{W}_{\text{neigh}}^{(k)} \cdot \mathrm{MEAN}_{u\in N(v)}\bigl(h_u^{(k)}\bigr) \Big), $$ ## GAT 图注意力网络(GAT)中最核心的运算:**图注意力层**。它的基本思想是: 1. **线性变换**:先对每个节点的特征 $\mathbf{h}_i$ 乘上一个可学习的权重矩阵 $W$,得到变换后的特征 $W \mathbf{h}_i$。 2. **自注意力机制**:通过一个可学习的函数 $a$,对节点 $i$ 和其邻居节点 $j$ 的特征进行计算,得到注意力系数 $e_{ij}$。这里会对邻居进行遮蔽(masked attention),即只计算图中有边连接的节点对。 3. **归一化**:将注意力系数 $e_{ij}$ 通过 softmax 进行归一化,得到 $\alpha_{ij}$,表示节点 $j$ 对节点 $i$ 的重要性权重。 4. **聚合**:最后利用注意力系数加权邻居节点的特征向量,并经过激活函数得到新的节点表示 $\mathbf{h}_i'$。 5. **多头注意力**:为增强表示能力,可并行地执行多个独立的注意力头(multi-head attention),再将它们的结果进行拼接(或在最后一层进行平均),从而得到最终的节点表示。 ### 注意力系数 1. **注意力系数(未归一化)** $$ e_{ij} = a\bigl(W\mathbf{h}_i,\; W\mathbf{h}_j\bigr) $$ 2. **注意力系数的 softmax 归一化** $$ \alpha_{ij} = \text{softmax}_j\bigl(e_{ij}\bigr) = \frac{\exp\bigl(e_{ij}\bigr)}{\sum_{k \in \mathcal{N}_i} \exp\bigl(e_{ik}\bigr)} $$ 3. **具体的注意力计算形式(以单层前馈网络 + LeakyReLU 为例)** $$ \alpha_{ij} = \frac{\exp\Bigl(\text{LeakyReLU}\bigl(\mathbf{a}^\top \bigl[\;W\mathbf{h}_i \,\|\, W\mathbf{h}_j\bigr]\bigr)\Bigr)} {\sum_{k\in \mathcal{N}_i} \exp\Bigl(\text{LeakyReLU}\bigl(\mathbf{a}^\top \bigl[\;W\mathbf{h}_i \,\|\, W\mathbf{h}_k\bigr]\bigr)\Bigr)} $$ - 其中,$\mathbf{a}$ 为可学习的参数向量,$\|$ 表示向量拼接(concatenation)。 **示例假设:** - **节点特征**: 假设每个节点的特征向量维度为 $F=2$。 $$ \mathbf{h}_i = \begin{bmatrix}1 \\ 0\end{bmatrix},\quad \mathbf{h}_j = \begin{bmatrix}0 \\ 1\end{bmatrix},\quad \mathbf{h}_k = \begin{bmatrix}1 \\ 1\end{bmatrix}. $$ - **线性变换矩阵 $W$**: 为了简化,我们令 $W$ 为单位矩阵(即 $W\mathbf{h} = \mathbf{h}$)。 $$ W = \begin{bmatrix}1 & 0 \\ 0 & 1\end{bmatrix}. $$ - **可学习向量 $\mathbf{a}$**: 假设 $\mathbf{a}$ 为 4 维向量,设 $$ \mathbf{a} = \begin{bmatrix}1 \\ 1 \\ 1 \\ 1\end{bmatrix}. $$ - 激活函数使用 LeakyReLU(负数斜率设为0.2,但本例中结果为正数,所以不变)。 --- **计算步骤:** 1. **计算 $W\mathbf{h}_i$、$W\mathbf{h}_j$ 和 $W\mathbf{h}_k$:** $$ W\mathbf{h}_i = \begin{bmatrix}1 \\ 0\end{bmatrix},\quad W\mathbf{h}_j = \begin{bmatrix}0 \\ 1\end{bmatrix}, \quad W\mathbf{h}_k = \begin{bmatrix}1 \\ 1\end{bmatrix} $$ 2. **构造拼接向量并计算未归一化的注意力系数 $e_{ij}$ 和 $e_{ik}$:** - 对于邻居 $j$: $$ \bigl[W\mathbf{h}_i \,\|\, W\mathbf{h}_j\bigr] = \begin{bmatrix}1 \\ 0 \\ 0 \\ 1\end{bmatrix}. $$ 内积计算: $$ \mathbf{a}^\top \begin{bmatrix}1 \\ 0 \\ 0 \\ 1\end{bmatrix} = 1+0+0+1 = 2. $$ 经过 LeakyReLU(正数保持不变): $$ e_{ij} = 2. $$ - 对于邻居 $k$,同理得到: $$ e_{ik} = 3. $$ 3. **计算 softmax 得到归一化注意力系数 $\alpha_{ij}$:** $$ \alpha_{ij} = \frac{\exp(2)}{\exp(2)+\exp(3)} = \frac{e^2}{e^2+e^3}\approx 0.269. $$ 同理: $$ \alpha_{ik} = \frac{\exp(3)}{\exp(2)+\exp(3)} \approx 0.731. $$ ### 特征聚合 **单头注意力聚合(得到新的节点特征)** $$ \mathbf{h}_i' = \sigma\Bigl(\sum_{j \in \mathcal{N}_i} \alpha_{ij} \,W \mathbf{h}_j\Bigr) $$ 对$i$ 的邻居节点加权求和,再经过非线性激活函数得到新的特征表示 **多头注意力(隐藏层时拼接)** 每个头都有自己的一组可学习参数,并独立计算注意力系数和输出特征。以捕捉邻居节点的多种不同关系或特征。 如果有 $K$ 个独立的注意力头,每个头输出 $\mathbf{h}_i'^{(k)}$,则拼接后的输出为: $$ \mathbf{h}_i' = \big\Vert_{k=1}^K \sigma\Bigl(\sum_{j \in \mathcal{N}_i} \alpha_{ij}^{(k)} \, W^{(k)} \mathbf{h}_j\Bigr) $$ 其中,$\big\Vert$ 表示向量拼接操作,$\alpha_{ij}^{(k)}$、$W^{(k)}$ 分别为第 $k$ 个注意力头对应的注意力系数和线性变换。 例假如: $$ \mathbf{h}_i'^{(1)} = \sigma\left(\begin{bmatrix} 0.6 \\ 0.4 \end{bmatrix}\right) = \begin{bmatrix} 0.6 \\ 0.4 \end{bmatrix}. \\ \mathbf{h}_i'^{(2)} = \sigma\left(\begin{bmatrix} 0.6 \\ 1.4 \end{bmatrix}\right) = \begin{bmatrix} 0.6 \\ 1.4 \end{bmatrix}. $$ 将两个头的输出在特征维度上进行拼接,得到最终节点 $i$ 的新特征表示: $$ \mathbf{h}_i' = \mathbf{h}_i'^{(1)} \,\Vert\, \mathbf{h}_i'^{(2)} = \begin{bmatrix} 0.6 \\ 0.4 \end{bmatrix} \,\Vert\, \begin{bmatrix} 0.6 \\ 1.4 \end{bmatrix} = \begin{bmatrix} 0.6 \\ 0.4 \\ 0.6 \\ 1.4 \end{bmatrix}. $$ **多头注意力(输出层时平均)** 在最终的输出层(例如分类层)通常会将多个头的结果做平均,而不是拼接: $$ \mathbf{h}_i' = \sigma\Bigl( \frac{1}{K} \sum_{k=1}^K \sum_{j \in \mathcal{N}_i} \alpha_{ij}^{(k)} \, W^{(k)} \mathbf{h}_j \Bigr) $$ ## 直推式学习与归纳式学习 **直推式学习(Transductive Learning)** 模型直接在固定的训练图上学习节点的表示或标签,结果只能应用于这张图中的节点,无法直接推广到新的、未见过的节点或图。 例如:DeepWalk ,它通过对固定图的随机游走生成节点序列来学习节点嵌入,因此只能得到训练图中已有节点的表示,一旦遇到新节点,需要重新训练或进行特殊处理。 **注意**:GCN是直推式的,因为它**依赖于整个图的归一化邻接矩阵**进行卷积操作,需要在固定图上训练。 **归纳式学习(Inductive Learning)** 模型学习的是一个映射函数或规则,可以将这种规则推广到未见过的**新节点**或**新图**上。这种方法能够处理动态变化的图结构或新的数据。 **例如:** 图神经网络的变体(GAT)都是归纳式的,因为它们在聚合邻居信息时学习一个共享的函数,该函数能够应用于任意新节点。 - 局部计算:GAT 的注意力机制仅在每个节点的局部邻域内计算,不依赖于全局图结构。 - 参数共享:模型中每一层的参数(如 $W$ 和注意力参数 $\mathbf{a}$)是共享的,可以直接应用于新的、未见过的图。 **泛化到新节点**:在许多推荐系统中,如果有新用户加入(新节点),我们需要给他们做个性化推荐,这就要求系统能够在不重新训练整个模型的情况下,为新用户生成表示(Embedding),并且完成推荐预测。 **泛化到新图:** 分子图预测。我们会用一批训练分子(每个分子是一张图)来训练一个 GNN 模型,让它学会如何根据图结构与原子特征来预测分子的某些性质(如毒性、溶解度、活性等)。训练完成后,让它在新的分子上做预测。 ## GNN的优点: **参数共享** - 浅层嵌入(如Deepwalk)为每个节点单独学习一个向量,参数量随节点数线性增长。 - GNN 使用统一的消息传递/聚合函数,所有节点共享同一套模型参数,大幅减少参数量。 **归纳式学习** - 浅层方法通常无法直接处理训练时未见过的新节点。 - GNN 能通过邻居特征和结构来生成新节点的表示,实现对新节点/新图的泛化。 **利用节点特征** - 浅层方法多半只基于连接关系(图结构)。 - GNN 可以直接整合节点的属性(文本、图像特征等),生成更具语义信息的嵌入。 **更强的表达能力** - GNN 通过多层聚合邻居信息,可学习到更丰富的高阶结构和特征交互,往往在多种任务上表现更优。