第八课开始,Jure又回归了。本节课的内容是图神经网络(Graph Neural Network, GNN),这也是目前非常新和非常热的一个内容。
在第七课中介绍的图表征学习的方法,总体而言都可以被称为“浅层”的学习。因为其中的编码器 E N C ( v ) \mathrm{ENC(v)} ENC(v)的本质还是一个embedding查找表,同时节点的相似度也只是依赖于它们在图机构里的共现相似度。这种浅层方法的缺点也是很明显:
这节课将会使用多层非线形变换函数来作为 E N C ( v ) \mathrm{ENC(v)} ENC(v),完成图表征的学习。
一个图 G G G,其中:
通过一个节点所在的邻居社区的特征和图结构来表征这个节点,因为这个节点的邻居和图结构一起构建了一个计算图。然后,再使用神经网络来聚合来自邻居(以及图结构)的信息。
这里一个核心的点在于:不同的点,通过聚合多层邻居会发现,它们的计算图是不一样的,因此神经网络学习到了不同的邻居图结构图特征。如下图:
聚合方法:
针对每个节点,这种多层聚合的基本思路是:
如下图所示:
这个图从右往左看,就相当于一个多层神经网络,输入层是每个节点的特征,中间每一层节点里的特这就已经是embedding了。就像上图里的 X C X_C XC是节点 C C C的初始特征,而第一层里的节点 C C C就已经是embedding后的值了。
那么这里面的核心是尖头对应的方盒子就是整个算法的关键。有两个问题:
公式:
按照上面的思想,可以给出下面的计算公式:
h v 0 = x v h_v^0 = \mathrm{x}_v hv0=xv
h v k = σ ( W k ∑ u ∈ N ( v ) h u k − 1 ∣ N ( v ) ∣ + B K h v k − 1 ) , ∀ k ∈ { 1 , … , K } h_v^k = \sigma(\mathrm{W}_k \displaystyle \sum_{u\in N(v)} \frac{h_u^{k-1}}{|N(v)|}+B_Kh_v^{k-1}), \forall{k} \in \{1, \dots, K\} hvk=σ(Wku∈N(v)∑∣N(v)∣huk−1+BKhvk−1),∀k∈{ 1,…,K}
z v = h v K z_v = h_v^K zv=hvK
这里初始的输入层就是每个节点自己的特征,最后的输出就是节点的embedding向量。
中间每层的隐藏层都是上面核心思路里的算法。其中, σ \sigma σ是一个非线性函数,如 R E L U \mathrm{RELU} RELU。 ∑ \sum ∑部分就是对每个节点进行邻居特征聚合平均的运算,然后进行一次线性变换就,即与权重矩阵 W k \mathrm{W}_k Wk相乘。括号里后半部分是和节点自身的embedding结合。
在这个公式里,我们需要训练的参数就是 W k W_k Wk和 B k B_k Bk。
当获得了节点的表征向量 z v z_v zv后,就可以设计损失函数来训练神经网络的参数了。参数的训练可以是:
L = ∑ v ∈ V y v l o g ( σ ( z v ⊤ θ ) ) + ( 1 − y v ) l o g ( 1 − σ ( z v ⊤ θ ) ) ) \mathcal{L} = \displaystyle \sum_{v \in V}y_vlog(\sigma(z_v^{\top}\theta)) + (1 -y_v)log(1-\sigma(z_v^{\top}\theta))) L=v∈V∑yvlog(σ(zv⊤θ))+(1−yv)log(1−σ(zv⊤θ)))
相比于上节课讲到的Transductive(转导式)的方法,深度图神经网络具有比较好的归纳(Inductive)能力,即它不局限于训练使用的图,而是可以被用于没见过的点、边和图。
主要原因是:构成深度图神经网络的参数是共享的,不受训练数据的束缚。哪怕全新的图数据,也可以使用训练得到的参数来进行embedding向量的计算。
把GCN的思想进一步泛化成通用的“消息传递+本地聚合”的模式。
h v k = σ ( [ A k ⋅ A G G ( h u k − 1 , ∀ u ∈ N ( v ) ) , B k h v k − 1 ] ) h_v^k=\sigma([A_k \cdot \mathrm{AGG}(h_u^{k-1}, \forall u \in N(v)), B_k h_v^{k-1}]) hvk=σ([Ak⋅AGG(huk−1,∀u∈N(v)),Bkhvk−1])
SAGE的这个公式和GCN有两个区别:
常用的聚合\mathrm{AGG}函数:
很多聚合算法可以用稀疏矩阵的计算来高效地实现的:
比如: H k − 1 = [ h 1 k − 1 , h 2 k − 1 , … , h n k − 1 ] H^{k-1}=[h_1^{k-1}, h_2^{k-1}, \dots, h_n^{k-1}] Hk−1=[h1k−1,h2k−1,…,hnk−1],则
∑ u ∈ N ( v ) h u k − 1 ∣ N v ∣ ⇒ H k = D − 1 A H k − 1 \displaystyle\sum_{u \in N(v)}\frac{\mathbf{h}_u^{k-1}}{|N_v|} \rArr H^{k}=D^{-1}AH^{k-1} u∈N(v)∑∣Nv∣huk−1⇒Hk=D−1AHk−1 H k = D − 1 / 2 A D 1 / 2 H k − 1 H^{k}=D^{-1/2}AD^{1/2}H^{k-1} Hk=D−1/2AD1/2Hk−1
对于边上的消息传递,对于不同的邻居设定不同的权值,采用加权聚合的方式。同时,这个权重也可以通过学习训练获得。这时候用到了注意力策略。
具体的注意力机制可以有多种选择,可以是简单的运算,还可以是带有参数的、可以和图神经网络一起训练的函数。
最新的GAT是多头注意力机制,包括并行独立的多个 α \alpha α,计算完成后,多个头再被合并起来或者加起来。
常见的注意力方法可以参考Attention is all you need这个论文里的方法实现。
Pinterest的案例是一个针对二部图进行物品推荐的例子。
给定Pinterest的二部图 G ( V , E ) G(V, E) G(V,E)。 V V V包含了两种节点 p i n pin pin和 b o a r d board board, E E E是从 p i n pin pin指向 b o a r d board board的边且仅能从 p i n pin pin指向 b o a r d board board。
图数据包括2B个 p i n pin pin,1B个 b o a r d board board,20B条边。且图是动态的,每时每刻都有新的点和边加入。点上面的特征很丰富,包含文字、图片等。
对 p i n pin pin的节点计算embedding,从而让在图上更接近的节点在embedding的向量空间里也接近。从而给下游的推荐任务提供更好的输入。
课程里面没有详细地介绍PinSage算法的细节。可以参考Graph Convolutional Neural Networks for Web-Scale Recommender Systems.
论文里的算法部分倒是不算很难,和GraphSage的算法类似。值得研究的是针对Pinterest的海量数据所做的工程优化,这个部分可以参考全面理解PinSage。