GCN基本原理与tensorflow2.0实现


图卷积神经网络(GCN)的核心思想: 学习一个映射 f ( . ) f(.) f(.),通过该映射图中的节点 v i v_i vi可以聚合它自己的特征 x i x_i xi与它的邻居特征 x j    ( j ∈ N ( v i ) ) x_j \;(j \in N(v_i)) xj(jN(vi))来生成节点的新 v i v_i vi表示。

图卷积本质上是一种aggregation(聚合)操作,是一种局部加权平均运算。在图中"局部"是指他的邻居,简单起见,把有边的权重定义为1,无边的权重定义为0。

基本符号定义

N = 1 , 2 , 3 ⋯ n N=1,2,3\cdots n N=1,2,3n 代表所有节点的编号

X i X_i Xi 代表节点 i i i 的特征向量

A A A 代表邻接矩阵, A i j A_{ij} Aij代表节点 i , j i,j i,j之间的边的权。

D D D 代表图的度的矩阵,是一个对角矩阵(是邻接矩阵的列和或行和),即: D i i = ∑ k = 1 N A i k D_{ii} = \sum_{k=1}^N A_{ik} Dii=k=1NAik

L = D − A L=D-A L=DA 是图的拉普拉斯矩阵(Laplacian Matrix)。

下面是一个例子(无权图):

在这里插入图片描述

图神经网络的公式定义

这是GCN图卷积层的示意图:

在这里插入图片描述

1、基本版本

先仔细思考:通过该映射图中的节点 v i v_i vi可以聚合它自己的特征 x i x_i xi与它的邻居特征 x j    ( j ∈ N ( v i ) ) x_j \;(j \in N(v_i)) xj(jN(vi))来生成节点的新 v i v_i vi表示 如何将这个过程用数学公式实现?主要包括两个部分:

(1)先聚合邻居特征,最简单的是加权平均法
a g g r e g a t e ( X i ) = ∑ j ∈ n e i g h b o r ( i ) A i j X j aggregate(\mathbf X_i) = \sum_{j \in neighbor(i)}A_{ij}X_j aggregate(Xi)=jneighbor(i)AijXj
注:A是带权邻接矩阵。

将其写成矩阵运算(矩阵式聚合):
a g g r e g a t e ( X i ) = A X aggregate(\mathbf X_i) = \mathbf A \mathbf X aggregate(Xi)=AX

(2)添加自环,加入自己的特征
a g g r e g a t e ( X ) = ( A + I ) X = A X + X a g g r r e g a t e ( X i ) = ∑ j ∈ N A i j X j + X i aggregate(X) = (A+I) X = AX +X \\ aggrregate(X_i) = \sum_{j \in N} A_{ij}X_{j} + X_{i} aggregate(X)=(A+I)X=AX+Xaggrregate(Xi)=jNAijXj+Xi
这样就实现了将节点本身的特征加回来了。

2、"差分"版本

存在这样一种场景:节点 v i v_i vi的特征与他的邻居节点 x j x_j xj的差距较大,这样的任务可能更加关注相邻节点间的"差分"。一般会用拉普拉斯矩阵 L = D − A L = D - A L=DA 来实现。
a g g r e g a t e ( X ) = ( D − A ) X = D X − A X a g g r r e g a t e ( X i ) = ∑ j ∈ N A i j X i − ∑ j ∈ N A i j X j = ∑ j ∈ N A i j ( X i − X j ) aggregate(X) =(D-A) X = DX - AX \\ \\ aggrregate(X_i) = \sum_{j \in N} A_{ij}X_{i}- \sum_{j \in N} A_{ij} X_{j} = \sum_{j \in N} A_{ij}(X_{i}- X_{j}) aggregate(X)=(DA)X=DXAXaggrregate(Xi)=jNAijXijNAijXj=jNAij(XiXj)
其中, D X DX DX可以理解为当前节点本来拥有的信息; A X AX AX 可以理解为本次操作要减少的信息。

3、“带权”归一化版本

无论是 A + I A+I A+I还是 D − A D-A DA,均是利用邻居节点和自身的节点求和,而不是平均。这会导致离群较远或者度较小的节点在聚合后特征较小,离群较近或者度较大的节点在聚合后特征较大。因此需要进行归一化。

A ^ = A + I \hat A = A+I A^=A+I或者 A ^ = D − A \hat A = D-A A^=DA D ^ \hat D D^ A ^ \hat A A^的度的矩阵。

在这里插入图片描述

所以,加权聚合的结果为:
a g g r e g a t e ( X ) = D ^ − 1 A ^ X aggregate(X) = \hat D^{-1} \hat A X aggregate(X)=D^1A^X
以下的公式解释了上式如何实现归一化:
a g g r e g a t e ( X i ) = ∑ k = 1 N D ^ i k − 1 ∑ j = 1 N A ^ i j X j = ∑ j = 1 N D ^ i i − 1 A ^ i j X j = ∑ j = 1 N A ^ i j D ^ i i X j = ∑ j = 1 N A ^ i j ∑ k = 1 N A ^ i k X j \begin{aligned} aggregate(X_i) &= \sum_{k=1}^N \hat D_{ik}^{-1}\sum_{j=1}^N \hat A_{ij} X_j \\ &= \sum_{j=1}^{N} \hat D_{ii}^{-1} \hat A_{ij} X_{j} \\ &= \sum_{j=1}^{N} \frac{ \hat A_{ij}}{\hat D_{ii}} X_{j} \\ & = \sum_{j=1}^{N} \frac{ \hat A_{ij}}{\sum_{k=1}^{N}\hat A_{ik}} X_{j} \end{aligned} aggregate(Xi)=k=1ND^ik1j=1NA^ijXj=j=1ND^ii1A^ijXj=j=1ND^iiA^ijXj=j=1Nk=1NA^ikA^ijXj
这样通过 D ^ − 1 \hat D^{-1} D^1操作,已经将求和变成加权平均求和,权值之和归一化为1。

4、对称归一化版本

在这里插入图片描述

“带权”归一化版本只考虑到了节点自身的度,实际上除了应该考虑聚合节点 i i i 的度 D ^ j j \hat D_{jj} D^jj ,还应该考虑被聚合节点 j j j的度 D ^ j j \hat D_{jj} D^jj,将二者的几何平均 D ^ j j D ^ j j \sqrt{\hat D_{jj} \hat D_{jj}} D^jjD^jj 引入:
aggregate ( X i ) = D ^ − 0.5 A ^ D ^ − 0.5 X = ∑ k = 1 N D ^ i k − 0.5 ∑ j = 1 N A ^ i j X j ∑ l = 1 N D ^ i l − 0.5 = ∑ j = 1 N D ^ i i − 0.5 A ^ i j X j D ^ j j − 0.5 = ∑ j = 1 N 1 D ^ i i 0.5 A ^ i j 1 D ^ j j 0.5 X j = ∑ j = 1 N A ^ i j D ^ i i D ^ j j X j \begin{aligned} \text {aggregate}\left(X_{i}\right) &=\hat{D}^{-0.5} \hat{A} \hat{D}^{-0.5} X \\ &=\sum_{k=1}^{N} \hat{D}_{i k}^{-0.5} \sum_{j=1}^{N} \hat{A}_{i j} X_{j} \sum_{l=1}^{N} \hat{D}_{i l}^{-0.5} \\ &=\sum_{j=1}^{N} \hat{D}_{i i}^{-0.5} \hat{A}_{i j} X_{j} \hat{D}_{j j}^{-0.5} \\ &=\sum_{j=1}^{N} \frac{1}{\hat{D} i i^{0.5}} \hat{A}_{i j} \frac{1}{\hat{D}_{j j}^{0.5}} X_{j} \\ &=\sum_{j=1}^{N} \frac{\hat{A}_{i j}}{\sqrt{\hat{D} i i \hat{D} j j}} X_{j} \end{aligned} aggregate(Xi)=D^0.5A^D^0.5X=k=1ND^ik0.5j=1NA^ijXjl=1ND^il0.5=j=1ND^ii0.5A^ijXjD^jj0.5=j=1ND^ii0.51A^ijD^jj0.51Xj=j=1ND^iiD^jj A^ijXj
显而易见,通过 D ^ − 0.5 A ^ D ^ − 0.5 \hat{D}^{-0.5} \hat{A} \hat{D}^{-0.5} D^0.5A^D^0.5操作,实现了 D ^ i i 和 D ^ j j \hat D_{ii}和\hat D_{jj} D^iiD^jj的集合平均,从而剔除了被聚合节点 j j j的度的影响。

这是图卷积的基本操作,这种图卷积是谱图卷积的一阶近似。接着只需要将图卷积层堆积起来就构成了图卷积网络GCN。

GCN基本结构

接下来来看两个GCN结构:

(1)结构一:多层GCN

在这里插入图片描述

GCN层通过聚集来自其邻居的特征信息来封装每个节点的隐藏表示。特征聚合后,将非线性变换应用于结果输出。通过堆叠多层,每个节点的最终隐藏表示形式将包含来自其他节点的信息。

(2)结构二:用于分类的FGCN

在这里插入图片描述

GCN层后面是池化层,以将图粗化为子图(聚合更多的信息)。因为要计算每个图形标签的概率,输出层是具有SoftMax函数的线性层。

GCN层的tensorflow2.0实现

import tensorflow as tf
from tensorflow.keras import activations, regularizers, constraints, initializers
spdot = tf.sparse.sparse_dense_matmul
dot = tf.matmul


class GCNConv(tf.keras.layers.Layer):
def __init__(self,
             units,
             activation=lambda x: x,
             use_bias=True,
             kernel_initializer='glorot_uniform',
             kernel_regularizer=None,
             kernel_constraint=None,
             bias_initializer='zeros',
             bias_regularizer=None,
             bias_constraint=None,
             activity_regularizer=None,
             **kwargs):
    # 初始化不需要训练的参数
    self.units = units
    # activation=None 使用线性激活函数(等价不使用激活函数)
    self.activation = activations.get(activation)
    self.use_bias = use_bias
    
    # 初始化方法定义了对Keras层设置初始化权重(bias)的方法 glorot_uniform
    self.kernel_initializer = initializers.get(kernel_initializer)
    self.bias_initializer = initializers.get(bias_initializer)
    
    # 加载正则化的方法
    self.kernel_regularizer = regularizers.get(kernel_regularizer)
    self.bias_regularizer = regularizers.get(bias_regularizer)
    self.activity_regularizer = regularizers.get(activity_regularizer)
    
    # 约束:对权重值施加约束的函数。
    self.kernel_constraint = constraints.get(kernel_constraint)
    self.bias_constraint = constraints.get(bias_constraint)

    super(GCNConv, self).__init__()

def build(self, input_shape):
    """ GCN has two inputs : [shape(An), shape(X)]
    """
    # gsize = input_shape[0][0]  # graph size
    fdim = input_shape[1][1]  # feature dim
    
    # hasattr 检查该对象self是否有某个属性'weight'
    if not hasattr(self, 'weight'):
        self.weight = self.add_weight(name="weight",
                                      shape=(fdim, self.units),
                                      initializer=self.kernel_initializer,
                                      constraint=self.kernel_constraint,
                                      trainable=True)
    if self.use_bias:
        if not hasattr(self, 'bias'):
            self.bias = self.add_weight(name="bias",
                                        shape=(self.units, ),
                                        initializer=self.bias_initializer,
                                        constraint=self.bias_constraint,
                                        trainable=True)
    super(GCNConv, self).build(input_shape)

 
def call(self, inputs):
    """ GCN has two inputs : [An, X]
    	对称归一化版本的GCN的核心公式计算过程
    """
    self.An = inputs[0]
    self.X = inputs[1]
    # isinstance 函数来判断一个对象是否是一个已知的类型
    if isinstance(self.X, tf.SparseTensor):
        h = spdot(self.X, self.weight)
    else:
        # 二维数组矩阵之间的dot函数运算得到的乘积是矩阵乘积
        h = dot(self.X, self.weight)
    output = spdot(self.An, h)

    if self.use_bias:
        output = tf.nn.bias_add(output, self.bias)

    if self.activation:
        output = self.activation(output)

    return output

完整代码

参考文章:

GCN(Graph Convolutional Network)的理解

如何理解 Graph Convolutional Network(GCN)?

从源头探讨 GCN 的行文思路

2020年,我终于决定入门GCN

GCN总结

图卷积神经网络(GCN)入门

  • 6
    点赞
  • 50
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
要在conda中配置Tensorflow 2.0,可以按照以下步骤进行: 1. 首先,确保已经安装了conda和相应的Python版本。如果没有安装,可以从Anaconda官网下载和安装。 2. 打开Anaconda Prompt或者终端,并创建一个新的conda环境,可以使用命令:conda create -n tf2.0 python=3.7 3. 激活新创建的环境,可以使用命令:conda activate tf2.0 4. 使用conda安装Tensorflow 2.0,可以使用命令:conda install tensorflow-gpu=2.0.0 5. 等待安装完成后,就成功配置了conda中的Tensorflow 2.0环境。 另外,如果你想使用pip进行安装,也可以按照以下步骤进行: 1. 激活你的conda环境,可以使用命令:conda activate tf2.0 2. 使用pip安装Tensorflow 2.0,可以使用命令:pip install tensorflow==2.0.0 -i https://pypi.tuna.tsinghua.edu.cn/simple 这样你就成功配置了conda中的Tensorflow 2.0环境。希望对你有帮助!<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [深度学习(基于Tensorflow2.0)学习笔记——Day2](https://download.csdn.net/download/weixin_38747211/14884742)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 33.333333333333336%"] - *2* [Conda安装Tensorflow2.0](https://blog.csdn.net/u010442263/article/details/125567460)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 33.333333333333336%"] - *3* [Anaconda安装+Tensorflow2.0安装配置+Pycharm安装+GCN调试(Window 10)](https://blog.csdn.net/adreammaker/article/details/125506038)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 33.333333333333336%"] [ .reference_list ]
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值