【GNN】第一章:图神经网络学习路径

图神经网络GNN

图神经网络, Graph Neural Networks, 是图数据+神经网络架构, 是一种处理图结构数据的深度学习方法,就是将神经网络模型拓展到图数据计算领域。本部分开始系列探索图数据挖掘领域的相关技术和算法。

【GNN】第一章:图神经网络入门

一、图神经网络是干什么的?

数据角度看,我们之前学的MLP、CNN、RNN、Transformer等深度学习架构,处理的都是结构化数据,比如下图这些数据:

这些结构化数据都是规则数据。比如上图的鸢尾花数据集就是一个二维表格数据,这个数据集中的所有样本都是独立同分布的,就是样本和样本之间是没有关系的。再比如上图的图像数据、音频数据、文本数据,这些数据的样本和样本之间仅仅隐含着一个位置序列关系或者时间序列关系。像上面这些表格数据、序列数据,我们都是可以将每个样本表示成矩阵、张量、序列(sequence) 等规则数据,然后喂入我们之前学的MLP、CNN、RNN、Transformer等深度学习架构中训练的。

但是在现实世界中,并不是所有的事物都可以用结构化数据来表示的,相反有更多的事物需要抽象成图问题,然后图数据来表示的。比如社交网络、交通路网、知识图谱、电商购物、文件系统、检测异常节点、蛋白质相互作用关系、分子结构、识别与疾病相关的基因、药物推荐等,这些事情就没法用结构化数据来表示,只能以图(Graph)的形式来表示实体之间的复杂关系,如下图所示:

上图就是图结构数据,是一个由节点组成的复杂关系网络,其中节点代表实体边代表实体之间的关系

所以,图数据是非规则的非结构化的数据:

任意的大小和复杂的拓扑结构;
没有固定的节点排序或参考点;
节点是无序的,节点可以有不同的邻居节点;
通常是动态的,并具有多模态的特征;
图的信息并非只蕴含在节点信息和边的信息中,图的信息还包括了图的拓扑结构。

那么,自然图神经网络是专门用来处理图数据的深度学习网络架构
或者说,不管你的数据是啥,只要你的数据可以抽象成图结构的形式,你的数据就适合用图神经网络跑一跑。比如小图片数据、序列数据:

可见,图神经网络适用的数据格式是非常随意的,它不像MLP、CNN、RNN、Transformer那样,必须要数据规整、要resize、要截断填补等,图神经网络要求的数据只要有点有边就行,至于几个点几条边都随意。也所以图数据无处不在,图应用无处不在,对应的图算法也是五花八门各种各样。

不管是互联网、社交、推荐、搜索,还是法律、历史、生物、医学,都充斥着海量的图数据。因为只要有关联,这些关联就可以被抽象成图数据嘛。而对这些图数据进行识别、处理、挖掘、应用就是自然而然的现实需求了。

也所以,现在只要你看到像"图机器学习、图数据挖掘、图神经网络、知识图谱、知识计算、对话问答、推荐系统、社会计算、媒体计算、网络智能、搜索引擎、社交网络、情感计算"等技术名词,你就要知道这些技术背后都是图。

也所以,图数据挖掘现在已经是IT界的一个必备的通用技能了,因为各行各业都需要。但是图数据挖掘并不简单,对应的算法也是五花八门、各有长短优劣。本部分只是从数据角度感性地窥视一下图神经网络是干啥的,下面我从应用场景、任务、算法、工具、学习线路等角度再细致梳理一遍这个领域。

二、学习路径概览

目前图神经网络使用最广泛的一个框架就是PyTorch Geometric,简称PyG,当然还有DGL库也是非常流行的,李沐老师推荐的就是DGL。这是PyG的官网地址:PyG Documentation — pytorch_geometric documentation 。PyG是斯坦福大学自建的PyTorch扩展库,是斯坦福大学专门为开发和实施图神经网络而开发的专用库。从官网上我们可以找到斯坦福CS224W图机器学习、图神经网络公开课 : CS224W | Home ,我个人也是从这个公开课切入学习的,下面简单介绍一下这个公开课的内容:

从课程内容上看,课程是先讲深度学习之前的图数据处理算法,也就是图数据的机器学习算法:图机器学习算法,也是我们经常说的传统图机器学习,对应的经典算法有Node2Vec、DeepWalk、PageRank等(2-4),然后才开始讲图深度学习网络(6-9,当然这个是重点),然后是知识图谱的算法(10、11),然后是子图检测(12、13),然后是图生成算法(14、15),最后是这个领域的一些高阶算法(16、17)。
这个课程基本也就是图数据挖掘涉及到的所有相关的知识点了。从中我们也可以看到,其实图神经网络只是其中的一个重点部分。所以后面我写的内容基本也是按照这个大脉络来写。

三、实际问题和学习内容的对应关系

下图是我在bilibili上看斯坦福大学CS224W图机器学习公开课-同济子豪兄中文精讲的视频总结的,如果觉得看不明白,自行到哔哩哔哩上搜索原视频观看。原视频作者实力太强了,他的视频价值非常非常高!在此表示深深的感谢!

上图是宏观角度。从上图我们可以看到一些现实中的实际项目需求对应的学术研究方向,以及这些学术研究方向下经典的算法,这些算法就是你实际项目的解决方案。
下图是微观角度。从实操层面来明确你实际项目的实现路径。

上图其实就是我们之前深度学习中的学习任务概念,就是如何把现实中的问题(项目需求)抽象成模型,这是你拿到一个项目后第一步要思考和确定的事情。

对于图学习任务来说,它又是分层的,分节点层面的任务、边层面的任务、子图层面任务、整图级层面的任务:

(1)节点层面的任务(Node level)
就是对节点进行分类或者回归,比如推断节点属性、检测异常节点,比如预测是否是垃圾邮件发送者、预测节点是否是信用卡欺诈用户等场景对应的就是节点分类任务。
如果所有节点都有标签,那就是监督学习任务,由已知的节点类别推推出未知的节点类别;
如果只有部分节点有标签,那就是半监督学习任务,由少部分已知节点类别推断出其他无标签节点的类别。

(2)边层面的任务(Edge-level)
就是对边进行分类和回归,由已知的链接推出未知的链接、预测两个节点之间是否有连接,比如道路交通的动态流量预测、推荐系统、药物副作用预测、药物与目标的相互作用识别、知识图谱的完成(knowledge graph completion)等任务,本质上都是边预测问题 link prediction。

(3)子图层面任务(subgraph level)
就是对节点进行聚类、或者相似度计算任务,比如社群检测、用户聚类、异常检测等需求对应的就是子图层面的任务。

(4)整图级层面的任务(Graph-level/Graph generation)
graph level可分为整图预测和图生成任务。
整图预测就是对整张图进行分类或归回,比如预测分子是否有毒,对整个分子属性进行预测等任务;
图生成比如生成新药物,生成分子结构。如果是动态生成的话,就是graph evolution,图演化,物理模拟,粒子位置变化的模拟。

当你的项目需求和学习任务匹配了以后,第二步就是确定用什么算法来实现你的学习任务,也就是确定是用机器学习算法还是深度学习算法来更好的完成你的任务。而算法的选择是要结合你的数据情况和算力资源来取舍的。

算法确定后,第三步是根据你预期要达到的模型效果,去极大地优化你的模型架构、数据处理、特征工程、数据增强、模型训练等实现细节。一个完整的项目要求是:任务-数据-架构-训练-硬件相互匹配、环环相扣的。比如你的数据处理一定要符合你的任务目标;你的架构设计一方面要匹配你的任务,另一方面还要匹配你的训练;模型的复杂度一方面要匹配数据,另一方面要匹配你的电脑硬件资源;模型的训练一方面要追求效果,另一方还追求效率,就是降低训练的时间成本和硬件成本,此时恰当的数据增强手段、或者更加高效的训练技术都可以降低你的训练成本。

所以,要完成一个实际项目除了根据上面两张图,对号入座你的解决方案、算法模型选择这种大方向,还要通盘考虑其他各个实操环节的细节。

四、图机器学习、图神经网络的相关工具

五、搭建环境:配置PyG

配置图神经网络库PyG,PyTorch Geometric,面向几何深度学习的PyTorch扩展库。几何深度学习指的是应用于图和其他不规则、非结构化数据的深度学习。从数据到架构到训练到可视化,PyG提供了一整套全面的工具,可以帮助我们实现基于图的深度学习任务。

配置PyG前你的电脑里面至少要有python、pytorch环境,所以我建议你最好在anaconda环境下配置。如果你觉得anaconda太重,你可以下载一个mini版的anaconda,然后再安装,就比较顺利。PyG不太好安装主要就是因为它有几个依赖,这几个依赖必须要安装对,才能顺利安装PyG。

我使用的是Anaconda + jupyter lab + pytorch配置图神经网络的运行环境。如果你的基础环境和我不一样,你再找找其他适合你的配置方式。PyG不是傻瓜式pip一键就安装了的,简单pip安装90%概率是失败的。

下面展示一下我的安装过程:


小结:
一是,你的python、pytorch都先安装好并可顺利运行。
二是,安装PyG的依赖库:torch-spares、torch-scatter、torch-spline_conv、torch-cluster、torch-lib。
三是,上官网https://github.com/pyg-team/pytorch_geometric 找到上面的依赖包并安装。
四是,pip 安装torch-geometric。

# GPF ## 一、GPF(Graph Processing Flow):利用图神经网络处理问题的一般化流程 1、图节点预表示:利用NE框架,直接获得全图每个节点的Embedding; 2、正负样本采样:(1)单节点样本;(2)节点对样本; 3、抽取封闭子图:可做类化处理,建立一种通用图数据结构; 4、子图特征融合:预表示、节点特征、全局特征、边特征; 5、网络配置:可以是图输入、图输出的网络;也可以是图输入,分类/聚类结果输出的网络; 6、训练和测试; ## 二、主要文件: 1、graph.py:读入图数据; 2、embeddings.py:预表示学习; 3、sample.py:采样; 4、subgraphs.py/s2vGraph.py:抽取子图; 5、batchgraph.py:子图特征融合; 6、classifier.py:网络配置; 7、parameters.py/until.py:参数配置/帮助文件; ## 三、使用 1、在parameters.py中配置相关参数(可默认); 2、在example/文件夹中运行相应的案例文件--包括链接预测、节点状态预测; 以链接预测为例: ### 1、导入配置参数 ```from parameters import parser, cmd_embed, cmd_opt``` ### 2、参数转换 ``` args = parser.parse_args() args.cuda = not args.noCuda and torch.cuda.is_available() torch.manual_seed(args.seed) if args.cuda: torch.cuda.manual_seed(args.seed) if args.hop != 'auto': args.hop = int(args.hop) if args.maxNodesPerHop is not None: args.maxNodesPerHop = int(args.maxNodesPerHop) ``` ### 3、读取数据 ``` g = graph.Graph() g.read_edgelist(filename=args.dataName, weighted=args.weighted, directed=args.directed) g.read_node_status(filename=args.labelName) ``` ### 4、获取全图节点的Embedding ``` embed_args = cmd_embed.parse_args() embeddings = embeddings.learn_embeddings(g, embed_args) node_information = embeddings #print node_information ``` ### 5、正负节点采样 ``` train, train_status, test, test_status = sample.sample_single(g, args.testRatio, max_train_num=args.maxTrainNum) ``` ### 6、抽取节点对的封闭子图 ``` net = until.nxG_to_mat(g) #print net train_graphs, test_graphs, max_n_label = subgraphs.singleSubgraphs(net, train, train_status, test, test_status, args.hop, args.maxNodesPerHop, node_information) print('# train: %d, # test: %d' % (len(train_graphs), len(test_graphs))) ``` ### 7、加载网络模型,并在classifier中配置相关参数 ``` cmd_args = cmd_opt.parse_args() cmd_args.feat_dim = max_n_label + 1 cmd_args.attr_dim = node_information.shape[1] cmd_args.latent_dim = [int(x) for x in cmd_args.latent_dim.split('-')] if len(cmd_args.latent_dim) == 1: cmd_args.latent_dim = cmd_args.latent_dim[0] model = classifier.Classifier(cmd_args) optimizer = optim.Adam(model.parameters(), lr=args.learningRate) ``` ### 8、训练和测试 ``` train_idxes = list(range(len(train_graphs))) best_loss = None for epoch in range(args.num_epochs): random.shuffle(train_idxes) model.train() avg_loss = loop_dataset(train_graphs, model, train_idxes, cmd_args.batch_size, optimizer=optimizer) print('\033[92maverage training of epoch %d: loss %.5f acc %.5f auc %.5f\033[0m' % (epoch, avg_loss[0], avg_loss[1], avg_loss[2])) model.eval() test_loss = loop_dataset(test_graphs, model, list(range(len(test_graphs))), cmd_args.batch_size) print('\033[93maverage test of epoch %d: loss %.5f acc %.5f auc %.5f\033[0m' % (epoch, test_loss[0], test_loss[1], test_loss[2])) ``` ### 9、运行结果 ``` average test of epoch 0: loss 0.62392 acc 0.71462 auc 0.72314 loss: 0.51711 acc: 0.80000: 100%|███████████████████████████████████| 76/76 [00:07<00:00, 10.09batch/s] average training of epoch 1: loss 0.54414 acc 0.76895 auc 0.77751 loss: 0.37699 acc: 0.79167: 100%|█████████████████████████████████████| 9/9 [00:00<00:00, 34.07batch/s] average test of epoch 1: loss 0.51981 acc 0.78538 auc 0.79709 loss: 0.43700 acc: 0.84000: 100%|███████████████████████████████████| 76/76 [00:07<00:00, 9.64batch/s] average training of epoch 2: loss 0.49896 acc 0.79184 auc 0.82246 loss: 0.63594 acc: 0.66667: 100%|█████████████████████████████████████| 9/9 [00:00<00:00, 28.62batch/s] average test of epoch 2: loss 0.48979 acc 0.79481 auc 0.83416 loss: 0.57502 acc: 0.76000: 100%|███████████████████████████████████| 76/76 [00:07<00:00, 9.70batch/s] average training of epoch 3: loss 0.50005 acc 0.77447 auc 0.79622 loss: 0.38903 acc: 0.75000: 100%|█████████████████████████████████████| 9/9 [00:00<00:00, 34.03batch/s] average test of epoch 3: loss 0.41463 acc 0.81132 auc 0.86523 loss: 0.54336 acc: 0.76000: 100%|███████████████████████████████████| 76/76 [00:07<00:00, 9.57batch/s] average training of epoch 4: loss 0.44815 acc 0.81711 auc 0.84530 loss: 0.44784 acc: 0.70833: 100%|█████████████████████████████████████| 9/9 [00:00<00:00, 28.62batch/s] average test of epoch 4: loss 0.48319 acc 0.81368 auc 0.84454 loss: 0.36999 acc: 0.88000: 100%|███████████████████████████████████| 76/76 [00:07<00:00, 10.17batch/s] average training of epoch 5: loss 0.39647 acc 0.84184 auc 0.89236 loss: 0.15548 acc: 0.95833: 100%|█████████████████████████████████████| 9/9 [00:00<00:00, 28.62batch/s] average test of epoch 5: loss 0.30881 acc 0.89623 auc 0.95132 ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

宝贝儿好

6元以上者可私信获PDF原文档

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值