图神经网络入门:GCN 与 GAT 的原理与 Python 实现
图神经网络入门:GCN 与 GAT 的原理与实现
一、图神经网络基础
图神经网络(GNN)用于处理非欧几里得数据(如图结构),核心思想是通过邻域聚合更新节点特征: $$h_v^{(k)} = \sigma \left( \mathbf{W}^{(k)} \cdot \text{AGGREGATE} \left( { h_u^{(k-1)}, \forall u \in \mathcal{N}(v) } \right) \right)$$ 其中 $h_v^{(k)}$ 是节点 $v$ 在第 $k$ 层的特征,$\mathcal{N}(v)$ 表示邻居节点集合。
二、GCN(图卷积网络)原理
GCN通过谱图理论实现卷积操作,单层传播公式: $$H^{(l+1)} = \sigma \left( \hat{D}^{-\frac{1}{2}} \hat{A} \hat{D}^{-\frac{1}{2}} H^{(l)} W^{(l)} \right)$$
- $\hat{A} = A + I$(添加自环的邻接矩阵)
- $\hat{D}$ 是 $\hat{A}$ 的度矩阵
- $H^{(l)}$ 是第 $l$ 层节点特征
- 每个节点聚合邻居信息时进行归一化处理
三、GAT(图注意力网络)原理
GAT引入注意力机制,节点 $i$ 对邻居 $j$ 的注意力系数: $$\alpha_{ij} = \frac{\exp \left( \text{LeakyReLU} \left( \mathbf{a}^T [W h_i | W h_j] \right) \right)}{\sum_{k \in \mathcal{N}(i)} \exp \left( \text{LeakyReLU} \left( \mathbf{a}^T [W h_i | W h_k] \right) \right)}$$ 输出特征计算: $$h_i' = \sigma \left( \sum_{j \in \mathcal{N}(i)} \alpha_{ij} W h_j \right)$$ 优势:动态学习邻居重要性权重,无需预先知道图结构。
四、Python实现(使用PyTorch Geometric)
1. 环境安装
pip install torch torch-geometric
2. GCN实现
import torch
from torch_geometric.nn import GCNConv
class GCN(torch.nn.Module):
def __init__(self, in_dim, hidden_dim, out_dim):
super().__init__()
self.conv1 = GCNConv(in_dim, hidden_dim)
self.conv2 = GCNConv(hidden_dim, out_dim)
def forward(self, data):
x, edge_index = data.x, data.edge_index
x = self.conv1(x, edge_index).relu()
x = self.conv2(x, edge_index)
return x
3. GAT实现
from torch_geometric.nn import GATConv
class GAT(torch.nn.Module):
def __init__(self, in_dim, hidden_dim, out_dim, heads=8):
super().__init__()
self.conv1 = GATConv(in_dim, hidden_dim, heads=heads)
self.conv2 = GATConv(hidden_dim*heads, out_dim, heads=1)
def forward(self, data):
x, edge_index = data.x, data.edge_index
x = self.conv1(x, edge_index).relu()
x = self.conv2(x, edge_index)
return x
4. 训练示例
dataset = Planetoid(root='/tmp/Cora', name='Cora') # 加载Cora数据集
device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')
model = GAT(in_dim=1433, hidden_dim=8, out_dim=7).to(device) # GCN同理
optimizer = torch.optim.Adam(model.parameters(), lr=0.01)
criterion = torch.nn.CrossEntropyLoss()
for epoch in range(200):
model.train()
optimizer.zero_grad()
out = model(data)
loss = criterion(out[data.train_mask], data.y[data.train_mask])
loss.backward()
optimizer.step()
五、关键对比
| 特性 | GCN | GAT |
|---|---|---|
| 聚合方式 | 固定归一化权重 | 动态注意力权重 |
| 计算开销 | 较低 | 较高(多头注意力) |
| 表达能力 | 受限于图结构 | 可学习邻居重要性 |
| 适用场景 | 结构规则的图(如分子图) | 异构图或需关注关键邻居的场景 |
提示:实际应用中,GAT通常需要更多训练数据以避免过拟合,可通过调整
heads参数平衡性能与计算成本。
更多推荐
所有评论(0)