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 小米 华为 单反 装机 图拉丁
 
   -> 人工智能 -> 图卷积网络原理及其基于paddlepaddle的实现 -> 正文阅读

[人工智能]图卷积网络原理及其基于paddlepaddle的实现

图卷积网络

这里的图是指Graph,一种数据结构。
图卷积网络关键问题在于如何定义在图上的卷积操作。目前有两种方法:

  • 谱方法
  • 空间方法

已经证明,谱方法是空间方法的一种特例。本文将简要介绍目前关于图卷积操作的基本方法,以其基于paddlepaddle平台实现了其中一种称为GCN的图卷积网络。由于图像可以视为一种特殊的Graph。因此图卷积网络也可以处理图像的数据。将实现后的网络用于MNIST数据集做图的分类,实验结果表明,图卷积网络具有很强的表达能力。

谱方法

对于一个图 G = ( V , E , W ) G=(V,E,W) G=(V,E,W),如果结点个数 n = ∣ V ∣ n=|V| n=V,那么邻接矩阵 W ∈ R n × n W\in \mathbb R^{n\times n} WRn×n。令 X ∈ R n × d X\in \mathbb R^{n \times d} XRn×d,其中每一列代表图上的一个信号,共d个信号。

假设 L L L W W W的规一化后的拉普拉斯矩阵,且其正交特征向量矩阵为 U U U。则图上信号 x x x的傅立叶变换和逆变换定义如下:
傅 立 叶 变 换 : x ^ = U ? x 傅 立 叶 逆 变 换 : x = U x ^ 傅立叶变换: \hat x = U^{\top}x \\ 傅立叶逆变换:x =U\hat x x^=U?xx=Ux^
根据卷积定理可以定义卷积操作如下。其中 U ? y = ( θ 1 , θ 2 , . . . , θ n ) ? , θ g = d i a g ( θ 1 , θ 2 , . . . , θ n ) U^\top y = (\theta_1, \theta_2,...,\theta_n)^\top, \theta_g=diag(\theta_1,\theta_2,...,\theta_n) U?y=(θ1?,θ2?,...,θn?)?,θg?=diag(θ1?,θ2?,...,θn?)
x ? G y = U ( U ? x ? ⊙ ? U ? y ) = U θ g U ? x \begin{aligned} x *_G y &= U(U^\top x \ \odot \ U^\top y) \\ &= U\theta_gU^\top x \end{aligned} x?G?y?=U(U?x??U?y)=Uθg?U?x?
那么GCN可表示如下。
x t , j = h ( ∑ i = 1 d U θ g U ? x t ? 1 , i ) x_{t,j}=h(\sum_{i=1}^{d} U\theta_gU^\top x_{t-1,i} ) xt,j?=h(i=1d?Uθg?U?xt?1,i?)
其中 x t , j x_{t,j} xt,j?表示第 t t t层第 j j j个信号。 d d d表示第 t ? 1 t-1 t?1层的信号个数。 h h h是一个非线性函数。上面公式的含义是:后一层中的某一个信号等于前一层所有d个信号卷积后相加,再过一个非线性变换。

以上的每一次卷积复杂度都是 O ( n 2 ) O(n^2) O(n2)。下面使用 g β g_{\beta} gβ? g θ g_{\theta} gθ?做近似,令 g β = ∑ i = 1 K β k Λ k g_\beta=\sum_{i=1}^{K}\beta_k\Lambda ^k gβ?=i=1K?βk?Λk。其中 Λ k \Lambda^k Λk是对角矩阵, 根据Chebyshev 多项计算。 Λ k = 2 Λ ? Λ k ? 1 + Λ k ? 2 \Lambda^k =2\Lambda \cdot \Lambda^{k-1} + \Lambda^{k-2} Λk=2Λ?Λk?1+Λk?2 Λ 0 = 0 , Λ 1 = Λ \Lambda^0 = 0,\Lambda^1 = \Lambda Λ0=0,Λ1=Λ Λ \Lambda Λ 表示矩阵L的特征值矩阵。根据稀疏矩阵乘法则复杂度可降为O(|E|)
x ? y = U θ β U ? x = ∑ i = 1 K β k L k x x*y= U\theta_\beta U^\top x = \sum_{i=1}^{K}\beta_kL^kx x?y=Uθβ?U?x=i=1K?βk?Lkx

空间方法

空间方法的基本思想是:

Aggregate the information of neighboring nodes to update the representation of center node。
即通过聚合邻居结点的信息来更新中心结点的表示

分为两个步骤:

  • 从邻居采样
  • 把采样结果做一个聚合(加权平均,最大值,…)

GCN

即 Graph Convolution Network。对于两层的图卷积网络定义如下。
Z = f ( X , A ) = s o f t m a x ( A ^ ? R E L U ( A ^ X W ( 0 ) ) W ( 1 ) ) Z=f(X,A) = softmax(\hat A \ \mathbf{RELU}(\hat AXW^{(0)})W^{(1)}) Z=f(X,A)=softmax(A^?RELU(A^XW(0))W(1))
其中 A ^ = D ~ ? 1 2 A ~ D ~ ? 1 2 \hat A=\tilde D^{-\frac{1}{2}} \tilde A \tilde D^{-\frac{1}{2}} A^=D~?21?A~D~?21?表示从邻居采样然后聚合。 A ~ = I N ? A , D ~ i i = ∑ j A ~ i j \tilde A=I_N-A, \tilde D_{ii} = \sum_j \tilde A_{ij} A~=IN??A,D~ii?=j?A~ij? A ∈ R n × n A \in \mathbb R^{n \times n} ARn×n表示图的邻接矩阵, I N I_N IN?是单位矩阵。 X ∈ R n × d X \in \mathbb R^{n \times d} XRn×d是图上的信号。 W ( 0 ) ∈ R d × c 0 , W ( 1 ) ∈ R c 0 × c 1 W^{(0)} \in \mathbb R^{d \times c_0}, W^{(1)} \in \mathbb R^{c_0 \times c_1} W(0)Rd×c0?,W(1)Rc0?×c1?都是卷积的参数。 c 0 , c 1 c_0,c_1 c0?,c1?表示卷积之后的信号个数。

请添加图片描述
图在做完卷积操作后,图的结构并没有改变。即结点个数不变,连接权重也不改变。唯一改变的是图上的信号和信号的个数。如上图所示,输入层3个信号经过两层卷积后变成了5个信号。

GAT

即Graph Attention Network。该方法使用Attention来聚合邻居信号。
α i j = exp ? ( L e a k y R e l u ( a ? ? [ W h i ? ∣ ∣ W h j ? ] ) ) ∑ k ∈ N i exp ? ( L e a k y R e l u ( a ? ? [ W h i ? ∣ ∣ W h k ? ] ) ) \alpha_{ij}=\frac{\exp(LeakyRelu(\vec{a}^\top[W\vec{h_i} ||W\vec{h_j}]))}{ \sum_{k\in N_i} \exp(LeakyRelu(\vec{a}^\top[W\vec{h_i} ||W\vec{h_k}]))} αij?=kNi??exp(LeakyRelu(a ?[Whi? ?Whk? ?]))exp(LeakyRelu(a ?[Whi? ?Whj? ?]))?
其中 N i N_i Ni?表示结点 i i i的所有邻居。 h i ? \vec{h_i} hi? ?表示结点 i i i的信号向量。|| 表示拼接操作。 a ? \vec a a 是注意力机制的参数, W W W是特征提取的参数。

请添加图片描述

MoNet

根据MoNet(论文中描述了一种一般化的空间方法)描述。卷积过程可形式化表述如下:
D j ( x ) f = ∑ y ∈ N ( x ) w j ( u ( x , y ) ) f ( y ) , j = 1 , . . . , J D_j(x)f=\sum_{y \in N(x)} w_j(\mathbf u(x,y))f(y), j=1,...,J Dj?(x)f=yN(x)?wj?(u(x,y))f(y),j=1,...,J

( f ? g ) ( x ) = ∑ j = 1 J g j D j ( x ) f (f * g)(x) = \sum_{j=1}^{J}g_jD_j(x) f (f?g)(x)=j=1J?gj?Dj?(x)f

其中 x x x y y y都表示图中的结点。

f ( y ) f(y) f(y)则表示结点 y y y上的信号值。

u ( x , y ) u(x,y) u(x,y)表示结点 x x x和结点 y y y的一个 d d d维向量

w j ( ? ) w_j(\cdot) wj?(?) 表示一个把 d d d维向量转换成权重的函数。

N ( x ) N(x) N(x) 表示结点 x x x的邻居结点。

D j ( x ) f D_j(x)f Dj?(x)f 表示结点 x x x从邻居那里聚合一次得到的值。

( f ? g ) ( x ) (f * g)(x) (f?g)(x) 表示结点 x x x从邻居那里聚合得到的 J J J个值,作加权平均。也就相当于卷积操作。 g i g_i gi?表示卷积核。

图池化

对图是否需要池化,仍有较大争议。现有如下方法:

  • 图粗糙:把几个结点集合成大结点。
  • 结点选择:自动学习一个量化结点重要性的函数。根据重要性选择结点。

表达能力

图卷积网络的基本任务有两个:

  • 结点分类:每个结点都有一个标签
  • 图分类:整个图有一个标签

单层GCN不能很好的区分结点。提高层数GCN能提高表达能力,但是表达能力有上限。GNN本质是一个 G → R d G\rightarrow R^d GRd的映射。其表达能力意味着能够区分图的能力. GIN(Graph isomorphism network)是一种比表达能力更加的强的图神经网络,它克服了GCN表达能力上限的问题。

代码实现

这部分实现了GCN。因为比较简单,而且效果好。
首先利用paddle的提供的功能,自定义一个卷积层。代码如下。

import paddle
import paddle.fluid as fluid
from paddle.autograd import PyLayer
import numpy as np


# GCN单层结构
class GCNLayer(fluid.dygraph.Layer):

    def __init__(self, A_hat, num_signals = 1, num_filters = 1):
        """
        A_hat - 由图的邻接矩阵计算而来的一个矩阵。维度为 (N, N)。N表示图中结点个数
        num_signals - 输入的信号个数
        num_filters - 卷积核个数,即输出信号个数
        """
        super(GCNLayer, self).__init__()
        self.A_hat = A_hat
        self.named_buffers = num_filters
        self.W = self.create_parameter(shape=[num_signals, num_filters], dtype='float64')

    def forward(self, X):
        """
        前向传播计算
        X - 图上的信号。维度为(N, C)
        输出 Y = relu(AXW) 
        """
        #print("X.shape", X.shape)
        x = fluid.layers.matmul(self.A_hat.astype("float64"),X.astype("float64"))
        x = fluid.layers.matmul(x, self.W)
        x = fluid.layers.soft_relu(x)
        return x

实验结果

本次实验使用GCN对MINST数据集进行网络模型优化和评估。该数据集训练集中包含了6万多张手写数字图片,以及对应的标签(即数字0~9)。 我们使用上面定义的图卷积层(GCNLayer)结合全连接层(Linear)简单地组建了一个图像分类网络。结构如下。

# Layer类继承方式组网
class GCN(fluid.dygraph.Layer):

    def __init__(self,  A, num_signals):
        """
        A - 图的邻接矩阵。维度为(N, N)。N表示图结点的个数
        num_signals - 图上信号的个数
        """
        super(GCN, self).__init__()
        N = A.shape[1]
        I = np.eye(N, dtype="float64")
        A_tilde = A + I
        D_tilde = np.sum(A_tilde, axis=0)
        D_inv = D_tilde**-0.5
        D_inv = np.diag(D_inv)
        A_hat = D_inv.dot(A_tilde).dot(D_inv)
        A_hat = paddle.to_tensor(A_hat)

        self.layer_1 = GCNLayer(A_hat, num_signals=num_signals, num_filters=16)
        self.layer_2 = GCNLayer(A_hat, num_signals=16, num_filters=8)
        self.layer_3 = GCNLayer(A_hat, num_signals=8, num_filters=4)
        self.layer_4 = GCNLayer(A_hat, num_signals=4, num_filters=2)
        self.layer_5 = GCNLayer(A_hat, num_signals=2, num_filters=1)
        self.sofxmax = fluid.layers.softmax
        self.flatten = paddle.nn.Flatten(start_axis=0, stop_axis=1)
        self.linear = paddle.nn.Linear(N * 1, 10)

    def forward(self, x):
        """
        前向传播计算
        X - 图上的信号。维度为(N, C)
        输出 Y = GCN(X) 
        """
        x = self.layer_1(x)
        x = self.layer_2(x)
        x = self.layer_3(x)
        x = self.layer_4(x)
        x = self.layer_5(x)
        x = self.flatten(x.astype("float32"))
        x = self.linear(x)
        x = self.sofxmax(x, axis=0)
        return x

然后导入数据,开始训练的参数自动优化。

# 加载数据集
from paddle.vision.transforms import ToTensor
train_dataset = paddle.vision.datasets.MNIST(mode='train', transform=ToTensor())
test_dataset = paddle.vision.datasets.MNIST(mode='test', transform=ToTensor())
train_dataset = list( map(lambda x: (paddle.reshape(x[0], [-1, 1]), x[1]), train_dataset) )
test_dataset = list( map(lambda x: (paddle.reshape(x[0], [-1, 1]), x[1]), test_dataset) )
#模型优化和评估
width = 28
height = 28
n_nodes = width * height
A = np.zeros((n_nodes, n_nodes), dtype="float64")
"""
因为图像也是一种特殊的Graph,因此在这里构造它的邻接矩阵。每个像素都是一个结点,并且它的邻居结点即上下左右相邻的四个像素。
"""
for i in range(width):
    for j in range(height):
        if(i - 1 >= 0):
            A[i * width + j, (i - 1) * width + j] = A[(i - 1) * width + j, i * width + j] = 1;
        if(i + 1 < width):
            A[i * width + j, (i + 1) * width + j] = A[(i + 1) * width + j, i * width + j] = 1;
        if(j - 1 >= 0):
            A[i * width + j, i * width + (j - 1)] = A[i * width + (j - 1), i * width + j] = 1;
        if(j + 1 < height):
            A[i * width + j, i * width + (j + 1)] = A[i * width + (j + 1), i * width + j] = 1;

print(A)
net = GCN(A, 1)
print(paddle.summary(net, input_size=(n_nodes , 1)))
model = paddle.Model(net) 
optim = paddle.optimizer.SGD(learning_rate=0.1, parameters=model.parameters())
model.prepare(optim, paddle.nn.CrossEntropyLoss(), paddle.metric.Accuracy())
model.fit(train_dataset)
model.evaluate(test_dataset)

实例化模型后,参数数量只有8000多个。

在这里插入图片描述

但是经过一轮学习后,准确率却高达78%。如果进行更多轮学习,或者增加网络参数,模型能力会更强!
在这里插入图片描述

总结

本文简要描述了图神经网络的基本原理,并基于现在深度学习框架paddlepaddle实现了GCN网络。通过对MINST的实验验证了图神经网络的能力。未来,希望能够在Java平台上实现一个深度学习框架,感兴趣欢迎与我联系。邮箱 cloudea@163.com。

  人工智能 最新文章
2022吴恩达机器学习课程——第二课(神经网
第十五章 规则学习
FixMatch: Simplifying Semi-Supervised Le
数据挖掘Java——Kmeans算法的实现
大脑皮层的分割方法
【翻译】GPT-3是如何工作的
论文笔记:TEACHTEXT: CrossModal Generaliz
python从零学(六)
详解Python 3.x 导入(import)
【答读者问27】backtrader不支持最新版本的
上一篇文章      下一篇文章      查看所有文章
加:2021-10-24 14:56:26  更:2021-10-24 14:57:23 
 
开发: 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年11日历 -2024/11/27 8:35:53-

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