GCN2Conv

class dgl.nn.pytorch.conv.GCN2Conv(in_feats, layer, alpha=0.1, lambda_=1, project_initial_features=True, allow_zero_in_degree=False, bias=True, activation=None)[source]

基类: Module

来自 Simple and Deep Graph Convolutional Networks 的带初始残差和恒等映射的图卷积网络 (GCNII)

其数学定义如下:

\[\mathbf{h}^{(l+1)} =\left( (1 - \alpha)(\mathbf{D}^{-1/2} \mathbf{\hat{A}} \mathbf{D}^{-1/2})\mathbf{h}^{(l)} + \alpha {\mathbf{h}^{(0)}} \right) \left( (1 - \beta_l) \mathbf{I} + \beta_l \mathbf{W} \right)\]

其中 \(\mathbf{\hat{A}}\) 是带自环的邻接矩阵,\(\mathbf{D}_{ii} = \sum_{j=0} \mathbf{A}_{ij}\) 是其对角度矩阵,\(\mathbf{h}^{(0)}\) 是初始节点特征,\(\mathbf{h}^{(l)}\) 是层 \(l\) 的特征,\(\alpha\) 是初始节点特征的比例,\(\beta_l\) 是调整恒等映射强度的超参数。其定义为 \(\beta_l = \log(\frac{\lambda}{l}+1)\approx\frac{\lambda}{l}\),其中 \(\lambda\) 是一个超参数。\(\beta\) 确保权重矩阵的衰减随着层数的增加而自适应地增加。

参数:
  • in_feats (int) – 输入特征大小;即 \(h_j^{(l)}\) 的维度数量。

  • layer (int) – 当前层的索引。

  • alpha (float) – 初始输入特征的比例。默认值: 0.1

  • lambda (float) – 用于确保权重矩阵的衰减自适应增加的超参数。默认值: 1

  • project_initial_features (bool) – 是否在初始特征和平滑特征之间共享一个权重矩阵。默认值: True

  • bias (bool, optional) – 如果为 True,则在输出中添加可学习的偏置。默认值: True

  • activation (可调用激活函数/层 或 None, optional) – 如果不是 None,则将激活函数应用于更新后的节点特征。默认值: None

  • allow_zero_in_degree (bool, optional) – 如果图中有入度为 0 的节点,这些节点的输出将是无效的,因为没有消息会传递到这些节点。这对某些应用有害,可能导致性能无声地下降。如果检测到输入图中有入度为 0 的节点,此模块将引发 DGLError。通过设置为 True,将抑制此检查,并允许用户自行处理。默认值: False

注意

入度为零的节点将导致输出值无效。这是因为没有消息会传递到这些节点,聚合函数将应用于空输入。避免此问题的一种常见做法是,如果图是同构图,则为图中的每个节点添加一个自环,这可以通过以下方式实现:

>>> g = ... # a DGLGraph
>>> g = dgl.add_self_loop(g)

对于某些图(例如异构图),调用 add_self_loop 不起作用,因为无法确定自环边的类型。对于这些情况,将 allow_zero_in_degree 设置为 True 可以解除代码阻塞并手动处理入度为零的节点。处理此问题的一种常见做法是在卷积后过滤掉入度为零的节点。

示例

>>> import dgl
>>> import numpy as np
>>> import torch as th
>>> from dgl.nn import GCN2Conv
>>> # Homogeneous graph
>>> g = dgl.graph(([0,1,2,3,2,5], [1,2,3,4,0,3]))
>>> feat = th.ones(6, 3)
>>> g = dgl.add_self_loop(g)
>>> conv1 = GCN2Conv(3, layer=1, alpha=0.5, \
...         project_initial_features=True, allow_zero_in_degree=True)
>>> conv2 = GCN2Conv(3, layer=2, alpha=0.5, \
...         project_initial_features=True, allow_zero_in_degree=True)
>>> res = feat
>>> res = conv1(g, res, feat)
>>> res = conv2(g, res, feat)
>>> print(res)
tensor([[1.3803, 3.3191, 2.9572],
        [1.3803, 3.3191, 2.9572],
        [1.3803, 3.3191, 2.9572],
        [1.4770, 3.8326, 3.2451],
        [1.3623, 3.2102, 2.8679],
        [1.3803, 3.3191, 2.9572]], grad_fn=<AddBackward0>)
forward(graph, feat, feat_0, edge_weight=None)[source]

说明

计算图卷积。

参数 graph:

图。

类型 graph:

DGLGraph

参数 feat:

输入特征,形状为 \((N, D_{in})\),其中 \(D_{in}\) 是输入特征的大小,\(N\) 是节点数。

类型 feat:

torch.Tensor

参数 feat_0:

初始特征,形状为 \((N, D_{in})\)

类型 feat_0:

torch.Tensor

参数 edge_weight:

在消息传递过程中使用的边权重。这等价于在上面的公式中使用加权邻接矩阵,并且 \(\tilde{D}^{-1/2}\tilde{A} \tilde{D}^{-1/2}\) 基于 dgl.nn.pytorch.conv.graphconv.EdgeWeightNorm

类型 edge_weight:

torch.Tensor, 可选

返回:

输出特征

返回类型:

torch.Tensor

抛出 DGLError:

如果输入图中有入度为 0 的节点,则会抛出 DGLError,因为没有消息会传递到这些节点。这将导致输出无效。可以通过将 allow_zero_in_degree 参数设置为 True 来忽略此错误。

注意

  • 输入形状: \((N, *, \text{in_feats})\),其中 * 表示任意数量的附加维度,\(N\) 是节点数。

  • 输出形状: \((N, *, \text{out_feats})\),其中除最后一个维度外,所有维度的形状与输入相同。

  • 权重形状: \((\text{in_feats}, \text{out_feats})\)

reset_parameters()[source]

说明

重新初始化可学习参数。