图神经网络:(大型图的有关处理)在Pumbed数据集上动手实现图神经网络

文章说明:
1)参考资料:PYG官方文档。超链。
2)博主水平不高,如有错误还望批评指正。
3)我在百度网盘上传了这篇文章的jupyter notebook和有关文献。超链。提取码8848。

文章目录

    • Pumed数据集
    • 文献阅读
    • 继续实验

Pumed数据集

导库

from torch_geometric.transforms import NormalizeFeatures
from torch_geometric.datasets import Planetoid

下载数据处理数据导入数据

dataset=Planetoid(root='/DATA/Planetoid',name='PubMed',transform=NormalizeFeatures())

其他说明1:这段代码会在C盘生成一个DATA的文件并将数据集放在DATA中,有强迫症注意一下。
其他说明2:如果下载发生错误直接去官网上下载。下载好了复制C:\DATA\Planetoid\PubMed\raw中。官网链接。不会有人没梯子吧。
数据描述

data=dataset[0]
print(data.num_nodes,end=" ");print(data.num_edges)
print(data.train_mask.sum().item(),end=" ");print(data.val_mask.sum().item(),end=" ");print(data.test_mask.sum().item())
print(data.has_isolated_nodes(),end=" ");print(data.has_self_loops(),end=" ");print(data.is_undirected(),end=" ")
#输出如下
#19717 88648
#60 500 1000
#False False True

其他说明:Pumbed数据集开源的生物医学文献数据库。不用细究。

文献阅读

参考文献: Cluster-GCN: An Efficient Algorithm for Training Deep and Large Graph Convolutional Networks。原文链接。

功能概述: 介绍一种方法在时间与空间完爆其他方法。其他方法是指:1)Full-batch gradient:在空间上:O(NLF)(N代表序列的长度,F代表特征的数量,L代表网络层数量)。在时间上,梯度下降收敛较慢。2)Mini-batch SGD:在时间空间上引入大量计算开销造成原因邻域扩展。计算某个节点损失需要第L-1层的嵌入然后需要第L-2层的嵌入递归下去。3)VR-GCN:克服上述领域扩展有关问题但是需要第L-1层的嵌入所以空间要求太高NG。然后Cluster-GCN就来啦。1)Cluster-GCN空间小特别是在大型图上2)Cluster-GCN在浅层GCN中速度等同于VR-GCN;深层GCN中Cluster-GCN快得多,Cluster-GCN是线性,VR-GCN是指数。3)尽管有些工作表明深层图神经网络的效果不佳,但是实验表明Cluster-GCN深层的效果不错。下图:各种方法的时空复杂度。
在这里插入图片描述

理论分析1::将节点划分为n组如 V 1 , V 2 , … V n ] \mathcal{V}_{1},\mathcal{V}_{2},\dots \mathcal{V}_{n}] V1,V2,Vn]。同组节点保存邻接不同组间直接断开。所以图被划分为 G ‾ = [ G 1 , G 2 , … , G n ] = [ { V 1 , E 1 } , { V 2 , E 2 } , … , { V n , E n } ] \overline{G}=[G_{1},G_{2},\dots,G_{n}]=[\{\mathcal{V}_{1},\mathcal{E}_{1}\},\{\mathcal{V}_{2},\mathcal{E}_{2}\},\dots,\{\mathcal{V}_{n},\mathcal{E}_{n}\}] G=[G1,G2,,Gn]=[{V1,E1},{V2,E2},,{Vn,En}]。这个相当于对图作近似。 Δ \Delta Δ保留了删除信息。特征向量以及标签按照节点划分划分。多层图神经网络便变为: Z L = A ‾ ′ σ ( A ‾ ′ σ ( … σ ( A ‾ ′ X W 0 ) W 1 ) …   ) W L − 1 Z^{L}=\overline{A}^{\prime}\sigma(\overline{A}^{\prime}\sigma(\dots\sigma(\overline{A}^{\prime}XW^{0})W^{1})\dots)W^{L-1} ZL=Aσ(Aσ(σ(AXW0)W1))WL1 A ‾ ′ \overline{A}^{\prime} A是分块对角阵 A ‾ \overline{A} A的标准化。损失函数变为: L A ‾ ′ = ∑ t ∣ V t ∣ N L A ‾ t t ′ \mathcal{L}_{\overline{A}^{\prime}}=\sum_{t}\frac{|\mathcal{V}_{t}|}{N}\mathcal{L}_{\overline{A}^{\prime}_{tt}} LA=tNVtLAtt and L A ‾ t t ′ = 1 ∣ V t ∣ ∑ i ∈ V t l o s s ( y i , z i L ) \mathcal{L}_{\overline{A}^{\prime}_{tt}}=\frac{1}{|\mathcal{V}_{t}|}\sum_{i \in \mathcal{V}_{t}}loss(y_{i},z_{i}^{L}) LAtt=Vt1iVtloss(yi,ziL) 。这个便就就是核心思想。大概就是按照下图右边那样进行分割。
在这里插入图片描述
理论分析2: 划分引入一种误差,这种误差是与 Δ \Delta Δ成正比,所以我们应该减小这种误差。于是引入Metis以及Graclus方法 。重点分析了Metics划分,比起随机划分效果更好如下:这些指标都是Accuracy_Score吧。
在这里插入图片描述
理论分析3:
还有问题。1)毕竟还是删除了一些边,模型效果可能还是受到影响。2)由于集群分配算法导致相似节点被分为了一堆,所以可能会与原始数据不同(PS:原文这样写的,我不能够理解),使用随机梯度算法可能会带来偏差吧。所以为了解决问题或者减小问题影响,提出了一个 stochastic multiple clustering方法。简单来说是这样的:随机梯度算法更新权重需要进行Batch的划分;之前邻接矩阵已经被处理成分块对角矩阵。选择m个对角矩阵进入Batch,前面删除的边重新加上。如下这样。(好吧这个图我也没看懂但是大致想法是清晰的)
在这里插入图片描述
结果如下:
在这里插入图片描述
算法的伪代码:
在这里插入图片描述

PS1:后面好像是实验的内容部分,没时间看就这样吧。PS:这是我的理解所以不一定对。

继续实验

导库

from torch_geometric.loader import ClusterData,ClusterLoader

聚类划分,构建批量

cluster_data=ClusterData(data,num_parts=128)
train_loader=ClusterLoader(cluster_data,batch_size=32,shuffle=True)

打印信息

total_num_nodes=0
for step,sub_data in enumerate(train_loader):
    print(f'Step {step + 1}:')
    print('=======')
    print(f'Number of nodes in the current batch: {sub_data.num_nodes}')
    print(sub_data)
    print()
    total_num_nodes+=sub_data.num_nodes
print(f'Iterated over {total_num_nodes} of {data.num_nodes} nodes!')
#输出如下
#Step 1:
#=======
#Number of nodes in the current batch: 4924
#Data(x=[4924, 500], y=[4924], train_mask=[4924], val_mask=[4924], test_mask=[4924], edge_index=[2, 15404])
#
#Step 2:
#=======
#Number of nodes in the current batch: 4939
#Data(x=[4939, 500], y=[4939], train_mask=[4939], val_mask=[4939], test_mask=[4939], edge_index=[2, 17834])
#
#Step 3:
#=======
#Number of nodes in the current batch: 4928
#Data(x=[4928, 500], y=[4928], train_mask=[4928], val_mask=[4928], test_mask=[4928], edge_index=[2, 17524])
#
#Step 4:
#=======
#Number of nodes in the current batch: 4926
#Data(x=[4926, 500], y=[4926], train_mask=[4926], val_mask=[4926], test_mask=[4926], edge_index=[2, 16042])
#
#Iterated over 19717 of 19717 nodes!

导库

from torch_geometric.nn import GCNConv
import torch.nn.functional as F
import torch

随便搭建

class GCN(torch.nn.Module):
    def __init__(self,hidden_channels):
        super(GCN,self).__init__()
        self.conv1=GCNConv(dataset.num_node_features,hidden_channels)
        self.conv2=GCNConv(hidden_channels,dataset.num_classes)
    def forward(self,x,edge_index):
        x=self.conv1(x,edge_index)
        x=x.relu()
        x=F.dropout(x,p=0.5,training=self.training)
        x=self.conv2(x,edge_index)
        return x

打印信息

model=GCN(hidden_channels=16)
print(model)
#输出如下
#GCN(
#  (conv1): GCNConv(500, 16)
#  (conv2): GCNConv(16, 3)
#)

开始训练

model=GCN(hidden_channels=16);optimizer=torch.optim.Adam(model.parameters(),lr=0.01,weight_decay=5e-4);criterion=torch.nn.CrossEntropyLoss()

def train():
      model.train()
      for sub_data in train_loader:
          out=model(sub_data.x,sub_data.edge_index)
          loss=criterion(out[sub_data.train_mask],sub_data.y[sub_data.train_mask])
          loss.backward()
          optimizer.step()
          optimizer.zero_grad()

def test():
      model.eval()
      out=model(data.x,data.edge_index)
      pred=out.argmax(dim=1)
      accs=[]
      for mask in [data.train_mask,data.val_mask,data.test_mask]:
          correct=pred[mask]==data.y[mask]
          accs.append(int(correct.sum())/int(mask.sum()))
      return accs

for epoch in range(1,51):
    loss=train()
    train_acc,val_acc,test_acc=test()
    print(f'Epoch: {epoch:03d}, Train: {train_acc:.4f}, Val Acc: {val_acc:.4f}, Test Acc: {test_acc:.4f}')
#最后一次输出如下
#Epoch: 050, Train: 0.9833, Val Acc: 0.8060, Test Acc: 0.7880

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/21360.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

不会Elasticsearch标准查询语句,如何分析数仓数据?

1 Elasticsearch的查询语句 ES中提供了一种强大的检索数据方式,这种检索方式称之为Query DSL,Query DSL是利用Rest API传递JSON格式的请求体(Request Body)数据与ES进行交互,这种方式的丰富查询语法让ES检索变得更强大,更简洁。 1.1 查询预发 # GET /…

案例分享|地弹现象导致DCDC电源芯片工作不正常

很多读者都应该听过地弹,但是实际遇到的地弹的问题应该很少。本案例就是一个DCDC电源芯片的案例。 1. 问题描述 如下图1 ,产品其中一个供电是12V转3.3V的电路,产品发货50K左右以后,大约有1%的产品无法启动,经过解耦定…

【C++】深入剖析C++11新特性

目录 一、C11简介 二、统一的列表初始化 1.{}初始化 2.std::initializer_list 三、声明 1.auto 2.decltype 3.nullptr 四、范围for 五、final和oberride 六、STL中一些变化 1.array 2.forward_list 3.unordered_map和unordered_set 七、右…

Python入门(十一)while循环(一)

while循环(一) 1.简介2.使用while循环3.让用户选择何时退出4.使用标志5.使用break退出循环6.在循环中使用continue7.避免无限循环 作者:xiou 1.简介 for循环用于针对集合中的每个元素都执行一个代码块,而while循环则不断运行&am…

虚幻引擎4利用粒子系统实现物体轨迹描绘

虚幻引擎4利用粒子系统实现物体轨迹描绘 目录 虚幻引擎4利用粒子系统实现物体轨迹描绘前言粒子系统利用粒子系统实现物体轨迹描绘创建粒子系统将粒子系统的产生位置绑定到运动物体上 小结 前言 由于在物体运动时,想要观察其总的运动轨迹,以便对其控制做…

CANoe-如何在Trace窗口显示SYN和FIN报文、同一条以太网报文在Trace窗口中的多条显示

1、如何在Trace窗口显示SYN和FIN报文 当我们使用CANoe实现TCP通信时,希望在Trace窗口直观显示报文的类型:SYN、ACK、FIN。显然Trace窗口也是支持这样的功能的。但很多时候由于一些人为的不正确的设置和配置,造成无法显示。 如果想解析出SYN报文,首先在Trace窗口选择正确的…

java注解

Target({ElementType.METHOD, ElementType.TYPE}) 注解的适用范围,可以用在什么地方,超过这个作用范围,编译的时候就会报错 值说明ElementType.METHOD用于描述方法ElementType.TYPE用于描述类、接口(包括注解类型) 或enum声明ElementType.LOCAL_VARIAB…

编程语言中,循环变量通常都用 i?你知道为什么吗?

01 前天,我在朋友圈发了一个问题: 为什么编程中,循环变量通常都是用 i ? 没想到,回复的人这么多!要连翻好几页。 这个问题,有 2/3 的人回答正确,有少部分人知道,但是不太确定。 习惯…

camunda如何发布和调用rest服务接口

一、camunda如何发布rest服务接口 Camunda BPM 平台本身提供了 REST API 接口,可以用于管理和操作 Camunda 平台中的各种资源和数据,如流程定义、流程实例、任务等。因此,我们可以通过编写 Camunda 应用程序的方式,将 Camunda RE…

最流行的开源 LLM (大语言模型)整理

本文对国内外公司、科研机构等组织开源的 LLM 进行了全面的整理。 Large Language Model (LLM) 即大规模语言模型,是一种基于深度学习的自然语言处理模型,它能够学习到自然语言的语法和语义,从而可以生成人类可读的文本。 所谓"语言模…

基于DBSCAN密度聚类的风电-负荷场景削减方法

​目录 ​ 1 主要内容 基于密度聚类的数据预处理: 场景提取: 算法流程: 2 部分程序 3 程序结果 4 下载链接 1 主要内容 该程序复现文章《氢能支撑的风-燃气耦合低碳微网容量优化配置研究》第三章内容,实现的是基于DBSCAN…

八股文大全

八股文大全 1. 基础篇1.1 网络基础1.1.1 TCP 三次握手1.1.2 TCP四次挥手![在这里插入图片描述](https://img-blog.csdnimg.cn/90a6997e8d414c84b499167c99da0397.png)1.1.3 TCP常见面试题 1. 基础篇 1.1 网络基础 1.1.1 TCP 三次握手 三次握手过程: 客户端——发…

开心档之MySQL 数据类型

目录 MySQL 数据类型 数值类型 日期和时间类型 字符串类型 MySQL 中定义数据字段的类型对你数据库的优化是非常重要的。 MySQL 支持多种类型,大致可以分为三类:数值、日期/时间和字符串(字符)类型。 数值类型 MySQL 支持所有标准 SQL 数值数据类型…

【信息安全案例】——信息内容安全(学习笔记)

📖 前言:在数字化时代,信息内容安全问题越来越引起人们的关注。信息内容安全主要包括对数据的机密性、完整性和可用性的保护,以及对用户隐私的保护等方面。针对信息内容安全的威胁,采取科学有效的安全措施和技术手段至…

面试京东失败,再看看2年前的面试题,根本不是一个难度···

刚从京东走出来,被二面难到了,我记得学长两年前去面试的时候,问的问题都特别简单,咋现在难度高了这么多。面试前我也刷过很多的题和看过很多资料,后来想想,这年头网上资料泛滥,测试面试文档更是…

从零玩转设计模式之外观模式-waiguanmos

title: 从零玩转设计模式之外观模式 date: 2022-12-12 15:49:05.322 updated: 2022-12-23 15:34:40.394 url: https://www.yby6.com/archives/waiguanmos categories: - 设计模式 tags: - 设计模式 什么是外观模式 外观模式是一种软件设计模式,它提供了一种将多个…

FastAPI 的路由介绍及使用

上一篇文章中,我介绍了 FastAPI 框架的安装和 HelloWorld 项目搭建方式。本文将介绍如何使用 Router 路由处理 FastAPI 中的请求。 什么是路由 路由 Router 就像是一个流水线上的线长,协调生产,下达命令给不同的组长进行分工,然…

Android实例——拼图游戏

拼图游戏 项目简介权限adapterPictureListAdapterPuzzleAdapter beanItemBean PresenterIPuzzlePresenterPuzzlePresenterImpl uiIGameCallback utilsConstantImagesUtilsScreenUtils ViewMainActivityPuzzleActivity 布局activity_main.xmlactivity_puzzle.xml 项目简介 选择…

手写西瓜书bp神经网络 mnist10 c#版本

本文根据西瓜书第五章中给出的公式编写,书中给出了全连接神经网络的实现逻辑,本文在此基础上编写了Mnist10手写10个数字的案例,网上也有一些其他手写的例子参考。demo使用unity进行编写,方便且易于查错。 该案例仅作为学习&#x…

ROS学习(1)——ROS1和ROS2的区别

因为机器人是一个系统工程,它包括了机械臂结构,电子电路,驱动程序,通信框架,组装集成,调试和各种感知决策算法等方面,任何一个人甚至是一个公司都不可能完成机器人系统的研发工作 。但是我们又希…