Convolution Layers
The k3_node.layers.conv module provides over 65 spatial, spectral, relational, and point-cloud graph convolution layers.
Message Passing Base Class
k3_node.layers.conv.MessagePassing
Bases: Layer
Base class for creating Message Passing Neural Networks (MPNNs).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
aggr
|
Union[str, List[str], Aggregation, None]
|
The aggregation scheme to use, such as |
'add'
|
flow
|
str
|
The direction of message passing ( |
'source_to_target'
|
node_dim
|
int
|
The axis along which to index node features. (default: |
-2
|
decomposed_layers
|
int
|
Number of decomposed layers for memory-efficient
aggregation. (default: |
1
|
Example
import numpy as np
import keras
from k3_node.layers import MessagePassing
x = np.random.rand(10, 8).astype("float32") # 10 nodes with 8 features each
edge_index = np.random.randint(0, 10, size=(2, 30)) # 30 random edges
# A minimal custom layer: average the neighbors' features, then transform them.
class MeanConv(MessagePassing):
def __init__(self, units, **kwargs):
super().__init__(aggr="mean", **kwargs)
self.dense = keras.layers.Dense(units)
def call(self, x, edge_index):
return self.dense(self.propagate(edge_index, x=x))
def message(self, x_j):
return x_j # features of the source node of every edge
layer = MeanConv(16)
out = layer(x, edge_index)
print(tuple(out.shape)) # (10, 16)
aggregate(inputs=None, index=None, ptr=None, dim_size=None, **kwargs)
Aggregates messages from neighbors as given by :obj:index.
call(inputs, edge_index=None, edge_attr=None, **kwargs)
Default call handler supporting both (x, edge_index) and legacy (inputs,) tuples.
edge_update(**kwargs)
Computes or updates edge attributes.
edge_updater(edge_index, size=None, **kwargs)
Computes or updates edge-level representations.
message(x=None, x_j=None, **kwargs)
Constructs messages from node :math:j to node :math:i.
propagate(*args, **kwargs)
The initial call to start propagating messages.
update(embeddings=None, **kwargs)
Updates node embeddings.
Core Graph Convolutions
GCNConv
k3_node.layers.conv.GCNConv
Bases: MessagePassing
The graph convolutional operator from the "Semi-supervised
Classification with Graph Convolutional Networks"
<https://arxiv.org/abs/1609.02907>_ paper.
.. math:: \mathbf{X}^{\prime} = \mathbf{\hat{D}}^{-1/2} \mathbf{\hat{A}} \mathbf{\hat{D}}^{-1/2} \mathbf{X} \mathbf{\Theta}
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
in_channels
|
int
|
Size of each input sample. |
required |
out_channels
|
int
|
Size of each output sample. |
required |
improved
|
bool
|
If set to :obj: |
False
|
cached
|
bool
|
If set to :obj: |
False
|
add_self_loops
|
bool
|
If set to :obj: |
True
|
normalize
|
bool
|
Whether to add self-loops and compute
symmetric normalization coefficients on the fly.
(default: :obj: |
True
|
bias
|
bool
|
If set to :obj: |
True
|
Example
import numpy as np
from k3_node.layers import GCNConv
x = np.random.rand(10, 8).astype("float32") # 10 nodes with 8 features each
edge_index = np.random.randint(0, 10, size=(2, 30)) # 30 random edges
layer = GCNConv(in_channels=8, out_channels=16)
out = layer(x, edge_index)
print(tuple(out.shape)) # (10, 16)
SAGEConv
k3_node.layers.conv.SAGEConv
Bases: MessagePassing
The GraphSAGE operator from the "Inductive Representation Learning on
Large Graphs" <https://arxiv.org/abs/1706.02216>_ paper.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
in_channels
|
Union[int, Tuple[int, int], None]
|
Size of each input sample, or a tuple for bipartite graphs. |
required |
out_channels
|
Optional[int]
|
Size of each output sample. |
None
|
aggr
|
Optional[Union[str, List[str], Aggregation]]
|
The aggregation scheme to use ( |
'mean'
|
normalize
|
bool
|
If set to :obj: |
False
|
root_weight
|
bool
|
If set to :obj: |
True
|
project
|
bool
|
If set to :obj: |
False
|
bias
|
bool
|
If set to :obj: |
True
|
Example
import numpy as np
from k3_node.layers import SAGEConv
x = np.random.rand(10, 8).astype("float32") # 10 nodes with 8 features each
edge_index = np.random.randint(0, 10, size=(2, 30)) # 30 random edges
layer = SAGEConv(in_channels=8, out_channels=16)
out = layer(x, edge_index)
print(tuple(out.shape)) # (10, 16)
GATConv
k3_node.layers.conv.GATConv
Bases: MessagePassing
The graph attentional operator from the "Graph Attention Networks"
<https://arxiv.org/abs/1710.10903>_ paper.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
in_channels
|
Union[int, Tuple[int, int]]
|
Size of each input sample, or a tuple for bipartite graphs. |
required |
out_channels
|
int
|
Size of each output sample. |
required |
heads
|
int
|
Number of multi-head-attentions. (default: |
1
|
concat
|
bool
|
If set to :obj: |
True
|
negative_slope
|
float
|
LeakyReLU angle of the negative slope. (default: |
0.2
|
dropout
|
float
|
Dropout probability of the normalized attention coefficients.
(default: |
0.0
|
add_self_loops
|
bool
|
If set to :obj: |
True
|
edge_dim
|
Optional[int]
|
Edge feature dimensionality (in case there are any).
(default: :obj: |
None
|
fill_value
|
Union[float, str]
|
The way to generate edge features of self-loops
(default: |
'mean'
|
bias
|
bool
|
If set to :obj: |
True
|
share_weights
|
bool
|
If set to :obj: |
False
|
residual
|
bool
|
If set to :obj: |
False
|
Example
import numpy as np
from k3_node.layers import GATConv
x = np.random.rand(10, 8).astype("float32") # 10 nodes with 8 features each
edge_index = np.random.randint(0, 10, size=(2, 30)) # 30 random edges
layer = GATConv(in_channels=8, out_channels=16, heads=2)
out = layer(x, edge_index)
print(tuple(out.shape)) # (10, 32)
GATv2Conv
k3_node.layers.conv.GATv2Conv
Bases: MessagePassing
The GATv2 operator from the "How Attentive are Graph Attention Networks?"
<https://arxiv.org/abs/2105.14491>_ paper, which fixes the static
attention problem of standard :class:~k3_node.layers.conv.GATConv.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
in_channels
|
Union[int, Tuple[int, int]]
|
Size of each input sample, or a tuple for bipartite graphs. |
required |
out_channels
|
int
|
Size of each output sample. |
required |
heads
|
int
|
Number of multi-head-attentions. (default: |
1
|
concat
|
bool
|
If set to :obj: |
True
|
negative_slope
|
float
|
LeakyReLU angle of the negative slope. (default: |
0.2
|
dropout
|
float
|
Dropout probability of the normalized attention coefficients.
(default: |
0.0
|
add_self_loops
|
bool
|
If set to :obj: |
True
|
edge_dim
|
Optional[int]
|
Edge feature dimensionality (in case there are any).
(default: :obj: |
None
|
fill_value
|
Union[float, str]
|
The way to generate edge features of self-loops
(default: |
'mean'
|
bias
|
bool
|
If set to :obj: |
True
|
share_weights
|
bool
|
If set to :obj: |
False
|
residual
|
bool
|
If set to :obj: |
False
|
Example
import numpy as np
from k3_node.layers import GATv2Conv
x = np.random.rand(10, 8).astype("float32") # 10 nodes with 8 features each
edge_index = np.random.randint(0, 10, size=(2, 30)) # 30 random edges
layer = GATv2Conv(in_channels=8, out_channels=16, heads=2)
out = layer(x, edge_index)
print(tuple(out.shape)) # (10, 32)
TransformerConv
k3_node.layers.conv.TransformerConv
Bases: MessagePassing
The graph transformer operator from the "Masked Label Prediction:
Unified Meta-Learning on Graph Neural Networks"
<https://arxiv.org/abs/2009.03509>_ paper.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
in_channels
|
Union[int, Tuple[int, int]]
|
Size of each input sample, or a tuple for bipartite graphs. |
required |
out_channels
|
int
|
Size of each output sample. |
required |
heads
|
int
|
Number of multi-head-attentions. (default: |
1
|
concat
|
bool
|
If set to :obj: |
True
|
beta
|
bool
|
If set to :obj: |
False
|
dropout
|
float
|
Dropout probability of the normalized attention coefficients.
(default: |
0.0
|
edge_dim
|
Optional[int]
|
Edge feature dimensionality (in case there are any).
(default: :obj: |
None
|
bias
|
bool
|
If set to :obj: |
True
|
root_weight
|
bool
|
If set to :obj: |
True
|
Example
import numpy as np
from k3_node.layers import TransformerConv
x = np.random.rand(10, 8).astype("float32") # 10 nodes with 8 features each
edge_index = np.random.randint(0, 10, size=(2, 30)) # 30 random edges
layer = TransformerConv(in_channels=8, out_channels=16, heads=2)
out = layer(x, edge_index)
print(tuple(out.shape)) # (10, 32)
GINConv
k3_node.layers.conv.GINConv
Bases: MessagePassing
The graph isomorphism operator from the "How Powerful are Graph
Neural Networks?" <https://arxiv.org/abs/1810.00826>_ paper.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
nn
|
Union[Callable, int]
|
A neural network :math: |
required |
eps
|
float
|
(Initial) :math: |
0.0
|
train_eps
|
bool
|
If set to :obj: |
False
|
Example
import numpy as np
import keras
from k3_node.layers import GINConv
x = np.random.rand(10, 8).astype("float32") # 10 nodes with 8 features each
edge_index = np.random.randint(0, 10, size=(2, 30)) # 30 random edges
mlp = keras.Sequential([keras.layers.Dense(16, activation="relu"), keras.layers.Dense(16)])
layer = GINConv(mlp)
out = layer(x, edge_index)
print(tuple(out.shape)) # (10, 16)
GINEConv
k3_node.layers.conv.GINEConv
Bases: MessagePassing
The modified :class:GINConv operator from the "Strategies for
Pre-training Graph Neural Networks" <https://arxiv.org/abs/1905.12265>_
paper, which is able to incorporate edge features into aggregation.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
nn
|
Callable
|
A neural network :math: |
required |
eps
|
float
|
(Initial) :math: |
0.0
|
train_eps
|
bool
|
If set to :obj: |
False
|
edge_dim
|
Optional[int]
|
Edge feature dimensionality. (default: :obj: |
None
|
Example
import numpy as np
import keras
from k3_node.layers import GINEConv
x = np.random.rand(10, 8).astype("float32") # 10 nodes with 8 features each
edge_index = np.random.randint(0, 10, size=(2, 30)) # 30 random edges
edge_attr = np.random.rand(30, 3).astype("float32") # 3 features per edge
mlp = keras.Sequential([keras.layers.Dense(16, activation="relu"), keras.layers.Dense(16)])
layer = GINEConv(mlp, edge_dim=3)
out = layer(x, edge_index, edge_attr)
print(tuple(out.shape)) # (10, 16)
ChebConv
k3_node.layers.conv.ChebConv
Bases: MessagePassing
The Chebyshev spectral graph convolutional operator from the
"Convolutional Neural Networks on Graphs with Fast Localized Spectral
Filtering" <https://arxiv.org/abs/1606.09375>_ paper.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
in_channels
|
int
|
Size of each input sample. |
required |
out_channels
|
int
|
Size of each output sample. |
required |
K
|
int
|
Chebyshev filter size :math: |
required |
normalization
|
Optional[str]
|
The normalization scheme for the graph
Laplacian ( |
'sym'
|
bias
|
bool
|
If set to :obj: |
True
|
Example
import numpy as np
from k3_node.layers import ChebConv
x = np.random.rand(10, 8).astype("float32") # 10 nodes with 8 features each
edge_index = np.random.randint(0, 10, size=(2, 30)) # 30 random edges
layer = ChebConv(in_channels=8, out_channels=16, K=2)
out = layer(x, edge_index)
print(tuple(out.shape)) # (10, 16)
AGNNConv
k3_node.layers.conv.AGNNConv
Bases: MessagePassing
The graph attentional propagation layer from the
"Attention-based Graph Neural Network for Semi-Supervised Learning"
<https://arxiv.org/abs/1803.03735>_ paper.
Example
TAGConv
k3_node.layers.conv.TAGConv
Bases: MessagePassing
The topology adaptive graph convolutional operator from the
"Topology Adaptive Graph Convolutional Networks"
<https://arxiv.org/abs/1710.10370>_ paper.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
in_channels
|
int
|
Size of each input sample. |
required |
out_channels
|
int
|
Size of each output sample. |
required |
K
|
int
|
Number of hops :math: |
3
|
bias
|
bool
|
If set to :obj: |
True
|
normalize
|
bool
|
Whether to apply symmetric normalization. (default: |
True
|
Example
import numpy as np
from k3_node.layers import TAGConv
x = np.random.rand(10, 8).astype("float32") # 10 nodes with 8 features each
edge_index = np.random.randint(0, 10, size=(2, 30)) # 30 random edges
layer = TAGConv(in_channels=8, out_channels=16, K=2)
out = layer(x, edge_index)
print(tuple(out.shape)) # (10, 16)
ARMAConv
k3_node.layers.conv.ARMAConv
Bases: MessagePassing
The ARMA graph convolutional operator from the "Graph Neural Networks
with Convolutional ARMA Filters" <https://arxiv.org/abs/1901.01343>_
paper.
Example
import numpy as np
from k3_node.layers import ARMAConv
x = np.random.rand(10, 8).astype("float32") # 10 nodes with 8 features each
edge_index = np.random.randint(0, 10, size=(2, 30)) # 30 random edges
layer = ARMAConv(in_channels=8, out_channels=16, num_stacks=1, num_layers=1)
out = layer(x, edge_index)
print(tuple(out.shape)) # (10, 16)
SGConv
k3_node.layers.conv.SGConv
Bases: MessagePassing
The simple graph convolutional operator from the "Simplifying Graph
Convolutional Networks" <https://arxiv.org/abs/1902.07153>_ paper.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
in_channels
|
int
|
Size of each input sample. |
required |
out_channels
|
int
|
Size of each output sample. |
required |
K
|
int
|
Number of hops :math: |
1
|
cached
|
bool
|
If set to :obj: |
False
|
add_self_loops
|
bool
|
If set to :obj: |
True
|
bias
|
bool
|
If set to :obj: |
True
|
Example
import numpy as np
from k3_node.layers import SGConv
x = np.random.rand(10, 8).astype("float32") # 10 nodes with 8 features each
edge_index = np.random.randint(0, 10, size=(2, 30)) # 30 random edges
layer = SGConv(in_channels=8, out_channels=16, K=2)
out = layer(x, edge_index)
print(tuple(out.shape)) # (10, 16)
SSGConv
k3_node.layers.conv.SSGConv
Bases: MessagePassing
The simple spectral graph convolutional operator from the
"Simple Spectral Graph Convolution" <https://arxiv.org/abs/2109.07191>_ paper.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
in_channels
|
int
|
Size of each input sample. |
required |
out_channels
|
int
|
Size of each output sample. |
required |
alpha
|
float
|
Teleport probability :math: |
required |
K
|
int
|
Number of hops :math: |
1
|
cached
|
bool
|
If set to :obj: |
False
|
add_self_loops
|
bool
|
If set to :obj: |
True
|
bias
|
bool
|
If set to :obj: |
True
|
Example
import numpy as np
from k3_node.layers import SSGConv
x = np.random.rand(10, 8).astype("float32") # 10 nodes with 8 features each
edge_index = np.random.randint(0, 10, size=(2, 30)) # 30 random edges
layer = SSGConv(in_channels=8, out_channels=16, alpha=0.1, K=2)
out = layer(x, edge_index)
print(tuple(out.shape)) # (10, 16)
APPNP
k3_node.layers.conv.APPNP
Bases: MessagePassing
The approximate personalized propagation of neural predictions (APPNP)
operator from the "Predict then Propagate: Combining Neural Networks with
Personalized PageRank for Classification on Graphs"
<https://arxiv.org/abs/1810.05997>_ paper.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
K
|
int
|
Number of iterations :math: |
required |
alpha
|
float
|
Teleport probability :math: |
required |
dropout
|
float
|
Dropout probability of edges or features during propagation.
(default: |
0.0
|
cached
|
bool
|
If set to :obj: |
False
|
add_self_loops
|
bool
|
If set to :obj: |
True
|
normalize
|
bool
|
Whether to apply symmetric normalization. (default: |
True
|
Example
APPNPConv
k3_node.layers.conv.APPNPConv
Bases: Conv
`k3_node.layers.APPNPConv`
Implementation of Approximate Personalized Propagation of Neural Predictions
Args:
channels: The number of output channels.
alpha: The teleport probability.
propagations: The number of propagation steps.
mlp_hidden: A list of hidden channels for the MLP.
mlp_activation: The activation function to use in the MLP.
dropout_rate: The dropout rate for the MLP.
activation: The activation function to use in the layer.
use_bias: Whether to add a bias to the linear transformation.
kernel_initializer: Initializer for the `kernel` weights matrix.
bias_initializer: Initializer for the bias vector.
kernel_regularizer: Regularizer for the `kernel` weights matrix.
bias_regularizer: Regularizer for the bias vector.
activity_regularizer: Regularizer for the output.
kernel_constraint: Constraint for the `kernel` weights matrix.
bias_constraint: Constraint for the bias vector.
**kwargs: Additional keyword arguments.
Example
import numpy as np
from k3_node.layers import APPNPConv
x = np.random.rand(10, 8).astype("float32") # 10 nodes with 8 features each
edge_index = np.random.randint(0, 10, size=(2, 30)) # 30 random edges
layer = APPNPConv(channels=16, alpha=0.1, propagations=2)
out = layer(x, edge_index)
print(tuple(out.shape)) # (10, 16)
PNAConv
k3_node.layers.conv.PNAConv
Bases: MessagePassing
The Principal Neighbourhood Aggregation graph convolutional operator
from the "Principal Neighbourhood Aggregation for Graph Nets"
<https://arxiv.org/abs/2004.05718>_ paper.
Example
import numpy as np
from k3_node.layers import PNAConv
x = np.random.rand(10, 8).astype("float32") # 10 nodes with 8 features each
edge_index = np.random.randint(0, 10, size=(2, 30)) # 30 random edges
deg = np.array([0, 2, 4, 3, 1]) # in-degree histogram of the training graphs
layer = PNAConv(in_channels=8, out_channels=16, aggregators=["mean", "max", "min", "std"],
scalers=["identity", "amplification"], deg=deg)
out = layer(x, edge_index)
print(tuple(out.shape)) # (10, 16)
get_degree_histogram(graphs)
staticmethod
Returns the histogram of in-degrees over graphs (a dataset, a list of graphs or a
loader), which PNA uses to normalize its degree scalers:
deg[d] is the number of nodes with d incoming edges.
GENConv
k3_node.layers.conv.GENConv
Bases: MessagePassing
The generalized graph convolution operator from the "DeeperGCN: All
You Need to Train Deeper GCNs" <https://arxiv.org/abs/2006.07739>_ paper.
Example
import numpy as np
from k3_node.layers import GENConv
x = np.random.rand(10, 8).astype("float32") # 10 nodes with 8 features each
edge_index = np.random.randint(0, 10, size=(2, 30)) # 30 random edges
edge_attr = np.random.rand(30, 3).astype("float32") # 3 features per edge
layer = GENConv(in_channels=8, out_channels=16, edge_dim=3)
out = layer(x, edge_index, edge_attr)
print(tuple(out.shape)) # (10, 16)
GatedGraphConv
k3_node.layers.conv.GatedGraphConv
Bases: MessagePassing
k3_node.layers.GatedGraphConv
Implementation of Gated Graph Convolution (GGC) layer
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
channels
|
The number of output channels. |
None
|
|
n_layers
|
The number of GGC layers to stack. |
None
|
|
activation
|
Activation function to use. |
None
|
|
use_bias
|
Whether to add a bias to the linear transformation. |
True
|
|
kernel_initializer
|
Initializer for the |
'glorot_uniform'
|
|
bias_initializer
|
Initializer for the bias vector. |
'zeros'
|
|
kernel_regularizer
|
Regularizer for the |
None
|
|
bias_regularizer
|
Regularizer for the bias vector. |
None
|
|
activity_regularizer
|
Regularizer for the output. |
None
|
|
kernel_constraint
|
Constraint for the |
None
|
|
bias_constraint
|
Constraint for the bias vector. |
None
|
|
**kwargs
|
Additional arguments to pass to the |
{}
|
Example
import numpy as np
from k3_node.layers import GatedGraphConv
x = np.random.rand(10, 8).astype("float32") # 10 nodes with 8 features each
edge_index = np.random.randint(0, 10, size=(2, 30)) # 30 random edges
layer = GatedGraphConv(out_channels=16, num_layers=2)
out = layer(x, edge_index)
print(tuple(out.shape)) # (10, 16)
ResGatedGraphConv
k3_node.layers.conv.ResGatedGraphConv
Bases: MessagePassing
The residual gated graph convolutional operator from the
"Residual Gated Graph ConvNets" <https://arxiv.org/abs/1711.07553>_ paper.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
in_channels
|
Union[int, Tuple[int, int]]
|
Size of each input sample, or a tuple for bipartite graphs. |
required |
out_channels
|
int
|
Size of each output sample. |
required |
act
|
Union[str, Callable]
|
Activation function :math: |
'sigmoid'
|
edge_dim
|
Optional[int]
|
Edge feature dimensionality. (default: :obj: |
None
|
root_weight
|
bool
|
If set to :obj: |
True
|
bias
|
bool
|
If set to :obj: |
True
|
Example
import numpy as np
from k3_node.layers import ResGatedGraphConv
x = np.random.rand(10, 8).astype("float32") # 10 nodes with 8 features each
edge_index = np.random.randint(0, 10, size=(2, 30)) # 30 random edges
layer = ResGatedGraphConv(in_channels=8, out_channels=16)
out = layer(x, edge_index)
print(tuple(out.shape)) # (10, 16)
SimpleConv
k3_node.layers.conv.SimpleConv
Bases: MessagePassing
A simple, parameter-free message passing operator.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
aggr
|
Union[str, List[str], Aggregation, None]
|
The aggregation scheme to use ( |
'sum'
|
combine_root
|
Optional[str]
|
The way to combine root node features with the
aggregated output ( |
None
|
Example
GraphConv
k3_node.layers.conv.GraphConv
Bases: MessagePassing
The graph neural network operator from the "Weisfeiler and Leman Go
Neural: Higher-order Graph Neural Networks"
<https://arxiv.org/abs/1810.02244>_ paper.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
in_channels
|
Union[int, Tuple[int, int]]
|
Size of each input sample, or a tuple for bipartite graphs. |
required |
out_channels
|
int
|
Size of each output sample. |
required |
aggr
|
str
|
The aggregation scheme to use ( |
'add'
|
bias
|
bool
|
If set to :obj: |
True
|
Example
import numpy as np
from k3_node.layers import GraphConv
x = np.random.rand(10, 8).astype("float32") # 10 nodes with 8 features each
edge_index = np.random.randint(0, 10, size=(2, 30)) # 30 random edges
layer = GraphConv(in_channels=8, out_channels=16)
out = layer(x, edge_index)
print(tuple(out.shape)) # (10, 16)
MFConv
k3_node.layers.conv.MFConv
Bases: MessagePassing
The molecular fingerprint graph convolutional operator from the
"Convolutional Networks on Graphs for Learning Molecular Fingerprints"
<https://arxiv.org/abs/1509.09292>_ paper.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
in_channels
|
Union[int, Tuple[int, int]]
|
Size of each input sample, or a tuple for bipartite graphs. |
required |
out_channels
|
int
|
Size of each output sample. |
required |
max_degree
|
int
|
The maximum degree of any node. (default: |
10
|
bias
|
bool
|
If set to :obj: |
True
|
Example
import numpy as np
from k3_node.layers import MFConv
x = np.random.rand(10, 8).astype("float32") # 10 nodes with 8 features each
edge_index = np.random.randint(0, 10, size=(2, 30)) # 30 random edges
layer = MFConv(in_channels=8, out_channels=16)
out = layer(x, edge_index)
print(tuple(out.shape)) # (10, 16)
Relational & Directed Convolutions
RGCNConv
k3_node.layers.conv.RGCNConv
Bases: MessagePassing
The relational graph convolutional operator from the
"Modeling Relational Data with Graph Convolutional Networks"
<https://arxiv.org/abs/1703.06103>_ paper.
Example
import numpy as np
from k3_node.layers import RGCNConv
x = np.random.rand(10, 8).astype("float32") # 10 nodes with 8 features each
edge_index = np.random.randint(0, 10, size=(2, 30)) # 30 random edges
edge_type = np.random.randint(0, 3, size=(30,)) # relation type of each edge
layer = RGCNConv(in_channels=8, out_channels=16, num_relations=3)
out = layer(x, edge_index, edge_type)
print(tuple(out.shape)) # (10, 16)
FastRGCNConv
k3_node.layers.conv.FastRGCNConv
Bases: RGCNConv
See :class:RGCNConv.
Example
import numpy as np
from k3_node.layers import FastRGCNConv
x = np.random.rand(10, 8).astype("float32") # 10 nodes with 8 features each
edge_index = np.random.randint(0, 10, size=(2, 30)) # 30 random edges
edge_type = np.random.randint(0, 3, size=(30,)) # relation type of each edge
layer = FastRGCNConv(in_channels=8, out_channels=16, num_relations=3)
out = layer(x, edge_index, edge_type)
print(tuple(out.shape)) # (10, 16)
RGATConv
k3_node.layers.conv.RGATConv
Bases: MessagePassing
The relational graph attentional operator from the
"Relational Graph Attention Networks" <https://arxiv.org/abs/1904.05811>_ paper.
Example
import numpy as np
from k3_node.layers import RGATConv
x = np.random.rand(10, 8).astype("float32") # 10 nodes with 8 features each
edge_index = np.random.randint(0, 10, size=(2, 30)) # 30 random edges
edge_type = np.random.randint(0, 3, size=(30,)) # relation type of each edge
layer = RGATConv(in_channels=8, out_channels=16, num_relations=3)
out = layer(x, edge_index, edge_type)
print(tuple(out.shape)) # (10, 16)
SignedConv
k3_node.layers.conv.SignedConv
Bases: MessagePassing
The signed graph convolutional operator from the "Signed Graph
Convolutional Network" <https://arxiv.org/abs/1808.06354>_ paper.
Example
import numpy as np
from k3_node.layers import SignedConv
x = np.random.rand(10, 8).astype("float32") # 10 nodes with 8 features each
edge_index = np.random.randint(0, 10, size=(2, 30)) # 30 random edges
pos_edge_index = edge_index[:, :15] # positive (e.g. "trust") edges
neg_edge_index = edge_index[:, 15:] # negative (e.g. "distrust") edges
layer = SignedConv(in_channels=8, out_channels=16, first_aggr=True)
out = layer(x, pos_edge_index, neg_edge_index)
print(tuple(out.shape)) # (10, 32): positive and negative embeddings, concatenated
DirGNNConv
k3_node.layers.conv.DirGNNConv
Bases: Layer
A directed graph neural network operator from the
"Directed Graph Neural Networks" <https://arxiv.org/abs/2301.07663>_ paper.
Example
import numpy as np
from k3_node.layers import DirGNNConv, GCNConv
x = np.random.rand(10, 8).astype("float32") # 10 nodes with 8 features each
edge_index = np.random.randint(0, 10, size=(2, 30)) # 30 random edges
# Runs the wrapped convolution on incoming and outgoing edges separately
layer = DirGNNConv(GCNConv(in_channels=8, out_channels=16))
out = layer(x, edge_index)
print(tuple(out.shape)) # (10, 16)
AntiSymmetricConv
k3_node.layers.conv.AntiSymmetricConv
Bases: Layer
The anti-symmetric graph convolutional operator from the
"Anti-Symmetric DGN: a Continuous approach to Deep Graph Neural Networks"
<https://arxiv.org/abs/2202.13085>_ paper.
Example
import numpy as np
from k3_node.layers import AntiSymmetricConv
x = np.random.rand(10, 8).astype("float32") # 10 nodes with 8 features each
edge_index = np.random.randint(0, 10, size=(2, 30)) # 30 random edges
layer = AntiSymmetricConv(in_channels=8)
out = layer(x, edge_index)
print(tuple(out.shape)) # (10, 8)
Advanced & Scaled Graph Convolutions
FiLMConv
k3_node.layers.conv.FiLMConv
Bases: MessagePassing
The FiLM graph convolutional operator from the
"GNN-FiLM: Graph Neural Networks with Feature-wise Linear Modulation"
<https://arxiv.org/abs/1906.12192>_ paper.
Example
import numpy as np
from k3_node.layers import FiLMConv
x = np.random.rand(10, 8).astype("float32") # 10 nodes with 8 features each
edge_index = np.random.randint(0, 10, size=(2, 30)) # 30 random edges
layer = FiLMConv(in_channels=8, out_channels=16)
out = layer(x, edge_index)
print(tuple(out.shape)) # (10, 16)
SuperGATConv
k3_node.layers.conv.SuperGATConv
Bases: MessagePassing
The self-supervised graph attentional operator from the
"How to Find Your Friendly Neighborhood: Graph Attention Design with Self-Supervision"
<https://openreview.net/forum?id=Wi5KUNlqWty>_ paper.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
attention_type
|
str
|
|
'MX'
|
neg_sample_ratio
|
float
|
Negative (random) pairs per positive edge in the attention loss. |
0.5
|
edge_sample_ratio
|
float
|
Fraction of edges used as positives in the attention loss. |
1.0
|
attention_loss_weight
|
float
|
If positive, the self-supervised attention loss is added to
the model loss ( |
0.0
|
Example
import numpy as np
from k3_node.layers import SuperGATConv
x = np.random.rand(10, 8).astype("float32") # 10 nodes with 8 features each
edge_index = np.random.randint(0, 10, size=(2, 30)) # 30 random edges
layer = SuperGATConv(in_channels=8, out_channels=16, heads=2)
out = layer(x, edge_index)
print(tuple(out.shape)) # (10, 32)
get_attention_loss()
The self-supervised attention loss of the last training call (as in PyG).
EGConv
k3_node.layers.conv.EGConv
Bases: MessagePassing
The Efficient Graph Convolution from the "Adaptive Filters and
Aggregator Fusion for Efficient Graph Convolutions"
<https://arxiv.org/abs/2104.01481>_ paper.
Example
import numpy as np
from k3_node.layers import EGConv
x = np.random.rand(10, 8).astype("float32") # 10 nodes with 8 features each
edge_index = np.random.randint(0, 10, size=(2, 30)) # 30 random edges
layer = EGConv(in_channels=8, out_channels=16, num_heads=2)
out = layer(x, edge_index)
print(tuple(out.shape)) # (10, 16)
MixHopConv
k3_node.layers.conv.MixHopConv
Bases: MessagePassing
The MixHop graph convolutional operator from the
"Higher-Order Graph Convolutional Networks via MixHop"
<https://arxiv.org/abs/1905.00067>_ paper.
Example
import numpy as np
from k3_node.layers import MixHopConv
x = np.random.rand(10, 8).astype("float32") # 10 nodes with 8 features each
edge_index = np.random.randint(0, 10, size=(2, 30)) # 30 random edges
layer = MixHopConv(in_channels=8, out_channels=16, powers=[0, 1, 2])
out = layer(x, edge_index)
print(tuple(out.shape)) # (10, 48)
PDNConv
k3_node.layers.conv.PDNConv
Bases: MessagePassing
The pathfinder discovery network convolutional operator from the
"Pathfinder Discovery Networks for Neural Message Passing"
<https://arxiv.org/abs/2010.12878>_ paper.
Example
import numpy as np
from k3_node.layers import PDNConv
x = np.random.rand(10, 8).astype("float32") # 10 nodes with 8 features each
edge_index = np.random.randint(0, 10, size=(2, 30)) # 30 random edges
edge_attr = np.random.rand(30, 3).astype("float32") # 3 features per edge
layer = PDNConv(in_channels=8, out_channels=16, edge_dim=3, hidden_channels=16)
out = layer(x, edge_index, edge_attr)
print(tuple(out.shape)) # (10, 16)
FAConv
k3_node.layers.conv.FAConv
Bases: MessagePassing
The Frequency Adaptive Graph Convolution operator from the
"Beyond Low-Frequency Information in Graph Convolutional Networks"
<https://arxiv.org/abs/2101.00797>_ paper.
Example
import numpy as np
from k3_node.layers import FAConv
x = np.random.rand(10, 8).astype("float32") # 10 nodes with 8 features each
edge_index = np.random.randint(0, 10, size=(2, 30)) # 30 random edges
x_0 = x # initial node representations
layer = FAConv(channels=8, eps=0.1)
out = layer(x, x_0, edge_index)
print(tuple(out.shape)) # (10, 8)
PANConv
k3_node.layers.conv.PANConv
Bases: MessagePassing
The path integral based convolution operator from the
"Path Integral Based Convolution and Pooling for Graph Neural Networks"
<https://arxiv.org/abs/2004.14805>_ paper.
Example
import numpy as np
from k3_node.layers import PANConv
x = np.random.rand(10, 8).astype("float32") # 10 nodes with 8 features each
edge_index = np.random.randint(0, 10, size=(2, 30)) # 30 random edges
layer = PANConv(in_channels=8, out_channels=16, filter_size=2)
out, weights = layer(x, edge_index) # also returns the learned path weights
print(tuple(out.shape)) # (10, 16)
LEConv
k3_node.layers.conv.LEConv
Bases: MessagePassing
The local extremum graph convolutional operator from the
"ASAP: Adaptive Structure Aware Pooling for Learning Hierarchical Graph
Representations" <https://arxiv.org/abs/1911.07979>_ paper.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
in_channels
|
Union[int, Tuple[int, int]]
|
Size of each input sample, or a tuple for bipartite graphs. |
required |
out_channels
|
int
|
Size of each output sample. |
required |
bias
|
bool
|
If set to :obj: |
True
|
Example
import numpy as np
from k3_node.layers import LEConv
x = np.random.rand(10, 8).astype("float32") # 10 nodes with 8 features each
edge_index = np.random.randint(0, 10, size=(2, 30)) # 30 random edges
layer = LEConv(in_channels=8, out_channels=16)
out = layer(x, edge_index)
print(tuple(out.shape)) # (10, 16)
ClusterGCNConv
k3_node.layers.conv.ClusterGCNConv
Bases: MessagePassing
The ClusterGCN graph convolutional operator from the
"Cluster-GCN: An Efficient Algorithm for Training Deep and Large Graph
Convolutional Networks" <https://arxiv.org/abs/1905.07953>_ paper.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
in_channels
|
int
|
Size of each input sample. |
required |
out_channels
|
int
|
Size of each output sample. |
required |
diag_lambda
|
float
|
Diagonal enhancement coefficient :math: |
0.0
|
add_self_loops
|
bool
|
If set to :obj: |
True
|
bias
|
bool
|
If set to :obj: |
True
|
Example
import numpy as np
from k3_node.layers import ClusterGCNConv
x = np.random.rand(10, 8).astype("float32") # 10 nodes with 8 features each
edge_index = np.random.randint(0, 10, size=(2, 30)) # 30 random edges
layer = ClusterGCNConv(in_channels=8, out_channels=16)
out = layer(x, edge_index)
print(tuple(out.shape)) # (10, 16)
GCN2Conv
k3_node.layers.conv.GCN2Conv
Bases: MessagePassing
The graph convolutional operator from the "Simple and Deep Graph
Convolutional Networks" <https://arxiv.org/abs/2007.02133>_ paper.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
channels
|
int
|
Size of each input and output sample. |
required |
alpha
|
float
|
The strength of the initial residual connection :math: |
required |
theta
|
Optional[float]
|
The hyperparameter for the identity mapping :math: |
None
|
layer
|
Optional[int]
|
The layer index :math: |
None
|
shared_weights
|
bool
|
If set to :obj: |
True
|
cached
|
bool
|
If set to :obj: |
False
|
add_self_loops
|
bool
|
If set to :obj: |
True
|
normalize
|
bool
|
Whether to apply symmetric normalization. (default: |
True
|
Example
import numpy as np
from k3_node.layers import GCN2Conv
x = np.random.rand(10, 8).astype("float32") # 10 nodes with 8 features each
edge_index = np.random.randint(0, 10, size=(2, 30)) # 30 random edges
x_0 = x # initial node representations (from the first layer)
layer = GCN2Conv(channels=8, alpha=0.1, theta=0.5, layer=1)
out = layer(x, x_0, edge_index)
print(tuple(out.shape)) # (10, 8)
LGConv
k3_node.layers.conv.LGConv
Bases: MessagePassing
The LightGCN operator from the "LightGCN: Simplifying and Powering
Graph Convolution Network for Recommendation"
<https://arxiv.org/abs/2002.02126>_ paper.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
normalize
|
bool
|
Whether to apply symmetric normalization. (default: |
True
|
Example
NNConv
k3_node.layers.conv.NNConv
Bases: MessagePassing
The continuous kernel-based convolutional operator from the
"Neural Message Passing for Quantum Chemistry"
<https://arxiv.org/abs/1704.01212>_ paper.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
in_channels
|
Union[int, Tuple[int, int]]
|
Size of each input sample, or a tuple for bipartite graphs. |
required |
out_channels
|
int
|
Size of each output sample. |
required |
nn
|
Callable
|
A neural network :math: |
required |
aggr
|
str
|
The aggregation scheme to use ( |
'add'
|
root_weight
|
bool
|
If set to :obj: |
True
|
bias
|
bool
|
If set to :obj: |
True
|
Example
import numpy as np
import keras
from k3_node.layers import NNConv
x = np.random.rand(10, 8).astype("float32") # 10 nodes with 8 features each
edge_index = np.random.randint(0, 10, size=(2, 30)) # 30 random edges
edge_attr = np.random.rand(30, 3).astype("float32") # 3 features per edge
# `nn` maps each edge's features to an [in_channels * out_channels] weight matrix
layer = NNConv(in_channels=8, out_channels=16, nn=keras.layers.Dense(8 * 16))
out = layer(x, edge_index, edge_attr)
print(tuple(out.shape)) # (10, 16)
CGConv
k3_node.layers.conv.CGConv
Bases: MessagePassing
The Crystal Graph Convolutional operator from the
"Crystal Graph Convolutional Neural Networks for an Accurate and
Interpretable Prediction of Material Properties"
<https://arxiv.org/abs/1710.10324>_ paper.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
channels
|
Union[int, Tuple[int, int]]
|
Size of each input sample, or a tuple for bipartite graphs. |
required |
dim
|
int
|
Edge feature dimensionality. (default: |
0
|
aggr
|
str
|
The aggregation scheme to use ( |
'add'
|
batch_norm
|
bool
|
If set to :obj: |
False
|
bias
|
bool
|
If set to :obj: |
True
|
Example
import numpy as np
from k3_node.layers import CGConv
x = np.random.rand(10, 8).astype("float32") # 10 nodes with 8 features each
edge_index = np.random.randint(0, 10, size=(2, 30)) # 30 random edges
edge_attr = np.random.rand(30, 3).astype("float32") # 3 features per edge
layer = CGConv(channels=8, dim=3)
out = layer(x, edge_index, edge_attr)
print(tuple(out.shape)) # (10, 8)
EdgeConv
k3_node.layers.conv.EdgeConv
Bases: MessagePassing
The edge convolutional operator from the "Dynamic Graph CNN for
Learning on Point Clouds" <https://arxiv.org/abs/1801.07829>_ paper.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
nn
|
Callable
|
A neural network :math: |
required |
aggr
|
str
|
The aggregation scheme to use ( |
'max'
|
Example
import numpy as np
import keras
from k3_node.layers import EdgeConv
x = np.random.rand(10, 8).astype("float32") # 10 nodes with 8 features each
edge_index = np.random.randint(0, 10, size=(2, 30)) # 30 random edges
nn = keras.Sequential([keras.layers.Dense(16, activation="relu"), keras.layers.Dense(16)])
layer = EdgeConv(nn)
out = layer(x, edge_index)
print(tuple(out.shape)) # (10, 16)
DynamicEdgeConv
k3_node.layers.conv.DynamicEdgeConv
Bases: EdgeConv
The dynamic edge convolutional operator from the "Dynamic Graph CNN
for Learning on Point Clouds" <https://arxiv.org/abs/1801.07829>_ paper,
which dynamically constructs a graph using :math:k-NN at each layer.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
nn
|
Callable
|
A neural network :math: |
required |
k
|
int
|
Number of nearest neighbors. (default: |
6
|
aggr
|
str
|
The aggregation scheme to use ( |
'max'
|
num_workers
|
int
|
Number of workers (ignored in Keras backend). |
1
|
Example
import numpy as np
import keras
from k3_node.layers import DynamicEdgeConv
x = np.random.rand(10, 8).astype("float32") # 10 nodes with 8 features each
edge_index = np.random.randint(0, 10, size=(2, 30)) # 30 random edges
nn = keras.Sequential([keras.layers.Dense(16, activation="relu"), keras.layers.Dense(16)])
layer = DynamicEdgeConv(nn, k=3)
out = layer(x) # k-NN graph is built from x
print(tuple(out.shape)) # (10, 16)
GeneralConv
k3_node.layers.conv.GeneralConv
Bases: MessagePassing
A general GNN layer adapted from the "Design Space for Graph Neural
Networks" <https://arxiv.org/abs/2011.08843>_ paper.
Example
import numpy as np
from k3_node.layers import GeneralConv
x = np.random.rand(10, 8).astype("float32") # 10 nodes with 8 features each
edge_index = np.random.randint(0, 10, size=(2, 30)) # 30 random edges
edge_attr = np.random.rand(30, 3).astype("float32") # 3 features per edge
layer = GeneralConv(in_channels=8, out_channels=16, in_edge_channels=3)
out = layer(x, edge_index, edge_attr)
print(tuple(out.shape)) # (10, 16)
Heterogeneous & Hypergraph Convolutions
HeteroConv
k3_node.layers.conv.HeteroConv
Bases: Layer
A generic wrapper for computing graph convolution on heterogeneous graphs.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
convs
|
Dict[Tuple[str, str, str], Layer]
|
A dictionary holding a bipartite GNN layer for each individual edge type. |
required |
aggr
|
str
|
The aggregation scheme to use for grouping node
embeddings generated by different relations (:obj: |
'sum'
|
Example
import numpy as np
from k3_node.layers import HeteroConv, SAGEConv
x_dict = {
"author": np.random.rand(3, 8).astype("float32"),
"paper": np.random.rand(4, 8).astype("float32"),
}
edge_index_dict = {
("author", "writes", "paper"): np.array([[0, 1, 2], [1, 2, 3]]),
("paper", "written_by", "author"): np.array([[1, 2, 3], [0, 1, 2]]),
}
# One convolution per edge type; results for the same node type are summed
layer = HeteroConv({
("author", "writes", "paper"): SAGEConv((8, 8), 16),
("paper", "written_by", "author"): SAGEConv((8, 8), 16),
}, aggr="sum")
out_dict = layer(x_dict, edge_index_dict)
print(tuple(out_dict["author"].shape), tuple(out_dict["paper"].shape)) # (3, 16) (4, 16)
HGTConv
k3_node.layers.conv.HGTConv
Bases: MessagePassing
The Heterogeneous Graph Transformer (HGT) operator from the
"Heterogeneous Graph Transformer" <https://arxiv.org/abs/2003.01332>_ paper.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
in_channels
|
int or Dict[str, int]
|
Size of each input sample of every node type. |
required |
out_channels
|
int
|
Size of each output sample. |
required |
metadata
|
Tuple[List[str], List[Tuple[str, str, str]]]
|
Node types and edge types. |
required |
heads
|
int
|
Number of multi-head-attentions. (default: :obj: |
1
|
Example
import numpy as np
from k3_node.layers import HGTConv
x_dict = {
"author": np.random.rand(3, 8).astype("float32"),
"paper": np.random.rand(4, 8).astype("float32"),
}
edge_index_dict = {
("author", "writes", "paper"): np.array([[0, 1, 2], [1, 2, 3]]),
("paper", "written_by", "author"): np.array([[1, 2, 3], [0, 1, 2]]),
}
metadata = (list(x_dict), list(edge_index_dict)) # (node types, edge types)
layer = HGTConv(in_channels={"author": 8, "paper": 8}, out_channels=16, metadata=metadata, heads=2)
out_dict = layer(x_dict, edge_index_dict)
print(tuple(out_dict["author"].shape), tuple(out_dict["paper"].shape)) # (3, 16) (4, 16)
HANConv
k3_node.layers.conv.HANConv
Bases: MessagePassing
The Heterogeneous Graph Attention Operator from the
"Heterogeneous Graph Attention Network" <https://arxiv.org/abs/1903.07293>_ paper.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
in_channels
|
int or Dict[str, int]
|
Size of each input sample of every node type. |
required |
out_channels
|
int
|
Size of each output sample. |
required |
metadata
|
Tuple[List[str], List[Tuple[str, str, str]]]
|
Node types and edge types. |
required |
heads
|
int
|
Number of multi-head-attentions. (default: :obj: |
1
|
negative_slope
|
float
|
LeakyReLU angle of the negative slope. (default: :obj: |
0.2
|
Example
import numpy as np
from k3_node.layers import HANConv
x_dict = {
"author": np.random.rand(3, 8).astype("float32"),
"paper": np.random.rand(4, 8).astype("float32"),
}
edge_index_dict = {
("author", "writes", "paper"): np.array([[0, 1, 2], [1, 2, 3]]),
("paper", "written_by", "author"): np.array([[1, 2, 3], [0, 1, 2]]),
}
metadata = (list(x_dict), list(edge_index_dict)) # (node types, edge types)
layer = HANConv(in_channels={"author": 8, "paper": 8}, out_channels=16, metadata=metadata, heads=2)
out_dict = layer(x_dict, edge_index_dict)
print(tuple(out_dict["author"].shape), tuple(out_dict["paper"].shape)) # (3, 16) (4, 16)
HEATConv
k3_node.layers.conv.HEATConv
Bases: MessagePassing
The heterogeneous edge-enhanced graph attentional operator from the
"Heterogeneous Edge-Enhanced Graph Attention Network For Multi-Agent
Trajectory Prediction" <https://arxiv.org/abs/2106.07161>_ paper.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
in_channels
|
int
|
Size of each input sample. |
required |
out_channels
|
int
|
Size of each output sample. |
required |
num_node_types
|
int
|
The number of node types. |
required |
num_edge_types
|
int
|
The number of edge types. |
required |
edge_type_emb_dim
|
int
|
The embedding size of edge types. |
required |
edge_dim
|
int
|
Edge feature dimensionality. |
required |
edge_attr_emb_dim
|
int
|
The embedding size of edge features. |
required |
heads
|
int
|
Number of multi-head-attentions. (default: :obj: |
1
|
concat
|
bool
|
Whether to concatenate multi-head attention. (default: :obj: |
True
|
negative_slope
|
float
|
LeakyReLU angle. (default: :obj: |
0.2
|
root_weight
|
bool
|
Whether to add root node features. (default: :obj: |
True
|
bias
|
bool
|
Whether to learn an additive bias. (default: :obj: |
True
|
Example
import numpy as np
from k3_node.layers import HEATConv
x = np.random.rand(10, 8).astype("float32") # 10 nodes with 8 features each
edge_index = np.random.randint(0, 10, size=(2, 30)) # 30 random edges
node_type = np.random.randint(0, 2, size=(10,))
edge_type = np.random.randint(0, 3, size=(30,))
edge_attr = np.random.rand(30, 5).astype("float32")
layer = HEATConv(in_channels=8, out_channels=16, num_node_types=2, num_edge_types=3,
edge_type_emb_dim=4, edge_dim=5, edge_attr_emb_dim=6, heads=2)
out = layer(x, edge_index, node_type, edge_type, edge_attr)
print(tuple(out.shape)) # (10, 32)
HypergraphConv
k3_node.layers.conv.HypergraphConv
Bases: MessagePassing
The hypergraph convolutional operator from the "Hypergraph Convolution
and Hypergraph Attention" <https://arxiv.org/abs/1901.08150>_ paper.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
in_channels
|
int
|
Size of each input sample. |
required |
out_channels
|
int
|
Size of each output sample. |
required |
use_attention
|
bool
|
Whether to use hypergraph attention. (default: :obj: |
False
|
attention_mode
|
str
|
Attention mode (:obj: |
'node'
|
heads
|
int
|
Number of multi-head-attentions. (default: :obj: |
1
|
concat
|
bool
|
Whether to concatenate heads. (default: :obj: |
True
|
negative_slope
|
float
|
LeakyReLU angle. (default: :obj: |
0.2
|
bias
|
bool
|
Whether to learn an additive bias. (default: :obj: |
True
|
Example
import numpy as np
from k3_node.layers import HypergraphConv
x = np.random.rand(10, 8).astype("float32") # 10 nodes with 8 features each
edge_index = np.random.randint(0, 10, size=(2, 30)) # 30 random edges
# Row 0: node index, row 1: hyperedge index (nodes 0-5 form two hyperedges)
hyperedge_index = np.array([[0, 1, 2, 3, 4, 5], [0, 0, 0, 1, 1, 1]])
layer = HypergraphConv(in_channels=8, out_channels=16)
out = layer(x, hyperedge_index)
print(tuple(out.shape)) # (10, 16)
DNAConv
k3_node.layers.conv.DNAConv
Bases: MessagePassing
The dynamic neighborhood aggregation operator from the "Just Jump:
Towards Dynamic Neighborhood Aggregation in Graph Neural Networks"
<https://arxiv.org/abs/1904.04849>_ paper.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
channels
|
int
|
Size of each input/output sample. |
required |
heads
|
int
|
Number of multi-head-attentions. (default: :obj: |
1
|
groups
|
int
|
Number of groups for linear projections. (default: :obj: |
1
|
dropout
|
float
|
Dropout probability. (default: :obj: |
0.0
|
cached
|
bool
|
Whether to cache GCN normalization. (default: :obj: |
False
|
normalize
|
bool
|
Whether to apply symmetric normalization. (default: :obj: |
True
|
add_self_loops
|
bool
|
Whether to add self-loops. (default: :obj: |
True
|
bias
|
bool
|
Whether to learn an additive bias. (default: :obj: |
True
|
Example
import numpy as np
from k3_node.layers import DNAConv
x = np.random.rand(10, 8).astype("float32") # 10 nodes with 8 features each
edge_index = np.random.randint(0, 10, size=(2, 30)) # 30 random edges
# DNAConv attends over the representations of all previous layers: [num_nodes, num_layers, channels]
x_all = np.random.rand(10, 3, 8).astype("float32")
layer = DNAConv(channels=8, heads=2, groups=2)
out = layer(x_all, edge_index)
print(tuple(out.shape)) # (10, 8)
WLConv
k3_node.layers.conv.WLConv
Bases: Layer
The Weisfeiler Lehman (WL) operator from the "A Reduction of a Graph
to a Canonical Form and an Algebra Arising During this Reduction"
<https://www.iti.zcu.cz/wl2018/pdf/wl_paper_translation.pdf>_ paper.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
**kwargs
|
Additional layer arguments. |
{}
|
Example
import numpy as np
from k3_node.layers import WLConv
colors = np.array([0, 1, 0, 1]) # discrete node colors (labels)
edge_index = np.array([[0, 1, 2, 3], [1, 2, 3, 0]])
layer = WLConv()
new_colors = layer(colors, edge_index) # one Weisfeiler-Lehman refinement step
print(tuple(new_colors.shape)) # (4,)
print(tuple(layer.histogram(new_colors).shape)) # (1, 2): color histogram per graph
GPSConv
k3_node.layers.conv.GPSConv
Bases: Layer
The general, powerful, scalable (GPS) graph transformer layer from the
"Recipe for a General, Powerful, Scalable Graph Transformer"
<https://arxiv.org/abs/2205.12454>_ paper.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
channels
|
int
|
Size of each input sample. |
required |
conv
|
Layer
|
The local message passing layer. |
None
|
heads
|
int
|
Number of multi-head-attentions. (default: :obj: |
1
|
dropout
|
float
|
Dropout probability. (default: :obj: |
0.0
|
act
|
str
|
Activation function. (default: :obj: |
'relu'
|
norm
|
str
|
Normalization function. (default: :obj: |
'batch_norm'
|
Call arguments: x, edge_index, batch (the graph of every node) and batch_size
(the number of graphs; pass it when training compiled so that shapes are static), plus any
arguments of the local conv such as edge_attr.
Example
import numpy as np
from k3_node.layers import GPSConv, GCNConv
x = np.random.rand(10, 8).astype("float32") # 10 nodes with 8 features each
edge_index = np.random.randint(0, 10, size=(2, 30)) # 30 random edges
batch = np.repeat([0, 1], 5) # two graphs with 5 nodes each
layer = GPSConv(channels=8, conv=GCNConv(8, 8), heads=2)
out = layer(x, edge_index, batch=batch)
print(tuple(out.shape)) # (10, 8)
Point Cloud & Geometric Convolutions
PointNetConv
k3_node.layers.conv.PointNetConv
Bases: MessagePassing
The PointNet set abstraction layer from the "PointNet++: Deep
Hierarchical Feature Learning on Point Sets in a Metric Space"
<https://arxiv.org/abs/1706.02413>_ paper.
Example
import numpy as np
import keras
from k3_node.layers import PointNetConv
x = np.random.rand(10, 8).astype("float32") # 10 nodes with 8 features each
edge_index = np.random.randint(0, 10, size=(2, 30)) # 30 random edges
pos = np.random.rand(10, 3).astype("float32") # 3D node positions
local_nn = keras.Sequential([keras.layers.Dense(16, activation="relu"), keras.layers.Dense(16)])
layer = PointNetConv(local_nn=local_nn)
out = layer(x, pos, edge_index)
print(tuple(out.shape)) # (10, 16)
PointConv
k3_node.layers.conv.PointConv = PointNetConv
module-attribute
PointTransformerConv
k3_node.layers.conv.PointTransformerConv
Bases: MessagePassing
The Point Transformer layer from the "Point Transformer"
<https://arxiv.org/abs/2012.09164>_ paper.
Example
import numpy as np
from k3_node.layers import PointTransformerConv
x = np.random.rand(10, 8).astype("float32") # 10 nodes with 8 features each
edge_index = np.random.randint(0, 10, size=(2, 30)) # 30 random edges
pos = np.random.rand(10, 3).astype("float32") # 3D node positions
layer = PointTransformerConv(in_channels=8, out_channels=16)
out = layer(x, pos, edge_index)
print(tuple(out.shape)) # (10, 16)
PointGNNConv
k3_node.layers.conv.PointGNNConv
Bases: MessagePassing
The PointGNN graph convolutional operator from the
"Point-GNN: Graph Neural Network for 3D Object Detection in a Point Cloud"
<https://arxiv.org/abs/2003.01251>_ paper.
Example
import numpy as np
import keras
from k3_node.layers import PointGNNConv
x = np.random.rand(10, 8).astype("float32") # 10 nodes with 8 features each
edge_index = np.random.randint(0, 10, size=(2, 30)) # 30 random edges
pos = np.random.rand(10, 3).astype("float32") # 3D node positions
layer = PointGNNConv(
mlp_h=keras.layers.Dense(3), # predicts a position offset per node
mlp_f=keras.layers.Dense(16), # edge feature network
mlp_g=keras.layers.Dense(8), # node update network (output size = input features)
)
out = layer(x, pos, edge_index)
print(tuple(out.shape)) # (10, 8)
PPFConv
k3_node.layers.conv.PPFConv
Bases: MessagePassing
The PPFNet graph convolutional operator from the
"PPFNet: Global Context Aware Local Features for Robust 3D Point
Matching" <https://arxiv.org/abs/1802.02669>_ paper.
Example
import numpy as np
import keras
from k3_node.layers import PPFConv
x = np.random.rand(10, 8).astype("float32") # 10 nodes with 8 features each
edge_index = np.random.randint(0, 10, size=(2, 30)) # 30 random edges
pos = np.random.rand(10, 3).astype("float32") # 3D node positions
normal = np.random.rand(10, 3).astype("float32") # surface normals
local_nn = keras.Sequential([keras.layers.Dense(16, activation="relu"), keras.layers.Dense(16)])
layer = PPFConv(local_nn=local_nn)
out = layer(x, pos, normal, edge_index)
print(tuple(out.shape)) # (10, 16)
FeaStConv
k3_node.layers.conv.FeaStConv
Bases: MessagePassing
The (fault-tolerant) feature-steered graph convolution operator from
the "FeaStNet: Feature-Steered Graph Convolutions for 3D Shape Analysis"
<https://arxiv.org/abs/1706.05206>_ paper.
Example
import numpy as np
from k3_node.layers import FeaStConv
x = np.random.rand(10, 8).astype("float32") # 10 nodes with 8 features each
edge_index = np.random.randint(0, 10, size=(2, 30)) # 30 random edges
layer = FeaStConv(in_channels=8, out_channels=16, heads=2)
out = layer(x, edge_index)
print(tuple(out.shape)) # (10, 16)
GMMConv
k3_node.layers.conv.GMMConv
Bases: MessagePassing
The gaussian mixture model convolutional operator from the "Geometric
Deep Learning on Graphs and Manifolds using Mixture Model CNNs"
<https://arxiv.org/abs/1611.08402>_ paper.
Example
import numpy as np
from k3_node.layers import GMMConv
x = np.random.rand(10, 8).astype("float32") # 10 nodes with 8 features each
edge_index = np.random.randint(0, 10, size=(2, 30)) # 30 random edges
edge_attr = np.random.rand(30, 3).astype("float32") # 3 features per edge
layer = GMMConv(in_channels=8, out_channels=16, dim=3, kernel_size=2)
out = layer(x, edge_index, edge_attr)
print(tuple(out.shape)) # (10, 16)
GravNetConv
k3_node.layers.conv.GravNetConv
Bases: MessagePassing
The GravNet operator from the "Learning Representations of Irregular
Particle-Detector Geometry with Distance-Weighted Graph Networks"
<https://arxiv.org/abs/1902.07987>_ paper.
Example
import numpy as np
from k3_node.layers import GravNetConv
x = np.random.rand(10, 8).astype("float32") # 10 nodes with 8 features each
edge_index = np.random.randint(0, 10, size=(2, 30)) # 30 random edges
# Neighbors are found by k-NN in a learned space, so no edge_index is needed
layer = GravNetConv(in_channels=8, out_channels=16, space_dimensions=3, propagate_dimensions=4, k=3)
out = layer(x)
print(tuple(out.shape)) # (10, 16)
MeshCNNConv
k3_node.layers.conv.MeshCNNConv
Bases: MessagePassing
The MeshCNN convolutional operator from the "MeshCNN: A Network With An Edge"
<https://arxiv.org/abs/1809.05910>_ paper.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
in_channels
|
int
|
Size of each input sample. |
required |
out_channels
|
int
|
Size of each output sample. |
required |
kernels
|
List[Layer]
|
A list of 5 neural network layers
that transform edge representations. (default: :obj: |
None
|
Example
import numpy as np
from k3_node.layers import MeshCNNConv
# In MeshCNN the "nodes" are mesh edges; each mesh edge has exactly 4 neighboring edges,
# listed in a fixed order in edge_index (4 incoming entries per mesh edge).
x = np.random.rand(4, 8).astype("float32") # features of 4 mesh edges
edge_index = np.array([
[1, 2, 3, 0, 0, 2, 3, 1, 0, 1, 3, 2, 0, 1, 2, 3], # neighboring mesh edge
[0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3], # mesh edge being updated
])
layer = MeshCNNConv(in_channels=8, out_channels=16)
out = layer(x, edge_index)
print(tuple(out.shape)) # (4, 16)
XConv
k3_node.layers.conv.XConv
Bases: Layer
The convolutional operator on :math:\mathcal{X}-transformed points
from the "PointCNN: Convolution On X-Transformed Points"
<https://arxiv.org/abs/1801.07791>_ paper.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
in_channels
|
int
|
Size of each input sample. |
required |
out_channels
|
int
|
Size of each output sample. |
required |
dim
|
int
|
Point cloud dimensionality. |
required |
kernel_size
|
int
|
Size of the convolving kernel. |
required |
hidden_channels
|
int
|
Dimensionality of lifted points. |
None
|
dilation
|
int
|
Dilation factor. (default: :obj: |
1
|
bias
|
bool
|
Whether to learn an additive bias. (default: :obj: |
True
|
num_workers
|
int
|
Kept for PyG compatibility. |
1
|
Example
import numpy as np
from k3_node.layers import XConv
x = np.random.rand(10, 8).astype("float32") # 10 nodes with 8 features each
edge_index = np.random.randint(0, 10, size=(2, 30)) # 30 random edges
pos = np.random.rand(10, 3).astype("float32") # 3D node positions
layer = XConv(in_channels=8, out_channels=16, dim=3, kernel_size=2)
out = layer(x, pos) # neighborhoods are built from `pos`
print(tuple(out.shape)) # (10, 16)
SplineConv
k3_node.layers.conv.SplineConv
Bases: MessagePassing
The spline-based convolutional operator from the "SplineCNN: Fast
Geometric Deep Learning with Continuous B-Spline Kernels"
<https://arxiv.org/abs/1711.08920>_ paper.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
in_channels
|
int or tuple
|
Size of each input sample. |
required |
out_channels
|
int
|
Size of each output sample. |
required |
dim
|
int
|
Pseudo-coordinate dimensionality. |
required |
kernel_size
|
int or List[int]
|
Size of the convolving kernel. |
required |
is_open_spline
|
bool or List[bool]
|
If set to :obj: |
True
|
degree
|
int
|
B-spline basis degree. (default: :obj: |
1
|
aggr
|
str
|
The aggregation scheme to use (:obj: |
'mean'
|
root_weight
|
bool
|
Whether to add transformed root node
features. (default: :obj: |
True
|
bias
|
bool
|
Whether to learn an additive bias. (default: :obj: |
True
|
Example
import numpy as np
from k3_node.layers import SplineConv
x = np.random.rand(10, 8).astype("float32") # 10 nodes with 8 features each
edge_index = np.random.randint(0, 10, size=(2, 30)) # 30 random edges
pseudo = np.random.rand(30, 2).astype("float32") # pseudo-coordinates in [0, 1]
layer = SplineConv(in_channels=8, out_channels=16, dim=2, kernel_size=3)
out = layer(x, edge_index, pseudo)
print(tuple(out.shape)) # (10, 16)
Spektral-Compatible Convolutions
CrystalConv
k3_node.layers.conv.CrystalConv
Bases: MessagePassing
k3_node.layers.CrystalConv
Implementation of Crystal Graph Convolutional Neural Networks (CGCNN) layer
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
channels
|
The number of channels/units (optional). |
None
|
|
edge_dim
|
The dimensionality of edge features (optional). |
None
|
|
aggregate
|
Aggregation function to use (one of 'sum', 'mean', 'max'). |
'sum'
|
|
activation
|
Activation function to use. |
None
|
|
use_bias
|
Whether to add a bias to the linear transformation. |
True
|
|
kernel_initializer
|
Initializer for the |
'glorot_uniform'
|
|
bias_initializer
|
Initializer for the bias vector. |
'zeros'
|
|
kernel_regularizer
|
Regularizer for the |
None
|
|
bias_regularizer
|
Regularizer for the bias vector. |
None
|
|
activity_regularizer
|
Regularizer for the output. |
None
|
|
kernel_constraint
|
Constraint for the |
None
|
|
bias_constraint
|
Constraint for the bias vector. |
None
|
|
**kwargs
|
Additional arguments to pass to the |
{}
|
Example
import numpy as np
from k3_node.layers import CrystalConv
x = np.random.rand(10, 8).astype("float32") # 10 nodes with 8 features each
edge_index = np.random.randint(0, 10, size=(2, 30)) # 30 random edges
edge_attr = np.random.rand(30, 3).astype("float32") # 3 features per edge
layer = CrystalConv(channels=8, edge_dim=3)
out = layer(x, edge_index, edge_attr)
print(tuple(out.shape)) # (10, 8)
DiffusionConv
k3_node.layers.conv.DiffusionConv
Bases: Conv
k3_node.layers.DiffusionConv
Implementation of Diffusion Convolutional Neural Networks (DCNN) layer
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
channels
|
The number of output channels. |
required | |
K
|
The number of diffusion steps. |
6
|
|
activation
|
Activation function to use. |
'tanh'
|
|
kernel_initializer
|
Initializer for the |
'glorot_uniform'
|
|
kernel_regularizer
|
Regularizer for the |
None
|
|
kernel_constraint
|
Constraint for the |
None
|
|
**kwargs
|
Additional arguments to pass to the |
{}
|
Example
import numpy as np
from k3_node.layers import DiffusionConv
x = np.random.rand(10, 8).astype("float32") # 10 nodes with 8 features each
edge_index = np.random.randint(0, 10, size=(2, 30)) # 30 random edges
layer = DiffusionConv(channels=8, out_channels=16, K=2)
out = layer(x, edge_index)
print(tuple(out.shape)) # (10, 16)
GraphConvolution
k3_node.layers.conv.GraphConvolution
Bases: Layer
k3_node.layers.GraphConvolution
Implementation of Graph Convolution (GCN) layer
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
units
|
Positive integer, dimensionality of the output space. |
required | |
activation
|
Activation function to use. |
None
|
|
use_bias
|
Whether to add a bias to the linear transformation. |
True
|
|
final_layer
|
Deprecated, use tf.gather or GatherIndices instead. |
None
|
|
input_dim
|
Deprecated, use |
None
|
|
kernel_initializer
|
Initializer for the |
'glorot_uniform'
|
|
kernel_regularizer
|
Regularizer for the |
None
|
|
kernel_constraint
|
Constraint for the |
None
|
|
bias_initializer
|
Initializer for the bias vector. |
'zeros'
|
|
bias_regularizer
|
Regularizer for the bias vector. |
None
|
|
bias_constraint
|
Constraint for the bias vector. |
None
|
|
**kwargs
|
Additional arguments to pass to the |
{}
|
Example
import numpy as np
from k3_node.layers import GraphConvolution
x = np.random.rand(10, 8).astype("float32") # 10 nodes with 8 features each
edge_index = np.random.randint(0, 10, size=(2, 30)) # 30 random edges
layer = GraphConvolution(units=16, activation="relu")
out = layer(x, edge_index)
print(tuple(out.shape)) # (10, 16)
GraphAttention
k3_node.layers.conv.GraphAttention
Bases: Layer
k3_node.layers.GraphAttention
Implementation of Graph Attention (GAT) layer
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
units
|
Positive integer, dimensionality of the output space. |
required | |
attn_heads
|
Positive integer, number of attention heads. |
1
|
|
attn_heads_reduction
|
{'concat', 'average'} Method for reducing attention heads. |
'concat'
|
|
in_dropout_rate
|
Dropout rate applied to the input (node features). |
0.0
|
|
attn_dropout_rate
|
Dropout rate applied to attention coefficients. |
0.0
|
|
activation
|
Activation function to use. |
'relu'
|
|
use_bias
|
Whether to add a bias to the linear transformation. |
True
|
|
final_layer
|
Deprecated, use tf.gather or GatherIndices instead. |
None
|
|
saliency_map_support
|
Whether to support saliency map calculations. |
False
|
|
kernel_initializer
|
Initializer for the |
'glorot_uniform'
|
|
kernel_regularizer
|
Regularizer for the |
None
|
|
kernel_constraint
|
Constraint for the |
None
|
|
bias_initializer
|
Initializer for the bias vector. |
'zeros'
|
|
bias_regularizer
|
Regularizer for the bias vector. |
None
|
|
bias_constraint
|
Constraint for the bias vector. |
None
|
|
attn_kernel_initializer
|
Initializer for the attention kernel weights matrix. |
'glorot_uniform'
|
|
attn_kernel_regularizer
|
Regularizer for the attention kernel weights matrix. |
None
|
|
attn_kernel_constraint
|
Constraint for the attention kernel weights matrix. |
None
|
|
**kwargs
|
Additional arguments to pass to the |
{}
|
Example
import numpy as np
from k3_node.layers import GraphAttention
x = np.random.rand(10, 8).astype("float32") # 10 nodes with 8 features each
edge_index = np.random.randint(0, 10, size=(2, 30)) # 30 random edges
layer = GraphAttention(units=16, attn_heads=2)
out = layer(x, edge_index)
print(tuple(out.shape)) # (10, 2)
PPNPPropagation
k3_node.layers.conv.PPNPPropagation
Bases: Layer
k3_node.layers.PPNPPropagation
Implementation of PPNP layer
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
units
|
Positive integer, dimensionality of the output space. |
None
|
|
final_layer
|
Deprecated. |
None
|
|
input_dim
|
Deprecated. |
None
|
|
**kwargs
|
Additional arguments to pass to the |
{}
|
Example
import numpy as np
from k3_node.layers import PPNPPropagation
x = np.random.rand(10, 8).astype("float32") # 10 nodes with 8 features each
edge_index = np.random.randint(0, 10, size=(2, 30)) # 30 random edges
layer = PPNPPropagation(units=16)
out = layer(x, edge_index)
print(tuple(out.shape)) # (10, 16)