excel中如何对矩阵得对角线进行求和_如何利用图卷积网络进行图形深度学习(第2部分)...

图上的机器学习是一项艰巨的任务,由于高度复杂但信息量丰富,本文是关于如何利用图卷积网络(GCN)进行深度学习的系列文章中的第二篇。我将简要回顾一下上一篇文章:

  1. 图形卷积网络的高级介绍
  2. 具有谱图卷积的半监督学习(本文)

简要回顾一下

在上一篇关于GCNs的文章中,我们看到了在GCNs中表达传播的一个简单的数学框架。总之,给定一个N×F⁰特征矩阵X和一个图的矩阵表示结构,例如,N × N邻接矩阵A的G,在GCN每个隐藏层可以表示为Hⁱ = f(Hⁱ⁻¹, A) ,其中ħ ⁰= X和˚F是传播规则。在H⁰= X和f是一个传播规则。每层Hⁱ 对应一个N×F特征矩阵,其中每一行是一个节点的特征表示。

我们看到了这种形式的传播规则

  1. f(Hⁱ, A) = σ(AHⁱWⁱ)和
  2. f(Hⁱ, A) = σ(D⁻¹ÂHⁱWⁱ)其中 = A + I,I是单位矩阵,以及D⁻¹是Â的度矩阵。

这些规则在通过应用权重Wⁱ和激活函数σ进行变换之前,将节点的特征表示计算为其邻居的特征表示的集合。通过将上面的传播规则1和2表示为f(Hⁱ,A)=变换(聚合(A,Hⁱ),Wⁱ),我们可以使聚合和变换步骤更加明确,其中变换(M,Wⁱ)= σ(MWⁱ)和规则1和聚合(A,Hⁱ)= AHⁱ集合体(A,Hⁱ)= D⁻¹Â Hⁱ 对于规则2。

正如我们在上一篇文章中所讨论的,规则1中的聚合将节点表示为其邻居特征表示的和,其具有两个显着缺点:

  • 节点的聚合表示不包含其自身的特征
  • 具有较大度的节点将在其特征表示中具有较大值,而具有较小度的节点将具有较小值,这使得可能导致梯度爆炸问题的出现并且使用对特征缩放敏感的随机梯度下降算法进行训练变得更加困难。

为了解决这两个问题,规则2首先通过向A 添加单位矩阵来强制执行自循环,并使用变换后的邻接矩阵Â= A + I进行聚合。接下来,通过乘以逆度矩阵D⁻¹来对特征表示进行归一化,将聚合转换为聚合特征表示的比例对节点度不变的均值。

下面我将把规则1称为求和规则,将规则2称为均值规则。

谱图卷积

Kipf和Welling最近的一篇论文提出了使用光谱传播规则进行快速近似谱图卷积:

c37e471f666a54922921daea1cc34ec5.png

与前一篇文章中讨论的总和均值规则相比,谱规则仅在聚合函数的选择上有所不同。虽然它有点类似于均值规则,因为它使用负幂的度矩阵D对聚合进行归一化,但归一化是不对称的。

作为加权和的聚合

到目前为止,我们可以理解所呈现的聚合函数作为加权和,其中每个聚合规则仅在它们的权重选择上不同。我们先来看看如何用加权和来表示相对简单的总和和均值规则表示为加权和。

求和规则

为了了解如何使用求和规则计算第i个节点的聚合特征表示,我们看到如何计算聚合中的第i行。

6ac9c53b611e1533c94cc758b6ed6bce.png

求和规则作为加权和

如上面在等式1a中所示,我们可以将第i个节点的聚合特征表示计算为向量矩阵乘积。我们可以把这个向量矩阵乘积写成一个简单的加权和,如公式1b所示,我们对X中的每N行求和。

等式1b中j节点对集合的贡献由A第i行第j列的值决定。由于A是邻接矩阵,如果第j个节点是第i个节点的邻居,则该值为1 ,否则为0。因此,等式1b对应于对第i个节点的邻居的特征表示求和。

总之,每个邻域的贡献仅取决于邻接矩阵A所定义的邻域。

均值规则

为了了解均值规则如何聚合节点表示,我们再次看到如何计算聚合中的第i行,现在使用均值规则。为简单起见,我们只考虑“raw”邻接矩阵的均值规则,而不考虑A和单位矩阵I之间的加法,这相当于向图中添加自循环。

c1eb8007d318b96b2d6a7046c6de47c4.png

加权和的均值规则

如上面的等式所示,推导现在略长。在等式2a中,我们首先将邻接矩阵A与逆度矩阵D相乘进行变换。在等式2b中更明确地进行该计算。逆度矩阵是对角线矩阵,其中沿对角线的值是节点的逆度,而位置(i, i)的值是第i个节点的逆度,位置(i,i)处的值是第i个节点的逆度。因此,我们可以移除其中一个求和符号,得到等式2c。在等式2d和2e中可以进一步减少等式2c。

如等式2e所示,我们现在再次对邻接矩阵A中的每N行求和。如在求和规则的讨论中所提到的,这对应于对每个第i个节点的邻居求和。但是,等式2e中加权和的权值现在保证与第i个节点的次数之和为1。因此,等式2e对应于第i个节点的邻居的特征表示的均值。

总和规则仅取决于邻接矩阵A定义的邻域,而均值规则也取决于节点度。

谱规则

我们现在有一个有用的框架来分析谱规则。

107ea927839a4c01f42729dc4d93c13d.png

作为加权和的谱规则

与均值规则一样,我们使用度矩阵D对邻接矩阵A进行变换。但是,如等式3a所示,我们将度矩阵提高到-0.5的幂并将其乘以A的每一边。该操作可以如等式3b所示进行细分。度矩阵(及其幂)是对角线的。因此,我们可以进一步简化等式3b,直到达到等式3e中的表达式。

等式3e显示了在计算第i个节点的聚合特征表示时,我们不仅要考虑第i个节点的度,还要考虑第j个节点的度。

与平均规则类似,谱规则对聚合进行归一化,聚合特征表示保持与输入特征大致相同的度。然而,谱规则在加权和中邻居的度越高权值越低,邻居的权值度越低权值越高。当低度邻居比高度邻居提供更多信息时可能会更有用。

GCN的半监督分类

除谱规则外,Kipf和Welling还证明了GCNs如何用于半监督分类。到目前为止,我们已经隐式地假设整个图表是可用的,即我们处于转换环境中。换句话说,我们知道所有节点,但不知道所有节点标签。

在我们看到的所有规则中,我们聚合在节点邻域上,因此共享邻居的节点往往具有相似的特征表示。如果图表具有同质性,则此属性非常有用,连接的节点往往是相似的(例如,具有相同的标签)。同质性发生在许多真实网络中,尤其是社交网络表现出很强的同质性。

正如我们在上一篇文章中看到的那样,即使是随机初始化的GCN也可以通过使用图结构,在同质图中实现节点的特征表示之间的良好分离。通过在标记节点上训练GCN,我们可以更进一步,有效地将节点标签信息传播到未标记的节点。这可以通过以下方式完成:

  1. 通过GCN执行前向传播。
  2. 在GCN的最后一层逐行应用sigmoid函数。
  3. 计算已知节点标签上的交叉熵损失。
  4. 反向传播损失并更新每层中的权重矩阵W.

Zachary空手道俱乐部的社区预测

让我们看看谱规则如何使用半监督学习将节点标签信息传播到未标记的节点。正如在以前的文章中,我们将使用Zachary空手道俱乐部作为一个例子。

Zachary空手道俱乐部

简而言之,Zachary空手道俱乐部是一个小型的社交网络,管理员和空手道俱乐部的教练之间会发生冲突。任务是预测空手道俱乐部的每个成员选择的冲突的哪一方。网络的图形表示可以在下面看到。每个节点代表空手道俱乐部的成员,并且成员之间的连接指示他们在俱乐部外进行交互。管理员和教练分别标有A和I。

c98388fc1c0c06c0ccf741bd9585429a.png

Zachary空手道俱乐部

MXNet中的谱图卷积

我在MXNet中实现了谱规则,这是一个易于使用和高效的深度学习框架。实施如下:

class SpectralRule(HybridBlock): def __init__(self, A, in_units, out_units, activation, **kwargs): super().__init__(**kwargs) I = nd.eye(*A.shape) A_hat = A.copy() + I D = nd.sum(A_hat, axis=0) D_inv = D**-0.5 D_inv = nd.diag(D_inv) A_hat = D_inv * A_hat * D_inv  self.in_units, self.out_units = in_units, out_units  with self.name_scope(): self.A_hat = self.params.get_constant('A_hat', A_hat) self.W = self.params.get( 'W', shape=(self.in_units, self.out_units) ) if activation == 'ident': self.activation = lambda X: X else: self.activation = Activation(activation) def hybrid_forward(self, F, X, A_hat, W): aggregate = F.dot(A_hat, X) propagate = self.activation( F.dot(aggregate, W)) return propagate
3427e92c0d34b518623e51df969c51b6.png

__init__以邻接矩阵A为输入,以图卷积层各节点特征表示的输入和输出维数为输入; in_units和out_units分别为输入和输出维数。通过与单位矩阵I相加,将邻接矩阵A加入自循环,计算度矩阵D,和邻接矩阵变换A到A_hat由谱规则的规定。这种变换不是严格必需的,但是计算效率更高,因为在层的每次向前传递过程中都会执行转换。

最后,在__init__的with子句中,我们存储了两个模型参数——A_hat存储为常量,权矩阵W存储为可训练参数。

hybrid_forward是个奇迹发生的地方。在向前传递中,我们使用以下输入执行此方法:X,上一层的输出,以及我们在构造函数__init__中定义的参数A_hat和W。

构建图卷积网络

现在我们已经实现了谱规则,我们可以将这些层叠加在一起。我们使用类似于前一篇文章中的两层架构,其中第一个隐藏层有4个单元,第二个隐藏层有2个单元。这种架构可以轻松地显示最终的二维嵌入。它与前一篇文章中的架构有不同之处:

  • 我们使用谱规则而不是平均规则。
  • 我们使用不同的激活函数:tanh激活函数用于第一层,否则死亡神经元的概率会很高,而第二层使用identity 函数,因为我们使用最后一层来对节点进行分类。

最后,我们在GCN顶部添加逻辑回归层以进行节点分类。

上述体系结构的Python实现如下。

def build_model(A, X): model = HybridSequential() with model.name_scope(): features = build_features(A, X) model.add(features) classifier = LogisticRegressor() model.add(classifier) model.initialize(Uniform(1)) return model, features
cee4c81d80ffeeb094760e2513f2c769.png

我已将包含图卷积层的网络的特征学习部分分离为features成分,将分类部分分离为classifier成分。单独的features成分使以后更容易可视化这些层的激活。作为分类器的Logistic回归器是一个分类层,它对最后一个图卷积层提供的每个节点的特征进行求和,并对这个求和应用sigmoid函数进行Logistic回归。

为了完整起见,构造features成分的代码是

def build_features(A, X): hidden_layer_specs = [(4, 'tanh'), (2, 'tanh')] in_units = in_units=X.shape[1]  features = HybridSequential() with features.name_scope(): for layer_size, activation_func in hidden_layer_specs: layer = SpectralRule( A, in_units=in_units, out_units=layer_size, activation=activation_func) features.add(layer) in_units = layer_size return features
1692c052f58890e555bc9134125ce396.png

Logistic回归的代码是

class LogisticRegressor(HybridBlock): def __init__(self, in_units, **kwargs): super().__init__(**kwargs) with self.name_scope(): self.w = self.params.get( 'w', shape=(1, in_units) ) self.b = self.params.get( 'b', shape=(1, 1) ) def hybrid_forward(self, F, X, w, b): # Change shape of b to comply with MXnet addition API b = F.broadcast_axis(b, axis=(0,1), size=(34, 1)) y = F.dot(X, w, transpose_b=True) + b return F.sigmoid(y)
0e3369718c388f415a843d88d7071804.png

训练GCN

训练GCN模型的代码如下所示。初始化二进制交叉熵损失函数cross_entropy和SGD优化器,训练器来学习网络参数。然后对模型进行指定次数的训练,其中计算每个训练示例的损失,并使用loss.backward()对错误进行反向传播。然后调用trainer.step来更新模型参数。在每个周期之后,由GCN层构造的特征表示形式存储在feature_representations列表中,稍后我们将对该列表进行检查。

def train(model, features, X, X_train, y_train, epochs): cross_entropy = SigmoidBinaryCrossEntropyLoss(from_sigmoid=True) trainer = Trainer( model.collect_params(), 'sgd', {'learning_rate': 0.001, 'momentum': 1}) feature_representations = [features(X).asnumpy()] for e in range(1, epochs + 1): for i, x in enumerate(X_train): y = array(y_train)[i] with autograd.record(): preds = model(X)[x] loss = cross_entropy(preds, y) loss.backward() trainer.step(1) feature_representations.append(features(X).asnumpy()) return feature_representations
8adc3375e60e86e18f9eb413b724aaf0.png

关键的是,只标记了教练和管理员的标签,并且网络中剩余的节点是已知的,但没有标记。GCN可以在图卷积过程中找到标记节点和未标记节点的表示形式,并可以在训练过程中利用这两个信息源进行半监督学习。

可视化功能

如上所述,存储每个时期的特征表示,这允许我们在训练期间看到特征表示如何改变。在下面我考虑两个输入特征表示。

表示1

在第一个表示中,我们简单地使用稀疏34×34 的单位矩阵,I,作为特征矩阵X表示。该表示具有可以在任何图中使用的优点,但是导致网络中的每个节点的输入参数,其需要大量的存储器和计算能力用于大型网络上的训练并且可能导致过度拟合。不过,空手道俱乐部网络非常小。使用该表示对网络进行5000个周期的训练。

e150e434b408cdca069c9624efc9e5cb.png

使用表示法1分析空手道俱乐部的分类错误

通过对网络中的所有节点进行集合分类,我们可以获得上面显示的网络中的错误分布。黑色表示错误分类。尽管近一半(41%)的节点被错误分类,但与管理员或教练(但不是两者)紧密相连的节点往往被正确分类。

31e9ab99b8e2ac1b8c867f53ddc344ca.gif

在使用表征1的训练过程中特征表征的变化

我已经说明了在训练期间特征表示如何变化。节点最初是紧密集群的,但随着训练的进行,教练和管理员被拉开,用它们拖动一些节点。

虽然管理员和教练的表示方式完全不同,但他们拖动的节点不一定属于他们的社区。这是因为图卷积在特征空间中嵌入了共享邻居的节点,但是共享邻居的两个节点可能无法同等地连接到管理员和教练。具体地,使用单位矩阵作为特征矩阵导致每个节点的高度局部表示,即,属于图的相同区域的节点可能紧密地嵌入在一起。这使得网络难以以归纳方式在远程区域之间共享公共知识。

表示2

我们将通过添加两个不特定于网络的任何节点或区域的特征来改进表示1。为此,我们计算从网络中的每个节点到管理员和教练的最短路径距离,并将这两个特征连接到先前的表示。

可能会认为这有点欺骗,因为我们注入了关于图中每个节点位置的全局信息; 理想情况下由features成分中的图卷积层捕获的信息。但是,图卷积层始终具有局部视角,并且捕获此类信息的能力有限。尽管如此,它仍然是理解GCNs的有用工具。

740d88cebd449526ea2811cdabe4c4d3.png

使用表示法1分析空手道俱乐部的分类错误

和前面一样,我们对网络中的所有节点进行分类,并绘制出错误在网络中的分布。这次,只有四个节点被错误分类;相对于表示1的显著改进。仔细检查特征矩阵后,这些节点要么与教练和管理员等距(在最短路径意义上),要么离管理员更近,但属于教练社区。使用表示1对GCN进行250个周期的训练。

ca635e49b9e675594baf1cc7b10bc94d.gif

使用表征2的训练过程中特征表征的变化

如图所示,这些节点在开始时再次非常紧密地聚集在一起,但在训练开始之前,它们在某种程度上分成了不同社区。随着训练的进行,社区之间的距离也会增加。

结论

在本文中,我对如何在GCNs中执行聚合进行了深入的解释,并展示了如何使用平均值、总和和谱规则来将其表示为加权和。希望您会发现,在您自己的图卷积网络中,这个框架可以帮助您考虑在聚合过程中可能需要的权重。

我还展示了如何在MXNet中实现和训练一个GCN,使用Zachary的空手道俱乐部的谱图卷积对图形执行半监督分类,这是一个简单的示例网络。我们看到仅仅使用两个标记的节点,GCN仍然可以在表示空间中实现两个网络社区之间的高度分离。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/529149.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

linux 开放5222端口,ejabberd 安装配置

ejabberdejabberd是基于Jabber/XMPP协议的即时通讯服务器,由GPLv2授权(免费和开放源码),采用Erlang/OTP开发。它的特点是,跨平台,容错,集群和模块化。ejabberd安装:1. 下载安装包:2.给权限&…

docker查找镜像_5 款非常好用的开源 Docker 工具,get一波~

本文同步Java知音社区,专注于Java作者:Shekhar Gulatihttp://dzone.com/articles/5-docker-utilities-you-should-know导读Docker 社区已经创建了许多开源工具,它们能帮我们处理各种用例。作者在本文中推荐了 5 款认为最有用的 Docker 工具&a…

else应输入一个语句是什么意思_Python学习基础篇 -4: Python中的转弯---分支语句

前言:本专栏以Python为主题,并尽可能保持每星期两到三更,直到将Python的基础知识浅析和讲解完毕,同时,有一定基础的同学可以移步 Python实战专栏 。背景:对于该系列文章的前三篇,自己读过的同学…

ofdm原理_OFDM技术简介

今日光电有趣、有料、有深度光电技术及科技资讯分享让整个世界变得温暖,他人因你的分享而变好!欢迎分享有价值的东西!今日光电因你而变,欢迎留言、分享...我们一起用科技光耀世界、温暖人间……OFDM技术作为4/5G物理层重要技术之一…

linux 内核被污染,导致Linux 4.20性能下降的STIBP已被Kernel 4.19系列内核移除

因为Linux Kernel 4.20默认启用了Spectre补丁STIBP,所以导致性能的下降,下降幅度甚至达到了50%,目前STIBP已经被移除,在最新发布的Linux Kernel 4.19.4、4.14.83内核当中已经移除了STIBP补丁。据称Linux Kernel 4.20就是启用了Spe…

a*算法matlab代码_NSGAII多目标优化算法讲解(附MATLAB代码)

小编今天为大家讲解NSGA-II多目标优化算法,提到多目标优化,大家可能第一个就想到NSGA-II算法,今天小编就带领大家解开NSGA-II的神秘面纱。NSGA-II全称是快速非支配排序遗传算法,这个算法的精髓体现在“快速非支配排序”这7个字上&…

octobercms 执行php代码_PHP7语言执行原理

常用的高级语言有很多种,根据运行的方式不同,大体分为两种:编译型语言和解释型语言。编译是指在应用源程序执行之前,就将程序源代码“翻译”成汇编语言,然后进一步根据软硬件环境编译成目标文件。一般称完成编译工作的…

convert.todatetime指定日期格式_JDK1.8新增日期时间类型

如果我们可以跟别人说:“我们在1502643933071见面,别晚了!”那么就再简单不过了。但是我们希望时间与昼夜和四季有关,于是事情就变复杂了。Java1.0中包含了一个Date类,但是它的大多数方法已经在Java 1.1引入Calendar类…

facebook对话链接_如何应用防错原则,看看 Facebook 和 Gmail 是怎么做的

欢迎来到有言有料,让思考更有张力本文共 3873 字,预计阅读 10 分钟作者|Siddharth Gulati译者|张聿彤本文翻译已获得作者的正式授权(授权截图如下)在用户界面(UI)设计中,重要的是要注意最细微的细节,以使用…

模拟灰度传感器循迹的程序_PLC编程,实例讲解西门子PLC模拟量编程

给大伙分享的是关于西门子S7-300PLC模拟量方面的实例,包含了以下几个方面的要点:1、对变送器进行取值,并进行控制2、对模数功能块 FC105 进行调用3、对 AI 模块进行设置4、对 AI 量程块进行选择这个实例, 调试的是一个流量调节回路…

作业调度C语言编写,【作业调度方案】 (C语言代码)

解题思路:如图所示,对于第一组样例输入,按照总工序提供的顺序,对于每个工件的工序从小到大,每次寻找有空闲机器的“空档”插入,就能让总加工时间最短。注意事项:按照约定,最短方案有且只有一种。参考代码:#…

python判断能否组成三角形_python三角形判定怎么做

python三角形判定怎么做?下面给大家带来具体的例子: 相关推荐:《Python视频教程》 例子:a int(input("The length of the side a ")) b int(input("The length of the side b ")) c int(input("The…

如何修改linux的java路径_修改桌面文件默认存储位置的正确方式及注意事项

之前写了篇关于如何修改桌面文件默认存储位置,许多人在修改后出现各种问题,今天重新来讲解一下关于修改桌面文件默认存储位置的正确方式及注意事项。第一步、在E盘下创建一个文件夹,随便取个名字,或者默认为【新建文件夹】&#x…

【LeetCode】链表精选12题

目录 快慢指针: 1. 相交链表(简单) 2. 环形链表(简单) 3. 快乐数(简单) 4. 环形链表 II(中等) 5. 删除链表的倒数第 N 个节点(中等) 递归迭…

python去重保留唯一一个值_Python DataFrame使用drop_duplicates()函数去重(保留重复值,取重复值)...

摘要 在进行数据分析时,我们经常需要对DataFrame去重,但有时候也会需要只保留重复值。 这里就简单的介绍一下对于DataFrame去重和取重复值的操作。 创建DataFrame 这里首先创建一个包含一行重复值的DataFrame。2.DataFrame去重,可以选择是否保…

自定义日历控android,Android 一个日历控件的实现小记

先看几张动态的效果图吧!这里主要记录一下在编写日历控件过程中一些主要的点:一、主要功能1、支持农历、节气、常用节假日2、日期范围设置,默认支持的最大日期范围[1900.1~2049.12]3、禁用日期范围设置4、初始化选中单个或多个日期5、单选、多…

android文件读取工具类,Android 下读取Assets Properties操作封装工具类

Android 下读取Assets Properties操作封装工具类发布时间:2018-06-03作者:laosun阅读(2081)为了方便使用,首先创建BaseApplication类,如下所示:import android.app.Application;import android.content.Context;/*** C…

python解压到指定文件夹_在Python中压缩和解压文件

Python部落(python.freelycode.com)组织翻译,禁止转载,欢迎转发。 如果你已经使用计算机一段时间,你可能遇到了.zip扩展名的文件。它们是可以保存许多其他文件,文件夹和子文件夹的压缩内容的特殊文件。这种类型的文件在使用互联网…

android bar布局,Android学习路线(十)如何将Action Bar叠放在你的布局上

默认状况下,action bar出如今activity窗口的顶部,略微减小了activity布局的总空间。若是你想隐藏或者显示action bar,在这堂用户体验的课程中,你能够经过调用htmlFigure 1. Gallerys action bar in overlay mode.android为了不在a…

geant4运行例子_Geant4--一次编译,运行多个Run,极大提升模拟效率

文|梁佐佐应唐光毅博士/后之约,对于Geant4模拟,我们看是否能解决这么一个问题:我现在想模拟探测器不同角度下的响应,每次模拟需要/run/beamOn 100, 可是我真的不想一遍一遍的去http://DetectorConstruction.cc中修改几…