理解图卷积网络的节点分类

在过去的十年中,神经网络取得了巨大的成功。但是,只能使用常规或欧几里得数据来实现神经网络的早期变体,而现实世界中的许多数据都具有非欧几里得的底层图形结构。数据结构的不规则性导致了图神经网络的最新发展。在过去的几年中,正在开发图神经网络的各种变体,其中之一就是图卷积网络(GCN)。GCN也被视为基本的图神经网络变体之一。

在本文中,我们将更深入地研究由Thomas Kipf和Max Welling开发的图卷积网络。我还将在使用NetworkX构建第一个图形时给出一些非常基本的示例。到本文结尾,我希望我们对图卷积网络内部的机制有更深入的了解。

图神经网络中的卷积

如果您熟悉卷积神经网络中的卷积层,则GCN中的“卷积”基本上是相同的操作。它是指将输入神经元乘以一组权重(通常称为过滤器或*内核)。*滤波器充当整个图像的滑动窗口,并使CNN能够从相邻单元中学习特征。在同一层中, 将在整个图像中使用相同的滤波器,这称为权重共享。例如,使用CNN对猫和非猫的图像进行分类,将在同一层中使用相同的过滤器来检测猫的鼻子和耳朵。

GCN执行类似的操作,其中模型通过检查相邻节点来学习特征。CNN和GNN之间的主要区别在于,CNN是专门为在常规(欧几里得)结构化数据上运行而构建的,而GNN是CNN的广义版本,其中节点连接的数量变化且节点无序(在非欧几里德结构上是不规则的)数据。

GCN本身可分为2种主要算法:空间图卷积网络频谱图卷积网络。在本文中,我们将重点介绍基于快速频谱的图卷积网络。

在深入探讨GCN内部发生的计算之前,让我们先简要回顾一下神经网络中的前向传播概念。如果您熟悉它,可以跳过以下部分。

神经网络正向传播简要回顾

在神经网络中,为了将要素表示传播到下一层(前进),我们执行以下方程式:

这基本上等效于线性回归中的y = mx + b,其中:

m等于权重

x输入要素

b偏差

上面的正向传递方程与线性回归的区别在于,神经网络应用非线性激活函数来表示潜在维度中的非线性特征。

回顾上面的方程式,对于第一个隐藏层(i = 0),我们可以简单地将方程式重写如下:

其中第0层的要素表示基本上是输入要素(X)

这个方程在图卷积网络中有何不同?

快速近似光谱图卷积网络

频谱GCN背后的原始想法是受信号/波传播的启发。我们可以将频谱GCN中的信息传播视为沿节点的信号传播。频谱GCN利用图拉普拉斯矩阵的特征分解来实现这种信息传播方法。简单来说,特征分解可以帮助我们理解图的结构,从而对图的节点进行分类。这有点类似于主成分分析(PCA)和线性判别分析(LDA)的基本概念,在这些概念中,我们使用特征分解来减少维数并执行聚类。如果您从未听说过特征分解和拉普拉斯矩阵,*请不用担心!*在这种快速逼近方法中,我们将不会明确使用它们。

在这种方法中,除了节点特征(或所谓的输入特征)外,我们还将考虑前向传播方程中的邻接矩阵(A)。A是代表前向传播方程中节点之间的边缘或连接的矩阵。在正向传递方程中插入A可使 模型基于节点的连通性学习特征表示。为简化起见,偏置b被 删去。所得的GCN可以看作是消息传递网络形式的频谱图卷积的一阶近似,其中信息沿着图内的相邻节点传播。

通过添加邻接矩阵作为附加元素,前向通过方程将变为:

什么是A *

A *是的规范化版本一个。为了更好地理解为什么我们需要对A进行规范化以及在GCN中进行正向传播期间会发生什么,让我们做一个实验。

建立图卷积网络

初始化图G

让我们开始使用NetworkX构建一个简单的无向图(G)。图形G将由6个节点组成,每个节点的特征将对应于该特定节点号。例如,节点1的节点特征为1,节点2的节点特征为2,依此类推。为简化起见,在本实验中我们将不分配边缘特征。

# -*- coding: utf-8 -*-
"""
Created on Sun Aug 30 07:55:57 2020@author: xiaohuihui
"""
import networkx as nx
import numpy as np
import matplotlib.pylab as plt
from scipy.linalg import fractional_matrix_powerimport warnings
warnings.filterwarnings('ignore',category=UserWarning)# 初始化图
G = nx.Graph(name="G") # 创建节点
for i in range(6):G.add_node(i,name=i)# 创建边并添加边到图里
edges = [(0,1),(0,2),(0,3),(1,2),(3,4),(3,5),(4,5)]
G.add_edges_from(edges)print("Graph Info:\n",nx.info(G))print("\nGraph Nodes:",G.nodes.data())nx.draw(G,with_labels=True,font_weight='bold')
plt.show()

结果:

Graph Info:Name: G
Type: Graph
Number of nodes: 6
Number of edges: 7
Average degree:   2.3333Graph Nodes: [(0, {'name': 0}), (1, {'name': 1}), (2, {'name': 2}), (3, {'name': 3}), (4, {'name': 4}), (5, {'name': 5})]

由于我们只有1个图,因此此数据配置是单模式 表示的示例。我们将构建一个GCN,它将学习节点特征表示。

将邻接矩阵(A)加入正向传播方程

下一步是从图G获得邻接矩阵(A)和节点特征矩阵(X)。

# 从图G获得邻接矩阵(A)和节点特征矩阵(X)
A = np.array(nx.attr_matrix(G,node_attr='name')[0])
X = np.array(nx.attr_matrix(G,node_attr='name')[1])
# 增加维度
X = np.expand_dims(X,axis=1)print('shape of A:',A.shape)
print('\nshape of X:\n',X.shape)
print('\nAdjacency Matrix(A):\n',A)
print('\nNode Features Matrix(X):\n',X)

结果:

shape of A: (6, 6)shape of X:(6, 1)Adjacency Matrix(A):[[0. 1. 1. 1. 0. 0.][1. 0. 1. 0. 0. 0.][1. 1. 0. 0. 0. 0.][1. 0. 0. 0. 1. 1.][0. 0. 0. 1. 0. 1.][0. 0. 0. 1. 1. 0.]]Node Features Matrix(X):[[0][1][2][3][4][5]]

现在,让我们研究如何通过将A加入前向传递方程式来增加模型的更丰富的特征表示。我们将执行AX的点积。在本文中,我们将此点积运算的结果称为AX

AX = np.dot(A,X)
print('Dot product of A and X (AX):\n',AX)

从结果可以明显看出,AX 代表相邻节点特征总和。例如,AX的第一行对应于连接到节点0(即节点1、2和3)的节点特征之和。这使我们知道了GCN中的传播机制是如何发生的,以及节点的连通性如何影响节点网络。 GCN看到的隐藏特征表示。

邻接矩阵和节点特征矩阵的点积表示相邻节点特征的总和。

但是,如果我们考虑得更多,我们将意识到,尽管AX总结了 相邻节点的特征,但它并未考虑节点本身的特征

加入自环并归一化A

为了解决这个问题,我们现在添加自环到的每个节点A.添加自环,基本上是一个节点连接到其自身的机制。就是说,邻接矩阵A的所有对角元素现在将变为1,因为每个节点都与其自身相连。让我们调用添加了自环的A作为A_hat并重新计算AX,它现在是A_hatX的点积:

# 添加自环
G_self_loops = G.copy()self_loops = []
for i in range(G.number_of_nodes()):self_loops.append((i,i))G_self_loops.add_edges_from(self_loops)# 添加自环后检查图
print('Edges of G with self-loops:\n',G_self_loops.edges)# 获取添加自环后的邻接矩阵
A_hat = np.array(nx.attr_matrix(G_self_loops,node_attr='name')[0])
print('Adjacency Matrix of added self-loops G(A-hat)',A_hat)# 计算AX
AX = np.dot(A_hat,X)
print("AX:\n",AX)

结果:

Edges of G with self-loops:[(0, 1), (0, 2), (0, 3), (0, 0), (1, 2), (1, 1), (2, 2), (3, 4), (3, 5), (3, 3), (4, 5), (4, 4), (5, 5)]
Adjacency Matrix of added self-loops G(A-hat) [[1. 1. 1. 1. 0. 0.][1. 1. 1. 0. 0. 0.][1. 1. 1. 0. 0. 0.][1. 0. 0. 1. 1. 1.][0. 0. 0. 1. 1. 1.][0. 0. 0. 1. 1. 1.]]
AX:[[ 6.][ 3.][ 3.][12.][12.][12.]]

现在,您可能会认识到另一个问题。元素AX进行预处理。类似于任何神经网络操作的数据预处理一样,我们需要对特征进行归一化以防止数值不稳定和消失/爆炸梯度,以使模型收敛。在GCN中,我们通过计算度矩阵(D)并使用AX 对D 的进行点积运算来对数据进行归一化:

在本文中我们将其称为DAX。在图形术语中,术语“度”是指节点连接到的边数。

# 度
Deg_Mat = G_self_loops.degree()
print('Degree Matrix of added self-loops G(D):',Deg_Mat)D = np.diag([deg for (n,deg) in list(Deg_Mat)])
print('Degree matrix of a as numpy-loops G as numpy array(D):\n',D)D_inv = np.linalg.inv(D)
print('Inverse of D:\n',D_inv)DAX = np.dot(D_inv,AX)
print('DAX:\n',DAX)

结果:

Degree Matrix of added self-loops G(D): [(0, 5), (1, 4), (2, 4), (3, 5), (4, 4), (5, 4)]
Degree matrix of a as numpy-loops G as numpy array(D):[[5 0 0 0 0 0][0 4 0 0 0 0][0 0 4 0 0 0][0 0 0 5 0 0][0 0 0 0 4 0][0 0 0 0 0 4]]
Inverse of D:[[ 0.2   0.    0.    0.    0.    0.  ][ 0.    0.25  0.    0.    0.    0.  ][ 0.    0.    0.25  0.    0.    0.  ][-0.   -0.   -0.    0.2  -0.   -0.  ][ 0.    0.    0.    0.    0.25  0.  ][ 0.    0.    0.    0.    0.    0.25]]
DAX:[[1.2 ][0.75][0.75][2.4 ][3.  ][3.  ]]

如果将DAXAX进行比较,则会注意到:

我们可以看到归一化对DAX的影响,与节点4和5相比,节点3对应的元素的值较低。但是,如果归一化后,节点3与节点4和5的初始值应该相同,为什么节点3具有不同的值?

让我们回顾一下我们的图表。节点3具有3个入射边缘,而节点4和5仅具有2个入射边缘节点3具有比节点4和5 高的程度的事实导致DAX中节点3的特征的加权较低。换句话说,节点的度越低,则该节点属于某个组或群集的能力就越强。

在Kipf和Welling 的论文中,进行对称归一化将使动力学更加有趣,因此,对归一化方程进行了以下修改:

让我们使用新的对称归一化公式计算归一化值:

# 对称归一化
D_half_norm = fractional_matrix_power(D, -0.5)
DADX = D_half_norm.dot(A_hat).dot(D_half_norm).dot(X)
print('DADX:\n', DADX)

结果:

DADX:[[1.27082039][0.75      ][0.75      ][2.61246118][2.92082039][2.92082039]]

回顾上一节中的方程式3,我们将意识到,现在我们有了 A * 的答案!在本文中,A * 称为重归一化技巧。

完成功能处理后,是时候完成我们的GCN了。

添加权重和激活函数

我们将使用ReLu作为激活函数构建一个2层GCN 。为了初始化权重,我们将使用随机种子,以便我们可以复制结果。请记住,权重初始化不能为0。在本实验中,我们将为隐藏层设置4个神经元。由于我们将在2维上绘制特征表示,因此将有2个输出神经元。

只是为了使其更简单,我们将使用numpy 重新编写归一化方程式,只是为了使其更简单。

# 添加权重与激活函数
# 初始化
np.random.seed(1)
n_h = 4 #隐藏层神经元个数
n_y = 2 #输出层神经元个数W0 = np.random.randn(X.shape[1],n_h)*0.01
W1 = np.random.randn(n_h,n_y)*0.01def relu(x):return np.maximum(0,x)# 建立GCN层
def gcn(A,H,W):I = np.identity(A.shape[0])A_hat = A + I #添加自环到A中D = np.diag(np.sum(A_hat,axis=0))#创建A的度矩阵D_half_norm = fractional_matrix_power(D, -0.5)eq = D_half_norm.dot(A_hat).dot(D_half_norm).dot(H).dot(W)return relu(eq)# 进行前向传播
H1 = gcn(A,X,W0)
H2 = gcn(A,H1,W1)
print('Features Representation from GCN output:\n', H2)

结果:

Features Representation from GCN output:[[0.00025561 0.        ][0.00015929 0.        ][0.00015929 0.        ][0.00048822 0.        ][0.00049817 0.        ][0.00049817 0.        ]]

做完了!我们刚刚建立了第一个前馈GCN模型!

绘制特征表示

GCN的“神奇之处”在于,即使不进行训练,它也可以学习特征表示。让我们通过2层GCN后可视化要素表示。

# 绘制特征表示
def plot_features(H2):x = H2[:,0]y = H2[:,1]size = 1000plt.figure(figsize=(10,8),dpi=80)plt.scatter(x, y, size)     plt.xlim([np.min(x)*0.9,np.max(x)*1.1])plt.ylim([-1,1])plt.xlabel('Feature Representation Dimension 0')plt.ylabel('Feature Representation Dimension 1')plt.title("Feature Representation")for i,row in enumerate(H2):string = '{}'.format(i)plt.annotate(string, (row[0],row[1]), fontsize=18, fontweight='bold')plt.show()plot_features(H2)

结果:

从上图可以清楚地看到有2个主要组,其中左组由节点0、1、2组成,右组由节点3、4、5组成。我们可以推断出GCN可以即使没有经过训练或反向传播,也已经学习了特征表示

重要要点

  • 权重分配方面,图卷积网络中的术语“卷积”类似于卷积神经网络*。*主要区别在于数据结构,其中GCN是CNN的通用版本,可以处理具有规律结构的数据。
  • 在GCN的前向传递方程中插入邻接矩阵(A),使模型可以学习相邻节点的特征。这种机制可以看作是沿着图内节点的消息传递操作。
  • 重归化技巧被用于对Thomas Kipf和Max Welling(2017)的基于快速近似谱图的卷积网络中的特征进行归一化。
  • GCN甚至可以在训练之前就学习特征表示。

参考文献

[1] T. Kipf and M. Welling, Semi-Supervised Classification with Graph Convolutional Networks (2017). arXiv preprint arXiv:1609.02907. ICLR 2017

[2] T. Kipf, https://tkipf.github.io/graph-convolutional-networks/

[3] Z. Wu, et. al., A Comprehensive Survey on Graph Neural Networks (2019).

[4] T. S. Jepsen, https://towardsdatascience.com/how-to-do-deep-learning-on-graphs-with-graph-convolutional-networks-7d2250723780

理解图卷积网络的节点分类相关推荐

  1. 图卷积网络-多标签分类

    首先理解一些以下: 1. 二分类:每一张图像输出一个类别信息2. 多类别分类:每一张图像输出一个类别信息3. 多输出分类:每一张图像输出固定个类别的信息4. 多标签分类:每一张图像输出类别的个数不固定 ...

  2. 带你换个角度理解图卷积网络

    摘要:本文带大家从另一个角度来理解和认识图卷积网络的概念. 本文分享自华为云社区<技术综述十二:图网络的基本概念>,原文作者:一笑倾城. 基础概念 笔者认为,图的核心思想是学习一个函数映射 ...

  3. 【论文笔记】Revisiting graph based collaborative Filtering:一种线性残差图图卷积网络方法

    Revisiting Graph based Collaborative Filtering:A Linear Residual Graph Convolutional Network Approac ...

  4. 图卷积网络原理(二)【图信号与图的拉普拉斯矩阵】

    矩阵乘法的三种视角 后续图卷积网络的原理讲解主要以矩阵乘法的显示展开,这里介绍矩阵乘法的几种不同的视角,这些视角有助于我们理解图卷积网络的逻辑过程. 对于矩阵 A∈Rm×nA\in R^{m\time ...

  5. 图卷积 节点分类_在节点分类任务上训练图卷积网络

    图卷积 节点分类 This article goes through the implementation of Graph Convolution Networks (GCN) using Spek ...

  6. 论文阅读笔记:《一种改进的图卷积网络半监督节点分类》

    论文阅读笔记:<一种改进的图卷积网络半监督节点分类> 文章目录 论文阅读笔记:<一种改进的图卷积网络半监督节点分类> 摘要: 引言 非欧几里得数据 1 深度池化对偶图神经网络 ...

  7. 图卷积网络 GCN Graph Convolutional Network(谱域GCN)的理解和详细推导

    文章目录 1. 为什么会出现图卷积神经网络? 2. 图卷积网络的两种理解方式 2.1 vertex domain(spatial domain):顶点域(空间域) 2.2 spectral domai ...

  8. 【论文翻译】HCGN:面向集体分类的异构图卷积网络深度学习模型

    HCGN:面向集体分类的异构图卷积网络深度学习模型 摘要 集合分类是研究网络数据的一项重要技术,旨在利用一组具有复杂依赖关系的互联实体的标签自相关性.随着各种异构信息网络的出现,集合分类目前正面临着来 ...

  9. 【Mo 人工智能技术博客】图卷积网络概述及其在论文分类上的应用

    近年来,深度学习在计算机视觉.自然语言处理等领域大放异彩.这些领域所面对的数据都是结构化的,如图像.音频.文本等,它们内部都有明确的排列规则.结构化的数据由于具有这些确定的规则而方便处理,但是在现实生 ...

最新文章

  1. Java项目:花店商城系统(java+Springboot+Maven+mybatis+Vue+Mysql)
  2. 百度投资创维10亿,联手构建智能家居AI生态
  3. 终于来热风了,又一次感觉到什么叫温暖!
  4. 160. Intersection of Two Linked Lists
  5. RabbitMQ死信实战(生产者)
  6. Unable to load native-hadoop library for your platform
  7. CSS盒子模型之详解
  8. gvim for php,转 : Gvim建立IDE编程环境 (Windows篇)
  9. 年轻的程序员该如何规划自己的未来
  10. 删除服务中的mysql服务
  11. 怎么解决python遇到问题_新手常见Python错误及异常解决处理方案
  12. html5跟html4有什么区别,Html5和Html4的区别
  13. InvocationTargetException 浅析
  14. ADT(Android) — Eclipse开发NOX夜神安卓模拟器如何进行横竖屏切换
  15. 网络安全中的数据挖掘技术(一)
  16. 视频教程-Docker 基础与实践(DevOps系列)-Linux
  17. 狂神SSM项目整合(含完整代码免费)
  18. 雅虎历任CEO的错误
  19. vnr懒人版教程_【转载】Galgame老司机实用工具:VNR使用教程
  20. 『TensorFlow』TFR数据预处理探究以及框架搭建

热门文章

  1. LaTeX不能识别eps文件?
  2. 【giegie哪有什么坏心思呢,不过是想带你白嫖网红爆款时间屏保呀!】Fliqlo屏幕保护程序(文末有下载链接呦)
  3. SQLyog下载及安装
  4. Android FM 外部短天线支持(ez fm)
  5. python提取电子发票_Python办公自动化—电子发票台账制作自动化(1)
  6. 论文笔记,物体六自由度位姿估计,DenseFusion: 6D Object Pose Estimation by Iterative Dense Fusion
  7. 转:从ubuntu中文论坛转载的一片超好的文章,慢慢学习中(转)
  8. js实现文件下载功能
  9. Python 爬虫 之 爬取王者荣耀的英雄们所有大皮肤图片,并 json 形式保存英雄列表信息到本地
  10. 分享:JavaScript弹出对话框的三种方式