GATConv
- class dgl.nn.pytorch.conv.GATConv(in_feats, out_feats, num_heads, feat_drop=0.0, attn_drop=0.0, negative_slope=0.2, residual=False, activation=None, allow_zero_in_degree=False, bias=True)[source]
基类:
Module
来自 Graph Attention Network (图注意力网络) 的图注意力层
\[h_i^{(l+1)} = \sum_{j\in \mathcal{N}(i)} \alpha_{i,j} W^{(l)} h_j^{(l)}\]其中 \(\alpha_{ij}\) 是节点 \(i\) 和节点 \(j\) 之间的注意力分数
\[ \begin{align}\begin{aligned}\alpha_{ij}^{l} &= \mathrm{softmax_i} (e_{ij}^{l})\\e_{ij}^{l} &= \mathrm{LeakyReLU}\left(\vec{a}^T [W h_{i} \| W h_{j}]\right)\end{aligned}\end{align} \]- 参数:
in_feats (int, 或 int 对) – 输入特征大小;即 \(h_i^{(l)}\) 的维度数量。GATConv 可以应用于同构图和单向二分图。如果该层应用于单向二分图,
in_feats
指定源节点和目标节点上的输入特征大小。如果给定一个标量,则源节点和目标节点的特征大小将取相同的值。out_feats (int) – 输出特征大小;即 \(h_i^{(l+1)}\) 的维度数量。
num_heads (int) – 多头注意力中的头数。
feat_drop (float, 可选) – 特征上的 Dropout 率。默认为:
0
。attn_drop (float, 可选) – 注意力权重上的 Dropout 率。默认为:
0
。negative_slope (float, 可选) – LeakyReLU 负斜率的角度。默认为:
0.2
。residual (bool, 可选) – 如果为 True,则使用残差连接。默认为:
False
。activation (可调用的激活函数/层 或 None, 可选.) – 如果不是 None,则对更新后的节点特征应用激活函数。默认:
None
。allow_zero_in_degree (bool, 可选) – 如果图中存在入度为 0 的节点,则这些节点的输出将无效,因为没有消息传递到这些节点。这对于某些应用程序是有害的,可能导致性能悄然下降。如果输入图中检测到入度为 0 的节点,此模块将引发 DGLError。通过设置为
True
,将取消检查并由用户自行处理。默认为:False
。bias (bool, 可选) – 如果为 True,则学习一个偏置项。默认为:
True
。
注意
入度为零的节点将导致输出值无效。这是因为没有消息会传递到这些节点,聚合函数将应用于空输入。避免这种情况的一个常见做法是,如果图是同构的,则为图中的每个节点添加自环,这可以通过以下方式实现:
>>> 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 GATConv
>>> # Case 1: Homogeneous graph >>> g = dgl.graph(([0,1,2,3,2,5], [1,2,3,4,0,3])) >>> g = dgl.add_self_loop(g) >>> feat = th.ones(6, 10) >>> gatconv = GATConv(10, 2, num_heads=3) >>> res = gatconv(g, feat) >>> res tensor([[[ 3.4570, 1.8634], [ 1.3805, -0.0762], [ 1.0390, -1.1479]], [[ 3.4570, 1.8634], [ 1.3805, -0.0762], [ 1.0390, -1.1479]], [[ 3.4570, 1.8634], [ 1.3805, -0.0762], [ 1.0390, -1.1479]], [[ 3.4570, 1.8634], [ 1.3805, -0.0762], [ 1.0390, -1.1479]], [[ 3.4570, 1.8634], [ 1.3805, -0.0762], [ 1.0390, -1.1479]], [[ 3.4570, 1.8634], [ 1.3805, -0.0762], [ 1.0390, -1.1479]]], grad_fn=<BinaryReduceBackward>)
>>> # Case 2: Unidirectional bipartite graph >>> u = [0, 1, 0, 0, 1] >>> v = [0, 1, 2, 3, 2] >>> g = dgl.heterograph({('A', 'r', 'B'): (u, v)}) >>> u_feat = th.tensor(np.random.rand(2, 5).astype(np.float32)) >>> v_feat = th.tensor(np.random.rand(4, 10).astype(np.float32)) >>> gatconv = GATConv((5,10), 2, 3) >>> res = gatconv(g, (u_feat, v_feat)) >>> res tensor([[[-0.6066, 1.0268], [-0.5945, -0.4801], [ 0.1594, 0.3825]], [[ 0.0268, 1.0783], [ 0.5041, -1.3025], [ 0.6568, 0.7048]], [[-0.2688, 1.0543], [-0.0315, -0.9016], [ 0.3943, 0.5347]], [[-0.6066, 1.0268], [-0.5945, -0.4801], [ 0.1594, 0.3825]]], grad_fn=<BinaryReduceBackward>)
- forward(graph, feat, edge_weight=None, get_attention=False)[source]
描述
计算图注意力网络层。
- 参数 graph:
图。
- 类型 graph:
DGLGraph
- 参数 feat:
如果给定 torch.Tensor,则输入特征的形状为 \((N, *, D_{in})\),其中 \(D_{in}\) 是输入特征的大小,\(N\) 是节点数。如果给定一对 torch.Tensor,则这对张量必须包含两个张量,其形状分别为 \((N_{in}, *, D_{in_{src}})\) 和 \((N_{out}, *, D_{in_{dst}})\)。
- 类型 feat:
torch.Tensor 或 torch.Tensor 对
- 参数 edge_weight:
一个包含边权重值的 1D 张量。形状: \((|E|,)\)。
- 类型 edge_weight:
torch.Tensor, 可选
- 参数 get_attention:
是否返回注意力值。默认为 False。
- 类型 get_attention:
bool, 可选
- 返回:
torch.Tensor – 输出特征的形状为 \((N, *, H, D_{out})\),其中 \(H\) 是头数,\(D_{out}\) 是输出特征的大小。
torch.Tensor, 可选 – 注意力值的形状为 \((E, *, H, 1)\),其中 \(E\) 是边数。仅当
get_attention
为True
时返回此值。
- 抛出 DGLError:
如果输入图中有入度为 0 的节点,它将引发 DGLError,因为没有消息会传递到这些节点。这将导致输出无效。通过将
allow_zero_in_degree
参数设置为True
可以忽略此错误。