GCN:基于切比雪夫多项式(chebyshev ploynomials)为核的图卷积推导与pytorch实现

GCN图卷积神经网络

顾名思义,图卷积神经网络,是对图信息进行卷积,从而获取相邻节点的信息和特征,本文将介绍和推导目前较为流行的以chebyshev ploynomials 契比雪夫多项式为核的图卷积公式,同时通过pytorch代码实现。
在这里插入图片描述

图卷积的定义

通过表示图信息的矩阵及上一层特征输入,输出该层对图信息的特征,表示如下:
H l = f ( H l − 1 , A ) H_l = f(H_{l-1},A) Hl=f(Hl1,A)
A代表邻接矩阵,或关于图表示的矩阵。
常用数学传播表示方式如下:
H l = σ ( D ~ − 1 2 A ~ D ~ − 1 2 H l − 1 W l − 1 ) H_l=\sigma(\widetilde{D}^{-\frac{1}{2}}\widetilde{A}\widetilde{D}^{-\frac{1}{2}}H_{l-1}W_{l-1}) Hl=σ(D 21A D 21Hl1Wl1)

其中 D ~ \widetilde{D} D 代表 A ~ \widetilde{A} A 的度矩阵

A ~ \widetilde{A} A 代表邻接矩阵 A A A与单位矩阵 I I I的和: A ~ = A + I \widetilde{A}=A+I A =A+I

H H H代表卷积后的特征,初始输入 H = X H=X H=X

σ \sigma σ为激活函数

推导

  1. 图的表示方式:

    1)邻接矩阵 A A A,表示节点与节点之间是否存在连接,若存在则为1,不存在为0,对角线均为0

    2)度矩阵 D D D ,只有对角线有值,表示该节点所连接边的个数

    ​3) Laplacian 拉普拉斯矩阵: L = D − A L=D-A L=DA 1)对称 2)非负特征值 3)正交

    ​ 归一化Laplacian: L s y m = D − 1 2 L D − 1 2 = I − D − 1 2 A D − 1 2 L^{sym}=D^{-\frac{1}{2}}LD^{-\frac{1}{2}}=I-D^{-\frac{1}{2}}AD^{-\frac{1}{2}} Lsym=D21LD21=ID21AD21

  2. 卷积公式:其中 F ( X ) F(X) F(X)表示傅里叶变换

    f ∗ g = F − 1 ( F ( f ) ∗ F ( g ) ) f*g=F^{-1}(F(f)*F(g)) fg=F1(F(f)F(g))

  3. 根据拉普拉斯矩阵正交特性,存在 U , U T U,U^T U,UT使得 L = U Λ U T L=U\Lambda U^T L=UΛUT 其中 Λ \Lambda Λ表示特征向量

    则Graph Fourier可对应表示如下:

    G F ( x ) = U T x GF(x)=U^Tx GF(x)=UTx

    根据卷积公式,对应图卷积公式如下:

    g ∗ x = U ( U T g U T x ) g*x=U(U^TgU^Tx) gx=U(UTgUTx)

    每一次卷积操作作用域都希望在中心节点附近的区域,则我们可以将 g g g看作关于拉普拉斯矩阵 L L L的函数 g ( L ) g(L) g(L),那么,每卷积一次则相当于传递一次相邻节点信息

    而由 L L L特征值特性: U T L = Λ U T U^TL=\Lambda U^T UTL=ΛUT 可知, U T g ( L ) U^Tg(L) UTg(L) 可看作是关于拉普拉斯矩阵 L L L的特征函数 g θ ( Λ ) g_\theta(\Lambda) gθ(Λ)

    则图卷积表达式可写作:

    g ∗ x = U ( U T g U T x ) = U g θ U T x g*x=U(U^TgU^Tx)=Ug_\theta U^Tx gx=U(UTgUTx)=UgθUTx

  4. 运算简化

    由于计算 g θ g_\theta gθ需要计算拉普拉斯矩阵特征值,计算复杂,因而提出利用切比雪夫Chebyshev polynomials多项式来进行近似计算,这里并不影响特征值的计算属性,只是通过切比雪夫多项式作为核能够将特征值矩阵计算化简为L,从而跳过特征值计算的步骤,表示如下。

    g θ = ∑ k = 0 K θ k T k ( Λ ~ ) g_\theta=\sum_{k=0}^{K}\theta_k T_k(\widetilde{\Lambda}) gθ=k=0KθkTk(Λ )

    其中 Λ ~ = 2 ∗ Λ Λ m a x − 1 \widetilde{\Lambda}=2*\frac{\Lambda}{\Lambda_{max}}-1 Λ =2ΛmaxΛ1,只是因为Chebyshev polynomials要求 x x x处于 [ − 1 , 1 ] [-1,1] [1,1]

    T k ( x ) = 2 x T k − 1 ( x ) − T k − 2 ( x ) T_k(x)=2xT_{k-1}(x)-T_{k-2}(x) Tk(x)=2xTk1(x)Tk2(x), T 0 = 0 T_0=0 T0=0, T 1 = 1 T_1=1 T1=1

    那么将上式代入卷积表达式可以得到:

    g ∗ x = U ∑ k = 0 K θ k T k ( Λ ~ ) U T x = ∑ k = 0 K θ K T k ( L ~ ) x g*x=U\sum_{k=0}^{K}\theta_k T_k(\widetilde{\Lambda})U^Tx\\=\sum_{k=0}^K\theta_K T_k(\widetilde{L})x gx=Uk=0KθkTk(Λ )UTx=k=0KθKTk(L )x

pytorch代码实现

包需求:

import numpy as np
import torch
import torch.nn as nn

1.Laplacian 以及scaled_Laplacian:

'''D matrix 根据邻接矩阵获取度矩阵'''
def get_d_matrix(adj_matrix):
    d_matrix = np.zeros((adj_matrix.shape[0], adj_matrix.shape[1]))
    for i in range(adj_matrix.shape[0]):
        d_matrix[i, i] = np.sum(adj_matrix[i, :])
    return d_matrix

'''Laplace matrix'''
def get_laplace_matrix(adj, d):
    d_turn = np.zeros((adj.shape[0], adj.shape[0]))
    for i in range(adj.shape[0]):
        d_turn[i, i] = np.power(d[i, i], -0.5)
    res = np.eye(adj.shape[0]) - d_turn @ adj @ d_turn
    return res


'''
get the  rou of matrix 获取矩阵谱半径,即最大绝对值特征值
'''
def getRou(x):
    lambdas, features = np.linalg.eig(x)
    return np.max(np.abs(lambdas))

'''
get scaled laplacian for chebyshev ploynomials
'''
def scaled_laplacian(L):
    res = (2*L)/getRou(L)-np.identity(L.shape[0])
    return res
  1. 契比雪夫多项式的实现
'''
get chebyshev ploynomials 
'''
def chebyshev_ploynomials(scaled_laplacian, K):
    '''
    :param scaled_laplacian: [-1,1]的拉普拉斯矩阵
    :param K: 多项式项数
    :return: list
    '''
    res = [np.identity(scaled_laplacian.shape[0]), scaled_laplacian]
    if K>=2:
        for i in range(2, K+1):
            res.append(2*scaled_laplacian*res[i-1]-res[i-2])
    return res
  1. pytorch 实现图卷积
'''
take chebyshev ploynomials as kernal for graph conv
'''
class Cheb_conv(nn.Module):
    def __init__(self, chebyshev_ploynomials, K, in_channel, out_channel):
        super(Cheb_conv, self).__init__()
        self.K = K
        self.chebyshev_ploynomials = chebyshev_ploynomials
        self.device = chebyshev_ploynomials[0].device
        self.thetaList = nn.ParameterList([nn.Parameter(torch.FloatTensor(in_channel, out_channel).to(self.device)) for _ in range(K)])
        self.relu = nn.ReLU()

    def forward(self, x):
        '''

        :param x: (batch, nodes_num, features(in_channel), seq_len)
        :return:
        '''
        batch_size, nodes_num, in_channel, seq_len = x.shape
        #(batch, seq_len, nodes_num, in_channel)
        x = x.permute(0,3,1,2)
        output = torch.zeros(batch_size, nodes_num, self.out_channels, seq_len).to(self.DEVICE)
        for i in range(self.K):
            cheb = self.chebyshev_ploynomials[i]
            #(batch, seq_len, nodes_num, in_channel)
            cash = cheb.matmul(x)
            # (batch, seq_len, nodes_num, out_channel)
            cash = self.cash.matmul(self.thetaList[i])
            #(batch, nodes_num, out_channel, seq_len)
            cash = cash.permute(0,2,3,1)
            output += cash

        return self.relu(output)
  • 10
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
GCN(Graph Convolutional Network)是一种用于数据的卷积神经网络。在PyTorch中,你可以使用DGL(Deep Graph Library)来实现GCN。 首先,确保已经安装了DGL库。你可以使用以下命令来安装: ``` pip install dgl ``` 下面是一个简单的示例代码,展示了如何使用DGL来实现GCN: ```python import dgl import torch import torch.nn as nn import torch.nn.functional as F from dgl.nn.pytorch import GraphConv class GCN(nn.Module): def __init__(self, in_features, hidden_features, out_features): super(GCN, self).__init__() self.conv1 = GraphConv(in_features, hidden_features) self.conv2 = GraphConv(hidden_features, out_features) def forward(self, g, features): x = F.relu(self.conv1(g, features)) x = self.conv2(g, x) return x # 使用示例 num_nodes = 5 # 中节点的数量 in_features = 10 # 输入特征的维度 hidden_features = 16 # 隐藏层特征的维度 out_features = 2 # 输出特征的维度 # 创建一个 g = dgl.graph(([0, 1, 1, 2, 3], [1, 2, 3, 0, 4])) # 定义边的连接方式 g = dgl.add_self_loop(g) # 添加自环 # 创建输入特征张量 features = torch.randn(num_nodes, in_features) # 创建GCN模型 model = GCN(in_features, hidden_features, out_features) # 前向传播 output = model(g, features) print(output) ``` 在这个示例中,我们首先使用DGL创建一个`g`,然后创建一个输入特征张量`features`。接下来,我们定义并创建了一个简单的GCN模型`GCN`,其中使用了`GraphConv`层来实现卷积操作。最后,我们通过调用模型的`forward`方法来进行前向传播,得到输出结果。 需要注意的是,这只是一个简单的示例,GCN的具体结构和参数设置可以根据具体任务进行调整和改进。另外,DGL还提供了更多的神经网络模型和操作,你可以根据需要进行进一步的学习和探索。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

xx_Mike

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值