图神经网络GNN算法

本文结合一个具体的无向图来对最简单的一种GNN进行推导。本文第一部分是数据介绍,第二部分为推导过程中需要用的变量的定义,第三部分是GNN的具体推导过程,最后一部分为自己对GNN的一些看法与总结。

Posted in Python onMay 11, 2022

前言

本文结合一个具体的无向图来对最简单的一种GNN进行推导。本文第一部分是数据介绍,第二部分为推导过程中需要用的变量的定义,第三部分是GNN的具体推导过程,最后一部分为自己对GNN的一些看法与总结。

1. 数据

利用networkx简单生成一个无向图:

# -*- coding: utf-8 -*-
"""
@Time : 2021/12/21 11:23
@Author :KI 
@File :gnn_basic.py
@Motto:Hungry And Humble

"""
import networkx as nx
import numpy as np
import matplotlib.pyplot as plt
import pandas as pd

G = nx.Graph()
node_features = [[2, 3], [4, 7], [3, 7], [4, 5], [5, 5]]
edges = [(1, 2), (1, 3), (2, 4), (2, 5), (1, 3), (3, 5), (3, 4)]
edge_features = [[1, 3], [4, 1], [1, 5], [5, 3], [5, 6], [5, 4], [4, 3]]
colors = []
edge_colors = []

# add nodes
for i in range(1, len(node_features) + 1):
    G.add_node(i, feature=str(i) + ':(' + str(node_features[i-1][0]) + ',' + str(node_features[i-1][1]) + ')')
    colors.append('#DCBB8A')

# add edges
for i in range(1, len(edge_features) + 1):
    G.add_edge(edges[i-1][0], edges[i-1][1], feature='(' + str(edge_features[i-1][0]) + ',' + str(edge_features[i-1][1]) + ')')
    edge_colors.append('#3CA9C4')

# draw
fig, ax = plt.subplots()

pos = nx.spring_layout(G)
nx.draw(G, pos=pos, node_size=2000, node_color=colors, edge_color='black')
node_labels = nx.get_node_attributes(G, 'feature')
nx.draw_networkx_labels(G, pos=pos, labels=node_labels, node_size=2000, node_color=colors, font_color='r', font_size=14)
edge_labels = nx.get_edge_attributes(G, 'feature')
nx.draw_networkx_edge_labels(G, pos, edge_labels=edge_labels, font_size=14, font_color='#7E8877')

ax.set_facecolor('deepskyblue')
ax.axis('off')
fig.set_facecolor('deepskyblue')
plt.show()

如下所示:

图神经网络GNN算法


其中,每一个节点都有自己的一些特征,比如在社交网络中,每个节点(用户)有性别以及年龄等特征。

5个节点的特征向量依次为:

[[2, 3], [4, 7], [3, 7], [4, 5], [5, 5]]

同样,6条边的特征向量为:

[[1, 3], [4, 1], [1, 5], [5, 3], [5, 6], [5, 4], [4, 3]]

2. 变量定义

图神经网络GNN算法

特征向量实际上也就是节点或者边的标签,这个是图本身的属性,一直保持不变。

3. GNN算法

GNN算法的完整描述如下:Forward向前计算状态,Backward向后计算梯度,主函数通过向前和向后迭代调用来最小化损失。

图神经网络GNN算法


主函数中:

图神经网络GNN算法

上述描述只是一个总体的概述,可以略过先不看。

3.1 Forward

早期的GNN都是RecGNN,即循环GNN。这种类型的GNN基于信息传播机制: GNN通过不断交换邻域信息来更新节点状态,直到达到稳定均衡。节点的状态向量 x 由以下 f w ​函数来进行周期性更新:

图神经网络GNN算法

 

图神经网络GNN算法


解析上述公式:对于节点 n ,假设为节点1,更新其状态需要以下数据参与:

图神经网络GNN算法

这里的fw只是形式化的定义,不同的GNN有不同的定义,如随机稳态嵌入(SSE)中定义如下:

图神经网络GNN算法

由更新公式可知,当所有节点的状态都趋于稳定状态时,此时所有节点的状态向量都包含了其邻居节点和相连边的信息。

这与图嵌入有些类似:如果是节点嵌入,我们最终得到的是一个节点的向量表示,而这些向量是根据随机游走序列得到的,随机游走序列中又包括了节点的邻居信息, 因此节点的向量表示中包含了连接信息。

证明上述更新过程能够收敛需要用到不动点理论,这里简单描述下:

如果我们有以下更新公式:

图神经网络GNN算法

GNN的Foward描述如下:

图神经网络GNN算法


解释:

图神经网络GNN算法

3.2 Backward

在节点嵌入中,我们最终得到了每个节点的表征向量,此时我们就能利用这些向量来进行聚类、节点分类、链接预测等等。

GNN中类似,得到这些节点状态向量的最终形式不是我们的目的,我们的目的是利用这些节点状态向量来做一些实际的应用,比如节点标签预测。

因此,如果想要预测的话,我们就需要一个输出函数来对节点状态进行变换,得到我们要想要的东西:

图神经网络GNN算法


最容易想到的就是将节点状态向量经过一个前馈神经网络得到输出,也就是说 g w g_w gw​可以是一个FNN,同样的, f w f_w fw​也可以是一个FNN:

图神经网络GNN算法


我们利用 g w g_w gw​函数对节点 n n n收敛后的状态向量 x n x_n xn​以及其特征向量 l n l_n ln​进行变换,就能得到我们想要的输出,比如某一类别,某一具体的数值等等。

在BP算法中,我们有了输出后,就能算出损失,然后利用损失反向传播算出梯度,最后再利用梯度下降法对神经网络的参数进行更新。

对于某一节点的损失(比如回归)我们可以简单定义如下:

图神经网络GNN算法

图神经网络GNN算法


有了z(t)后,我们就能求导了:

图神经网络GNN算法

图神经网络GNN算法

z(t)的求解方法在Backward中有描述:

图神经网络GNN算法

图神经网络GNN算法

因此,在Backward中需要计算以下导数:

图神经网络GNN算法

4.总结与展望

本文所讲的GNN是最原始的GNN,此时的GNN存在着不少的问题,比如对不动点隐藏状态的更新比较低效。

由于CNN在CV领域的成功,许多重新定义图形数据卷积概念的方法被提了出来,图卷积神经网络ConvGNN也被提了出来,ConvGNN被分为两大类:频域方法(spectral-based method )和空间域方法(spatial-based method)。2009年,Micheli在继承了来自RecGNN的消息传递思想的同时,在架构上复合非递归层,首次解决了图的相互依赖问题。在过去的几年里还开发了许多替代GNN,包括GAE和STGNN。这些学习框架可以建立在RecGNN、ConvGNN或其他用于图形建模的神经架构上。

GNN是用于图数据的深度学习架构,它将端到端学习与归纳推理相结合,业界普遍认为其有望解决深度学习无法处理的因果推理、可解释性等一系列瓶颈问题,是未来3到5年的重点方向。

因此,不仅仅是GNN,图领域的相关研究都是比较有前景的,这方面的应用也十分广泛,比如推荐系统、计算机视觉、物理/化学(生命科学)、药物发现等等。

以上就是图神经网络GNN算法基本原理详解的详细内容!


Tags in this post...

Python 相关文章推荐
python打开文件并获取文件相关属性的方法
Apr 23 Python
尝试用最短的Python代码来实现服务器和代理服务器
Jun 23 Python
Python中文分词工具之结巴分词用法实例总结【经典案例】
Apr 15 Python
Python使用Selenium+BeautifulSoup爬取淘宝搜索页
Feb 24 Python
Python装饰器简单用法实例小结
Dec 03 Python
Python程序包的构建和发布过程示例详解
Jun 09 Python
浅谈pytorch grad_fn以及权重梯度不更新的问题
Aug 20 Python
python自动化工具之pywinauto实例详解
Aug 26 Python
Python中turtle库的使用实例
Sep 09 Python
Python Selenium截图功能实现代码
Apr 26 Python
Python多线程thread及模块使用实例
Apr 28 Python
浅析Python模块之间的相互引用问题
Feb 26 Python
python神经网络ResNet50模型
May 06 #Python
python和anaconda的区别
May 06 #Python
python神经网络Xception模型
May 06 #Python
Python使用永中文档转换服务
May 06 #Python
Python tensorflow卷积神经Inception V3网络结构
May 06 #Python
Python实现Matplotlib,Seaborn动态数据图
May 06 #Python
PYTHON InceptionV3模型的复现详解
You might like
攻克CakePHP系列三 表单数据增删改
2008/10/22 PHP
ThinkPHP CURD方法之field方法详解
2014/06/18 PHP
PHP中使用Session配合Javascript实现文件上传进度条功能
2014/10/15 PHP
php计算到指定日期还有多少天的方法
2015/04/14 PHP
Thinkphp3.2.3分页使用实例解析
2016/07/28 PHP
PHP设计模式之适配器模式原理与用法分析
2018/04/25 PHP
Thinkphp框架使用list_to_tree 实现无限级分类列出所有节点示例
2020/04/04 PHP
使用Apache的rewrite
2021/03/09 Servers
[原创]后缀就扩展名为js的文件是什么文件
2007/12/06 Javascript
js树形控件脚本代码
2008/07/24 Javascript
保证JavaScript和Asp、Php等后端程序间传值编码统一
2009/04/17 Javascript
Array.prototype 的泛型应用分析
2010/04/30 Javascript
jQuery-ui中自动完成实现方法
2010/06/10 Javascript
自己实现ajax封装示例分享
2014/04/01 Javascript
ECMAScript 5中的属性描述符详解
2015/03/02 Javascript
IE下JS保存图片的简单实例
2016/07/15 Javascript
JS实现向iframe中表单传值的方法
2017/03/24 Javascript
ES6新特性七:数组的扩充详解
2017/04/21 Javascript
JS触摸事件、手势事件详解
2017/05/04 Javascript
Node.js 使用命令行工具检查更新
2017/06/08 Javascript
jQuery validata插件实现方法
2017/06/25 jQuery
JavaScript简介_动力节点Java学院整理
2017/06/26 Javascript
Vue使用枚举类型实现HTML下拉框步骤详解
2018/02/05 Javascript
Node.js 利用cheerio制作简单的网页爬虫示例
2018/03/01 Javascript
vue.js实现备忘录demo
2019/06/26 Javascript
js设计模式之单例模式原理与用法详解
2019/08/15 Javascript
[02:15]2014DOTA2国际邀请赛 赛后退役选手回顾
2014/08/01 DOTA
使用Python更换外网IP的方法
2018/07/09 Python
使用python将图片格式转换为ico格式的示例
2018/10/22 Python
python为什么会环境变量设置不成功
2020/06/23 Python
德国原装品牌香水、化妆品和手表网站:BRASTY.DE
2016/10/16 全球购物
Falconeri美国官网:由羊绒和羊毛制成的针织服装
2018/04/08 全球购物
现代家居用品及礼品:LBC Modern
2018/06/24 全球购物
两道JAVA笔试题
2016/09/14 面试题
房地产管理毕业生自荐信
2013/11/04 职场文书
安全施工责任书
2014/08/25 职场文书