IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 人工智能 -> 简单理解图神经网络 GNN -> 正文阅读

[人工智能]简单理解图神经网络 GNN

简单理解图神经网络 GNN

前言

图神经网络(Graph Neural Networks,GNN)最早由The Graph Neural Network Model(Gori et al., 2005)提出。近年来,深度学习领域关于图神经网络的研究热情日益高涨,图神经网络已经成为各大深度学习顶会的研究热点。

本文主要介绍图神经网络的基本原理,通过简单的方式理解 GNN, GCN 是如何工作的,尽量把原理说清楚。

Overview

总的来说,GNN 就是做了这么一件事情:利用图的节点信息去生成节点(图)的 Embedding 表示

Graph Neural Network(GNN)

既然是 Graph,那么我们的数据就是一张

其中 h A , h B , h C , h D , h E h_A, h_B, h_C, h_D, h_E hA?,hB?,hC?,hD?,hE?分别是节点 A , B , C , D , E A, B, C, D, E A,B,C,D,E的所包含的信息,你也可以简单理解为是这个节点的特征

GNN 可分为三步:1. 聚合;2. 更新;3. 循环。

首先是聚合。通过观察上面的图我们可以发现,节点 A A A有三个邻居节点 B , C , D B,C,D B,C,D,显然这是一个非常重要的信息,节点 A A A与这三个节点有密切的联系。举个例子,如果我们不知道节点 A A A是否有钱,但是我们发现节点 B , C , D B,C,D B,C,D都非常有钱,那么很大程度上节点 A A A也非常有钱,也就是通过节点的邻居信息判断这个节点的信息。那么要如何利用这个特征呢?

就像在一开始说的,GNN 就是利用图的节点信息去生成节点(图)的 Embedding 表示,这也就是聚合。我们可以通过简单的方式获取邻居的信息:

N A = a ? h B + b ? h C + c ? h D = a ? ( 2 , 2 ) + b ? ( 3 , 3 ) + c ? ( 4 , 4 ) \begin{aligned}N_A &= a \cdot h_B + b \cdot h_C + c \cdot h_D \\ &= a \cdot (2,2) + b \cdot (3,3) + c \cdot (4,4) \end{aligned} NA??=a?hB?+b?hC?+c?hD?=a?(2,2)+b?(3,3)+c?(4,4)?

其中 a , b , c a,b,c a,b,c为常数,也可以通过训练得到或者是手动设定,我们这里简单理解为常数。

好了,通过上面的简单的方式,我们得到了节点 A A A的邻居的信息,我们将这个信息作为节点 A A A信息的补充

再来是更新。当我们获取了邻居的信息后,自然也不能忘了节点 A A A本身的信息:

( h A + α ? N A ) (h_A + \alpha \cdot N_A) (hA?+α?NA?)

其中 α \alpha α为常数(同样也可以通过训练得到或者是手动设定,这里简单理解为常数)。当然了,肯定不能直接简单加起来就作为节点 A A A的新的信息,而是需要进行一些处理,其实也就是常规的线性变换,再过个激活函数:

h A = σ ( W ( h A + α ? N A ) ) \begin{aligned}h_A = \sigma (W (h_A + \alpha \cdot N_A)) \end{aligned} hA?=σ(W(hA?+α?NA?))?

其中 σ \sigma σ为激活函数, W W W为权重矩阵, h A h_A hA?为节点 A A A的信息, N A N_A NA?为节点 A A A的邻居信息。

简而言之,聚合更新就是把节点的邻居的信息添加到这个节点中。

现在,一次聚合操作就完成了,经过一次聚合之后:

  • 节点 A A A中有 B , C , D B,C,D B,C,D的信息;
  • 节点 B B B中有 A , C A,C A,C的信息;
  • 节点 C C C中有 A , B , D , E A,B,D,E A,B,D,E的信息;
  • 节点 D D D中有 A , C A,C A,C的信息;
  • 节点 E E E中有 C C C的信息;

第二次聚合也是类似的,仍然以节点 A A A为例,计算节点 A A A的邻居信息。但此时当节点 A A A聚合节点 C C C的时候,由于节点 C C C中包含了节点 E E E的信息,所以这时节点 A A A获得了二阶邻居 E E E的信息。

归根结底,GNN 就是一个提取特征的方法。

Graph Convolutional Network(GCN)

好了,讲完了 GNN 的总体思路,让我们具体来看看 GCN 是怎么做的。还是以下面这幅图为例:

同样的,我们需要获取节点 A A A的邻居信息:

N A = a ? h B + b ? h C + c ? h D = a ? ( 2 , 2 ) + b ? ( 3 , 3 ) + c ? ( 4 , 4 ) \begin{aligned}N_A &= a \cdot h_B + b \cdot h_C + c \cdot h_D \\ &= a \cdot (2,2) + b \cdot (3,3) + c \cdot (4,4) \end{aligned} NA??=a?hB?+b?hC?+c?hD?=a?(2,2)+b?(3,3)+c?(4,4)?

这里我们使用矩阵的方式来表示图,邻接矩阵 A A A,以及隐藏层矩阵 H H H

A = [ 0 1 1 1 0 1 0 1 0 0 1 1 0 1 1 1 0 1 0 0 0 0 1 0 0 ] H = [ 1 1 2 2 3 3 4 4 5 5 ] A = \begin{bmatrix} 0 & 1 & 1 & 1 & 0 \\ 1 & 0 & 1 & 0 & 0 \\ 1 & 1 & 0 & 1 & 1 \\ 1 & 0 & 1 & 0 & 0 \\ 0 & 0 & 1 & 0 & 0 \end{bmatrix} \quad H = \begin{bmatrix} 1 & 1 \\ 2 & 2 \\ 3 & 3 \\ 4 & 4 \\ 5 & 5 \end{bmatrix} A=???????01110?10100?11011?10100?00100????????H=???????12345?12345????????

这里假设 a = b = c = 1 a=b=c=1 a=b=c=1,那么,节点 A A A的邻居信息就可以表示为:

N A = [ 0 1 1 1 0 ] [ 1 1 2 2 3 3 4 4 5 5 ] = [ 9 9 ] = A 0 , ? H \begin{aligned} N_A &= \begin{bmatrix} 0 & 1 & 1 & 1 & 0 \end{bmatrix} \begin{bmatrix} 1 & 1 \\ 2 & 2 \\ 3 & 3 \\ 4 & 4 \\ 5 & 5 \end{bmatrix} =\begin{bmatrix}9 & 9\end{bmatrix} \\ &= A_{0,*}H \end{aligned} NA??=[0?1?1?1?0?]???????12345?12345????????=[9?9?]=A0,??H?

其中 A 0 , ? A_{0,*} A0,??表示矩阵 A A A的第一行,即节点 A A A的邻居关系。另外别忘了加上节点 A A A自身的信息,具体来说,可以通通过加上单位矩阵 I I I的方式实现:

N A = ( [ 0 1 1 1 0 ] + [ 1 0 0 0 0 ] ) [ 1 1 2 2 3 3 4 4 5 5 ] = [ 10 10 ] = ( A 0 , ? + I 0 , ? ) H \begin{aligned} N_A &= \left( \begin{bmatrix} 0 & 1 & 1 & 1 & 0 \end{bmatrix} + \begin{bmatrix} 1 & 0 & 0 & 0 & 0 \end{bmatrix}\right) \begin{bmatrix} 1 & 1 \\ 2 & 2 \\ 3 & 3 \\ 4 & 4 \\ 5 & 5 \end{bmatrix} =\begin{bmatrix}10 & 10\end{bmatrix} \\ &= (A_{0,*} + I_{0,*})H \end{aligned} NA??=([0?1?1?1?0?]+[1?0?0?0?0?])???????12345?12345????????=[10?10?]=(A0,??+I0,??)H?

同理,我们可以得到所有节点的邻居信息 N N N:

N = ( A + I ) H : = A ~ H \begin{aligned}N &= (A + I)H \\ &:= \tilde{A}H \end{aligned} N?=(A+I)H:=A~H?

A ~ = A + I \tilde{A} = A + I A~=A+I

现在,就可以写出隐藏层的更新方程了,与之前的思路类似,常规的线性变换,再过个激活函数:

H ( l + 1 ) = σ ( A ~ H ( l ) W ( l ) ) H^{(l+1)} = \sigma (\tilde{A}H^{(l)}W^{(l)}) H(l+1)=σ(A~H(l)W(l))

其中 l l l为循环层数, σ \sigma σ为激活函数, W W W为隐藏层的权重矩阵。

现在还有最后一个问题,你会发现,现在我们的矩阵 A ~ \tilde{A} A~中,非零元素均为 1 1 1,即简单的将当前节点的邻居信息相加,可以想象的是它会越来越「膨胀」。

A ~ = [ 1 1 1 1 0 1 1 1 0 0 1 1 1 1 1 1 0 1 1 0 0 0 1 0 1 ] \tilde{A} = \begin{bmatrix} 1 & 1 & 1 & 1 & 0 \\ 1 & 1 & 1 & 0 & 0 \\ 1 & 1 & 1 & 1 & 1 \\ 1 & 0 & 1 & 1 & 0 \\ 0 & 0 & 1 & 0 & 1 \end{bmatrix} A~=???????11110?11100?11111?10110?00101????????

实际上,解决这个问题并不麻烦,归一化就行了。在图 Graph 中,我们可以借助「度」来进行归一化。具体为什么这么做、为什么要进行归一化我们放在后面讲:关于归一化的一些问题

具体什么是这里就不赘述了,给出度矩阵:

D = [ 3 0 0 0 0 0 2 0 0 0 0 0 4 0 0 0 0 0 2 0 0 0 0 0 1 ] D ~ = [ 4 0 0 0 0 0 3 0 0 0 0 0 5 0 0 0 0 0 3 0 0 0 0 0 2 ] D = \begin{bmatrix} 3 & 0 & 0 & 0 & 0 \\ 0 & 2 & 0 & 0 & 0 \\ 0 & 0 & 4 & 0 & 0 \\ 0 & 0 & 0 & 2 & 0 \\ 0 & 0 & 0 & 0 & 1 \end{bmatrix} \quad \tilde{D} = \begin{bmatrix} 4 & 0 & 0 & 0 & 0 \\ 0 & 3 & 0 & 0 & 0 \\ 0 & 0 & 5 & 0 & 0 \\ 0 & 0 & 0 & 3 & 0 \\ 0 & 0 & 0 & 0 & 2 \end{bmatrix} D=???????30000?02000?00400?00020?00001????????D~=???????40000?03000?00500?00030?00002????????

其中, D , D ~ D,\tilde{D} D,D~分别是 A , A ~ A,\tilde{A} A,A~的度矩阵。

这里直接给出 GCN 论文 Semi-Supervised Classification with Graph Convolutional Networks 中的归一化方法,它的本质是对称归一化的拉普拉斯矩阵

D ~ ? 1 / 2 A ~ D ~ ? 1 / 2 \tilde{D}^{-1/2}\tilde{A}\tilde{D}^{-1/2} D~?1/2A~D~?1/2

关于上面的归一化方法,我们同样在后面具体讨论:关于归一化的一些问题,如果你不想了解细节也没关系,你只需要知道它的作用即可。

至此为止,我们可以得到完整的隐藏层的更新方程:

H ( l + 1 ) = σ ( D ~ ? 1 / 2 A ~ D ~ ? 1 / 2 H ( l ) W ( l ) ) H^{(l+1)} = \sigma (\tilde{D}^{-1/2}\tilde{A}\tilde{D}^{-1/2}H^{(l)}W^{(l)}) H(l+1)=σ(D~?1/2A~D~?1/2H(l)W(l))

其中 l l l为循环层数, σ \sigma σ为激活函数, W W W为隐藏层的权重矩阵, A ~ = ( A + I ) \tilde{A} = (A + I) A~=(A+I) D ~ \tilde{D} D~ A ~ \tilde{A} A~的度矩阵。虽然式子长得难看了点,但我想如果你了解了上面讲的内容,也就不难理解了。

关于归一化的一些问题

现在,让我们回到上面没解决的问题:

  1. 为什么要进行归一化?
  2. 论文中为什么使用 D ~ ? 1 / 2 A ~ D ~ ? 1 / 2 \tilde{D}^{-1/2}\tilde{A}\tilde{D}^{-1/2} D~?1/2A~D~?1/2进行归一化?

问题一

首先,为什么要进行归一化?这个问题其实在上面也有简单的解释。矩阵 A ~ \tilde{A} A~中,非零元素均为 1 1 1,那么这就意味着,在计算 A ~ H \tilde{A}H A~H时,就是简单的将当前节点的邻居信息相加,各个邻居一视同仁。

问题二

归一化

一个直观的归一化方法是:平均化聚合每个节点的信息

A ~ = [ 1 1 1 1 0 1 1 1 0 0 1 1 1 1 1 1 0 1 1 0 0 0 1 0 1 ] → [ 1 / 4 1 / 4 1 / 4 1 / 4 0 1 / 3 1 / 3 1 / 3 0 0 1 / 5 1 / 5 1 / 5 1 / 5 1 / 5 1 / 3 0 1 / 3 1 / 3 0 0 0 1 / 2 0 1 / 2 ] = D ~ ? 1 A ~ \tilde{A} = \begin{bmatrix} 1 & 1 & 1 & 1 & 0 \\ 1 & 1 & 1 & 0 & 0 \\ 1 & 1 & 1 & 1 & 1 \\ 1 & 0 & 1 & 1 & 0 \\ 0 & 0 & 1 & 0 & 1 \end{bmatrix} \quad \rightarrow \quad \begin{bmatrix} 1/4 & 1/4 & 1/4 & 1/4 & 0 \\ 1/3 & 1/3 & 1/3 & 0 & 0 \\ 1/5 & 1/5 & 1/5 & 1/5 & 1/5 \\ 1/3 & 0 & 1/3 & 1/3 & 0 \\ 0 & 0 & 1/2 & 0 & 1/2 \end{bmatrix} =\tilde{D}^{-1}\tilde{A} A~=???????11110?11100?11111?10110?00101???????????????1/41/31/51/30?1/41/31/500?1/41/31/51/31/2?1/401/51/30?001/501/2????????=D~?1A~

其中, D ~ ? 1 \tilde{D}^{-1} D~?1 A ~ \tilde{A} A~的度矩阵的逆。从数学的角度,上面的平均化也就是 D ~ ? 1 A ~ \tilde{D}^{-1}\tilde{A} D~?1A~的过程。现在我们已经将求和变成了加权平均,权值之后归一化为 1 1 1了。

对称归一化

那么为什么不直接使用简单的平均化方法呢?第一个缺点就是 D ~ ? 1 A ~ \tilde{D}^{-1}\tilde{A} D~?1A~不再是对称矩阵了,这不是我们想要看到的。

第二个缺点我们来看一个比较特殊的例子,在下面这幅图中,我们发现节点 A A A只有一个邻居节点 C C C,另一方面节点 C C C有着包括 A A A在内的 6 个邻居节点。

按照上面的平均化思路,当节点 A A A聚合节点 C C C时,节点 C C C所有的特征会完全加到节点 A A A上,但实际上,节点 A A A和节点 C C C的差距是很明显的。举个例子,节点 A A A是我,节点 C C C是老板,老板管着一票人,我只是一个苦命的打工人,不可能说把老板的工资完全加到我身上,然后我拿着一半我的工资,一半老板的工资,美滋滋。

那么一个科学的方法就是同时考虑节点 A A A C C C的邻居数量,即「度」,具体来说,可以考虑几何平均数 D ~ i i D ~ j j \sqrt{\tilde{D}_{ii} \tilde{D}_{jj}} D~ii?D~jj? ?,回到 D ~ ? 1 / 2 A ~ D ~ ? 1 / 2 \tilde{D}^{-1/2}\tilde{A}\tilde{D}^{-1/2} D~?1/2A~D~?1/2

( D ~ ? 1 / 2 A ~ D ~ ? 1 / 2 H ) i = ( D ~ ? 1 / 2 A ~ ) i D ~ ? 1 / 2 H = ( ∑ k D ~ i k ? 1 / 2 A ~ i ) D ~ ? 1 / 2 H = D ~ i i ? 1 / 2 ∑ j A ~ i j ∑ k D ~ j k ? 1 / 2 H j = D ~ i i ? 1 / 2 ∑ j A ~ i j D ~ j j ? 1 / 2 H j = ∑ j 1 D ~ i i D ~ j j A ~ i j H j \begin{aligned} (\tilde{D}^{-1/2}\tilde{A}\tilde{D}^{-1/2}H)_i &= (\tilde{D}^{-1/2}\tilde{A})_i \tilde{D}^{-1/2}H \\ &= \left( \sum_k \tilde{D}_{ik}^{-1/2}\tilde{A}_i \right) \tilde{D}^{-1/2}H \\ &= \tilde{D}_{ii}^{-1/2} \sum_j \tilde{A}_{ij} \sum_k \tilde{D}_{jk}^{-1/2} H_j \\ &= \tilde{D}_{ii}^{-1/2} \sum_j \tilde{A}_{ij} \tilde{D}_{jj}^{-1/2} H_j \\ &= \sum_j \frac{1}{\sqrt{\tilde{D}_{ii} \tilde{D}_{jj}}} \tilde{A}_{ij} H_j \end{aligned} (D~?1/2A~D~?1/2H)i??=(D~?1/2A~)i?D~?1/2H=(k?D~ik?1/2?A~i?)D~?1/2H=D~ii?1/2?j?A~ij?k?D~jk?1/2?Hj?=D~ii?1/2?j?A~ij?D~jj?1/2?Hj?=j?D~ii?D~jj? ?1?A~ij?Hj??

不考虑复杂的推导过程,只看结论,论文中的对称归一化方法就是使用了上面说的结论,同时考虑两个节点的邻居数量。那么,前面的例子就变成了:

D ~ ? 1 / 2 A ~ D ~ ? 1 / 2 = [ 1 2 0 0 0 0 0 1 3 0 0 0 0 0 1 5 0 0 0 0 0 1 3 0 0 0 0 0 1 2 ] [ 1 1 1 1 0 1 1 1 0 0 1 1 1 1 1 1 0 1 1 0 0 0 1 0 1 ] [ 1 2 0 0 0 0 0 1 3 0 0 0 0 0 1 5 0 0 0 0 0 1 3 0 0 0 0 0 1 2 ] = [ 1 4 1 2 3 1 2 5 1 2 3 0 1 2 3 1 3 1 15 0 0 1 2 5 1 15 1 5 1 15 1 10 1 2 3 0 1 15 1 3 0 0 0 1 10 0 1 2 ] \begin{aligned} \tilde{D}^{-1/2}\tilde{A}\tilde{D}^{-1/2} &= \begin{bmatrix} \frac{1}{2} & 0 & 0 & 0 & 0 \\ 0 & \frac{1}{\sqrt{3}} & 0 & 0 & 0 \\ 0 & 0 & \frac{1}{\sqrt{5}} & 0 & 0 \\ 0 & 0 & 0 & \frac{1}{\sqrt{3}} & 0 \\ 0 & 0 & 0 & 0 & \frac{1}{\sqrt{2}} \end{bmatrix} \begin{bmatrix} 1 & 1 & 1 & 1 & 0 \\ 1 & 1 & 1 & 0 & 0 \\ 1 & 1 & 1 & 1 & 1 \\ 1 & 0 & 1 & 1 & 0 \\ 0 & 0 & 1 & 0 & 1 \end{bmatrix} \begin{bmatrix} \frac{1}{2} & 0 & 0 & 0 & 0 \\ 0 & \frac{1}{\sqrt{3}} & 0 & 0 & 0 \\ 0 & 0 & \frac{1}{\sqrt{5}} & 0 & 0 \\ 0 & 0 & 0 & \frac{1}{\sqrt{3}} & 0 \\ 0 & 0 & 0 & 0 & \frac{1}{\sqrt{2}} \end{bmatrix}\\ &= \begin{bmatrix} \frac{1}{4} & \frac{1}{2\sqrt{3}} & \frac{1}{2\sqrt{5}} & \frac{1}{2\sqrt{3}} & 0 \\ \frac{1}{2\sqrt{3}} & \frac{1}{3} & \frac{1}{\sqrt{15}} & 0 & 0 \\ \frac{1}{2\sqrt{5}} & \frac{1}{\sqrt{15}} & \frac{1}{5} & \frac{1}{\sqrt{15}} & \frac{1}{\sqrt{10}} \\ \frac{1}{2\sqrt{3}} & 0 & \frac{1}{\sqrt{15}} & \frac{1}{3} & 0 \\ 0 & 0 & \frac{1}{\sqrt{10}} & 0 & \frac{1}{2} \end{bmatrix} \end{aligned} D~?1/2A~D~?1/2?=????????21?0000?03 ?1?000?005 ?1?00?0003 ?1?0?00002 ?1?????????????????11110?11100?11111?10110?00101????????????????21?0000?03 ?1?000?005 ?1?00?0003 ?1?0?00002 ?1??????????=????????41?23 ?1?25 ?1?23 ?1?0?23 ?1?31?15 ?1?00?25 ?1?15 ?1?51?15 ?1?10 ?1??23 ?1?015 ?1?31?0?0010 ?1?021???????????

最后,大佬们是如何想出 D ~ ? 1 / 2 A ~ D ~ ? 1 / 2 \tilde{D}^{-1/2}\tilde{A}\tilde{D}^{-1/2} D~?1/2A~D~?1/2的呢?其实,这个公式很接近对称归一化的拉普拉斯矩阵
L s y m = D ? 1 / 2 L D ? 1 / 2 = I ? D ? 1 / 2 A D ? 1 / 2 L^{sym} = D^{-1/2}LD^{-1/2} = I - D^{-1/2}AD^{-1/2} Lsym=D?1/2LD?1/2=I?D?1/2AD?1/2

Graph Attention Network(GAT)

如果你熟悉 Attention 机制,那么在了解了上面的内容之后,就不难理解 Graph Attention Network(GAT) 了,无非就是对邻居节点的权重进行自动学习,这里就不再细说了。

总结

最后,还是想强调一点,GNN 就是做了这么一件事情:利用图的节点信息去生成节点(图)的 Embedding 表示。就是那么一个 Embedding 的方法。

参考资料

  人工智能 最新文章
2022吴恩达机器学习课程——第二课(神经网
第十五章 规则学习
FixMatch: Simplifying Semi-Supervised Le
数据挖掘Java——Kmeans算法的实现
大脑皮层的分割方法
【翻译】GPT-3是如何工作的
论文笔记:TEACHTEXT: CrossModal Generaliz
python从零学(六)
详解Python 3.x 导入(import)
【答读者问27】backtrader不支持最新版本的
上一篇文章      下一篇文章      查看所有文章
加:2022-07-04 22:54:12  更:2022-07-04 22:55:37 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年12日历 -2024/12/29 7:42:59-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码
数据统计