全网最详细解读《GIN-HOW POWERFUL ARE GRAPH NEURAL NETWORKS》!!!

Abstract + Introduction

GNNs 大都遵循一个递归邻居聚合的方法,经过 k 次迭代聚合,一个节点所表征的特征向量能够捕捉到距离其 k-hop 邻域的邻居节点的特征,然后还可以通过 pooling 获取到整个图的表征(比如将所有节点的表征向量相加后用于表示一个图表征向量)。

关于邻居聚合策略以及池化策略都有很多相关的研究,并且这些 GNNs 已经达到了目前最先进的性能,然而对于 GNNs 的各种性质以及性能上限我们并没有一个理论性的认识,也没有对 GNN 表征能力的形式化分析。言下之意:这些 GNNs 模型的研究虽然效果很好,但并没有系统理论的支撑,并不知道是基于什么导致了更好的性能,而是基于经验主义的。

本文提出了一个理论框架以分析 GNNs 表征的能力,正式描述了不同 GNNs 变体在学习表征以及区分不同图结构时的性能。该理论框架由 GNN 与 WL-test 之间的密切联系所启发。与 GNN 类似,WL-test 也会递归地聚合节点的邻居特征。也是因为 WL-test 聚合更新的性质使其性能强大。既然二者在操作上都非常相似,那么从理论上看 GNN 也能够具备跟 WL-test 一样强大的判别能力

为了在数学上形式化上述见解,理论框架首先会将给定节点的邻居节点特征向量表示为一个 multiset,即一个可能包含重复元素的集合。GNNs 的邻居聚合就能够被看作是对 multiset 进行处理的聚合函数。

作者研究了 multiset 聚合函数的多种变体,并从理论上分析了聚合函数对于区分不同 multiset 的判别能力。为了具备强大的表征能力,GNN 必须将不同的 multiset 聚合成不同的表示。只要聚合函数能够达到跟 hash 散列一样的单射性,那么理论上是能够达到跟 WL-test 一样的判别能力的。因此,聚合函数的单射性越强,GNN 的表征能力就越强。

该篇论文的研究成果总结如下:

  • 展示了 GNNs 在区分图结构时,理论上能够达到与 WL-test 相似的性能。
  • 在上述条件下,建立了邻居聚合以及 Graph readout 的 condition。
  • 识别了当下流行的 GNN 变体(GCN,GraphSAGE)无法区分的图结构,并精确表征了其能够成功捕捉的图结构类型。
  • 开发了一个简单的神经网络架构 GIN,并且证明了它在表征能力上与 WL-test 性能相当。

作者通过图数据集的分类任务验证了理论,其中 GNN 的表征能力对于捕获图结构的信息至关重要。研究比较了基于不同聚合函数 GNNs,结果证明性能最强大的 GIN 模型从经验的角度来看也具备高表征能力,几乎能够完美拟合训练数据,而一些较弱的 GNN 变体则通常欠拟合训练数据。此外,表征能力更强的 GNNs 在测试集精度上比其他模型性能更优,主要表现在图分类任务上达到了目前最优的性能。

PRELIMINARIES

我们用 \(G=(V, E)\) 表示一个图,节点特征向量表示为 \(X_v\)。我们主要考虑两个任务:

  1. 节点分类任务:每个节点 \(v ∈ V\) 都有一个关联的标签 \(y_v\) 并且我们的目标是去学习每个节点 \(v\) 的表征向量 \(h_v\),每个节点 \(v\) 的标签预测过程能够被表示为 \(y_v = f(h_v)\)
  2. 图分类任务:给定图集合 \(\{G_1, G_2, ..., G_n\} ∈ G\) 并且其标签集合为 \(\{y_1, y_2, ..., y_n\} ∈ Y\),目标是学习每个图的表征向量 \(h_G\) 以预测图的标签,整个过程可以被表示为 \(y_G = g(h_G)\)

Graph Neural Networks. GNNs 利用图的结构和节点特征 \(X_v\) 去学习一个节点表征向量 \(h_v\)(或是整个图的表征向量 \(h_G\))。当前 GNNs 都采用了邻居聚合策略,通过聚合策略迭代更新每个节点的表征向量。经过 k 次聚合迭代后,一个节点的表征能够捕捉 k-hop 邻居节点的特征信息。形式上,第 k 层 GNN 可表示为:

img

其中 \(h_v(k)\) 表示节点 \(v\) 在第 k 次迭代的特征向量。我们初始化 \(h(0)=X_v\),并且 \(N(v)\) 是节点 V 的邻居节点集合。

公式表达的意思即:先聚合节点 \(v\) 的邻居节点表征,得到 \(a_v(k)\),然后结合 \(a_v(k)\) 与节点自身的表征 \(h_v(k-1)\) 生成节点 \(v\) 新的表征 \(h_v(k)\)

对于 Aggregate 以及 combine 的选择对于 GNN 的性能有着至关重要的影响,并且也有很多相关的研究,比如 GraphSAGE 的 Aggregate 则表示为如下:

img

其中 \(W\) 是可学习的参数矩阵,\(Max\) 表示为 element-wise max-pooling。Combine 则表示为一个线性映射 \(W·[h_v(k-1), a_v(k)]\)

即:GraphSAGE 会将所有的邻居节点进行一个线性投影,然后通过 ReLU 激活,再取出其中的最大值作为邻居聚合后的表征向量。这个邻居节点 multiset 的表征向量会跟节点自身的表征向量拼在一起作线性投影。

而在 GCN 中 则是采用了 element-wise mean-poolinig,并且 Aggregate 和 Combine 过程结合到了一起:

img

即:GCN 会先对邻居节点以及节点自身取平均,然后对结果线性投影,然后通过 ReLU 激活,结果作为最终的节点表征向量。

而许多其他的 GNNs 聚合/Combine 过程都能够被公式 2.1 表示。

对于节点分类任务,最后一次迭代的节点的表征 \(h_v(K)\) 则会被用于预测。对于图分类任务,\(READOUT\) 函数则会聚合最后一次迭代的节点特征得到一个图表征向量 \(h_G\)

img

READOUT 可以是简单的排列不变函数,比如对所有图节点特征求和,也可以是更加复杂的图级别池化函数。

Weisfeiler-Lehman test. 图同构问题是指 判别两个图是否具备拓扑相同性。而 WL-test 则是针对图同构问题的一个高效的算法,它的判别操作过程类似于 GNN 中的邻居聚合,wL-test 迭代地聚合节点与邻居节点的标签,将聚合的标签进行一次 hash 散列为一个新的唯一标签。如果在某次迭代中,两个图之间的节点标签不同,则可以判定两个图是非同构的。

下图是图同构问题的一个简单判别流程,从上至下的 3 个图中,2 和 3 为同构图,1 则是与二者为异构图。相同的颜色表示相同的节点特征,邻居聚合散列后会生成一个新的特征。若经过若干次迭代后,若对应节点的颜色不同,则能够断言二者互为异构图。

img

WL-test 只能够判别两个图不是同构图,但并不能判定两个图一定是同构图。

而 Shervashidze et al. 又基于 WL-test 提出了 WL subtree kernel 算法,该算法能够评估两个图的相似性。

作者并没有详细解释 WL subtree kernel 的具体计算过程,这里我们也不必过于纠结具体的算法,只需要知道 WL WL subtree kernel 能够高效地判定两个图结构的相似性。

如果我们能够在图分类任务中,精确而高效地判定出两个图的相似性,那么在预测任务中,就更容易确定两个图是否属于一个类别。而 GNN 的聚合操作与 WL-test 高度相似,因此我们可以合理怀疑:GNN 能够在图相似性评估的过程(图表征学习)中达到 WL-test 的性能水平。只要聚合函数能起到跟 hash 函数一样的单射性,那么理论上二者是能够达到同级别的性能水平的。

img

Figure 1. 简单表述了经过 2 次 WL-test 迭代后,每个节点聚合的邻居信息。这个过程是跟 GNN agreegation 高度相似的。

3 THEORETICAL FRAMEWORK: OVERVIEW

整个论文中,作者假设节点的特征向量是离散的(毕竟特征向量值连续的情况下,99.9999% 都不会聚合出一个相同的嵌入,作者也就没牛逼可吹了)。作者将这样的图称为有限图。对于有限图,更深卷积层的特征向量也同样是离散的。

img

作者这里给出了 Multiset 的定义,但我们不用太关注这个概念,直接将其理解为节点的邻居即可。

为了研究 GNN 的表征能力,作者分析了 GNN 什么情况下会将两个节点映射到嵌入空间中的相同位置。直观地说,一个最强大的 GNN 只有在两个节点具备相同的邻居子树结构时才会将它们映射到同一个嵌入空间的位置。我们也可以将问题简化为:GNN是否映射两个相同的邻域特征(multiset)映射到相同的嵌入表示。毕竟最强大的 GNN 永远不会将两个不同的邻域特征映射到同一个嵌入,即聚合函数必须是单射 injective 的。因此,我们将 GNN 的聚合函数抽象为一种可以由 neural network 表示的 multiset function,并分析该函数是否能够表示为 injective multiset function。

只要 multiset function 能表示为单射函数,这就意味着在 GNN 的聚合邻居操作中,对于不同邻域的特征,聚合后能够获取到一个唯一的输出表征,这样就能够捕捉到更多的图结构信息以及邻居节点的特征信息。GNN 就能够获得非常强大的表征能力。

injective function,即单射函数,表示输入跟输出是一对一的关系,即对于不同的输入x,f(x) 永远不可能存在相同的输出。

接下来,我们将利用这个推论(injective multiset function)来开发一个最强大的 GNN。在 Section.5 我们研究了当下流行的 GNN variants 并且发现它们的聚合方式都本质上不满足 injective 的特性,因此其模型的表征能力都不太强,但这些模型也可以捕获到 Graph 的其他的有趣的属性。

4 BUILDING POWERFUL GRAPH NEURAL NETWORKS

首先我们给出了 GNN 模型的最大表征能力,即具备单射性的聚合策略。理想情况下,最强大的 GNN 可以通过将不同的图结构映射到不同的嵌入空间来区分它们。然而,这种将任意两个不同的 Graph 映射到不同的嵌入空间的能力意味着要解决一个困难的图同构问题。即:我们希望同构图映射到相同的嵌入空间,非同构图映射到不同的嵌入空间。但在我们的分析中,我们利用一个稍微弱一些的标准来定义 GNN 的表征能力 —— WL-test,它通常能够很好地区分非同构图,并且性能也较高,除了少数例外情况(比如正则图)。

img

引理2:只要图神经网络能够将任意两个异构图划分到两个不同的嵌入,那么 WL-test 也一定可以将这两个图判定为异构图。简单来说,图神经网络能做的,WL-test 一定能做;但图神经网络不能做的,WL-test 也能做。

因此,任何基于聚合的 GNN 在区分不同的图方面最多也就跟 WL-test 一样强大。那么是否存在与 WL-test 一样强大的 GNN 呢?

Theorem 3. 给出了肯定的答案:若邻居聚合函数与 Readout function 都是 injective function,那么这样的 GNN 与 WL-test 一样强大。

img

定理3:若对于任意两个非同构图 \(G_1\) and \(G_2\)(由 WL-test 判定),那么只要 GNN 具备足够多层且满足下面两个条件,就能够将两图映射到不同的嵌入:

  1. GNN 通过式子 \(h_v(k)=φ(h_v(k-1), f(\{h_u(k-1):u∈N(v)\}))\) 聚合并且递归更新节点特征

    其中,函数 \(f(x)\) 的入参为 multisets,\(φ(x)\) 表示一个 combination 操作,且满足 injective。

  2. GNN 的 graph-level readout 入参也是 multisets(即节点特征 \(\{h_v(k)\}\)),并且 readout 满足 injective。

作者已经在附录中给出了定理3的证明。对于有限图,单射性能够很好地描述一个函数是否能够维持输入信息的独特性。但对于无限图,由于其中的节点特征是连续的,则需要进一步考虑。

此外,描述学习到的特征在函数图像中的亲密度也是一件非常有趣的事情。我们将把这些问题留到未来的工作,并且将重心放到输入节点特征来自可数集合的情况。

img

引理4:主要是告诉我们,只要特征空间是离散的,那么在聚合后依然能够得到一个离散的特征空间。本篇论文也是在特征离散的前提下讨论的。

除了区分不同的图以外,GNN 还有一个重要的优点,即能够捕获图结构的相似性。而 WL-test 是无法捕获图之间的相似性的,这也是为什么我们不直接采用 WL-test 到图数据任务处理中。

原因在于:WL-test 中节点的特征向量本质上是 one-hot encodings,即描述节点属于哪个类别的 one-hot 编码,且经过邻居聚合 hash 后得到的也只是 “代表新的节点类别的 one-hot”,无法得到一个具备节点特征与图结构信息的空间嵌入,因此不能捕获子树之间的相似性。

相比之下,满足 Theorem 3 的 GNN 通过学习将邻居节点特征聚合映射到一个向量空间,相隔较远距离的嵌入大概率不属于一个类别,而相隔较近的嵌入则同属一个类别。这使得 GNN 不仅可以区分不同的图结构,还可以将近似的图结构映射到相似的嵌入,并捕获图结构之间的依赖关系。捕获节点的结构相似性被证明是有助于泛化的,特别是当邻居的特征向量的是稀疏的,或者存在噪声边缘特征时。

4.1 GRAPH ISOMORPHISM NETWORK (GIN)

在确立了最强大的 GNN 的开发条件后(满足单射的聚合函数),我们接下来开发一个简单的架构,图同构网络 GIN,它能够被证明满足 Theorem 3. 中的条件。这个模型推广了 WL-test 从而实现了 GNNs 系模型的最强判别能力。

为了建模一个单射邻居聚合函数,作者提出了一种 “deep multisets” 理论,即:用神经网络参数化 “通用的单射邻居聚合函数”。下一个 Lemma 说明了 sum-aggregators 能够在邻居聚合函数上具备单射的性质。

img

引理5:假设向量空间 \(\mathcal{X}\) 是离散的,那么一定存在函数 \(f\) 将节点特征进行投影到一个 n 维嵌入的函数,使得 \(h(X) = \sum_{x ∈ X} f(x)\) 的值对于每一个位于向量空间 \(\mathcal{X}\) 的 multiset \(X\) 都能取到一个唯一的值。此外,任何一个 multiset function \(g\) 都能被拆解为 \(g(X) = φ(\sum_{x ∈ X} f(x))\),其中 \(φ\) 是某个函数。

引理5,主要就是证明了 sum-aggregation 的单射性,我们明白这一点即可。

作者在论文附录中证明了 Lemma 5. 这里我们先不去管证明了。

Deep MultiSets 和 sets 最重要的一个区别是:是否满足单射的性质。比如 mean-aggregator 就不满足单射性质。(后面会解释 mean-aggregation 为什么不满足单射性)

“Deep MultiSets 和 sets 最重要的一个区别是:是否满足单射的性质。” 这句话我并不是看的很懂,个人的理解是:聚合函数的参数的丰富程度能够决定能否满足单射的性质,比如平均聚合的多集特征中,真正处理的只是整个特征集合中的一部分特征。

以 Lemma 5. 中的 “通用的单射邻居聚合函数” 建模机制作为构建模块,我们可以构想出一个聚合方案,该方案能够表示一个 “入参为节点以及其邻居 multiset” 的泛函数,因此满足 Theorem 3. 中的 injective condition。下一个推论给出了一个简单而具体的公式。

img

推论6:对于参数 \(\epsilon\),由无限种可能使得 \(h(c, X) = (1 + \epsilon) * f(c) + \sum_{x ∈ X} f(x)\) 对于每一个元组 (c, X) 都能够拿得唯一的值。

其实跟引理5 差不太多,只需要把 c 理解为节点自身,X 理解为节点邻居多集即可。

鉴于普遍近似理论 universal approximation theorem (Hornik et al., 1989; Hornik, 1991),我们可以利用 MLPs 建模并学习 Corollary 6. 中的 \(f\) and \(ϕ\) 函数。实际操作上,我们用单层感知机对 \(f^{(k+1)}◦ϕ^{(k)}\) 进行建模,因为 MLPs 能够表示函数的组合。

在第一次迭代聚合时,若输入的特征是 one-hot encodings,那么我们在进行 sum 聚合之前并不需要 MLPs,因为这些特征的求和操作已经满足单射性质。我们可以让 \(\epsilon\) 作为一个可学习参数或是固定参数。那么此时 GIN 的聚合操作可以由如下公式表示:

img

一般来说,可能存在许多其他强大的 GNNs。但 GIN 是最强大的 GNNs 之一,同时也很简单。

4.2 GRAPH-LEVEL READOUT OF GIN

通过 GIN 学习的节点嵌入可以直接用于节点分类问题以及链路预测问题,但对于图分类问题,我们提出了以下方法:通过节点的嵌入构造整个图的嵌入。一般我们会把这个过程称为 Graph Readout

Graph Readout 的一个重要因素是:随着迭代(聚合)次数增加,对应于子树结构的节点表征会变得更加精细以及覆盖范围更广。因此足够的迭代次数是获得良好判别能力的关键。然而,有时较少迭代的特征也可能会带来更好的泛化能力,所以并不是一味的增加聚合次数就能够让性能变得更好。

因此,作者利用到了每一次迭代聚合的节点表征信息,通过类似 Jumping Knowledge Networks (Xu et al., 2018) 的架构来实现,并用下列 Readout concat 方案替换 Eq 2.4:

img

即,把每一次迭代聚合得到的表征进行一个 concat。

基于 Theorem 3. 和 Corollary 6. GNN 能够很好地推广 WL-test 和 WL subtree kernel(在求和之前,我们不需要额外的 MLP,原因跟 Eq 4.1 的相同,此时的 sum 已经满足了单射性质)

5 LESS POWERFUL BUT STILL INTERESTING GNNS

接下来,我们研究一下不满足 Theorem 3 (单射)条件的 GNNs,包括 GCN,GraphSAGE。再从两个方面开展关于聚合函数 Eq4.1 的消融实验

  1. 用 1-layer 的感知机而不采用 MLPs(单纯邻域节点线性求和作为聚合策略是否可行)
  2. 均值池化或最大池化,而不采用 sum(不采用求和而是采用 mean or max 的聚合策略是否可行)

我们将会惊讶地发现,这些 GNN 变体会无法识别一些简单的图,并且性能也不如 wL-test 强大。但尽管如此,采用 mean aggregators 的模型(如 GCN)在节点分类任务中还是会得到不错的结果。为了更便于理解,我们将精确地描述不同 GNN 变体能或不能捕捉到的图,并且讨论有关 “图学习” 的含义。

5.1 1-LAYER PERCEPTRONS ARE NOT SUFFICIENT

Lemma 5 中的函数 \(f\) 能够将截然不同的 multisets 映射到一个唯一的 Embeddings 上。基于普遍近似理论,函数 \(f\) 能够被 MLP 参数化。尽管如此,许多现有的 GNNs 都采用的是单层的感知机,然后通过 Relu 进行非线性激活。这样的单层映射属于广义线性模型的例子。因此我们感兴趣的是:单层感知机是否能够用于图学习。但 Lemma 7 表明,确实存在单层感知机永远无法区分的 multisets。

img

引理7:确实存在不同的多集 \(X_1 ≠ X_2\),但对于任何映射 \(W\) 二者映射后的嵌入都是相等的。单层感知机可以是某种线性映射,此时 GNN 层会退化为简单的邻域特征求和。但引理7是建立在线性映射中缺乏偏置项 bias 的基础上的。

虽然有了偏置项和足够大的输出维度,单层感知机大概率能够区分不同的 multisets,但尽管如此,与采用多层感知机的模型不同,单层感知机即便是带有偏置项,也不属于 multisets function 的通用逼近函数。因此,即便 1-layer GNN 能够将不同的图嵌入到不同的表征,但这种嵌入可能无法充分捕获两个图的相似性,并且对于简单分类器(比如线性分类器)来说很难拟合。在 Section 7 中我们将会看到,1-layer GNN 在应用图分类任务时,会导致严重的欠拟合,并且在 test Accuracy 方面也通常比 MLPs GNN 表现差。

5.2 STRUCTURES THAT CONFUSE MEAN AND MAX-POOLING

如果我们在聚合操作中,将 \(h(X) = \sum_{x∈X}f(x)\) 替换为 GCN 中的 mean pooling 或者 GraphSAGE 中的 max pooling 可能会发生什么?

平均池化聚合以及最大池化聚合都仍然属于 well-defined 的多集函数,因为它们都是排列不变的。但它们都不满足单射性。图2根据聚合器的表征能力对三种聚合器进行了排名,并且图3阐述了 max-pooling 和 mean-pooling 无法区分的结构。节点颜色表明了不同的节点特征,并且我们假设 GNNs 会在 combine 操作之前先执行 Aggregation。

img

对于 sum 聚合来说,能够捕捉 multiset 中所有特征的信息,而 mean 聚合能捕捉部分比例特征的信息,而 max 聚合则忽略了特征信息的多样性。

img

在 Figure 3a 中,所有的节点都具备相同的特征,因此对于 mean 和 max 聚合都会得到相同的结果,不具备单射性。即便两个图从结构上来看并不相同,但 mean and max 聚合却能够取到相同的值,也就意味着在这种情况下,mean and max 聚合无法捕获到任何图结构的信息。但对于 sum pooling aggregators 能够给出不同的值,也就意味着 sum aggregator 能够区分这两种图结构(但单纯的线性求和可能无法获取到图结构信息)。同样的参数也可以应用于任何无标记的图。如果使用节点度而不是常量值作为节点输入特征,原则上,mean 聚合可以起到类似 sum 聚合的作用,但最大池化不能。

Fig.3a 表明,平均和最大池化对于区分具备重复特征的节点是困难的。我们定义 \(h_{color}\) 为节点特征的映射结果(相同特征会映射到相同的颜色)。Fig.3b 表明,对于两个不同结构的图,最大池化聚合 \(max(h_{g}, h_{r})\) and \(max (h_{g}, h_{r}, h_{r})\) 能够取到相同的表征。因此最大池化聚合并不能区分这两张图。但 sum aggregator 仍然能够区分。同样地,对于 Fig.3c,mean and max pooling 同样会无法区分,因为 \(\frac{1}{2}(hg + hr) = \frac{1}{4}(hg + hg + hr + hr)\)

5.3 MEAN LEARNS DISTRIBUTIONS

为了描述 mean aggregator 能够区分的 multisets 类别,我们考虑一个例子:\(X_1=(S, m)\) and \(X_2=(S, k·m)\),其中 \(X_1\) and \(X_2\) 拥有相同元素但个数不同(但成比例)的集合,任何平均聚合器都将 \(X_1\)\(X_2\) 映射到相同的嵌入,因为它只是对 \(X_i\) 的特征取平均值。

若在 graph 任务中,若 提取统计信息以及信息分布提取特定结构信息 更加重要,那么 mean aggregator 的效果还不错。此外,若节点特征多样且重复性较少时,mean aggregator 跟 sum aggregator 的效果一样好。或许这能够被解释为什么平均存在一定的局限性,但平均聚合 GNNs 对节点分类的任务依然很有效,比如文章主题分类,社群检测这类任务,它们都属于节点特征丰富,且邻域特征分布为分类任务提供了更明显的信息。

5.4 MAX-POOLING LEARNS SETS WITH DISTINCT ELEMENTS

Fig.3 的例子表明:最大池化会将多个具备相同特征的节点视为单个节点(即,将 multiset 看作为单个 set)。最大池化捕捉特征的并非确切的图结构信息,也不是图节点的分布信息。最大池化适用于识别 “代表性骨架”,Qi et al. 的工作从经验上表明,最大池化聚合学习适合识别 3D 点云的 “骨架”,并且对噪声和异常值具有更强的鲁棒性。为了完整性起见,下一个推论表明,最大池化聚合器捕获了 multiset 的底层集合。

可以将 3D 点云理解为三维图像,一般会应用于建筑安全隐患识别,城市管理等。

img

推论9:可以简单理解为,max 聚合能够捕捉到结构相似的底层结构信息。其实跟最大池化的特性比较相似,具备更好的鲁棒性以及抗噪性,但缺点是会丢失一些信息。但即便如此,依然能够捕获到底层结构相同的类别。

5.5 REMARKS ON OTHER AGGREGATORS

还有一些其他的非标准邻居聚合方式,但本篇论文并未提及,比如:weighted average via attention (Velickovic et al., 2018),LSTM pooling (Hamilton et al., 2017a; Murphy et al., 2018). 本文强调的是:该理论框架足够普适去描述基于聚合方式的 GNNs 的表征性能。未来会考虑应用框架去分析和理解其他的聚合方式。

尽管 GNNs 取得了成功(从经验主义的角度来看),但用数学方法研究其性质的工作相对较少。一个例外是Scarselli et.al(2009a)的工作,他认为:最早的 GNN 模型(Scarselli et.al,2009b)可以在概率上近似于 measurable functions。Lei et.al(2017)表明,他们提出的架构位于图核的 RKHS(abbr. reproducing kernel Hilbert space 再生式原子核希尔伯特空间) 中,但没有明确研究它可以区分哪些图。这些作品都侧重于一个特定的体系结构,并不容易推广到多个体系结构。

相比之下,上述结论为分析和描述一个广泛类别的 GNN 的表达能力提供了一个更一般的理论框架。最近,许多基于 GNN 的架构被提出,包括和聚合和 MLP(巴塔格利亚等人,2016;斯卡塞利等人,2009b;Duvenaud等人,2015),而大多数没有理论推导。与许多先前的 GNN 架构相比,我们的图同构网络(GIN)在理论上更加充分,并且简单而强大。

measurable functions: 不太理解这个概念具体是什么函数,我个人暂且理解为可以通过公式表达的函数(或者能够通过最大近似理论去利用 MLPs 逼近的函数)

7 EXPERIMENTS

在实验部分比较了 GIN 于其他较弱的 GNN 变体在测试集,训练集上的表现。训练集能够去评估模型的表征能力,且测试集能评估模型的泛化能力。

Datasets. 我们采用 9 个图分类 benchmarks:4个生物信息学数据集(MUTAG,PTC,NCI1,PROTEINS)以及5个社交网络数据集(COLLAB,IMDB-BINARY,IMDB-MULTI,REDDIT-BINARY,REDDIT-MULTI5K)。重要的是,我们实验目的并不是让模型依赖于输入节点的特征,而是主要让模型从网络结构中学习。因此,在生物信息学 Graph 中,节点具有分类输入特征;但在社交网络中,节点没有特征。

对于社交网络数据集,我们创建节点特征如下:对于 REDDIT 数据集,我们将所有的节点特征向量设置为统一(因此,这里的特征是不具备信息的);对于其他的社交网络 Graphs,我们基于节点 degrees 去生成 one-hot encodings 以表示节点特征。数据集统计汇总于 table.1 更多的数据细节可以在 Appendix.I 中找到。

Models and configurations. 我们评估了 GINs(Eqs.4.1 and 4.2)以及其他 less powerful GNN 变体。而针对 GIN 框架,我们考虑它的两个变体:

  1. 基于 Eq.4.1 进行梯度下降学习参数 \(\epsilon\) 的 GIN-\(\epsilon\)
  2. 一个更简单的 GIN-0,其中 Eq.4.1 的参数 \(\epsilon\) 固定为0。

实验表明 GIN-0 有更强大的性能:GIN-0 不仅与 GIN-\(\epsilon\) 同样拟合训练数据,而且具备良好的泛化性能,而在测试精度方面略微但始终优于GIN-\(\epsilon\)。对于其他较弱的 GNN 变体 我们考虑替换 GIN-0 的 sum 聚合,采用 mean or max-pooling,或者替换多层感知机为单层感知机。

在 Fig.4 以及 Table.1 中,模型会根据 其采用的聚合方式/感知机的层数 来命名,例如 mean-1-layer 和 max-1-layer 分别对应了 GCN 和 GraphSAGE,并且会在此基础上进行较小的修改。我们对 GINs 以及 GNN 变体都采用相同的 Graph Readout(Eq.4.2),为了更好的测试性能,生物学信息数据集上采用 sum readout,社交网络数据集采用 mean readout。

实验采用十折交叉验证,并且报告了交叉验证中,10次验证精度的平均值和标准差。对于所有的模型配置,采用5个 GNN 层(包括输入层),并且 MLPs 采用2层。Batch Normalization 应用于每一个 hidden layer。采用 Adam optimizer 并且初始化学习率为 0.01 并且以每 50 次 epochs 进行一次衰减率为 0.5 的权重衰减。我们对于每个数据集都需要调整的超参为:

  1. hidden units number:对于生物信息学 Graph 采用 {16, 32},社交网络 Graph 采用 64
  2. batch size:
  3. dropout ratio:{0, 0.5} after dense layer
  4. epochs number:调整为 10 次平均交叉验证精度最好的 single epoch

注意,由于数据集size较小,使用验证集进行超参调整时非常不稳定的,比如 MUTAG 验证集只包含 18 条数据。

img

我们还报告了对于不同 GNNs 的训练精度,所有的模型超参都是固定的:

  • 5 GNN layers(include input layer)
  • hidden units of size 64
  • minibatch of size 128
  • dropout ratio 0.5

为了比较,WL subtree kernel 的训练精度也会被报告,其中我们将迭代次数设置为4,对比 5 GNN layers。

Baselines. 我们将上述 GNNs 与最先进的图分类基准进行比较:

  1. WL subtree kernel,采用 C-SVM 作为分类器,我们调整的超参为 SVM 的 C;WL iterations number \(∈ \{1,2,...,6\}\)
  2. 最先进的深度学习架构 —— DCNN,PATCHY-SAN,DGCNN
  3. Anonymous Walk Embeddings

对于深度学习方法和 AWL,我们报告了原始论文中报告的准确度。

img

7.1 RESULTS

Training set performance. 我们通过比较 GNNs 的训练精度来验证之前对 GNN 模型表征能力的理论分析。具备较高表征能力的模型应该具备较高的训练准确度。Fig.4 展示了具备相同超参的 GINs 和较弱的 GNN 变体的训练曲线。首先,理论上最强大的 GNN,即 GIN-\(\epsilon\) 和 GIN-0 都能够完美地拟合所有的训练集。

而在实验中,对比 GIN-0 可以发现,GIN-\(\epsilon\) 针对参数 \(\epsilon\) 的学习并没有在拟合训练数据中获得收益;采用 mean/max pooling 或单层感知机的 GNN 变体在许多数据集上都产生了严重的过拟合。可以发现,这些模型的训练精度水平与之前分析的 模型表征能力进行的排名 一致,在训练精度方面

  • MLPs 大于 1-layer perceptions
  • sum aggregators 大于 mean / max aggregators

在我们的数据集上,GNN 的训练精度从未超过 WL subtree kernel 的训练精度,这是意料之中的,因为 GNN 通常比 WL-test 的判别能力低。例如在 IMDBBINARY 上,没有任何一个模型能够完美地拟合训练集,GNN 最多也只能够达到与 wL kernel 相同的训练精度。这种实验结果与论文得出的结论一致,即 WL-test 是基于聚合的 GNN 的表征能力上限。然而 WL kernel 无法学习如何组合节点特征(即不能具备泛化能力),这对于预测任务来说是非常关键的,接下来将说明这个部分。

Test set performance.

接下来,我们比较 test accuracies。虽然我们的理论结果并没有直接谈到 GNNs 的泛化能力,但我们有理由去期待具备强大表征能力的 GNNs 能够准确捕捉感兴趣的图结构,从而能够很好地泛化。Table.1 比较了 GINs(Sum-MLP),其他 GNN 变体以及一些最先进的 test accuracy baselines。

首先,对于 GINs,尤其是 GIN-0,在 9 个数据集上都比较弱的 GNN 变体表现都好。GINs 在社交网络数据集上表现更好,这种类型的数据包含了大量的训练图数据。

而对于 Reddit 数据集,所有节点都共享相同的标量作为节点特征。GINs 以及 sum-aggregation GNNs 都准确地捕获了图结构,并且显著优于其他模型。然而,mean-aggregation GNNs 无法捕获未标记图的任何结构(如 Section 5.2 所预测的一样),并且表现甚至不如随机预测。

即使提供节点的 degree 作为输入特征,基于 mean-aggregation GNNs 也远远不如 sum-aggregation GNNs(在 REDDIT-BINARY 数据集上,mean-mlp aggregation 准确率为 71.2±4.6%,在REDDIT-MULTI5K 准确率为 41.3±2.1%)

比较 GINs(GIN-0 以及 GIN-\(\epsilon\)),我们观察到 GIN-0 的性能略优于 GIN-\(\epsilon\)。由于两种模型都能够很好地拟合训练数据,GIN-0 可能是因为比 GIN-\(\epsilon\) 更简单因此获得了更好的泛化能力。

8 CONCLUSION

在本文中,我们开发了一个关于 GNNs 表征能力推到的理论基础,并证明了当下流行的 GNN variants 的表征能力上限。我们还基于邻域聚合设计了一个可证明的性能最强大的 GNN。未来工作的一个有趣方向是超越邻域聚合(或消息传递),以追求更强大的图学习架构。为了完成这个愿景,理解和改进 GNN 的泛化特性以及更好地理解它们的优化前景也会很有趣。

本文转载于网络 如有侵权请联系删除

相关文章

  • Android自己主动化測试解决方式

     如今,已经有大量的Android自己主动化測试架构或工具可供我们使用,当中包含:ActivityInstrumentation,MonkeyRunner,Robotium,以及Robolectric。另外LessPainful也提供服务来进行真实设备上的自己主动化測试。   Android自身提供了对instrumentation測试的基本支持,当中之中的一个就是位于android.test包内的ActivityInstrumentationTestCase2类,它扩展了JUnit的TestCase类来提供Androidactivities的功能測试。在应用測试中,每个activity首先会被Instrumentation初始化,然后再载入到Android模拟器或设备的Dalvik虚拟机中来运行。   AndroidSDK自带一个測试工具MonkeyRunner,它提供的API和执行环境能够执行Python语言编写的測试代码。它提供API来连接设备,安装/卸载应用,执行应用,截屏,比对图片来推断特定命令执行后的屏幕是否包括预期信息,以及执行相应用的測试。MonkeyRunner使用A

  • EasyDSS/EasyNVR这样的流媒体平台为什么要实现负载均衡?有什么意义?

    负载均衡是一种网络技术,用来在多个计算机(计算机集群)、网络连接、CPU、磁碟驱动器或其它资源中分配负载,以达到最佳化资源使用、最大化吞吐率、最小化响应时间、同时避免过载的目的。在视频服务技术迅速发展的这几年,负载均衡技术更是被应用在了视频平台当中,在分布式系统中,负载均衡作为连接内外的门户,对系统有着重要作用。负载均衡技术视频行业的运用越来越广泛,其中主要有两种:一种是用于安防行业的视频直播,比如通过EasyNVR、EasyGBS建立的公安网系统直播、校园全天候直播、养殖场/渔场监控直播等。在这类场景运用中,不少项目团队都具备几百甚至上千个前端设备的接入量,并且需要在没有客户端的情况下实现视频上传的云存储,而庞大的设备接入量将是一个需要突破的重要方面;另一种是用于在线教育直播或者娱乐直播,比如利用EasyDSS实现的在线教育直播、在线医疗直播、体育赛事赛事直播等。这类直播以庞大的用户访问量为主,可能一台设备的视频流需要承载千万人的同时访问。毫无疑问,这两种情况下,在视频传输、存储及调阅的过程中,都需要考虑视频服务架构的稳定性、可扩容性、负载均衡。因此在这些直播当中,不得不提的一个重要

  • Linux这些年经历了什么?

    今日,Linux基金会在Twitter上发布推文宣布,其小企鹅的标志“Tux”已经30周岁了,还为其设计了一系列的庆祝海报,以便大家转发分享。虽然离Linux的生日还有一段时间,但是今年Linux基金会已经提前先帮小企鹅“Tux”过生日了。在今年4月,Linux还会在其线上商店推出30周年纪念周边。 Tux是Linux的吉祥物,也是Linux和开源社群的象征,想必大家对这个形象不会陌生,据说英国Linux用户组(BritishLUG)甚至在当地的动物园认养了几只企鹅。而Tux的形象在这期间也改版过好几次:不过,虽然推文上是祝Tux生日快乐,但实际上Tux真正确定、并对外公布是在1996年,真正30岁的是Linux(1991年诞生)。 不知不觉,Linux“出道”已经30年了,作为自由软件和开放源代码软件发展中最具代表性的例子,你对它的了解到底有多少?今天我们就一起回首一下,Linux的起源和30年来的重要事件。 1.Linux的诞生说到Linux,就不得不提到Linux之父——LinusTorvalds。用美国《时代》周刊的评价来说,那就是:“有些人生来就具有统帅百万人的领导风范;另一

  • 利用Python来完成屏幕录制

    前段时间做视频时需要演示电脑端的操作,因此要用到屏幕录制,下载了个迅捷屏幕录制,但是没有vip录制的视频有水印且只能录制二分钟,于是鄙人想了下能不能通过万能的python来实现呢?经过一晚上的尝试发现这条路是可以走的通的。分享一下自己的想法,整体思路是PIL模块中的ImageGrab不停的获得当前屏幕,利用opencv写入视频流话不多说,直接上代码,有什么更好的建议,欢迎大家交流!"""python+opencv实现屏幕录制_by-_Zjh_""" fromPILimportImageGrab importnumpyasnp importcv2 p=ImageGrab.grab()#获得当前屏幕 k=np.zeros((200,200),np.uint8) a,b=p.size#获得当前屏幕的大小 fourcc=cv2.VideoWriter_fourcc(*'XVID')#编码格式 video=cv2.VideoWriter('test.avi',fourcc,16,(a,b))#输出

  • 最近频被提及的VR培训,现况究竟如何?

    为什么越来越多人把目光投向VR培训领域?正文共3007字13图;预计阅读时间8分钟VR一直是近些年的热门话题,除了在游戏领域的应用外,VR培训领域也备受关注。如今,VR培训正在被越来越多的行业所运用,比如医疗、教育、军事等方面。甚至有业内人士指出:预计到2022年,VR培训市值将达180亿美元。 那么,为什么越来越多人把目光投向VR培训领域?VR培训现阶段发展状况如何?其实,VR培训的市场需求很大通过VR技术,任何场景几乎都能够被创建、模拟出来。而逼真、互动、情节化的特点,是它独特的魅力所在,正是这些特点让VR可以作为一个强大的培训工具存在着。当然,VR培训既然受到越来越多人的青睐,就必然有着传统培训方式不可替代的优势。安全性:成本和风险低,高危行业需求大利用VR培训,可以打破场地和设备的限制。例如,对于轨道交通、煤矿、安防、航空航天等专业性领域,如果用传统的培训方式,对培训场地和所用设备要求都比较高,成本自然也很高,而且培训过程中还存在发生意外的潜在风险。可见,传统的培训方式显然不能很好地满足高危行业的培训需求,而相比之下,VR培训则不失为一种解决方案。利用VR技术构建培训和控制系统

  • 计算机的启动过程(详细)

    对于使用电脑用户来说,打开电源启动电脑几乎是每天必做的事情,但计算机在显示这些启动画面的时候都在做什么呢?大多数用户都未必清楚。下面就向大家介绍一下从打开电源到出现Windows桌面的蓝天白云,计算机到底都背后干了哪些工作。电脑的启动过程中有一个非常完善的硬件自检机制。对于采用AWARDBIOS的电脑来说,它在上电自检那短暂的几秒钟内,就可以完成100多个检测步骤。首先让我们了解两个基本概念:第一个是BIOS(BasicInputOutputSystem:基本输入输出系统),BIOS实际上就是被"固化"在计算机硬件中、直接与硬件打交道的一组程序,它为计算机提供最低级、最直接的硬件控制。计算机的很多硬件中都有BIOS,最常见的比如:主板(也称为系统BIOS)、显示卡以及其它一些设备(例如IDE控制器、SCSI卡或网卡等)中都存在BIOS,其中系统BIOS是我们要介绍的主角。因为计算机的启动过程是在它的控制下进行的。BIOS程序一般被存放在主板ROM(只读存储芯片)之中,即使在关机或掉电以后,程序也不会丢失。第二个基本概念是内存的地址,通常计算机中安装有32MB、64M

  • 使用sublime text 开发node.js

    http://blog.csdn.net/jwkfreedom/article/details/8450005 本机环境:windows764位 1.下载安装sublimetext, 不用注册即可完全使用,只是偶尔弹框提示购买,完全可以忍受。 2.在sublimetext下按Ctrl+Shift+p 在输入框里输入install,然后选择PackageControl:InstallPackage 3.在接下来的对话框中输入nodejs 我这里已经安装过nodejs相关插件,所以没有显示相关插件。如果没有安装过,会显示nodejs相关插件,请全部安装。 4把build环境设定为nodejs 在SublimeText2菜单-->Tools-->BuildSystem-->Nodejs  5.配置环境  Preferences-->PackageSetting-->Nodejs-->Default  我的配置:   [plain] viewplaincopy  

  • Django-xadmin

    目录Admin列表页配置详情页配置Xadmin1.1.安装1.2.使用1.2.1站点的全局配置1.2.2站点Model管理1.3、xadmin报错 Admin django内置了一个强大的组件叫Admin,提供给网站管理员快速开发运营后台的管理站点。 站点文档:https://docs.djangoproject.com/zh-hans/2.2/ref/contrib/admin/ 辅助文档:https://www.runoob.com/django/django-admin-manage-tool.html 注意:要使用Admin,必须先创建超级管理员.pythonmanage.pycreatesuperuser 复制 访问地址:http://127.0.0.1:8000/admin,访问效果如下: admin站点默认并没有提供其他的操作给我们,所以一切功能都需要我们进行配置,在项目中,我们每次创建子应用的时候都会存在一个admin.py文件,这个文件就是用于配置admin站点功能的文件。 admin.py里面允许我们编写的代码一共可以分成2部分: 列表页配置 主要用于针对项目中各

  • java中变量的内存分配

    java中的变量大体分为:类(静态)变量、成员变量、局部变量,在class文件被jvm的类加载器加载后,随后这些变量被分配至内存中。但是,它们何时被分配至内存的何处呢? jvm把自己运行时管理的内存称为运行时数据区。主要分为栈、堆、方法区,java变量就存在这3个区中。 下表为栈、堆、方法区内存分配情况: 运行时数据区 内存分配时机 分配内容 备注 栈 线程执行方法时 •当前线程中局部基本类型的变量(boolean、char、byte、short、int、long、float、double)•对象引用(非基本类型的对象在JVM栈上仅存放一个指向堆上的地址)•returnAddress......   堆 new创建对象时 •对象实例及其成员变量•数组值 •可以认为Java中所有通过new创建的对象的内存都在此分配•是GC回收的主要区域 方法区 类加载器加载class文件时 •类的信息(名称、修饰符等)•类中的静态变量(从jdk7开始移至堆中)•类中定义为final类型的常量(

  • 友友们

    欢迎添加友链, ?tsjkht@foxmail.com 或者评论区留言 本文来自博客园,作者:泥烟,CSDN同名,转载请注明原文链接:https://www.cnblogs.com/Knight02/p/friends.html

  • YARN

    YARN和MR1的区别: 1、YARN1框架分为资源调度和任务调度,而MR1中都由JobTracker完成。YARN是一个通用的分布式调度系统。 2、MR1的setUp和cleanUp等任务,是在TaskTracker上的任务执行,具体的实现见OutputCommitter。YARN的setUp和cleanUp等任务由AppMaster执行,具体的实现也是OutputCommitter。 3、MR1在资源调度时不灵活。MR1的每个TaskTracker有固定的Map和Reduce槽,每个槽的内存和CPU也是固定的。YARN的资源粒度更小。 4、Yarnchild为抽象的容器,MR1强调任务在独立的JVM进程上运行。 5、Yarnchild直接向AppMaster汇报,而不像MR1需要经过TaskTracker再向JobTracker汇报。 6、AppMaster定时的向ResourceManager发心跳,ResourceManager负责AppMaster的failOver。 7、YARN支持更好的failOver。 其他: 1、MR1、YARN和阿里云的伏羲的failOver恢复都

  • 最短路径与贪婪

    //文章转载自Vamei. 图是由节点和连接节点的边构成的。节点之间可以由路径,即边的序列。根据路径,可以从一点到达另一点。在一个复杂的图中,图中两点可以存在许多路径。最短路径讨论了一个非常简单的图论问题,图中从A点到B点,那条路径耗费最短?   这个问题又异常复杂,因为网络的构成状况可能很复杂。 一个最简单的思路,是找出所有可能的从A到B的路径,再通过比较,来寻找最短路径。然而,这并没有将问题简化多少。因为搜索从A到B的路径,这本身就是很复杂的事情。而我们在搜索所有路径的过程中,有许多路径已经绕了很远,完全没有搜索的必要。比如从上海到纽约的路线,完全没有必要先从上海飞到南极,再从南极飞到纽约,尽管这一路径也是一条可行的路径。 所以,我们需要这样一个算法:它可以搜索路径,并当已知路径包括最短路径时,即停止搜索。我们先以无权网络为例,看一个可行的最短路径算法。   无权网络 无权网络(unweightednetwork)是相对于加权网络的,这里的“权”是权重。每条边的耗费相同,都为1。路径的总耗费即为路径上边的总数。   我们用“甩鞭子”的方式,来寻找最短

  • 自定义控件开发知识点

    声明:部分代码及图片来自:http://www.cnblogs.com/holywolf/archive/2008/12/15/1355299.html 1.自定义控件开发,需要继承Control(在System.Web.UI命名空间下)或WebControl(在System.Web.UI.WebControls命名空间下)或CompositeControl(在System.Web.UI.WebControls命名空间下) 2.重写CreateChildControls方法(ascx不一定要重写),该类在Control类上定义,此方法用于创建控件层次,以便为回发和呈现做准备。 3.重写父类的Render方法,在该方法中将服务器控件的内容传递给HtmlTextWriter对象以在客户端呈现内容 更多说明点击:http://msdn.microsoft.com/zh-cn/library/ms178472.aspx#lifecycle_events ===================以上是开发自定义控件必须要做的========================= 4.在.NET中,Sy

  • 第十一节,FTP,虚拟用户

    虚拟用户,区别于本地用户,只适用于FTP的用户 可以更加细化操作   1.关防火墙 2.装包 3.改配置文件,但是最好先备份   备份: mv /etc/vsftpd/vsftpd.conf  /etc/vsftpd/vsftpd.conf.bak vim /etc/vsftpd/vsftpd.conf 输入下面内容 *********************************** anonymous_enable=NO local_enable=YES write_enable=YES local_umask=022 dirmessage_enable=YES xferlog_enable=YES xferlog_file=/var/log/vsftpd.log connect_from_port_20=YES xferlog_std_format=YES ascii_upload_enable=YES ascii_download_enable=YES   chroot_local_user=YE

  • 英语词组/短语-20211223

    mutualunderstanding相互理解 thesourceoftheriver河流的源头 accidentalfall意外摔倒/跌倒 culturalsymbol文化元素/符合 ahugepit大坑 makeamistake犯错 theperformanceofthecontestant参赛者的表演 adominantposition主导地位 marketshare市场份额 beavailabletodosth.可以做某事 bereluctanttodosth.不情愿做某事 本文来自博客园,作者:草叶睡蜢,转载请注明原文链接:https://www.cnblogs.com/tjubuntu/p/15761206.html

  • 20170710总结

    今天是数据结构的最后一天。上午考试一反常态,花式翻车。T1是签到水题,居然没开longlong,int爆成负;T2T3用的是I64d(调试为windows下),考试为linux下,应该用lld,爆零了。T2是一个splay的版题,但是因为对翻转操作不熟悉,没有写正解。看来得多写写splay,因为比较好写又灵活的平衡树就是splay了(当然,treap也算)。T3写了一个玄学的值域主席树优化,虽然最坏复杂度还是O(n^2),但是如果值域范围小,在10000以内都能过,因而我Task3和Task4都过了一半以上,可惜是子任务,不然就赚了。T3正解是分块,不太好写。隔壁小胖学长说是莫队,而且他的程序碾压标程,三项都比标程好,,ԾㅂԾ,,...莫队大法好 下午先讲了树链剖分,然后讲了一些数据结构杂题。杂题的思维难度都比较高,而且根本看不出和数据结构有什么联系。个人认为,数据结构其实就是工具,和解题方法无关,方法归方法,数据结构只是在解题的时候进行优化。除了版题以外,对于其他数据结构题,想的时候还是不要使劲往数据结构上靠,应该先全面想,再在局部用数据结构优化,这样才能打开思维。

  • 大数据存储技术基础

    一、绪论 1.存储的本质 信息跨越空间的传递——通讯  信息跨越时间的传递——存储 通讯:利用具有跨越空间特性的物理现象---声音、光、电 存储:利用具有时间稳态的物理现象---物理稳态、磁稳态、半导体稳态 什么是存储? 存储: ·它是数据临时或长期驻留的物理媒介;·它是保证数据完整安全存放的方式或行为。 计算机存储系统: 指计算机中由存放程序和数据的各种存储设备(介质)、控制部件与接口及管理信息调度的设备(硬件)和算法(软件)所组成的系统。 存储的主要指标: 容量:可以存下多少东西 速度:读写带宽、读写次数/秒(IOPS) 持久性:数据能够保存多久大小:体积是多少 方便性:是否方便移动和携带 功耗:消耗能耗高低 性价比:单位价格下主要指标如何,例如速度、容量等指标;  1.1存储介质的发展历程 (1)存储的历史 象形文字、石刻楔形文字、竹简、纸质印刷 现在进入“磁器时代”,大部分数据都是用硬盘保存,磁盘称为当今世界数据存储的主流技术 存储器设备:计算机系统中的记忆设备,用来存放程序和数据  (2)存储器的发展 存储器类别:打孔纸卡、穿孔纸带、威廉管、

  • Hihocoder-小Hi的烦恼

    解题思路: 其实题目自带的题解已经交代的比较清楚了。但是如果完全按照题目自带的解法来计算,肯定是会超时的。因为无论如何还是O(n^2)的解法,当然也可能是彩笔我比较菜只能写出这样的。 所以需要一些转换。 这个题目给的内存空间为1024M,显然我们要用空间换时间了。 就以单个科目为例吧。假设a[i]表示第i个学生在语文这个科目上的排名,index[a[i]]=i表示语文排名为a[i]的是第i个学生。这个时候,设置bitset<maxn>yuwen[maxn],其中yuwen[i]表示在语文成绩排名为i的前面的学生集合。 所以可以O(n)得到整个yuwen集合,然后再利用前面索引出来的index,就可以整体O(n)的求出结果了。 代码: #include<bits/stdc++.h> usingnamespacestd; constintmaxn=3e4+5; inta[maxn][5],inx[maxn][5]; bitset<maxn>bs[maxn][5],ans; intmain(){ ios::sync_with_stdio(fals

  • windows主机网络信息获取程序设计

    掌握windows系统获取网络信息的各种API函数的功能与调用方法,掌握设计程序显示获取到相关网络信息的方法,掌握网络字节数据与主机字节数据之间的转换。掌握这些API函数调用的错误处理方法。 利用本地网络信息开发接口IPHelperAPI编写主机网络信息获取程序依实现获取网络的配置信息、管理网络适配器和获取相关信息、管理网络接口和获取相关信息、获取IP和ICMP中的信息、管理路由信息和获取arp信息、接收TCP和UDP信息等的目的。 1.使用ipconfig获取本地网络信息 在cmd中使用ipconfig命令获取网络信息,结果见最后贴图  2.利用IPHelperAPI获取本地网络适配器信息 编写获取本地网络信息的程序,代码如下: #include "stdafx.h" #pragma comment(lib,"IPHLPAPI.lib") #include <winsock2.h> #include <iphlpapi.h> #include <stdio.

  • Jenkins部署项目到Docker容器

    背景 一个负责数据清洗的项目,以Kafka消费者的方式接受数据并处理。当消费数据数量过多时,要对项目进行性能优化。 优化方式:服务器通过部署多个项目增加项目进程的方式增加Kafka消费者的数量。每个进程里使用线程池异步做业务处理。 环境 Ubuntu18 Java8 Jenkins 前置条件 Jenkins安装完成 Jenkins配置关键点 上传项目jar包及Dockerfile文件到服务器 上传文件后,自动执行脚本文件 步骤 打开Jenkins页面,选择项目进行部署配置,基本配置网上一大把,这里只会详细说明Jenkins构建后操作,如下图 发送服务器文件(Sourcefiles):项目打包完成,所有文件都会存在target目录下 项目jar包:项目构建的jar包 Dockerfile文件:Docker构建镜像基本配置,这个文件位置,你可以自己决定,Dockerfile文件内容如下 #该镜像需要依赖的基础镜像 FROMjava:8 #COPY:将应用的配置文件复制到docker容器的/目录下 #此处作用:将当前目录下所有jar合并打包到docker根目

  • Java抽象类

    一、抽象类相关的概念     如果一个类中没有包含足够的信息来描绘一个具体的对象,这样的类就是抽象类。     用abstract修饰的类就是抽象类。如果某个类中包含有抽象方法,那么该类就必须定义成抽象类。但是抽象类中不一定有抽象方法。           publicabstractclassShapes{                 publicabstractvoiddraw();}     用abstract修饰的类就是抽象类。如果某个类中包含有抽象方法,那么该类就必须定义成抽象类。      抽象类可以有成员属性和非抽象的成员方法。      抽象类不能被实例化,但可以有构造函数。      抽象类只能用作基类,表示的是一种继承关系。继承抽象类的非抽象类必须实现其中的所有抽象方法,而已实现方法的参数、返回值要和抽象类中的方法一样。否则,该类也必须声明为抽象类。 二、抽象方法      在某些情况下,类无法(或者没有必要)提供方法的具体实现,可以将此方法声明成抽象方法;     &nb

相关推荐

推荐阅读