特征图注意力_深入理解图注意力机制

6389f1dc0bf5d268f65f1884b883f78d.png

文章来源于机器之心DGL专栏,作者:张昊、李牧非、王敏捷、张峥。

图卷积网络 Graph Convolutional Network (GCN) 告诉我们将局部的图结构和节点特征结合可以在节点分类任务中获得不错的表现。美中不足的是 GCN 结合邻近节点特征的方式和图的结构依依相关,这局限了训练所得模型在其他图结构上的泛化能力。

Graph Attention Network (GAT) 提出了用注意力机制对邻近节点特征加权求和。邻近节点特征的权重完全取决于节点特征,独立于图结构。

在这个教程里我们将:

  • 解释什么是 Graph Attention Network
  • 演示用 DGL 实现这一模型
  • 深入理解学习所得的注意力权重
  • 初探归纳学习 (inductive learning)

难度:★★★★✩(需要对图神经网络训练和 Pytorch 有基本了解)

在 GCN 里引入注意力机制

GAT 和 GCN 的核心区别在于如何收集并累和距离为 1 的邻居节点的特征表示。

在 GCN 里,一次图卷积操作包含对邻节点特征的标准化求和:

3901c9638750fd559de7ba957455b8a7.png

其中 N(i) 是对节点 i 距离为 1 邻节点的集合。我们通常会加一条连接节点 i 和它自身的边使得 i 本身也被包括在 N(i) 里。

fde3e1686d0469bdedcadfc45b8f6123.png

是一个基于图结构的标准化常数;σ是一个激活函数(GCN 使用了 ReLU);W^((l)) 是节点特征转换的权重矩阵,被所有节点共享。由于 c_ij 和图的机构相关,使得在一张图上学习到的 GCN 模型比较难直接应用到另一张图上。解决这一问题的方法有很多,比如 GraphSAGE 提出了一种采用相同节点特征更新规则的模型,唯一的区别是他们将 c_ij 设为了|N(i)|。

图注意力模型 GAT 用注意力机制替代了图卷积中固定的标准化操作。以下图和公式定义了如何对第 l 层节点特征做更新得到第 l+1 层节点特征:

a8ef3ff51c607f2b606086ac94748ba1.png
图 1:图注意力网络示意图和更新公式

对于上述公式的一些解释:

  • 公式(1)对 l 层节点嵌入

f2494cca6d033cf2c63b436c06cb9fb7.png

做了线性变换,W^((l)) 是该变换可训练的参数

  • 公式(2)计算了成对节点间的原始注意力分数。它首先拼接了两个节点的 z 嵌入,注意 || 在这里表示拼接;随后对拼接好的嵌入以及一个可学习的权重向量 做点积;最后应用了一个 LeakyReLU 激活函数。这一形式的注意力机制通常被称为加性注意力,区别于 Transformer 里的点积注意力。
  • 公式(3)对于一个节点所有入边得到的原始注意力分数应用了一个 softmax 操作,得到了注意力权重。
  • 公式(4)形似 GCN 的节点特征更新规则,对所有邻节点的特征做了基于注意力的加权求和。

出于简洁的考量,在本教程中,我们选择省略了一些论文中的细节,如 dropout, skip connection 等等。感兴趣的读者们欢迎参阅文末链接的模型完整实现。

本质上,GAT 只是将原本的标准化常数替换为使用注意力权重的邻居节点特征聚合函数。

GAT 的 DGL 实现

以下代码给读者提供了在 DGL 里实现一个 GAT 层的总体印象。别担心,我们会将以下代码拆分成三块,并逐块讲解每块代码是如何实现上面的一条公式。

import torch
import torch.nn as nn
import torch.nn.functional as F

class GATLayer(nn.Module):
    def __init__(se
  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,关于注意力机制的代码,我们先来了解一下注意力机制(Graph Attention Network,简称GAT)。 GAT是一种基于结构的注意力机制,它在结构中进行节点分类、分类等任务时,能够自适应地学习每个节点在不同邻居节点上所占的重要性,从而更准确地进行分类。下面是一个简单的GAT实现: ```python import torch import torch.nn as nn import torch.nn.functional as F class GraphAttentionLayer(nn.Module): def __init__(self, in_features, out_features, dropout, alpha, concat=True): super(GraphAttentionLayer, self).__init__() self.in_features = in_features self.out_features = out_features self.dropout = dropout self.alpha = alpha self.concat = concat self.W = nn.Parameter(torch.zeros(size=(in_features, out_features))) nn.init.xavier_uniform_(self.W.data, gain=1.414) self.a = nn.Parameter(torch.zeros(size=(2*out_features, 1))) nn.init.xavier_uniform_(self.a.data, gain=1.414) self.leakyrelu = nn.LeakyReLU(self.alpha) def forward(self, h, adj): Wh = torch.mm(h, self.W) a_input = self._prepare_attentional_mechanism_input(Wh) e = self.leakyrelu(torch.matmul(a_input, self.a).squeeze(2)) zero_vec = -9e15*torch.ones_like(e) attention = torch.where(adj > 0, e, zero_vec) attention = F.softmax(attention, dim=1) attention = F.dropout(attention, self.dropout, training=self.training) h_prime = torch.matmul(attention, Wh) if self.concat: return F.elu(h_prime) else: return h_prime def _prepare_attentional_mechanism_input(self, Wh): N = Wh.size()[0] Wh_repeated_in_chunks = Wh.repeat_interleave(N, dim=0) Wh_repeated_alternating = Wh.repeat(N, 1) all_combinations_matrix = torch.cat([Wh_repeated_in_chunks, Wh_repeated_alternating], dim=1) return all_combinations_matrix.view(N, N, 2 * self.out_features) ``` 在这个代码中,我们定义了一个名为GraphAttentionLayer的类,它继承于nn.Module类。在它的__init__方法中,我们定义了一些必要的参数,包括输入特征维度、输出特征维度、dropout率、LeakyReLU函数的负斜率系数以及是否将节点特征注意力机制的输出进行拼接。W和a是需要学习的参数,其中W是线性变换的权重矩阵,a是注意力机制的权重矩阵。我们使用xavier_uniform_方法对这两个参数进行初始化。 在forward方法中,我们首先将节点特征矩阵h与权重矩阵W相乘,得到Wh。然后,我们通过_prepare_attentional_mechanism_input方法将Wh转换为用于注意力计算的输入矩阵a_input。接着,我们将a_input与注意力权重矩阵a相乘,得到每个节点与其邻居之间的注意力系数e。我们使用LeakyReLU函数将e中的负值裁剪掉。然后,我们对每个节点的邻居节点计算softmax,得到它们之间的注意力权重。我们使用dropout对注意力权重进行随机失活,以防止过拟合。最后,我们将注意力权重与Wh相乘,得到每个节点的新特征h_prime。如果concat参数为True,我们将h_prime与原始节点特征进行拼接并使用ELU函数作为输出;否则,我们直接返回h_prime作为输出。 需要注意的是,这个代码中的实现是基于PyTorch框架的,如果你使用其他的深度学习框架,可能需要做一些调整。同时,这个代码只是GAT的一个简单实现,如果你想深入学习GAT,还需要阅读相关论文并了解更多细节。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值