本篇博客是对论文 Velikovi, Petar, Cucurull, Guillem, Casanova, Arantxa,et al. Graph Attention Networks, 2018, ICLR的解读与python复现, 全文阅读约10分钟。
博主关于图神经网络的文章
DeepLearning | 图卷积神经网络(GCN)解析(论文、算法、代码)
DeepLearning | 图注意力网络Graph Attention Network(GAT)论文、模型、代码解析
DeepLearning | 图卷积网络基于拓扑结构的分类(T-GCN)
关于半监督学习
基于分歧的半监督学习方法
机器学习教程 之 半监督学习 Tri-training方法 (论文、数据集、代码)
机器学习教程 之 半监督学习 Co-training 协同训练 (论文、算法、数据集、代码)
机器学习教程 之 半监督学习 Coreg 协同回归算法 (论文、算法、数据集、代码)
机器学习教程 之 半监督学习 基于图正则项的半监督极限学习机
这些博客都提供了算法的讲解和python的代码复现,感兴趣的可以了解一下
目录
一、Graph Attention Network
1.1 GAT的优点
图注意力网络(GAT)是作者对图卷积网络(GCN)的改进。它的主要创新点在于利用了注意力机制(Attention Mechanism)来自动的学习和优化节点间的连接关系,这一作法有以下几个优点:
- 克服了GCN只适用于直推式学习的缺陷(在训练期间需要测试时的图数据),可以应用于我们熟悉的归纳式学习任务(在训练期间不需要测试时的图数据)。
- 使用注意力权重代替了原先非0即1的节点连接关系,即两个节点间的关系可以被优化为连续数值,从而获得更丰富的表达
- 由于attention值的计算是可以在节点间并行进行的,网络的计算相当高效
1.2 Graph Attention layer的输入输出
作为一层网络,图注意力层的输入为
图注意力层的输出为
同样的, F ′ {F}' F′表示输出的特征维度。
从图注意力层的输入输出可以看出,其本质上也是对特征的一种变换,和其余的网络层功能是类似的。
1.3 Graph Attention layer的attention机制
首先需要定义一个特征变换矩阵 W ∈ R F × F ′ W \in \mathbb{R}^{F \times {F}'} W∈RF×F′ 用于每一个节点从输入到输出的变换。
-
GAT中的attention机制被称为self-attention,记为 f f f,其功能如下:
e i j = f ( W h i , W h j ) e_{ij}=f(Wh_{i},Wh_{j}) eij=f(Whi,Whj)
如图所示,该式表示了self-attention利用节点 i i i和节点 j j j的特征作为输入计算出了 e i j e_{ij} eij, 而 e i j e_{ij} eij则表示了节点 j j j对于节点 i i i的重要性。
-
需要说明的是,这里的节点 j j j是节点 i i i的近邻,而节点 i i i可能是拥有多个近邻的,因此就有了下面的 s o f t m a x softmax softmax归一化操
a i j = s o f t m a x ( e i j ) = e x p ( e i j ) ∑ k ∈ χ i e x p ( e i k ) a_{ij}=softmax(e_{ij})=\frac{exp(e_{ij})}{\sum_{k \in \chi_{i} }exp(e_{ik})} aij=softmax(eij)=∑k∈χiexp(eik)exp(eij) χ i \chi_{i} χi是节点 i i i 的近邻集合。 -
那么说了这么久,这个self-attention机制,也就是我们一开始提到的 a ( W h i , W h j ) a(Wh_{i},Wh_{j}) a(Whi,Whj)是怎么计算的呢?其实也很简单
f ( W h i , W h j ) = L e a k y R e L U ( a [ W h i ∣ ∣ W h j ] ) f(Wh_{i},Wh_{j}) = LeakyReLU(a[Wh_{i} || Wh_{j}]) f(Whi,Whj)=LeakyReLU(a[Whi∣∣Whj])
这里的 a ∈ R 2 F ′ a \in \mathbb{R}^{2{F}'} a∈R2F′ 表示需要训练的网络参数, ∣ ∣ || ∣∣表示的是矩阵拼接操作, L e a r k y R e L u LearkyReLu LearkyReLu则是一种激活函数,是 R e L u ReLu ReLu的一种改进。 -
最后给出图感知层的定义,即
h i ′ = σ ( ∑ j ∈ χ i a i j W h j ) {h}'_{i}=\sigma(\sum_{j \in \chi_{i}}a_{ij}Wh_{j}) hi′=σ(∑j∈χiaijWhj)
上面就是GAT的attention计算方法了,其中会有两个知识点会影响理解
- self-attention机制为什么可以表示节点间的重要性
- L e a r k y R e L u LearkyReLu LearkyReLu的定义
对于上面这两点,如果知道的话,再结合对GCN的理解,可以很容易的get到GAT的点和含义,如果不清楚的话可能会有点迷糊。
- attention机制实际上是在有监督的训练下计算两个向量的匹配程度,从而揭示其重要性和影响,由于本篇博客不是专门介绍attention的,这里不做多余的解释,日后会补上相应的博客。
-
L
e
a
r
k
y
R
e
L
u
LearkyReLu
LearkyReLu的定义如下:
y = { x i f x > = 0 a x e l s e y=\left\{\begin{matrix} x & if x >=0 \\ ax & else \end{matrix}\right. y={xaxifx>=0else 即引入了一个系数 a a a来取消 R e L U ReLU ReLU的死区。
1.4 多头attention机制
- 为了稳定self−attention的学习过程,GAT还采用了一种多头机制,即独立的计算K个attention,然后将其获得的特征拼接起来,获得一个更全面的表述,表示如下
h i ′ = ∣ ∣ k = 1 K σ ( ∑ j ∈ χ i a i j k W k h j ) {h}'_{i}=||^{K}_{k=1} \sigma(\sum_{j \in \chi_{i}}a^{k}_{ij}W^{k}h_{j}) hi′=∣∣k=1Kσ(∑j∈χiaijkWkhj) 这里的 || 表示矩阵拼接的操作,其余的符号和上面描述的一致。 - 同时,考虑到在网络的最后一层输出层如果还采用这种拼接的方式扩大特征维度,可能不合理,因此,GAT又为输出层定义了平均的操作
h i ′ = σ ( 1 K ∑ k = 1 K ∑ j ∈ χ i a i j k W k h j ) {h}'_{i}= \sigma(\frac{1}{K}\sum^{K}_{k=1}\sum_{j \in \chi_{i}}a^{k}_{ij}W^{k}h_{j}) hi′=σ(K1∑k=1K∑j∈χiaijkWkhj)
多头attention机制如图所示
二、GAN的python复现
模型的核心代码如下
import numpy as np
import tensorflow as tf
from utils import layers
from models.base_gattn import BaseGAttN
class GAT(BaseGAttN):
def inference(inputs, nb_classes, nb_nodes, training, attn_drop, ffd_drop,
bias_mat, hid_units, n_heads, activation=tf.nn.elu, residual=False):
attns = []
for _ in range(n_heads[0]):
attns.append(layers.attn_head(inputs, bias_mat=bias_mat,
out_sz=hid_units[0], activation=activation,
in_drop=ffd_drop, coef_drop=attn_drop, residual=False))
h_1 = tf.concat(attns, axis=-1)
for i in range(1, len(hid_units)):
h_old = h_1
attns = []
for _ in range(n_heads[i]):
attns.append(layers.attn_head(h_1, bias_mat=bias_mat,
out_sz=hid_units[i], activation=activation,
in_drop=ffd_drop, coef_drop=attn_drop, residual=residual))
h_1 = tf.concat(attns, axis=-1)
out = []
for i in range(n_heads[-1]):
out.append(layers.attn_head(h_1, bias_mat=bias_mat,
out_sz=nb_classes, activation=lambda x: x,
in_drop=ffd_drop, coef_drop=attn_drop, residual=False))
logits = tf.add_n(out) / n_heads[-1]
return logits
三、GAT代码、论文、数据集下载
微信搜索“老和山算法指南”获取下载链接与技术交流群
有问题可以私信博主,点赞关注的一般都会回复,一起努力,谢谢支持。