本文属于图神经网络的系列文章,文章目录如下:
- 从图(Graph)到图卷积(Graph Convolution):漫谈图神经网络模型 (一)
- 从图(Graph)到图卷积(Graph Convolution):漫谈图神经网络模型 (二)
- 从图(Graph)到图卷积(Graph Convolution):漫谈图神经网络模型 (三)
在上一篇博客中,我们简单介绍了基于循环图神经网络的两种重要模型,在本篇中,我们将着大量笔墨介绍图卷积神经网络中的卷积操作。接下来,我们将首先介绍一下图卷积神经网络的大概框架,借此说明它与基于循环的图神经网络的区别。接着,我们将从头开始为读者介绍卷积的基本概念,以及其在物理模型中的涵义。最后,我们将详细地介绍两种不同的卷积操作,分别为空域卷积和时域卷积,与其对应的经典模型。读者不需有任何信号处理方面的基础,傅里叶变换等概念都会在本文中详细介绍。
图卷积缘起
在开始正式介绍图卷积之前,我们先花一点篇幅探讨一个问题:为什么研究者们要设计图卷积操作,传统的卷积不能直接用在图上吗? 要理解这个问题,我们首先要理解能够应用传统卷积的图像(欧式空间)与图(非欧空间)的区别。如果把图像中的每个像素点视作一个结点,如下图左侧所示,一张图片就可以看作一个非常稠密的图;下图右侧则是一个普通的图。阴影部分代表卷积核,左侧是一个传统的卷积核,右侧则是一个图卷积核。卷积代表的含义我们会在后文详细叙述,这里读者可以将其理解为在局部范围内的特征抽取方法。
仔细观察两个图的结构,我们可以发现它们之间有2点非常不一样:
- 在图像为代表的欧式空间中,结点的邻居数量都是固定的。比如说绿色结点的邻居始终是8个(边缘上的点可以做Padding填充)。但在图这种非欧空间中,结点有多少邻居并不固定。目前绿色结点的邻居结点有2个,但其他结点也会有5个邻居的情况。
- 欧式空间中的卷积操作实际上是用固定大小可学习的卷积核来抽取像素的特征,比如这里就是抽取绿色结点对应像素及其相邻像素点的特征。但是因为图里的邻居结点不固定,所以传统的卷积核不能直接用于抽取图上结点的特征。
真正的难点聚焦于邻居结点数量不固定上。那么,研究者如何解决这个问题呢?其实说来也很简单,目前主流的研究从2条路来解决这件事:
- 提出一种方式把非欧空间的图转换成欧式空间。
- 找出一种可处理变长邻居结点的卷积核在图上抽取特征。
这两条实际上也是后续图卷积神经网络的设计原则,图卷积的本质是想找到适用于图的可学习卷积核。
图卷积框架(Framework)
上面说了图卷积的核心特征,下面我们先来一窥图卷积神经网络的全貌。如下图所示,输入的是整张图,在Convolution Layer 1
里,对每个结点的邻居都进行一次卷积操作,并用卷积的结果更新该结点;然后经过激活函数如ReLU
,然后再过一层卷积层Convolution Layer 2
与一词激活函数;反复上述过程,直到层数达到预期深度。与GNN类似,图卷积神经网络也有一个局部输出函数,用于将结点的状态(包括隐藏状态与结点特征)转换成任务相关的标签,比如水军账号分类,本文中笔者称这种任务为Node-Level
的任务;也有一些任务是对整张图进行分类的,比如化合物分类,本文中笔者称这种任务为Graph-Level
的任务。卷积操作关心每个结点的隐藏状态如何更新,而对于Graph-Level
的任务,它们会在卷积层后加入更多操作。本篇博客主要关心如何在图上做卷积,至于如何从结点信息得到整张图的表示,我们将在下一篇系列博客中讲述。
多说一句,GCN与GNN乍看好像还挺像的。为了不让读者误解,在这里我们澄清一下它们根本上的不同:GCN是多层堆叠,比如上图中的Layer 1
和Layer 2
的参数是不同的;GNN是迭代求解,可以看作每一层Layer参数是共享的。
卷积(Convolution)
正如我们在上篇博客的开头说到的,图卷积神经网络主要有两类,一类是基于空域的,另一类则是基于频域的。通俗点解释,空域可以类比到直接在图片的像素点上进行卷积,而频域可以类比到对图片进行傅里叶变换后,再进行卷积。傅里叶变换的概念我们先按下不讲,我们先对两类方法的代表模型做个大概介绍。
基于空域卷积的方法直接将卷积操作定义在每个结点的连接关系上,它跟传统的卷积神经网络中的卷积更相似一些。在这个类别中比较有代表性的方法有 Message Passing Neural Networks(MPNN)[1], GraphSage[2], Diffusion Convolution Neural Networks(DCNN)[3], PATCHY-SAN[4]等。
基于频域卷积的方法则从图信号处理起家,包括 Spectral CNN[5], Cheybyshev Spectral CNN(ChebNet)[6], 和 First order of ChebNet(1stChebNet)[7]等。
在介绍这些具体的模型前,先让我们从不同的角度来回顾一下卷积的概念,重新思考一下卷积的本质。
基础概念
由维基百科的介绍我们可以得知,卷积是一种定义在两个函数(\(f\)跟\(g\))上的数学操作,旨在产生一个新的函数。那么\(f\)和\(g\)的卷积就可以写成\(f*g\),数学定义如下:
\[(f*g)(t)={\int}_{-\infty}^{\infty}f(\tau)g(t-\tau) (连续形式)\]
\[(f*g)(t)={\sum}_{\tau=-\infty}^{\infty}f(\tau)g(t-\tau) (离散形式)\]
实例:掷骰子问题
光看数学定义可能会觉得非常抽象,下面我们举一个掷骰子的问题,该实例参考了知乎问题"如何通俗易懂地解释卷积"[8]的回答。
想象我们现在有两个骰子,两个骰子分别是\(f\)跟\(g\),\(f(1)\)表示骰子\(f\)向上一面为数字\(1\)的概率。同时抛掷这两个骰子1次,它们正面朝上数字和为4的概率是多少呢?相信读者很快就能想出它包含了三种情况,分别是:
- \(f\) 向上为1,\(g\) 向上为3;
- \(f\) 向上为2,\(g\) 向上为2;
- \(f\) 向上为3,\(g\) 向上为1;
最后这三种情况出现的概率和即问题的答案,如果写成公式,就是 \(\sum_{\tau=1}^{3}f(\tau)g(4-\tau)\)。可以形象地绘制成下图:
如果稍微扩展一点,比如说我们认为 \(f(0)\) 或者 \(g(0)\) 等是可以取到的,只是它们的值为0而已。那么该公式可以写成\(\sum_{\tau=-\infty}^{\infty}f(\tau)g(4-\tau)\)。仔细观察,这其实就是卷积\((f*g)(4)\)。如果将它写成内积的形式,卷积其实就是 \([f(-\infty),\cdots,f(1),\cdots,f(\infty)] \cdot [g(\infty),\cdots,g(3),\cdots,g(-\infty)]\)。这么一看,是不是就对卷积的名字理解更深刻了呢? 所谓卷积,其实就是把一个函数卷(翻)过来,然后与另一个函数求内积。
对应到不同方面,卷积可以有不同的解释:\(g\) 既可以看作我们在深度学习里常说的核(Kernel),也可以对应到信号处理中的滤波器(Filter)。而 \(f\) 可以是我们所说的机器学习中的特征(Feature),也可以是信号处理中的信号(Signal)。f和g的卷积 \((f*g)\)就可以看作是对\(f\)的加权求和。下面两个动图就分别对应信号处理与深度学习中卷积操作的过程[9][10]。
空域卷积(Spatial Convolution)
介绍完卷积的基础概念后,我们先来介绍下空域卷积(Spatial Convolution)。从设计理念上看,空域卷积与深度学习中的卷积的应用方式类似,其核心在于聚合邻居结点的信息。比如说,一种最简单的无参卷积方式可以是:将所有直连邻居结点的隐藏状态加和,来更新当前结点的隐藏状态。
这里非参式的卷积只是为了举一个简单易懂的例子,实际上图卷积在建模时需要的都是带参数、可学习的卷积核。
消息传递网络(Message Passing Neural Network)
消息传递网络(MPNN)[1] 是由Google科学家提出的一种模型。严格意义上讲,MPNN不是一种具体的模型,而是一种空域卷积的形式化框架。它将空域卷积分解为两个过程:消息传递与状态更新操作,分别由\(M_{l}(\cdot)\)和\(U_{l}(\cdot)\)函数完成。将结点\(v\)的特征\(\mathbf{x}_v\)作为其隐藏状态的初始态\(\mathbf{h}_{v}^0\)后,空域卷积对隐藏状态的更新由如下公式表示:
\[\mathbf{h}_{v}^{l+1}=U_{l+1}(\mathbf{h}_v,\sum_{u{\in}ne[v]}M_{l+1}(\mathbf{h}_v^l,\mathbf{h}_u^l,\mathbf{x}_{vu}))\]
其中\(l\)代表图卷积的第\(l\)层,上式的物理意义是:收到来自每个邻居的的消息\(M_{l+1}\)后,每个结点如何更新自己的状态。
如果读者还记得GGNN的话,可能会觉得这个公式与GGNN的公式很像。实际上,它们是截然不同的两种方式:GCN中通过级联的层捕捉邻居的消息,GNN通过级联的时间来捕捉邻居的消息;前者层与层之间的参数不同,后者可以视作层与层之间共享参数。MPNN的示意图如下[11]:
图采样与聚合(Graph Sample and Aggregate)
MPNN很好地概括了空域卷积的过程,但定义在这个框架下的所有模型都有一个共同的缺陷:卷积操作针对的对象是整张图,也就意味着要将所有结点放入内存/显存中,才能进行卷积操作。但对实际场景中的大规模图而言,整个图上的卷积操作并不现实。GraphSage[2]提出的动机之一就是解决这个问题。从该方法的名字我们也能看出,区别于传统的全图卷积,GraphSage利用采样(Sample)部分结点的方式进行学习。当然,即使不需要整张图同时卷积,GraphSage仍然需要聚合邻居结点的信息,即论文中定义的aggregate的操作。这种操作类似于MPNN中的消息传递过程。
具体地,GraphSage中的采样过程分为三步:
- 在图中随机采样若干个结点,结点数为传统任务中的
batch_size
。对于每个结点,随机选择固定数目的邻居结点(这里邻居不一定是一阶邻居,也可以是二阶邻居)构成进行卷积操作的图。 - 将邻居结点的信息通过\(aggregate\)函数聚合起来更新刚才采样的结点。
- 计算采样结点处的损失。如果是无监督任务,我们希望图上邻居结点的编码相似;如果是监督任务,即可根据具体结点的任务标签计算损失。
最终,GraphSage的状态更新公式如下:
\[\mathbf{h}_{v}^{l+1}=\sigma(\mathbf{W}^{l+1}\cdot aggregate(\mathbf{h}_v^l,\{\mathbf{h}_u^l\}),{\forall}u{\in}ne[v])\]
GraphSage的设计重点就放在了\(aggregate\)函数的设计上。它可以是不带参数的\(max\), \(mean\), 也可以是带参数的如\(LSTM\)等神经网络。核心的原则仍然是,它需要可以处理变长的数据。在本系列博客的第三篇笔者会介绍卷积神经网络中针对图任务的ReadOut
操作,\(aggregate\)函数的设计与其有异曲同工之妙,此处就不展开叙述了。
图结构序列化(PATCHY-SAN)
我们之前曾提到卷积神经网络不能应用在图结构上是因为图是非欧式空间,所以大部分算法都沿着找到适用于图的卷积核这个思路来走。而 PATCHY-SAN 算法 [4] 另辟蹊径,它将图结构转换成了序列结构,然后直接利用卷积神经网络在转化成的序列结构上做卷积。由于 PATCHY-SAN在其论文中主要用于图的分类任务,我们下面的计算过程也主要针对图分类问题(例如,判断某个社群的职业)。
那么,图结构转换成序列结构最主要的挑战在何处呢,如果简单的话,为什么以前的工作没有尝试把图转成序列结构呢?就笔者个人的观点来看,这种序列转换要保持图结构的两个特点:1. 同构的性质。 2. 邻居结点的连接关系。对于前者而言,意味着当我们把图上结点的标号随机打乱,得到的仍应是一样的序列。简单来说就是,同构图产生的序列应当相似,甚至一样;对于后者,则意味着我们要保持邻居结点与目标结点的距离关系,如在图中的三阶邻居在序列中不应该成为一阶邻居等。
PATCHY-SAN 通过以下三个步骤来解决这两个问题:
- 结点选择(Node Squenece Selection)。该过程旨在与通过一些人为定义的规则(如度大的结点分数很高,邻居的度大时分数较高等)为每个结点指定一个在图中的排序。在完成排序后,取出前 \(\omega\) 个结点作为整个图的代表。
- 邻居结点构造(Neighborhood graph construction)。在完成结点排序后,以第1步选择的结点为中心,得到它们的邻居(这里的邻居可以是第一阶邻居,也可以是二阶邻居)结点,就构成了 \(\omega\) 个团。根据第1步得到的结点排序对每个团中的邻居结点进行排序,再取前 \(k\) 个邻居结点按照顺序排列,即组成 \(\omega\) 个有序的团。
- 图规范化(Graph Noermalization)。按照每个团中的结点顺序可将所有团转换成固定长度的序列(\(k+1\)),再将它们按照中心结点的排序从前到后依次拼接,即可得到一个长度为 \({\omega}*(k+1)\) 的代表整张图的序列。这样,我们就可以直接使用带1D的卷积神经网络对该序列建模,比如图分类(可类比文本序列分类)。值得注意的一点是,在第1步和第2步中,如果取不到 \(\omega\) 或 \(k\) 个结点时,要使用空结点作填充(padding)。
一个形象的流程图如下所示,图源自论文[4]。
下图可能可以帮助读者更好地理解这种算法,图来自[12]。整个流程自底向上:首先根据自定义规则对图里的结点进行排序,然后选择前6个结点,即图中的 1至6;接着我们把这些结点
频域卷积(Spectral Convolution)
空域卷积非常直观地借鉴了图像里的卷积操作,但据笔者的了解,它缺乏一定的理论基础。而频域卷积则不同,相比于空域卷积而言,它主要利用的是图傅里叶变换(Graph Fourier Transform)实现卷积。简单来讲,它利用图的拉普拉斯矩阵(Laplacian matrix)导出其频域上的的拉普拉斯算子,再类比频域上的欧式空间中的卷积,导出图卷积的公式。虽然公式的形式与空域卷积非常相似,但频域卷积的推导过程却有些艰深晦涩。接下来我们将攻克这部分看起来很难的数学公式,主要涉及到傅里叶变换(Fourier Transform)和拉普拉斯算子(Laplacian operator)。即使读者没有学过任何相关知识也不要紧,笔者将尽可能用形象的描述解释每个公式的涵义,让读者能感悟这些公式的美妙之处。
前置内容
如上所述,在本小节,我们将介绍两个主要的知识点:傅里叶变换与拉普拉斯算子。在介绍之前,我们先抛出两个问题:1. 什么是傅里叶变换; 2. 如何将傅里叶变换扩展到图结构上。这两个问题是前置内容部分要解决的核心问题,读者可带着这两个问题,完成下面内容的阅读。
傅里叶变换(Fourier Transform)
借用维基百科的说法,傅里叶变换(Fourier Transform, FT)会将一个在空域(或时域)上定义的函数分解成频域上的若干频率成分。换句话说,傅里叶变换可以将一个函数从空域变到频域。先抛开傅里叶变换的数学公式不谈,用 \(F\) 来表示傅里叶变换的话,我们先讲一个很重要的恒等式:
\[(f*g)(t)=F^{-1}[F[f(t)]{\bigodot}F[g(t)]]\]
这里的\(F^{-1}\)指的是傅里叶逆变换,\(\bigodot\)是哈达玛乘积,指的是两个矩阵(或向量)的逐点乘积(Element-wise Multiplication)。仔细观察上面这个公式,它的直观含义可以用一句话来概括:空(时)域卷积等于频域乘积。简单来说就是,如果要算 \(f\) 与 \(g\) 的卷积,可以先将它们通过傅里叶变换变换到频域中,将两个函数在频域中相乘,然后再通过傅里叶逆变换转换出来,就可以得到 \(f\) 与 \(g\) 的卷积结果。下面的动图形象地展示了傅里叶变换的过程,这里我们把函数 \(f\) 傅里叶变换后的结果写作 \(\hat{f}\).
那傅里叶变换能干啥呢,有一个简单的应用是给图像去除一些规律噪点。比如说下面这个例子,原图来自知乎 [13]。
在傅里叶变换前,图像上有一些规律的条纹,直接在原图上去掉条纹有点困难,但我们可以将图片通过傅里叶变换变到频谱图中,频谱图中那些规律的点就是原图中的背景条纹。
只要在频谱图中擦除这些点,就可以将背景条纹去掉,得到下图右侧的结果。
除了可以用来分离噪声点与正常点,傅里叶变换还凭借上面的恒等式,在加速卷积运算方面有很大的潜力,快速傅里叶变换(Fast Fourier Transform)也是由此而生。实际上呢,现在大家最常用的卷积神经网络,完全可以搭配傅里叶变换。下面这张图就表示了一个普通的卷积神经网络如何与傅里叶变换搭配,其中的 IFFT 即 快速傅里叶变换的逆变换(Inverse Fast Fourier Transform:
其实笔者在初识傅里叶变换时很好奇,既然FFT可以加速卷积神经网络,为什么现在的卷积神经网络不用呢? 在经过一些搜索与思考后,笔者将自己得到的结论抛砖引玉供读者参考:我们现在的卷积神经网络的核都很小,常见的都如1,3,5之类,卷积操作的时间开销本来就不大。如果要搭配FFT,还需要做傅里叶变换与逆变换,时间开销并不一定会减小。
说了这么半天,傅里叶变换的公式是什么样呢?实际上,\(f\)经过傅里叶变换后的结果\(\hat{f}\)就如下所示,其中 \(i=\square{-1}\),\(\omega\)是频率相位。
\[\hat{f}(t)={\int}f(x){\exp}^{-i{\omega}t}dx\]
参考文献
[1]. Neural Message Passing for Quantum Chemistry, https://arxiv.org/abs/1704.01212
[2]. Inductive Representation Learning on Large Graphs, https://arxiv.org/abs/1706.02216
[3]. Diffusion-Convolutional Neural Networks, https://arxiv.org/abs/1511.02136
[4]. Learning Convolutional Neural Networks for Graphs, https://arxiv.org/pdf/1605.05273
[5]. Spectral Networks and Locally Connected Networks on Graphs, https://arxiv.org/abs/1312.6203
[6]. Convolutional neural networks on graphs with fast localized spectral filtering, https://papers.nips.cc/paper/6081-convolutional-neural-networks-on-graphs-with-fast-localized-spectral-filtering
[7]. Semi-Supervised Classification with Graph Convolutional Networks, https://arxiv.org/pdf/1609.02907
[8]. 如何通俗易懂地解释卷积, https://www.zhihu.com/question/22298352
[9]. https://en.wikipedia.org/wiki/Convolution
[10]. https://mlnotebook.github.io/post/CNN1/
[11]. http://snap.stanford.edu/proj/embeddings-www
[12]. https://zhuanlan.zhihu.com/p/37840709
[13]. https://www.zhihu.com/question/20460630/answer/105888045
[最后一次更新于 2019.7.28]