文章目录
摘要,
本周阅读了The graph neural network model这篇论文,论文提出了一种新的神经网络模型–图神经网络(graph neural network,GNN)模型,该模型扩展了已有的神经网络方法,使之适用于处理以图论表示的数据。该GNN模型可以直接处理大多数实用的图形类型,非循环的、循环的、有向的和无向的。通过看文章和相关资料的学习,对GNN的基本概念,相关流程以及GNN算法的实现原理和过程有了基本的认识。
Abstract
This week, I read the paper titled “The Graph Neural Network Model.” The paper introduces a novel neural network model known as the Graph Neural Network (GNN). This model extends existing neural network methodologies to make them applicable for processing data represented in graph form. The GNN model is capable of directly handling a wide variety of practical graph types, including acyclic, cyclic, directed, and undirected graphs. Through the study of the paper and supplementary materials, I have gained a fundamental understanding of the basic concepts of GNN, its related processes, as well as the principles and procedures behind the implementation of GNN algorithms.
1 GNN介绍
GNN 可以理解为是由 Graph(图) + Nerual Networks 组合而成的
- 图神经网络(Graph Neural Network,GNN)是一类用于处理图结构数据的深度学习模型。图结构数据中的实体以节点的形式表示,实体之间的关系以边的形式表示。GNN的目标是从图结构数据中学习有用的表示,并利用这些表示进行各种任务,例如节点分类、图分类、链接预测等。
- 图神经网络的核心思想是通过消息传递机制(message-passing mechanism)来聚合节点的邻居信息,并更新节点的特征表示。这个过程通常会进行多轮迭代,以便捕获图中更远距离的信息。最终,每个节点的特征表示将包含其邻居和更远节点的信息。
- 图神经网络的基本组成部分包括:
节点特征矩阵:用于表示图中每个节点的初始特征。
邻接矩阵:用于表示图中节点之间的连接关系。
图卷积层:用于聚合邻居节点的信息并更新节点特征。
输出层:根据任务需求设计的输出层,用于输出预测结果。
基本组件
- 节点表示:每个节点初始的特征向量可通过特征工程获取,通常包括用户的基本信息、行为特征等。
- 消息传递机制:定义如何从邻居节点汇聚信息,包含聚合函数和更新函数。常见的聚合函数有求和、平均和最大池化等。
- 损失函数:根据具体任务设置,如节点分类、边预测等。选择合适的损失函数能够提高模型的性能。
GNN的强大之处在于其能够有效处理非结构化数据,捕捉图中的局部和全局结构,从而在多种任务中实现优越的性能。
相对于传统的神经网络模型,GNN在处理图数据时有一些优势:
- 能够学习到节点和边之间的复杂关系。与传统神经网络只能处理类似向量或矩阵的数据不同,GNN天然地适用于处理有复杂关系的数据,如社交网络、蛋白质结构中残基之间的关系等。
- 具有很强的泛化性能。不同于传统的机器学习方法,GNN可以在没有预训练的情况下进行端到端的学习和推理。这意味着GNN可以更好地适应广泛的数据和任务,并且可以避免过度拟合。
- 涉及节点和边的信息量非常大,对于节点和边上存在多种属性或者情境信息的任务,在GNN中可以很自然地将这些信息进行整合。这些属性可以来自节点和边的语义信息、拓扑信息、上下文信息和其他相关信息。
- 强大的可扩展性:GNN已经在多个领域实现预测性能的颠覆,但其最大优势是可扩展性。 我们可以在GNN中添加更多的参数并训练它们以适用于特定的问题
2 GNN流程
通过一个简单的例子,简单对GNN流程有个初步的了解
如图表示各节点之间的关系,(x,x,x,x)表示各节点的初始特征
2.1 聚合
核心思路:将邻居的信息结合到自己身上,作为自己特征的补充
- 假设现在需要判断A节点的分类,但有时单看A节点自己的特征无法确定其属于哪个类别,从图中可以看出,A节点和B、C、D都有关系,这时B、C、D的特征就可以从一定程度上决定A的类别。
- 以A节点为例,邻居信息N = a ∗ \ast ∗(2,2,2,2,2) + b ∗ \ast ∗(3,3,3,3,3) + c ∗ \ast ∗(4,4,4,4,4),其中a,b,c是边的权重,假如b对a很重要,则a的值就可以设置的高一些,假如c对a不是很重要,则c的值就可以设置的低一些。邻居信息N可以理解为对A的特征信息的一个补足
2.2 更新
一次GNN操作:
- A节点的总特征,就是自己的特征 加 α \alpha α倍的邻居信息N,再乘权重W,再经过一个激活函数,最终得到的是经过一层GNN操作之后A的最终信息。
- A的最终的特征= σ ( w ( ( 1 , 1 , 1 , 1 ) + α ∗ N ) ) \sigma(w((1,1,1,1)+\alpha\ast N)) σ(w((1,1,1,1)+α∗N))
其中 σ \sigma σ是激活函数(relu,sigmoid等),w是模型需要训练的参数
2.3 循环
- 经过一次聚合后:A中有B,C,D的信息;B中有A,C的信息;C中有A,B,D,E的信息;D中有A,C的信息;E中有C的信息;第二次聚合之后以此类推。GNN层数越多,GNN的“感受野”越大,每个点考虑其他点的信息越多,考虑越全面.
- 以A节点为例,此时A聚合C的时候,由于C中有上一层聚合得到的E的信息,所以这时A获得了二阶邻居E的特征。
通过聚合更新,我们能够得到每个节点的表达,也就是特征feature,此时:节点分类就可以直接拿去分类,计算loss,优化权重W;关联预测则将两个节点的特征拼接起来,做分类,计算loss,做优化。
归根到底,GNN就是一个提取特征的方法
利用networkx简单生成一个无向图
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, 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()
如下图所示:
其中,每一个节点都有自己的一些特征,比如在社交网络中,每个节点(用户)有性别以及年龄等特征
5个节点的特征向量依次为:
[2, 6], [3, 5], [6, 7], [4, 6], [7, 8]
同样,6条边的特征向量为:
[1, 3], [4, 1], [1, 5], [5, 3], [5, 6], [5, 4]
根据上述相关概念和符号,该图中:
- 节点特征向量 l n l_{n} ln,如 l 1 = ( 2 , 6 ) l_1=(2,6) l1=(2,6)
- 边特征向量 l ( n 1 , n 2 ) l_{(n1,n2)} l(n1,n2)表示边(n1,n2)的特征向量,如 l ( 1 , 2 ) = ( 1 , 3 ) l_{(1,2)}=(1,3) l(1,2)=(1,3)
特征向量实际上也就是节点或者边的标签,这个是图本身的属性,一直保持不变。
3 GNN算法原理
3.1 图神经网络(GNN)模型的基本概念和符号
-
图的定义:
G ( N , E ) G(N,E) G(N,E)表示一个图,其中N是节点(node)的集合, E是边(edge)的集合。 -
邻居和连接
n e [ n ] : ne[n]: ne[n]:表示节点n的邻居节点集合,即与n通过边相连的节点
c o [ n ] : co[n]: co[n]:表示以n为顶点的边的集合。 -
标签
l n ∈ R l N : l_{n}\in R^{l_N}: ln∈RlN:表示与节点 n n n相关的标签,是一个实数向量。
l ( n 1 , n 2 ) ∈ R l E : l_{(n1,n2)}\in R^{l_E}: l(n1,n2)∈RlE:表示与边(n1,n2)相关的标签,也是一个实数向量。
l : l: l:表示通过将图中所有标签堆叠在一起得到的向量。 -
标签的一般表示
如果 y y y是包含图中数据的向量, S S S是节点(或边)的子集,那么 y s y_s ys表示中 y y y中选择与 S S S中节点(或边)相关的分量得到的向量
l n e [ n ] : l_{ne[n]}: lne[n]:表示包含节点 n n n所有邻居标签的向量。 -
图的类型
非位置图(Nonpositional graphs):没有为节点的邻居分配特定的逻辑位置。
位置图(Positional graphs):为每个节点 n n n的邻居分配一个唯一的整数标识符,以指示其逻辑位置。形式上,对于位置图中的每个节点 n n n,存在一个注入函数 v n : n e [ n ] − > 1