9.3 KiB
在这部分(论文 2.1 节 “Graph Attentional Layer”)中,作者提出了图注意力网络(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),再将它们的结果进行拼接(或在最后一层进行平均),从而得到最终的节点表示。 该部分给出的公式主要包括注意力系数的计算、softmax 归一化、多头注意力的聚合方式等,下面逐一用 Markdown 数学公式的形式列出。
\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),再将它们的结果进行拼接(或在最后一层进行平均),从而得到最终的节点表示。
该部分给出的公式主要包括注意力系数的计算、softmax 归一化、多头注意力的聚合方式等,下面逐一用 Markdown 数学公式的形式列出。
公式列表(Markdown 格式)
注意:以下公式与论文中编号对应(如 (1)、(2)、(3)、(4)、(5)、(6) 等)。
- 注意力系数(未归一化)
e_{ij} = a\bigl(W\mathbf{h}_i,\; W\mathbf{h}_j\bigr)
- 注意力系数的 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)}
$\alpha_{ij}$表示节点 i
对节点 j
的注意力权重
- 具体的注意力计算形式(以单层前馈网络 + 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)。
- 单头注意力聚合(得到新的节点特征)
\mathbf{h}_i' = \sigma\Bigl(\sum_{j \in \mathcal{N}_i} \alpha_{ij} \,W \mathbf{h}_j\Bigr)
其中,\sigma
表示非线性激活函数(如 ELU、ReLU 等),\mathcal{N}_i
表示节点 i
的邻居节点集合(可包含 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' =
\sigma\Bigl(
\frac{1}{K} \sum_{k=1}^K \sum_{j \in \mathcal{N}_i}
\alpha_{ij}^{(k)} \, W^{(k)} \mathbf{h}_j
\Bigr)
以上即是论文中 2.1 节(Graph Attentional Layer)出现的主要公式及其简要说明。
2. GAT 的聚合方式
-
GAT 使用了一种自适应的、可学习的注意力机制来聚合节点及其邻居的信息。
-
具体来说,GAT 的聚合公式为:
h_i^{(l+1)} = \sigma\left(\sum_{j \in \mathcal{N}(i) \cup \{i\}} \alpha_{ij} W h_j^{(l)}\right)
其中:
\alpha_{ij}
是节点i
和节点j
之间的注意力系数,通过以下方式计算:\alpha_{ij} = \frac{\exp(\text{LeakyReLU}(a^T [W h_i \| W h_j]))}{\sum_{k \in \mathcal{N}(i) \cup \{i\}} \exp(\text{LeakyReLU}(a^T [W h_i \| W h_k]))}
a
是一个可学习的注意力向量。\|
表示特征拼接操作。W
是可学习的权重矩阵。\sigma
是非线性激活函数。
-
特点:
- GAT 的聚合权重是动态的,通过注意力机制学习得到。
- 权重是非对称的,且可以捕捉节点之间的复杂关系。
- 相当于对节点及其邻居进行了一种加权信息传递,权重由数据驱动。
3. GCN 和 GAT 的对比
特性 | GCN | GAT |
---|---|---|
聚合方式 | 固定的加权平均 | 自适应的注意力加权 |
权重是否可学习 | 否(权重由节点度数决定) | 是(通过注意力机制学习) |
权重是否对称 | 是 | 否 |
表达能力 | 较弱(固定的聚合方式) | 较强(动态的聚合方式) |
计算复杂度 | 较低 | 较高(需要计算注意力系数) |
适用场景 | 简单的图结构任务 | 复杂的图结构任务 |
4. 直观理解
-
GCN:
- 类似于对邻居节点进行“民主投票”,每个邻居的权重是固定的(由度数决定)。
- 适合处理节点度数分布均匀、关系相对简单的图。
-
GAT:
- 类似于对邻居节点进行“加权投票”,每个邻居的权重是动态学习的。
- 适合处理节点度数分布不均匀、关系复杂的图。
5. 总结
- GCN 使用的是固定的、归一化的加权平均,权重由节点度数决定。
- GAT 使用的是自适应的、可学习的注意力权重,权重通过数据驱动的方式学习得到。
- GAT 的表达能力更强,但计算复杂度也更高;GCN 更简单高效,但表达能力相对较弱。
希望这个解释能帮助你更好地理解 GCN 和 GAT 的区别!如果还有疑问,欢迎继续讨论!
我们可以通过一个简单的例子来说明多头注意力拼接的计算过程。假设有两个注意力头($K=2$),且我们考虑一个节点 i
以及它的两个邻居 j=1
和 $j=2$。我们假设每个节点的输入特征 \mathbf{h}_j
是一个二维向量,并且每个注意力头的线性变换 W^{(k)}
将输入保持为二维(这里为了简化,取 W^{(1)}
为单位矩阵,而 W^{(2)}
为一个放大2倍的矩阵)。另外,我们假设各头对应的注意力权重(归一化后的)如下:
-
注意力头1:
\alpha_{i1}^{(1)} = 0.6
\alpha_{i2}^{(1)} = 0.4
-
注意力头2:
\alpha_{i1}^{(2)} = 0.3
\alpha_{i2}^{(2)} = 0.7
同时设定节点特征为:
\mathbf{h}_1 = \begin{bmatrix} 1 \\ 0 \end{bmatrix}
\mathbf{h}_2 = \begin{bmatrix} 0 \\ 1 \end{bmatrix}
下面按照每个注意力头计算节点 i
的新特征,再进行拼接:
注意力头 1 的计算
-
线性变换:
W^{(1)}
为单位矩阵,所以W^{(1)}\mathbf{h}_1 = \begin{bmatrix} 1 \\ 0 \end{bmatrix},\quad W^{(1)}\mathbf{h}_2 = \begin{bmatrix} 0 \\ 1 \end{bmatrix}.
-
加权求和:
对邻居加权求和得到\sum_{j\in\mathcal{N}_i} \alpha_{ij}^{(1)} \, W^{(1)}\mathbf{h}_j = 0.6\begin{bmatrix} 1 \\ 0 \end{bmatrix} + 0.4\begin{bmatrix} 0 \\ 1 \end{bmatrix} = \begin{bmatrix} 0.6 \\ 0.4 \end{bmatrix}.
-
非线性激活:
假设激活函数\sigma
是 ReLU,则\mathbf{h}_i'^{(1)} = \sigma\left(\begin{bmatrix} 0.6 \\ 0.4 \end{bmatrix}\right) = \begin{bmatrix} 0.6 \\ 0.4 \end{bmatrix}.
注意力头 2 的计算
-
线性变换:
假设W^{(2)}
为将输入放大2倍的矩阵,即W^{(2)} = \begin{bmatrix} 2 & 0 \\ 0 & 2 \end{bmatrix}.
则有
W^{(2)}\mathbf{h}_1 = \begin{bmatrix} 2 \\ 0 \end{bmatrix},\quad W^{(2)}\mathbf{h}_2 = \begin{bmatrix} 0 \\ 2 \end{bmatrix}.
-
加权求和:
使用注意力权重\sum_{j\in\mathcal{N}_i} \alpha_{ij}^{(2)} \, W^{(2)}\mathbf{h}_j = 0.3\begin{bmatrix} 2 \\ 0 \end{bmatrix} + 0.7\begin{bmatrix} 0 \\ 2 \end{bmatrix} = \begin{bmatrix} 0.6 \\ 1.4 \end{bmatrix}.
-
非线性激活:
同样使用 ReLU 激活\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}.
总结
- 每个注意力头独立计算:先用各自的线性变换
W^{(k)}
对邻居节点特征进行转换,再用对应的注意力系数\alpha_{ij}^{(k)}
加权求和,最后经过非线性激活\sigma
得到输出 $\mathbf{h}_i'^{(k)}$。 - 最后将所有
K
个头的输出通过拼接操作合并成最终的节点特征表示 $\mathbf{h}_i'$。
这个例子展示了多头注意力机制如何通过多个独立的注意力头捕捉不同的子空间特征,最后将它们合并形成更丰富的表示。