论文来源:In The 25th ACM SIGKDD Con ference on Knowledge Discovery and Data Mining (KDD ’19), August 4–8, 2019, Anchorage, AK, USA. ACM, New York, NY, USA, 10 pages.
作者:Wei-Lin Chiang
论文题目:Cluster-GCN: An Efficient Algorithm for Training Deep andLarge Graph Convolutional Networks
论文题目(中文):GCN聚类:一种用于训练深度大型图卷积网络的高效的算法
使用聚类算法标识密集子图相关联的节点块,限制密集子图的领域搜索。该策略在同等精度的情况下,提高了内存和计算的效率。
4. 实验
数据集:
1) Amazon2M,200万个节点和6100万条边,是Reddit的5倍
2) Reddit
3) PPI
网络:
1) Cluster-GCN
2) VR-GCN
3)GaAN
数据集 Cluster-GCN VR-GCN
计算量 内存\GB 计算量 内存\GB
3-layer GCN Amazon2M 1523s 2.2 1961s 11.2
4-layer GCN Amazon2M 36m - Fail Fail
其中 是所有 个节点在第 层的嵌入,并且 ; 是归一化和正则化的邻接矩阵 是特征转换矩阵,将为下游任务学习。请注意,为简单起见,我们假设所有图层的特征尺寸均相同 。激活函数 通常设置为元素方式ReLU。
半监督节点分类是GCN的流行应用。 当将GCN用于此应用程序时,目标是通过最小化损失函数来学习(1)中的权重矩阵:
其中 包含标记节点的所有标记; 是 的第 行,其真实标签为 ,指示节点 的最终层预测。 在实践中,交叉熵损失通常用于多类或多标签问题中的节点分类。
3 提出的算法
我们首先讨论先前训练方法的瓶颈来激励提出的算法
表1:GCN训练算法的时间和空间复杂度。 是层数, 是节点数, 是邻接矩阵中的非零数, 是特征数。为简单起见,我们假设所有图层的特征数量都是固定的。对于基于SGD的方法, 是批处理大小, 是每个节点的采集的邻点数。请注意,由于采用了方差减少技术,因此VR-GCN的 可以小于GraphSAGE和FastGCN。对于内存杂度, 用于存储 ,而另一项用于存储嵌入节点。为简单起见,我们省略了用于存储图形(GCN)或子图形(其他方法)的内存,因为它们是固定的,通常不是主要瓶颈。
在原始论文[9]中,全梯度下降用于训练GCN,但是它具有很高的计算和存储成本。在存储器方面,通过反向传播来计算(2)的全梯度需要存储所有需要 空间的嵌入矩阵 。 在收敛速度方面,由于每个时期仅更新一次模型,因此训练需要更多时期来收敛。
研究表明,在最近的一些工作中,mini-batch SGD可以提高GCN的训练速度和内存需求。SGD不需要计算完整的梯度,而只需要基于每次更新的小批量计算梯度。 在本文中,我们使用 ,大小为 。 表示一批节点索引,并且每个SGD步骤将计算梯度估计
去执行更新。尽管在历元方面收敛更快,但SGD将在GCN训练上引入另一种计算开销(如下文所述),这使其与全梯度下降相比,其每历时时间要慢得多。
为什么vanilla mini-batch SGD的每个时期时间较慢? 我们考虑与一个节点 关联的梯度的计算: 。 显然,这需要嵌入节点 ,这取决于其在上一层中邻居的嵌入。 要获取我的邻居节点的嵌入的每个节点,我们还需要进一步汇总每个邻居节点的邻居的嵌入。 假设GCN具有 层,并且每个节点的平均度为 ,要获得节点 的梯度,我们需要为一个节点聚合图中 个节点的特征。 也就是说,我们需要获取图中节点 邻居的信息,以执行一次更新。 由于与 相乘,因此计算每个嵌入需要 时间,因此在平均计算中,与一个节点关联的梯度需要 时间。
嵌入利用率可以反映计算效率。 如果一批中有多个节点,那么时间复杂度就不那么直接了,因为不同的节点可能具有重叠的Hopk邻居,并且嵌入计算的次数可以小于最坏情况 。 为了反映mini-batch SGD的计算效率,我们定义了“嵌入利用率”的概念来表征计算效率。 在算法过程中,如果将节点 嵌入在第 层 中,并且将 重复使用 次以进行 层的嵌入计算,那么我们说 的嵌入利用率是 ,对于随机采样的mini-batch SGD,由于图通常是大而稀疏的,所以 非常小。假设 是一个很小的常数(hop- 几乎没有重叠),然后mini-batch SGD计算每个epoch需要 嵌入, 这导致每次更新的 时间和每个epoch的 时间。
我们在图1的左面板中说明了邻域扩展问题。相反,全批次梯度下降具有最大的嵌入利用率-每个嵌入将在上层重复 (平均度)次。 结果,原始的全梯度下降[9]仅需要计算每个时期的 个嵌入,这意味着平均而言,仅 嵌入计算就可以获取一个节点的梯度。
为了使小批量SGD工作,以前的方法试图限制邻域扩展的大小,但是并不能提高嵌入利用率。 GraphSAGE [5]统一采样一个固定大小的邻居集,而不是使用完整邻居集。 我们将样本量表示为 。 这导致每个损失项的 嵌入计算,但也使得梯度估计的准确性降低。 FastGCN [1]提出了一种重要的采样策略来改善梯度估计。 VR-GCN [2]提出了一种策略,用于存储所有 个节点和L层的先前计算的嵌入,并将其重新用于未采样的邻居。
尽管用于存储所有 个嵌入的内存使用量很高,但我们发现它们的策略非常有用,并且在实践中,即使对于较小的 (例如2)也可以导致良好的收敛。 我们在表1中总结了时间和空间复杂度。显然,所有基于SGD的算法在层数方面都面临指数复杂性,对于VR-GCN,即使r很小,它们也会产生巨大的空间复杂性, 可能会超出GPU的内存容量。 在下文中,我们介绍了Cluster-GCN算法,该算法实现了两个世界中的佼佼者-每个历元的时间复杂度和完全梯度下降的时间相同,而vanilla SGD的存储复杂度也相同。
3.1 Vanilla Cluster-GCN
我们的Cluster-GCN技术受到以下问题的激励:在小型批处理SGD更新中,我们可以设计批处理和相应的计算子图以最大程度地提高嵌入利用率吗? 我们通过将嵌入利用的概念与聚类目标联系起来来回答这一肯定的问题。
考虑到以下情况:在每个批次中,我们计算从第1层到 的一组节点 的嵌入。由于同一子图 ( 内的链接)用于计算的每一层,因此我们可以看到嵌入利用率 是该批次 中的边数。因此,为最大化嵌入节点的效率,我们应该设计批次 去最大化批内边缘通过这种方法,我们可以将SGD更新的效率与图聚类算法联系起来。
现在我们正式介绍Cluster-GCN。 对于图 ,我们将其节点划分为 个组: ,其中 由第 个分区中的节点组成。 因此,我们有 个子图,
,
其中每个 仅由 中节点之间的链接组成。 重组节点后,将邻接矩阵划分为 个子矩阵,如下
每个对角矩阵块 是包含在 是 的邻接矩阵。 是图 的邻接矩阵, 包含两个分区 和 的链接; 是包含 的对角块的矩阵。类似地,我们可以根据分区 将特征矩阵 和训练标签 分区为 和 ,其中 和 分别由 中的节点的特征和标签组成。
这种块对角近似 的好处是GCN的目标函数可分解为不同的批次(簇)。 令 表示 的归一化版本,由于 的块对角形式(记 是 对应的对角块),最终的嵌入矩阵变为
损失函数可以分解为:
。
然后,Cluster-GCN基于(6)和(7)中的分解形式。 在每个步骤中,我们对一个簇 进行采样,然后根据 的梯度进行SGD更新,这仅需要当前批次的子图 , , 和模型 。 该实现只需要矩阵乘积的前向和后向传播,比以前的基于SGD的训练方法中使用的邻域搜索过程更容易实现。
我们使用图聚类算法对图进行分区。 图聚类方法(例如Metis [8]和Graclus [4])旨在在图的顶点上构建分区,以使聚类内的链接比聚类间的链接更多,以更好地捕获聚类和社区结构。 图。 这些正是我们需要的,因为:1)如前所述,嵌入利用率等于每个批次的集群内链接。 直观地讲,每个节点及其邻居通常位于同一群集中,因此经过几跳之后,几率很高的邻居节点仍位于同一群集中。 2)由于我们用块对角线近似值 代替 ,并且误差与簇间链接 成正比,因此我们需要找到一个分区以使簇间链接的数量最小。
在图1中,我们说明了具有全图 和具有聚类分区 的图的邻域展开。 我们可以看到cluster-GCN可以避免繁重的邻域搜索,而将注意力集中在每个集群内的邻点上。 在表2中,我们显示了两种不同的ent节点分区策略:随机分区与群集分区。 我们通过使用随机分区和METIS将图分为10个部分。 然后将一个分区作为批处理执行SGD更新。 我们可以看到,在相同的纪元数下,使用聚类分区可以获得更高的准确性。 这表明使用图聚类很重要,并且不应随机形成分区。
时间和空间的复杂性。 由于 中的每个节点仅链接到 内部的节点,因此每个节点无需在 外部执行邻点搜索。 每一批的计算将纯粹是矩阵乘积 和一些按元素进行的运算,因此每批的总时间复杂度为 。 因此,每个时期的总时间复杂度变为 。 平均而言,每批只需要计算 嵌入,它是线性的,而不是L的指数。就空间复杂度而言,在每批中,我们只需要加载b个样本并将其嵌入存储在每一层上,结果 在 内存中用于存储嵌入。 因此,我们的算法比所有以前的算法都具有更高的内存效率。 此外,我们的算法仅需要将子图加载到GPU内存中,而不是整个图(尽管图通常不是内存瓶颈)。 表1总结了详细的时间和内存复杂性。
表2:图的随机分区与聚类分区(在小批量SGD上进行训练)。 集群分区可以消除分区间链接,从而提高性能(根据测试F1分数)。 这三个数据集都是公共GCN数据集。 我们将在实验部分解释PPI数据。 Cora具有2,708个节点和13,264个边缘,而Pubmed具有19,717个节点和108,365个边缘。
图2:基于la bel分布的熵值直方图。 在这里,我们在每个批次中使用随机分区与聚类分区。 大多数聚类分区的批次具有较低的标签熵,表明每个批次内的标签分布偏斜。 相比之下,随机分配将导致批处理中较大的标签熵,尽管如前所述效率较低。 在此示例中,我们将Reddit数据集划分为300个簇。
3.2 Stochastic Multiple Partitions
虽然vanilla Cluster-GCN实现了很好的计算量和内存复杂度,仍然还有两个潜在的问题。
在图分区之后,一些线被移除,因此会受到影响。
图聚类算法倾向于将相似节点聚在一起。因此,集群的分布可能与原始数据集不同,导致在执行SGD更新时对整个梯度进行有偏差的估计。
在图2中,我们通过使用Redtis数据和Metis形成的簇来演示不平衡标签分布的示例,并根据其簇的标签分布计算每个簇的熵值。 与随机分区相比,我们清楚地看到大多数簇的熵较小,这表明簇的标签分布偏向某些特定标签,这增加了不同批次之间的方差,并可能影响SGD的收敛。
为了解决上述问题,我们提出了随机聚类算法合并集群之间的链接,并减少不同批次的差异。我们首先将图分为 类 ,其中 相对较大。只为SGD更新构建批处理 时,不只是考虑一个集群,我们随机的选择 个集群,表示为 并且包括他们的节点 在这个批次。此外,所选集群之间的链接
被添加进区块。图3展示了我们的算法-对于每个时期,将选择不同的群集组合作为批次。 我们在Reddit上进行了一项实验,以证明该方法的有效性。 在图4中,我们可以观察到将多个群集作为一批使用可以改善收敛。 我们的最终Cluster-GCN算法在算法1中给出。
3.3 训练深度GCNs的问题
先前训练更深的GCN的尝试[9]似乎暗示增加更多的层是无济于事的。 但是,实验中使用的数据集可能太小而无法给出适当的理由。 例如,[9]考虑了只有数百个训练节点的图,对于它们而言,过拟合可能是一个问题。 此外,我们观察到深层GCN模型的优化变得困难,因为这可能会阻碍前几层的信息传递。 在[9]中,他们采用类似于残差连接[6]的技术,以使模型能够将信息从上一层传送到下一层。 具体来说,他们修改(1),将第1层的隐藏表示添加到下一层。
在这里,我们提出了另一种简单的技术来改善深层GCN的训练。 在原始GCN设置中,每个节点都汇总前一层的邻居表示。 但是,在深层GCN的背景下,该策略可能不适合,因为它没有考虑层数。 凭直觉,附近的邻居应该比远处的节点贡献更多。 因此,我们提出了一种更好地解决此问题的技术。该想法是放大每个GCN层中使用的邻接矩阵 的对角线部分。 这样,我们在每个GCN层的聚合中将更多的权重放在前一层的表示上。 一个示例是如下向 添加身份。
尽管式(9)似乎是合理的,但对所有节点使用相同的权重而不考虑其邻居数可能不适合,而且,当使用更多层时,值可能呈指数增长,因此可能会出现数值不稳定性。 因此,我们提出(9)的修改版本,以更好地维护邻域信息和数值范围。 我们首先将一个身份添加到原始A并执行规范化
然后考虑
在第4.3节中介绍了采用“对角增强”技术的实验结果,我们证明了这种新的规范化策略可以帮助构建更深的GCN并实现SOTA性能。
4实验
我们评估了在两个任务上训练GCN的拟议方法:对四个公共数据集进行多标签分类和多分类。数据集的统计信息如表3所示。请注意,Reddit数据集是迄今为止我们所看到的最大的GCN公共数据集,并且Amazon2M数据集是我们自己收集的,并且比Reddit更大。
在比较中,我们包括以下最新的GCN培训算法:
表3:数据统计
表4:实验中用的参数
Cluster-GCN(我们提出的算法):提出的快速GCN训练方法。
VRGCN3 [2]:它维护了图中所有节点的历史嵌入,并扩展到仅几个邻居以加快训练速度。 如[2] 4中所建议的,将采样的邻居数设置为2。
GraphSAGE5 [5]:它对每个节点采样固定数目的邻居。 我们在GraphSAGE中为每一层使用默认的采样大小设置(S1 = 25,S2 = 10)。
我们在PyTorch[13]中实现了我们的方法。对于其他方法,我们使用其github页面上所有原始论文的代码。由于[9]很难缩放到大图,因此在此我们不进行比较。同样如[2]所示,VRGCN比FastGCN更快,因此在此我们不与FastGCN进行比较。对于所有方法,我们使用Adam优化器,其学习率为0.01,辍学率为20%,权重衰减为零。采用[5]提出的均值聚合器,所有方法的隐藏单元数均相同。请注意,此处不考虑(11)之类的技术。在每个实验中,我们为所有方法考虑相同的GCN架构。对于VRGCN和GraphSAGE,我们遵循原始论文提供的设置,并将批大小设置为512。对于Cluster-GCN,表4列出了每个数据集的每批分区和集群的数量。请注意,集群被视为培训中不考虑预处理步骤及其运行时间。在第6节中,我们展示了图聚类仅需要一小部分预处理时间。所有实验均在配备NVIDIATeslaV100GPU(16GB内存),20核IntelXeonCPU(2.20GHz)和192GBRAM的计算机上进行。
4.1 中等数据大小的训练性能
训练时间vs准确度:首先,我们在训练速度方面将我们提出的方法与其他方法进行了比较。 在图6中,x轴显示训练时间(以秒为单位),y轴显示验证集的准确性(F1得分)。 我们绘制了具有2、3、4层GCN的三个数据集的训练时间与准确性的关系。 由于GraphSAGE比VRGCN和我们的方法慢,因此GraphSAGE的曲线仅出现在PPI和Reddit数据集中。 我们可以看到,对于具有不同层数的GCN,我们的方法对于PPI和Reddit数据集都是最快的。
表5:比较不同数据集上的内存使用情况。 括号中的数字表示模型中使用的隐藏单位的大小。
表6:在PyTorch和TensorFlow中进行稀疏Tensor操作的基准测试。 使用具有两个线性层的网络,并且时序包括正向和反向操作。 括号中的数字表示第一层中隐藏单元的大小。 使用亚马逊数据。
对于Amazon数据,由于节点的要素不可用,因此将同一个矩阵用作要素矩阵 。在此设置下,参数矩阵 的形状变为334863x128。 因此,计算主要由稀疏矩阵运算(例如 )主导。 对于3层情况,我们的方法仍比VRGCN快,但对于2层和4层方法,则较慢。 原因可能来自不同框架的稀疏矩阵运算速度.VRGCN在TensorFlow中实现,而Cluster-GCN在PyTorch中实现,其稀疏张量支持仍处于早期阶段。 在表6中,我们显示了TensorFlow和PyTorch对Amazon数据进行正向/反向操作的时间,并且使用了一个简单的两层网络来对两个框架进行基准测试。 我们可以清楚地看到TensorFlow比PyTorch更快。当隐藏单元的数量增加时,差异会更大。 这可以解释为什么Cluster-GCN在Amazon数据集中的训练时间更长。
内存使用比较:内存使用情况比较:对于训练大型GCN,除了训练时间外,训练所需的内存使用情况还重要十倍,这将直接限制可伸缩性。 内存使用情况包括训练GCN多个时期所需的内存。 如第3节所述,为了加快训练速度,VRGCN需要在训练过程中保存历史嵌入,因此与Cluster-GCN相比,VRGCN需要更多的训练内存。 由于指数邻域增长问题,GraphSAGE也比Cluster-GCN具有更高的内存要求。 在表5中,我们将内存使用情况与VRGCN不同层的GCN的内存使用情况进行了比较。 当增加层数时,Cluster-GCN的内存使用不会增加很多。 原因是当增加一层时,引入的额外变量是权重矩阵 ,与子图和节点特征相比,该矩阵较小。 虽然VRGCN需要保存每一层的历史记录嵌入,但是这些嵌入通常很密集,并且很快将占据内存使用量。 从表5中可以看出,Cluster-GCN比VRGCN具有更高的内存效率。 例如,在Reddit数据上训练隐藏维度为512的4层GCN时,VRGCN需要2064MB内存,而Cluster-GCN仅使用308MB内存
表7:Amazon2M中最常见的类别。
4.2 在Amazon2M上的实验结果
一个新的数据集:Amazon2M。到目前为止,用于测试GCN的最大的公共数据是Reddit数据集,其统计信息如表3所示,其中包含约200K节点。如图6所示,可以在几百秒内完成对这些数据的GCN训练。为了测试GCN训练算法的可扩展性,我们基于亚马逊共同购买网络构建了一个更大的图,该图包含200万个节点和6100万个边缘[11,12]。原始共同购买数据来自Amazon-3M6。在图中,每个节点都是一个产品,并且图中的链接表示是否同时购买了两个产品。每个节点的功能都是通过从产品描述中提取词袋功能,然后进行主成分分析[7]来将尺寸缩小为100来生成的。此外,我们将顶级类别用作该产品/节点(有关最常见的类别,请参见表7)。表3列出了该数据集的详细统计信息。
在表8中,我们将VRGCN与具有不同层数的GCN的VRGCN进行了比较,包括训练时间,内存使用情况和测试准确性(F1得分)。 从表中可以看出:
1) VRGCN比带有2层GCN的Cluster-GCN快,但是在增加一层且达到类似精度时,它比Cluster-GCN慢。
2) 在内存使用方面,VRGCN使用的内存比Cluster-GCN多得多(对于3层情况,是5倍),并且在训练4层GCN时会耗尽内存,而Cluster-GCN不需要 增加层数时会增加很多内存,并且在训练4层GCN时可以达到此数据的最佳准确性。
4.3 训练深度GCN
在本节中,我们考虑具有更多层的GCN。 我们首先在表9中显示Cluster-GCN和VRGCN的时序比较。PPI用于基准测试,两种方法都运行200个纪元。我们观察到VRGCN的运行时间呈指数增长,这是因为VRGCN昂贵的邻域查找能力,而运行 Cluster-GCN的时间仅线性增长。
接下来,我们研究使用更深的GCN是否可以获得更好的准确性。 在第4.3节中,我们讨论了修改邻接矩阵A以便于训练深层GCN的不同策略。我们将对角线增强技术应用于深层GCN并且在PPI上运行实验。
表8:Amazon2M的运行时间,内存和测试准确性(F1分数)的比较。
图5:8层GCN上的收敛图。 我们展示了历元数(x轴)与验证准确性(y轴)。 除使用(11)的方法外,所有方法均无法融合。
表9:使用不同数量的GCN图层时的运行时间比较。 我们使用PPI并将这两种方法都运行200个纪元。
表10:最新论文中报告的最新的测试准确性。
结果显示在表11中。对于2到5层的情况,所有方法的准确性都会随着添加的层数的增加而增加,这表明更深的GCN可能有用。但是,当使用7或8个GCN层时,前三种方法无法在200个纪元内收敛,并且会大大降低精度。可能的原因是针对更深层GCN的优化变得更加困难。我们在图5中显示了一个8层GCN的详细收敛性。利用提出的对角线增强技术(11),可以显着改善收敛性,并且可以实现类似的精度。
训练更深的GCNs得到的最后的结果。通过Cluster-GCN的设计和提出的归一化方法,我们现在能够训练更深的GCN以达到更好的准确性(F1分数)。 我们将测试的准确性与表10中其他现有方法进行了比较。对于PPI,Cluster-GCN可以通过训练具有2048个隐藏单元的5层GCN来获得最新的结果。 对于Reddit,使用具有128个隐藏单元的4层GCN。
5总结
我们提出了ClusterGCN,这是一种新的GCN训练算法,该算法快速且内存高效。 实验结果表明,该方法可以在大型图上训练非常深的GCN,例如在节点数超过200万的图上,使用2G内存和实现90.41的准确度(F1分数)的训练时间不到一个小时。使用提出的方法,我们能够成功地训练更深的GCN,从而在PPI和Reddit数据集上达到更好的测试F1分数。
表11:使用不同对角线增强技术的比较。 对于所有方法,我们提出了200个纪元内达到的最佳验证精度。 在此实验中使用PPI,辍学率为0.1。 其他设置与4.1节相同。 标记为红色的数字表示收敛性较差。
图6:不同的GCN训练方法的比较。 我们介绍了以秒为单位的训练时间(x轴)与运动F1得分(y轴)之间的关系。
表12:实验中使用的训练,验证和测试拆分。 请注意,对于两个亚马逊数据集,我们仅分为训练集和测试集。
表13:在训练GCN之前,图聚类算法(METIS)的运行时间和数据预处理。