文章目录
GAT
题:Graph Attention Networks
摘要:
提出了图形注意网络(GAT) ,这是一种基于图结构数据的新型神经网络结构,利用掩蔽的自我注意层来解决基于图卷积或其近似的先前方法的缺点。通过叠加层,节点能够参与其邻域的特征,我们能够(隐式地)为邻域中的不同节点指定不同的权重,而不需要任何代价高昂的矩阵操作(如反演) ,或者依赖于预先知道图的结构。通过这种方法,我们同时解决了基于谱的图形神经网络的几个关键问题,并使我们的模型容易地适用于归纳和转导问题。我们的 GAT 模型已经实现或匹配了四个已建立的转导和归纳图基准的最新结果: Cora,Citeseer 和 Pubmed 引用网络数据集,以及protein-protein interaction dataset(其中测试图在训练期间保持不可见)。
在Paper with code 网址,可找到对应论文和github源码,原论文使用TensorFlow实现,本篇主要对Pytorch版本的 PyGAT附详细注释帮助理解和测试。
截图及下文代码注释参考自视频:GAT详解及代码实现
视频中的eij的实现与源码不同,视频中是先拼接两个W,再与a乘;
源码在_prepare_attentional_mechanism_input()函数中先分别与a乘,再拼接。
代码实现【PyGAT】
在PyGAT :
- layers.py中定义Simple GAT layer实现(GraphAttentionLayer)和Sparse version GAT layer实现(SpGraphAttentionLayer)。
- models.py 实现两个版本加入Multi-head机制
- trains.py 使用model定义的GAT构建模型进行训练,使用cora数据集
GraphAttentionLayer【一个图注意力层实现】
class GraphAttentionLayer(nn.Module):
"""
Simple GAT layer, similar to https://arxiv.org/abs/1710.10903
"""
def __init__(self, in_features, out_features, dropout, alpha, concat=True):
super(GraphAttentionLayer, self).__init__()
self.dropout = dropout#dropout参数
self.in_features = in_features#结点向量的特征维度
self.out_features = out_features#经过GAT之后的特征维度
self.alpha = alpha#LeakyReLU参数
self.concat = concat# 如果为true, 再进行elu激活
# 定义可训练参数,即论文中的W和a
self.W = nn.Parameter(torch.empty(size=(in_features, out_features)))
nn.init.xavier_uniform_(self.W.data, gain=1.414)# xavier初始化
self.a = nn.Parameter(torch.empty(size=(2*out_features, 1)))
nn.init.xavier_uniform_(self.a.data, gain=1.414)# xavier初始化
# 定义leakyReLU激活函数
self.leakyrelu = nn.LeakyReLU(self.alpha)
def forward(self, h, adj):
'''
adj图邻接矩阵,维度[N,N]非零即一
h.shape: (N, in_features), self.W.shape:(in_features,out_features)
Wh.shape: (N, out_features)
'''
Wh = torch.mm(h, self.W) # 对应eij的计算公式
e = self._prepare_attentional_mechanism_input(Wh)#对应LeakyReLU(eij)计算公式
zero_vec = -9e15*torch.ones_like(e)#将没有链接的边设置为负无穷
attention = torch.where(adj > 0,