一.基础内容。
1.邻接矩阵
邻接矩阵表示顶点间关系,是n阶方阵(n为顶点数量)。邻接矩阵分为有向图邻接矩阵和无向图邻接矩阵。无向图邻接矩阵是对称矩阵,而有向图的邻接矩阵不一定对称。
2.度矩阵
度矩阵是对角阵,对角上的元素为各个顶点的度。顶点vi的度表示和该顶点相关联的边的数量。无向图中顶点vi的度d(vi)=N(i)。
有向图中,顶点vi的度分为顶点vi的出度和入度,即从顶点vi出去的有向边的数量和进入顶点vi的有向边的数量。
3.特征矩阵
特征矩阵是设 A 是n阶方阵,如果存在数m和非零n维列向量 x,使得 Ax=mx 成立,则称 m 是矩阵A的一个特征值或本征值。设A是n阶方阵,如果数λ和n维非零列向量x使关系式Ax=λx成立,那么这样的数λ称为矩阵A特征值,非零向量x称为A的对应于特征值λ的特征向量。式Ax=λx也可写成( A-λE)X=0。这是n个未知数n个方程的齐次线性方程组,它有非零解的充分必要条件是系数行列式| A-λE|=0。
4.拉普拉斯算子和拉普拉斯矩阵
拉普拉斯算子:
拉普拉斯矩阵:
( 这个东东以前没有接触过,自我感觉有点儿难,这个链接里面讲的挺详细的https://zhuanlan.zhihu.com/p/238644468)
5.逆矩阵
二.图卷积网络(GCN)
图数据中的空间特征具有以下特点:
1) 节点特征:每个节点有自己的特征;(体现在点上)
2) 结构特征:图数据中的每个节点具有结构特征,即节点与节点存在一定的联系。(体现在边上)
总地来说,图数据既要考虑节点信息,也要考虑结构信息,图卷积神经网络就可以自动化地既学习节点特征,又能学习节点与节点之间的关联信息。
图卷积的核心思想是利用『边的信息』对『节点信息』进行『聚合』从而生成新的『节点表示』。对图像(image)中某一个像素进行卷积实际上是对该像素及相邻像素进行加权求和,那么在图(graph)结构中对某一个节点卷积就应该是对该节点和其邻居节点进行加权求和。
上面的公式中W为卷积变换的参数,可以训练优化。A矩阵为邻接矩阵,Aij不为0则表示节点i,j为邻居。H为所有节点的特征向量矩阵,每一行是一个节点的特征向量,H(0)就是X矩阵。
话不多说,上图来 !!!
上述图的邻接矩阵为
A = np.matrix([
[0, 1, 0, 0],
[0, 0, 1, 1],
[0, 1, 0, 0],
[1, 0, 1, 0]],
dtype=float
)
接下来,需要抽取出特征!我们基于每个节点的索引为其生成两个整数特征。
In [3]: X = np.matrix([
[i, -i]
for i in range(A.shape[0])
], dtype=float)
X
Out[3]: matrix([
[ 0., 0.],
[ 1., -1.],
[ 2., -2.],
[ 3., -3.]
])
按照传播规则H(l)*A
In [6]: A * X
Out[6]: matrix([
[ 1., -1.],
[ 5., -5.],
[ 1., -1.],
[ 2., -2.]]
现在图卷积层将每个节点表示为其相邻节点的聚合。但没有包含自身的特征,所以要加入自环(加上一个单位矩阵)
In [4]: I = np.matrix(np.eye(A.shape[0]))
I
Out[4]: matrix([
[1., 0., 0., 0.],
[0., 1., 0., 0.],
[0., 0., 1., 0.],
[0., 0., 0., 1.]
])
In [8]: A_hat = A + I
A_hat * X
Out[8]: matrix([
[ 1., -1.],
[ 6., -6.],
[ 3., -3.],
[ 5., -5.]])
归一化处理:
归一化的目的是希望输入数据的不同维度的特征具有相近的取值范围,从而能够更快的通过梯度下降找到最优解。(http://blog.csdn.net/cdknight_happy/article/details/106453319)
将邻接矩阵 A 与度矩阵 D 的逆相乘,对其进行变换,从而通过节点的度对特征表征进行归一化。因此,我们简化后的传播规则如下:
f(X, A) = D⁻¹AX
让我们看看发生了什么。我们首先计算出节点的度矩阵。注意:此处计算节点的度是用节点的入度,也可以根据自身的任务特点用出度,在本文中,这个选择是任意的。一般来说,您应该考虑节点之间的关系是如何与您的具体任务相关。例如,您可以使用in-degree来进行度矩阵计算,前提是只有关于节点的in-neighbors的信息与预测其具体任务中的标签相关。相反,如果只有关于外部邻居的信息是相关的,则可以使用out-degree。最后,如果节点的out-和in-邻居都与您的预测相关,那么您可以基于in-和out-度的组合来计算度矩阵。
计算度矩阵
In [9]: D = np.array(np.sum(A, axis=0))[0]
D = np.matrix(np.diag(D))
D
Out[9]: matrix([
[1., 0., 0., 0.],
[0., 2., 0., 0.],
[0., 0., 2., 0.],
[0., 0., 0., 1.]
])
变换之后
In [10]: D**-1 * A
Out[10]: matrix([
[0. , 1. , 0. , 0. ],
[0. , 0. , 0.5, 0.5],
[0. , 0.5, 0. , 0. ],
[1. , 0. , 1. , 0. ]
])
邻接矩阵上应用传播规则:
In [11]: D**-1 * A * X
Out[11]: matrix([
[ 1. , -1. ],
[ 2.5, -2.5],
[ 0.5, -0.5],
[ 2. , -2. ]
])
可以观察到,邻接矩阵中每一行的权重(值)都除以该行对应节点的度。
但是上面归一化得到的A不是对称矩阵,通常使用对称归一化的方法
接下来就要将自环和归一化整合在一起,并加入权重W和激活函数,在这里选择保持特征表征的维度,并应用 ReLU 激活函数,Relu函数的公式是f(x)=max(0,x)。权重W可以为[[1,-1],[-1,1]],如果我们想要减小输出特征表征的维度,我们可以减小权重矩阵 W 的规模为[[1],[-1]]
A-hat = A + I
D-hat = np.array(np.sum(A-hat , axis = 0))[0]
D-hat = np,matrix(np.diag(D-hat))
def relu(x):
return (abs(x) + x) / 2
In [51]: W = np.matrix([
[1, -1],
[-1, 1]
])
relu(D_hat**-1 * A_hat * X * W)
Out[51]: matrix(
[[1., 0.],
[4., 0.],
[2., 0.],
[5., 0.]])
将上面的优化方法结合在一起,就是GCN 的卷积公式了:
三.GCN预测
GCN可以用最后一层卷积层得到的节点特征向量进行预测,假设GCN只有两层,则预测的公式如下:
分类的损失函数如下:
四.GCN图神经网络的性质
4.1、 GCN与CNN的关系
图象是一种特殊的图数据,CNN中的卷积运算相较于GCN中的卷积运算,最大的区别是没有显式的表达出邻接矩阵。GCN中的卷积计算是用来处理更普遍的非结构化的图数据的。
从网络连接方式来看,二者都是局部连接。GCN的计算作用在其一阶子图上;CNN的计算作用在中心像素的N*N像素栅格内;节点下一层的特征计算只依赖于自身邻域的方式,在网络连接上表现为局部连接的结构。
二者卷积核的权重式处处共享的。都作用于全图的所有节点。参数共享会大大减少每一层网络的参数量,可以有效地避免过拟合现象的出现。
从模型的层面看,感受域随着卷积层的增大而变大。每多一层卷积运算,中心节点就能多融合进更外一圈的信息。
4.2、 GCN能够对图数据进行端到端的学习(一端是数据,一端是任务)
端到端的学习实现了一种自动化地从数据种进行高效学习的机制,但是离不开背后大量的针对特定类型数据的学习任务的适配工作
4.2.1、 图数据包含的信息
属性信息:描述了图中对象的固有属性。
结构信息:描述了对象之间的关联性质。
4.2.2、 GCN计算过程
首先对属性信息进行仿射变换,学习了属性特征之间的交互模式,然后迭代式的聚合邻居节点的特征,从而更新当前节点的特征。
4.2.3、 GCN的优势
GCN对表示学习和任务学习一起进行端到端的优化。
GCN对结构信息和属性信息的学习是同步进行的(在同一个网络层里同时学习)。
4.3、 GCN是一个低通滤波器
4.4、 GCN的问题-过于平滑
在使用多层GCN之后,节点的区分性变得越来越差,节点的表示向量趋于一致,这使得相应的学习任务变得更加困难,我们将这个问题称为多层GCN的过平滑问题