图卷积网络(GCN)

mac2024-04-21  6

一、GCN的理解

关于GCN的学习主要是基于 Semi-Supervised Classification with Graph Convolutional Networks 这篇论文和网上的一些博客。

GCN的提出

图结构每个节点的相邻节点的数量是不确定的,因此用来处理欧几里得空间数据的常规CNN无法对其进行特征的提取,因此有了图卷积网络(Graph Convolutional Network, GCN)来对图中的节点进行特征提取。

GCN简介

GCN的输入包括 N ∗ N N * N NN( N N N是节点的数量)的邻接矩阵 A A A N ∗ C N * C NC( C C C是每个节点特征的数量)的特征矩阵 X X X,输出每个节点的特征F(它的维度是 N ∗ C o u t p u t N * C_{output} NCoutput).

GCN的设计理念

我理解的GCN的设计理念和CNN有很大相似之处: 局部特征和权值共享。

图像里的局部特征是指邻域的特征,图结构的局部特征是指相连节点的特征,这里是通过 A X AX AX 获得。

F = A X = { a 11 a 12 ⋯ a 1 n a 21 a 22 ⋯ a 2 n ⋮ ⋮ ⋱ ⋮ a n 1 a n 2 ⋯ a n n } ∗ { x 11 x 12 ⋯ x 1 c x 21 x 22 ⋯ x c ⋮ ⋮ ⋱ ⋮ x n 1 x n 2 ⋯ x n c } F = AX = \left\{ \begin{matrix} a_{11} & a_{12} & \cdots & a_{1n} \\ a_{21} & a_{22} & \cdots & a_{2n} \\ \vdots & \vdots & \ddots & \vdots \\ a_{n1} & a_{n2} & \cdots & a_{nn} \end{matrix} \right\} * \left\{ \begin{matrix} x_{11} & x_{12} & \cdots & x_{1c} \\ x_{21} & x_{22} & \cdots & x_{c} \\ \vdots & \vdots & \ddots & \vdots \\ x_{n1} & x_{n2} & \cdots & x_{nc} \end{matrix} \right\} F=AX=a11a21an1a12a22an2a1na2nannx11x21xn1x12x22xn2x1cxcxnc

F i j = a i 1 x 1 j + a i 2 x 2 j + ⋯ + a i n x n j F_{ij} = a_{i1}x_{1j} + a_{i2}x_{2j} + \cdots + a_{in}x_{nj} Fij=ai1x1j+ai2x2j++ainxnj

可以看到第 i i i个节点的第 j j j个特征是由第 i i i个节点的相邻节点的第 j j j个特征相加得到,这与CNN的局部特征类似。

但是这种操作会带来两个问题,一是它并没有考虑自身节点的特征,因此需要对邻接矩阵做如下处理:

A ~ = A + I \tilde A = A + I A~=A+I

二是,可能会导致节点的特征的量级不一样,比如假如节点1有10,000个相邻节点,而节点10有1个相邻节点,那么会导致节点1的特征是10,000个相邻节点特征的和,而节点10的特征是1个相邻节点的特征的和,这会导致不同节点的特征量级不一样。这个可以通过对特征除以节点的度进行处理,矩阵的形式就是:

D ~ A ~ X \tilde D \tilde A X D~A~X

D ~ \tilde D D~ A ~ \tilde A A~的节点的度构成的对角矩阵。

论文中的GCN layer的结构是:

F = G C N ( A , X ) = σ ( D ~ − 1 2 A ~ D ~ − 1 2 X W ) F = GCN(A, X) = \sigma(\tilde D^{-\frac{1}{2}} \tilde A \tilde D^{-\frac{1}{2}}XW) F=GCN(A,X)=σ(D~21A~D~21XW)

其中 W W W是待学习的参数, σ \sigma σ是激活函数.

三、实现的代码

基于PyTorch复现的代码已上传至https://github.com/zhulf0804/GCN.PyTorch

F = G C N ( A , X ) = D ~ − 1 2 A ~ D ~ − 1 2 R e L U ( D ~ − 1 2 A ~ D ~ − 1 2 X W 1 ) W 2 F = GCN(A, X) = \tilde D^{-\frac{1}{2}} \tilde A \tilde D^{-\frac{1}{2}} ReLU(\tilde D^{-\frac{1}{2}} \tilde A \tilde D^{-\frac{1}{2}}XW_1)W_2 F=GCN(A,X)=D~21A~D~21ReLU(D~21A~D~21XW1)W2

网络结构 两个GCN层,第一个GCN层的激活函数是ReLU,且第一层的参数添加L2正则化(weight_decay=5e-4),第二个GCN层没有激活函数,也不添加L2正则化。Dropout设置为0.5,中间层的dim是16。Loss函数是交叉熵损失函数,学习方法是Adam算法,学习率设置为固定的0.01。

半监督学习 在训练中使用半监督学习。半监督学习利用无标签数据来提高监督学习的性能,即同时使用有标签的数据和无标签的数据。在GCN里表现为,所有的数据(V(边), E(节点))都参与训练,但每类只包含特定个数(这里使用的是20个)有标签的数据,其它的数据也参与训练但无标签,在计算损失函数的时候只考虑带有标签的数据。详细配置请查看实验结果部分。

四、实验结果

在数据集citeseer, cora,pubmed上进行了训练和测试。

1. 数据集简介

这是三个文本分类数据集,官网链接。每个数据集都包含文档的bag-of-words表示和文档的引用链接(citation links)。Bag-of-words表示为一个由0, 1组成的高维特征向量,0表示不包含这个word,1表示包含这个word。基于引用链接构建了来构建图:如果文档 i i i引用了 j j j,则 a i j = a j i = 1 a_{ij} = a_{ji} = 1 aij=aji=1。Citeseer, cora和pubmed数据集分别包含6,7和3类数据,类别名称如下所示。

citeseer: Agents, AI, DB, IR, ML, HCIcora: Case_Based, Genetic_Algorithms, Neural_Networks, Probabilistc_Methods, Reinforcement_Learning, Rule_Learning, Theorypubmed: Diabetes_Mellitus_Experimental, Diabetes_Mellitus_Type_1, Diabetes_Mellitus_Type_2

更详细的数据信息如下

训练集、验证集和测试集的划分和https://github.com/tkipf/gcn一样,详细信息如下表所示。

DatasetNodesEdgesFeaturesClasses#train#val#testCiteseer3,3274,7323,7036120(20 each class)500(29, 86, 116, 106, 94, 69)1000(77, 182, 181, 231, 169, 160)Cora2,7085,4291,4337140(20 each class)500(61, 36, 78, 158, 81, 57, 29)1000(130, 91, 144, 319, 149, 103, 64)Pubmed19,71744,338500360(20 each class)500(98, 194, 208)1000(180, 413, 407)

注:

括号内的数字表示每一类的数量刚开始一直好奇citeseer数据集的Nodes的数量,论文中给的是3,327,官网数据集上的是3,312。后来弄明白图中的节点数量是3,327,但是有15个没有特征向量,所以是3,312。

实验结果

Accuracy

Citeseer(%)Cora(%)Pubmed(%)this repo70.882.579.2paper70.381.579.0

T-SNE可视化

citeseer

cora

pubmed

Accuracy和Loss训练曲线

训练样本数量对模型的影响(citeseer, 200 epoches的效果, 论文中train samples是120)

# train samplesaccuracy(%)12070.824070.636071.5

两个GCN层都加入L2正则化对模型的影响(citeseer, 200 epoches的效果)

gcn1gcn2accuracy(%)experimentregreg71.9paperregno-reg70.8

不同weight_decay和dropout对模型的影响

weight_decaydropouttrain ac(%)val ac(%)test ac(%)5e-30.790.868.470.15e-30.591.770.471.55e-30.293.371.071.85e-30.094.268.869.65e-40.797.570.070.85e-40.598.370.270.85e-40.298.370.870.75e-40.098.371.071.75e-50.7100.067.868.35e-50.5100.070.669.15e-50.2100.068.269.55e-50.0100.067.468.00.00.7100.068.068.00.00.5100.068.067.60.00.2100.063.859.70.00.0100.064.863.6

Note: 5e-4, 0.5是论文中的默认参数.

五、总结与不足

GCN的功能强大,两层的GCN只需少量有label的数据,通过半监督学习方法即可实现高准确率的分类。GCN对模型中的一些超参数不敏感,比如是否两层都加L2正则化,weight_decay和dropout的参数,训练样本数量等。GCN训练时间快,甚至在CPU上即可很快训练。但有很多多维的稀疏的数据,导致对空间需求大,或者需要额外的数据结构来处理存储、处理这种稀疏数据。上述实验的结果都是在CPU上训练得到。也写了GPU的训练版本,在citeseer和cora数据集上可以很快训练,但在pubmed数据上就爆了内存。所以后续考虑利用torch.sparse数据结构实现GPU版本的模型。
最新回复(0)