PyGAT图注意力模型

​  PyGAT实现的分类器: https://www.aliyundrive.com/s/vfK8ndntpyc

  还在发烧,不是特别清醒,就简单写了写。用GAT进行关系预测,GAT可能是只做中间层,不过本来在GAT这一层就为了能懂就简化了很多地方了,如果再加别的,预测正确率大概率很低。尝试了直接用GAT预测边权(没用稀疏矩阵的版本),内存不够没办法跑(需要至少100G+),试了少一些节点,也基本预测不出来,所以这里只介绍GAT基本实现和GAT进行分类。

​   代码是用ANACONDA的IPYTHON虚拟环境里运行的。

​   需要安装pytorch,在conda prompt输入以下命令:

conda install pytorch torchvision torchaudio cpuonly -c pytorch

​   不用conda可以↓,选Pip,得到Pip的命令安装PyTorch。CUDA没有对应的版本就选CPU。

​   https://pytorch.org/

GAT

​   GAT对于一个图,按照其输入的节点特征预测输出新的节点的特征。

​   GAT是一种能够直接作用于图并且利用其结构信息的卷积神经网络,可用于网络中的半监督学习问题,学习网络中结点的特征与网络结构的信息。主要思想是对每个结点的邻居及其自身的信息作加权平均,按照其输入的节点特征输出新的节点特征。图注意力模型用注意力机制对邻近节点特征加权求和,每个节点可以根据邻节点的特征,为其分配不同的权值,将权重称为注意力系数,然后根据注意力系数进行加权求和,得到节点的新特征。

​   图注意力模型训练得到的是一个计算好节点的注意力权重的图,得到该图以后,就可以输入节点特征,得到新的节点特征。这个新的特征是什么取决于使用图注意力模型的目的。

GAT模型

  假设输入特征维度为x,输出特征维度为y。

  GAT是图注意力层+MUTIHEAD机制,MUTIHEAD机制相当于有多个图注意力层,每个层输出是n1,n2,n3…个新特征,最后再将这些特征转变为y个特征,也就是最终输出的特征

注意力系数计算

  构建图注意力层的第一步是计算注意力系数,对所有节点计算他的所有相邻节点的注意力系数。计算注意力系数公式如下:

•eij:节点i对邻居j的注意力系数

•W:可学习的参数矩阵

•a:可学习参数,一个向量,将多维特征转化为一个数

  得到注意力系数后,将该节点与所有邻居节点的注意力系数做归一化处理,就得到了注意力系数。这个归一化是指数归一化,并且归一化之前要使用L e a k y R e L U 进行非线性激活。归一后就得到了节点i和节点j的注意力系数。

聚合

  得到计算好的注意力系数,将特征进行加权求和,经激活函数激活后就得到了每个节点的新特征。

计算的例子

  https://zhuanlan.zhihu.com/p/412270208这里有一个图注意力模型的具体的计算的例子,可以看一下,就知道GAT是怎么由输入得到输出的了,这里的GAT代码是PyGAT的官方代码,对cora数据集分类,如果能看懂就知道GAT怎么用了,或者可以看看开头文件里的代码,用了PyGAT的模型,训练的部分简化了,删除了稀疏矩阵运算的版本。

模型定义

  图注意力层的定义如下:

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表示随机放弃多少邻节点,一般0.2self.in_features = in_features                     #输入特征self.out_features = out_features                  #输出特征self.alpha = alpha                                    #激活函数用的参数,0.2self.concat = concatself.W = nn.Parameter(torch.empty(size=(in_features, out_features))) #参数矩阵Wnn.init.xavier_uniform_(self.W.data, gain=1.414)                     #初始化self.a = nn.Parameter(torch.empty(size=(2*out_features, 1)))          #参数向量ann.init.xavier_uniform_(self.a.data, gain=1.414)                     #初始化self.leakyrelu = nn.LeakyReLU(self.alpha)                              #激活函数

  注意力层计算的过程在forward函数中,输入是h,原特征矩阵,输出是新特征矩阵。

    def forward(self, h, adj):Wh = torch.mm(h, self.W) # h.shape: (N, in_features), Wh.shape: (N, out_features)e = self._prepare_attentional_mechanism_input(Wh)                       zero_vec = -9e15*torch.ones_like(e)attention = torch.where(adj > 0, e, zero_vec)                           #邻接矩阵为0的位置表示没有边,注意力系数为0attention = F.softmax(attention, dim=1)                                 #指数归一化attention = F.dropout(attention, self.dropout, training=self.training)  #drop 0.2 的邻节点的注意力系数h_prime = torch.matmul(attention, Wh)                                  #输出特征if self.concat:return F.elu(h_prime)                                               #激活后的输出特征else:return h_prime

  GAT模型就是在图注意力层基础上MUTIHEAD机制的实现,但是MUTIHEAD机制不是图注意力模型必须的,只有1个图注意力层就可以算是一个图注意力模型了。
  下面看一下GAT模型的定义,MUTIHEAD机制的实现不重要,所以不看具体实现,只看参数。init中,nfeat是输入特征的维度,nhid是中间层,也就是如果有多个注意力层的情况下,注意力层的输出特征维度,nclass是最终的输出维度,因为这个GAT实现的是一个分类器,所以输出特征数就是类别数,即如果有n类,输出特征就应该有n个,每个输出值表示该样本是该类别的概率。例如每个样本都有一些自己的特征,一共有三类,把特征以及该样本和其他样本的关系输入到训练好的GAT,输出特征是0.1,0.5,0.4,就表示该样本是第一类,第二类,第三类的概率是0.1,0.5,0.4。至于为什么输出是概率,就涉及到模型训练的损失函数了,这部分内容可以看一下交叉熵相关的知识。顶着烧的我反正是没太看懂

class GAT(nn.Module):def __init__(self, nfeat, nhid, nclass, dropout, alpha, nheads):def forward(self, x, adj):

模型训练

  GAT能把输入特征变换为输出特征,是需要训练的。GAT一共两个可变参数,参数矩阵W和参数a,已经在模型定义时用nn.Parameter声明成参数了,接下来只要定义训练函数,就能训练出合适的模型了。

  怎么训练出合适的模型,让模型能够得到预期的输出,取决于模型的任务。对于分类任务来说,应该用已有数据的标签来训练模型,让模型得到的样本标签能够尽量贴近真实标签。

  首先要实例化一个模型,假设实例化一个三分类GAT模型:

hidden = int(labels.max()) + 1                  #直接把中间层特征数也设置成输出特征数了
model = GAT(nfeat=features.shape[1], nhid=hidden,                        #中间层特征数,模型可以在每一层有不同的输出特征数nclass=int(labels.max()) + 1,       #类别即输出特征数dropout=0.2, nheads= 1, alpha=0.2)

  训练模型用的优化器也要实例化一个:

patience = 100 #100次LOSS没有下降,就停止训练
epochs = 1000
optimizer = optim.Adam(model.parameters(), lr=0.001,                #学习率,训练慢了可以调大一点 weight_decay=5e-4)

  单轮次的训练就是用GAT算输出,然后用输出和正确结果计算损失,然后使用优化器进行优化,优化器会优化参数。损失函数就是上面提到的交叉熵。其中labels是ONEHOT编码,例如有三个类别type1,type2,type3,编码就是001,010,100,至于为什么使用ONEHOT编码,这也是和交叉熵有关的。

def train(epoch):t = time.time()model.train()optimizer.zero_grad()output = model(features, adj)                                        # 算输出loss_train = F.nll_loss(output[idx_train], labels[idx_train])     # nll_loss损失函数acc_train = accuracy(output[idx_train], labels[idx_train])loss_train.backward()optimizer.step()                                                  # 使用优化器优化loss_val = F.nll_loss(output[idx_train], labels[idx_train])acc_val = accuracy(output[idx_train], labels[idx_train])# 输出单轮训练结果print('Epoch: {:04d}'.format(epoch+1),'loss_train: {:.4f}'.format(loss_train.data.item()),'acc_train: {:.4f}'.format(acc_train.data.item()),'loss_val: {:.4f}'.format(loss_val.data.item()),'acc_val: {:.4f}'.format(acc_val.data.item()),'time: {:.4f}s'.format(time.time() - t))return loss_val.data.item()

  这样的训练进行多轮,直到所有轮次训练完或者损失函数算的loss值不再变化。

t_total = time.time()
loss_values = []
bad_counter = 0
best = epochs + 1
best_epoch = 0
for epoch in range(epochs):loss_values.append(train(epoch))torch.save(model.state_dict(), '{}.pkl'.format(epoch))if loss_values[-1] < best:best = loss_values[-1]best_epoch = epochbad_counter = 0else:bad_counter += 1if bad_counter == patience:breakfiles = glob.glob('*.pkl')for file in files:epoch_nb = int(file.split('.')[0])if epoch_nb < best_epoch:os.remove(file)

  train.py里用随机生成的数据进行了训练,运行一下就可以看到模型训练的过程结果,训练好的最佳参数的模型会保存到一个pkl文件里,最后的测试部分,会读入文件中的模型,测试中有一个idx_test是用于测试的数据的下标,我没有定义测试数据,所以将测试的这部分注释掉了。

  (原来的数据集中标签是一整份的,idx_train是用于训练的样本下标,idx_test是用于测试的样本下标,例如idx_train是0-4,表示labels[0:4]都是训练用的)

  最后说明一下期末各数据集的数据,human_sls中的数据为边权,similarity中的数据为特征,gene-list中的数据为所有基因(节点),实验的要求就是建立一个图,可以预测human_sls中的边权,即基因关系,可以用五折交叉或其他方法把边权划分出一部分训练模型,一部分用来验证。

数据挖掘期末-图注意力模型相关推荐

  1. GAT: 图注意力模型介绍及PyTorch代码分析

    文章目录 GAT: 图注意力模型介绍及代码分析 原理 图注意力层(Graph Attentional Layer) 情境一:节点和它的一个邻居 情境二:节点和它的多个邻节点 聚合(Aggregatio ...

  2. Graph Attention Network (GAT) 图注意力模型

    文章目录 1. GAT基本原理 1.1 计算注意力系数(attention coefficient) 1.2 特征加权求和(aggregate) 1.3 multi-head attention 2. ...

  3. 特征图注意力_向往的GAT(图注意力模型)

    0 GRAPH ATTENTION NETWORKS的诞生 随着GCN的大红大紫(可以参考如何理解 Graph Convolutional Network(GCN)?),graph领域的deep le ...

  4. GAT:图注意力模型介绍及PyTorch代码分析

    文章目录 1.计算注意力系数 2.聚合 2.1 附录--GAT代码 2.2 附录--相关代码 3.完整实现 3.1 数据加载和预处理 3.2 模型训练 1.计算注意力系数 对于顶点 iii ,通过计算 ...

  5. 【ICLR 2018图神经网络论文解读】Graph Attention Networks (GAT) 图注意力模型

    论文题目:Graph Attention Networks 论文地址:https://arxiv.org/pdf/1710.10903.pdf 论文代码:https://github.com/Peta ...

  6. 图深度学习,入门教程七,残差多层图注意力模型

    深度学习还没学完,怎么图深度学习又来了?别怕,这里有份系统教程,可以将0基础的你直接送到图深度学习.还会定期更新哦. 主要是基于图深度学习的入门内容.讲述最基本的基础知识,其中包括深度学习.数学.图神 ...

  7. 【Pytorch神经网络实战案例】22 基于Cora数据集实现图注意力神经网络GAT的论文分类

    注意力机制的特点是,它的输入向量长度可变,通过将注意力集中在最相关的部分来做出决定.注意力机制结合RNN或者CNN的方法. 1 实战描述 [主要目的:将注意力机制用在图神经网络中,完成图注意力神经网络 ...

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

    文章来源于机器之心DGL专栏,作者:张昊.李牧非.王敏捷.张峥. 图卷积网络 Graph Convolutional Network (GCN) 告诉我们将局部的图结构和节点特征结合可以在节点分类任务 ...

  9. GAT - Graph Attention Network 图注意力网络 ICLR 2018

    文章目录 1 相关介绍 GCN的局限性 本文贡献(创新点) attention 引入目的 相关工作 谱方法 spectral approaches 非谱方法 non-spectral approach ...

最新文章

  1. RDKit | 通过分析活性化合物确定指标阈值
  2. java 多条件比较_Java 多条件复杂排序小结
  3. 网易发布云计算战略,“为解放程序员而来”
  4. Docker教程-文件传输
  5. 指纹图谱相似度评价软件_基于指纹图谱和网络药理学对当归四逆汤中桂枝的Qmarker预测分析...
  6. Java 9对可选的补充
  7. Android 使用fastboot烧录镜像
  8. C++自学26:联合体(union/17)
  9. HTML URL编码
  10. 190606每日一句
  11. 改善宝宝过敏就吃伊敏舒,azg与Aibeca爱楽倍佳携手守护中国宝宝成长
  12. Go:实现Abs绝对值函数 (附完整源码)
  13. python练习题17
  14. N-Tiers开发方式(如何使用VB.NET撰写COM+组件)
  15. 一加手机可以刷鸿蒙系统吗,朋友想把1+手机安装鸿蒙系统,老板收费350,大家千万别被骗了!...
  16. Lync 2013 语言包安装
  17. Linux --VS Code安装与配置
  18. Android Notification消息提示
  19. mysql实体指的是_数据库中,实体是指( )。
  20. HTML5 直播协议之 WebSocket 和 MSE

热门文章

  1. iOS开发中那些容易被我们忽略的代码,常用代码集合
  2. 小白初写Spring核心容器功能
  3. DMC-Net: Generating Discriminative Motion Cues for Fast Compressed Video Action Recognition 论文赏析
  4. qdialog 只有点击才能获得焦点_盘点那些只有在校学生才能获得的教育专属优惠产品。...
  5. 让DedeCMS的栏目页标题显示页码数
  6. 新H5中用canvas画一个数字钟表
  7. python中排序从小到大_面试官:如何用Python实现三个整数从小到大排序?
  8. 视频太大怎么传给对方微信?视频传微信太大怎么办?
  9. 响铃:入局双11营销大战,搜狗翻译宝Pro的“新生活方式”宣言
  10. 清华邓俊辉数据结构学习笔记(4) - 二叉搜索树、高级搜索树