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})\)。