diff --git a/gnngraphs/.documenter-siteinfo.json b/gnngraphs/.documenter-siteinfo.json index 5e1c8b55b..1da45b3d8 100644 --- a/gnngraphs/.documenter-siteinfo.json +++ b/gnngraphs/.documenter-siteinfo.json @@ -1 +1 @@ -{"documenter":{"julia_version":"1.10.5","generation_timestamp":"2024-11-08T08:44:16","documenter_version":"1.7.0"}} \ No newline at end of file +{"documenter":{"julia_version":"1.10.5","generation_timestamp":"2024-11-09T14:46:50","documenter_version":"1.7.0"}} \ No newline at end of file diff --git a/gnngraphs/api/gnngraph/index.html b/gnngraphs/api/gnngraph/index.html index cf41476f3..e5350018b 100644 --- a/gnngraphs/api/gnngraph/index.html +++ b/gnngraphs/api/gnngraph/index.html @@ -1,4 +1,4 @@ -GNNGraph · GNNGraphs.jl

GNNGraph

Documentation page for the graph type GNNGraph provided by GNNGraphs.jl and related methods.

Besides the methods documented here, one can rely on the large set of functionalities given by Graphs.jl thanks to the fact that GNNGraph inherits from Graphs.AbstractGraph.

Index

GNNGraph type

GNNGraphs.GNNGraphType
GNNGraph(data; [graph_type, ndata, edata, gdata, num_nodes, graph_indicator, dir])
+GNNGraph · GNNGraphs.jl

GNNGraph

Documentation page for the graph type GNNGraph provided by GNNGraphs.jl and related methods.

Besides the methods documented here, one can rely on the large set of functionalities given by Graphs.jl thanks to the fact that GNNGraph inherits from Graphs.AbstractGraph.

Index

GNNGraph type

GNNGraphs.GNNGraphType
GNNGraph(data; [graph_type, ndata, edata, gdata, num_nodes, graph_indicator, dir])
 GNNGraph(g::GNNGraph; [ndata, edata, gdata])

A type representing a graph structure that also stores feature arrays associated to nodes, edges, and the graph itself.

The feature arrays are stored in the fields ndata, edata, and gdata as DataStore objects offering a convenient dictionary-like and namedtuple-like interface. The features can be passed at construction time or added later.

A GNNGraph can be constructed out of different data objects expressing the connections inside the graph. The internal representation type is determined by graph_type.

When constructed from another GNNGraph, the internal graph representation is preserved and shared. The node/edge/graph features are retained as well, unless explicitely set by the keyword arguments ndata, edata, and gdata.

A GNNGraph can also represent multiple graphs batched togheter (see MLUtils.batch or SparseArrays.blockdiag). The field g.graph_indicator contains the graph membership of each node.

GNNGraphs are always directed graphs, therefore each edge is defined by a source node and a target node (see edge_index). Self loops (edges connecting a node to itself) and multiple edges (more than one edge between the same pair of nodes) are supported.

A GNNGraph is a Graphs.jl's AbstractGraph, therefore it supports most functionality from that library.

Arguments

  • data: Some data representing the graph topology. Possible type are
    • An adjacency matrix
    • An adjacency list.
    • A tuple containing the source and target vectors (COO representation)
    • A Graphs.jl' graph.
  • graph_type: A keyword argument that specifies the underlying representation used by the GNNGraph. Currently supported values are
    • :coo. Graph represented as a tuple (source, target), such that the k-th edge connects the node source[k] to node target[k]. Optionally, also edge weights can be given: (source, target, weights).
    • :sparse. A sparse adjacency matrix representation.
    • :dense. A dense adjacency matrix representation.
    Defaults to :coo, currently the most supported type.
  • dir: The assumed edge direction when given adjacency matrix or adjacency list input data g. Possible values are :out and :in. Default :out.
  • num_nodes: The number of nodes. If not specified, inferred from g. Default nothing.
  • graph_indicator: For batched graphs, a vector containing the graph assignment of each node. Default nothing.
  • ndata: Node features. An array or named tuple of arrays whose last dimension has size num_nodes.
  • edata: Edge features. An array or named tuple of arrays whose last dimension has size num_edges.
  • gdata: Graph features. An array or named tuple of arrays whose last dimension has size num_graphs.

Examples

using GraphNeuralNetworks
 
 # Construct from adjacency list representation
@@ -34,7 +34,7 @@
 # Both source and target are vectors of length num_edges
 source, target = edge_index(g)

A GNNGraph can be sent to the GPU using e.g. Flux's gpu function:

# Send to gpu
 using Flux, CUDA
-g = g |> Flux.gpu
source
Base.copyFunction
copy(g::GNNGraph; deep=false)

Create a copy of g. If deep is true, then copy will be a deep copy (equivalent to deepcopy(g)), otherwise it will be a shallow copy with the same underlying graph data.

source

DataStore

Base.copyFunction
copy(g::GNNGraph; deep=false)

Create a copy of g. If deep is true, then copy will be a deep copy (equivalent to deepcopy(g)), otherwise it will be a shallow copy with the same underlying graph data.

source

DataStore

GNNGraphs.DataStoreType
DataStore([n, data])
 DataStore([n,] k1 = x1, k2 = x2, ...)

A container for feature arrays. The optional argument n enforces that numobs(x) == n for each array contained in the datastore.

At construction time, the data can be provided as any iterables of pairs of symbols and arrays or as keyword arguments:

julia> ds = DataStore(3, x = rand(Float32, 2, 3), y = rand(Float32, 3))
 DataStore(3) with 2 elements:
   y = 3-element Vector{Float32}
@@ -78,8 +78,8 @@
 julia> ds2.a
 2-element Vector{Float64}:
  1.0
- 1.0
source

Query

GNNGraphs.adjacency_listMethod
adjacency_list(g; dir=:out)
-adjacency_list(g, nodes; dir=:out)

Return the adjacency list representation (a vector of vectors) of the graph g.

Calling a the adjacency list, if dir=:out than a[i] will contain the neighbors of node i through outgoing edges. If dir=:in, it will contain neighbors from incoming edges instead.

If nodes is given, return the neighborhood of the nodes in nodes only.

source
GNNGraphs.edge_indexMethod
edge_index(g::GNNGraph)

Return a tuple containing two vectors, respectively storing the source and target nodes for each edges in g.

s, t = edge_index(g)
source
GNNGraphs.edge_indexMethod
edge_index(g::GNNHeteroGraph, [edge_t])

Return a tuple containing two vectors, respectively storing the source and target nodes for each edges in g of type edge_t = (src_t, rel_t, trg_t).

If edge_t is not provided, it will error if g has more than one edge type.

source
GNNGraphs.graph_indicatorMethod
graph_indicator(g::GNNGraph; edges=false)

Return a vector containing the graph membership (an integer from 1 to g.num_graphs) of each node in the graph. If edges=true, return the graph membership of each edge instead.

source
GNNGraphs.graph_indicatorMethod
graph_indicator(g::GNNHeteroGraph, [node_t])

Return a Dict of vectors containing the graph membership (an integer from 1 to g.num_graphs) of each node in the graph for each node type. If node_t is provided, return the graph membership of each node of type node_t instead.

See also batch.

source
GNNGraphs.has_isolated_nodesMethod
has_isolated_nodes(g::GNNGraph; dir=:out)

Return true if the graph g contains nodes with out-degree (if dir=:out) or in-degree (if dir = :in) equal to zero.

source
GNNGraphs.is_bidirectedMethod
is_bidirected(g::GNNGraph)

Check if the directed graph g essentially corresponds to an undirected graph, i.e. if for each edge it also contains the reverse edge.

source
GNNGraphs.khop_adjFunction
khop_adj(g::GNNGraph,k::Int,T::DataType=eltype(g); dir=:out, weighted=true)

Return $A^k$ where $A$ is the adjacency matrix of the graph 'g'.

source
GNNGraphs.laplacian_lambda_maxFunction
laplacian_lambda_max(g::GNNGraph, T=Float32; add_self_loops=false, dir=:out)

Return the largest eigenvalue of the normalized symmetric Laplacian of the graph g.

If the graph is batched from multiple graphs, return the list of the largest eigenvalue for each graph.

source
GNNGraphs.normalized_laplacianFunction
normalized_laplacian(g, T=Float32; add_self_loops=false, dir=:out)

Normalized Laplacian matrix of graph g.

Arguments

  • g: A GNNGraph.
  • T: result element type.
  • add_self_loops: add self-loops while calculating the matrix.
  • dir: the edge directionality considered (:out, :in, :both).
source
GNNGraphs.scaled_laplacianFunction
scaled_laplacian(g, T=Float32; dir=:out)

Scaled Laplacian matrix of graph g, defined as $\hat{L} = \frac{2}{\lambda_{max}} L - I$ where $L$ is the normalized Laplacian matrix.

Arguments

  • g: A GNNGraph.
  • T: result element type.
  • dir: the edge directionality considered (:out, :in, :both).
source
Graphs.LinAlg.adjacency_matrixFunction
adjacency_matrix(g::GNNGraph, T=eltype(g); dir=:out, weighted=true)

Return the adjacency matrix A for the graph g.

If dir=:out, A[i,j] > 0 denotes the presence of an edge from node i to node j. If dir=:in instead, A[i,j] > 0 denotes the presence of an edge from node j to node i.

User may specify the eltype T of the returned matrix.

If weighted=true, the A will contain the edge weights if any, otherwise the elements of A will be either 0 or 1.

source
Graphs.degreeMethod
degree(g::GNNGraph, T=nothing; dir=:out, edge_weight=true)

Return a vector containing the degrees of the nodes in g.

The gradient is propagated through this function only if edge_weight is true or a vector.

Arguments

  • g: A graph.
  • T: Element type of the returned vector. If nothing, is chosen based on the graph type and will be an integer if edge_weight = false. Default nothing.
  • dir: For dir = :out the degree of a node is counted based on the outgoing edges. For dir = :in, the ingoing edges are used. If dir = :both we have the sum of the two.
  • edge_weight: If true and the graph contains weighted edges, the degree will be weighted. Set to false instead to just count the number of outgoing/ingoing edges. Finally, you can also pass a vector of weights to be used instead of the graph's own weights. Default true.
source
Graphs.degreeMethod
degree(g::GNNHeteroGraph, edge_type::EType; dir = :in)

Return a vector containing the degrees of the nodes in g GNNHeteroGraph given edge_type.

Arguments

  • g: A graph.
  • edge_type: A tuple of symbols (source_t, edge_t, target_t) representing the edge type.
  • T: Element type of the returned vector. If nothing, is chosen based on the graph type. Default nothing.
  • dir: For dir = :out the degree of a node is counted based on the outgoing edges. For dir = :in, the ingoing edges are used. If dir = :both we have the sum of the two. Default dir = :out.
source
Graphs.neighborsMethod
neighbors(g::GNNGraph, i::Integer; dir=:out)

Return the neighbors of node i in the graph g. If dir=:out, return the neighbors through outgoing edges. If dir=:in, return the neighbors through incoming edges.

See also outneighbors, inneighbors.

source

Transform

Query

GNNGraphs.adjacency_listMethod
adjacency_list(g; dir=:out)
+adjacency_list(g, nodes; dir=:out)

Return the adjacency list representation (a vector of vectors) of the graph g.

Calling a the adjacency list, if dir=:out than a[i] will contain the neighbors of node i through outgoing edges. If dir=:in, it will contain neighbors from incoming edges instead.

If nodes is given, return the neighborhood of the nodes in nodes only.

source
GNNGraphs.edge_indexMethod
edge_index(g::GNNGraph)

Return a tuple containing two vectors, respectively storing the source and target nodes for each edges in g.

s, t = edge_index(g)
source
GNNGraphs.edge_indexMethod
edge_index(g::GNNHeteroGraph, [edge_t])

Return a tuple containing two vectors, respectively storing the source and target nodes for each edges in g of type edge_t = (src_t, rel_t, trg_t).

If edge_t is not provided, it will error if g has more than one edge type.

source
GNNGraphs.graph_indicatorMethod
graph_indicator(g::GNNGraph; edges=false)

Return a vector containing the graph membership (an integer from 1 to g.num_graphs) of each node in the graph. If edges=true, return the graph membership of each edge instead.

source
GNNGraphs.graph_indicatorMethod
graph_indicator(g::GNNHeteroGraph, [node_t])

Return a Dict of vectors containing the graph membership (an integer from 1 to g.num_graphs) of each node in the graph for each node type. If node_t is provided, return the graph membership of each node of type node_t instead.

See also batch.

source
GNNGraphs.has_isolated_nodesMethod
has_isolated_nodes(g::GNNGraph; dir=:out)

Return true if the graph g contains nodes with out-degree (if dir=:out) or in-degree (if dir = :in) equal to zero.

source
GNNGraphs.is_bidirectedMethod
is_bidirected(g::GNNGraph)

Check if the directed graph g essentially corresponds to an undirected graph, i.e. if for each edge it also contains the reverse edge.

source
GNNGraphs.khop_adjFunction
khop_adj(g::GNNGraph,k::Int,T::DataType=eltype(g); dir=:out, weighted=true)

Return $A^k$ where $A$ is the adjacency matrix of the graph 'g'.

source
GNNGraphs.laplacian_lambda_maxFunction
laplacian_lambda_max(g::GNNGraph, T=Float32; add_self_loops=false, dir=:out)

Return the largest eigenvalue of the normalized symmetric Laplacian of the graph g.

If the graph is batched from multiple graphs, return the list of the largest eigenvalue for each graph.

source
GNNGraphs.normalized_laplacianFunction
normalized_laplacian(g, T=Float32; add_self_loops=false, dir=:out)

Normalized Laplacian matrix of graph g.

Arguments

  • g: A GNNGraph.
  • T: result element type.
  • add_self_loops: add self-loops while calculating the matrix.
  • dir: the edge directionality considered (:out, :in, :both).
source
GNNGraphs.scaled_laplacianFunction
scaled_laplacian(g, T=Float32; dir=:out)

Scaled Laplacian matrix of graph g, defined as $\hat{L} = \frac{2}{\lambda_{max}} L - I$ where $L$ is the normalized Laplacian matrix.

Arguments

  • g: A GNNGraph.
  • T: result element type.
  • dir: the edge directionality considered (:out, :in, :both).
source
Graphs.LinAlg.adjacency_matrixFunction
adjacency_matrix(g::GNNGraph, T=eltype(g); dir=:out, weighted=true)

Return the adjacency matrix A for the graph g.

If dir=:out, A[i,j] > 0 denotes the presence of an edge from node i to node j. If dir=:in instead, A[i,j] > 0 denotes the presence of an edge from node j to node i.

User may specify the eltype T of the returned matrix.

If weighted=true, the A will contain the edge weights if any, otherwise the elements of A will be either 0 or 1.

source
Graphs.degreeMethod
degree(g::GNNGraph, T=nothing; dir=:out, edge_weight=true)

Return a vector containing the degrees of the nodes in g.

The gradient is propagated through this function only if edge_weight is true or a vector.

Arguments

  • g: A graph.
  • T: Element type of the returned vector. If nothing, is chosen based on the graph type and will be an integer if edge_weight = false. Default nothing.
  • dir: For dir = :out the degree of a node is counted based on the outgoing edges. For dir = :in, the ingoing edges are used. If dir = :both we have the sum of the two.
  • edge_weight: If true and the graph contains weighted edges, the degree will be weighted. Set to false instead to just count the number of outgoing/ingoing edges. Finally, you can also pass a vector of weights to be used instead of the graph's own weights. Default true.
source
Graphs.degreeMethod
degree(g::GNNHeteroGraph, edge_type::EType; dir = :in)

Return a vector containing the degrees of the nodes in g GNNHeteroGraph given edge_type.

Arguments

  • g: A graph.
  • edge_type: A tuple of symbols (source_t, edge_t, target_t) representing the edge type.
  • T: Element type of the returned vector. If nothing, is chosen based on the graph type. Default nothing.
  • dir: For dir = :out the degree of a node is counted based on the outgoing edges. For dir = :in, the ingoing edges are used. If dir = :both we have the sum of the two. Default dir = :out.
source
Graphs.neighborsMethod
neighbors(g::GNNGraph, i::Integer; dir=:out)

Return the neighbors of node i in the graph g. If dir=:out, return the neighbors through outgoing edges. If dir=:in, return the neighbors through incoming edges.

See also outneighbors, inneighbors.

source

Transform

GNNGraphs.add_edgesMethod
add_edges(g::GNNGraph, s::AbstractVector, t::AbstractVector; [edata])
 add_edges(g::GNNGraph, (s, t); [edata])
 add_edges(g::GNNGraph, (s, t, w); [edata])

Add to graph g the edges with source nodes s and target nodes t. Optionally, pass the edge weight w and the features edata for the new edges. Returns a new graph sharing part of the underlying data with g.

If the s or t contain nodes that are not already present in the graph, they are added to the graph as well.

Examples

julia> s, t = [1, 2, 3, 3, 4], [2, 3, 4, 4, 4];
 
@@ -101,12 +101,12 @@
 julia> add_edges(g, [1,2], [2,3])
 GNNGraph:
     num_nodes: 3
-    num_edges: 2
source
GNNGraphs.add_edgesMethod
add_edges(g::GNNHeteroGraph, edge_t, s, t; [edata, num_nodes])
 add_edges(g::GNNHeteroGraph, edge_t => (s, t); [edata, num_nodes])
-add_edges(g::GNNHeteroGraph, edge_t => (s, t, w); [edata, num_nodes])

Add to heterograph g edges of type edge_t with source node vector s and target node vector t. Optionally, pass the edge weights w or the features edata for the new edges. edge_t is a triplet of symbols (src_t, rel_t, dst_t).

If the edge type is not already present in the graph, it is added. If it involves new node types, they are added to the graph as well. In this case, a dictionary or named tuple of num_nodes can be passed to specify the number of nodes of the new types, otherwise the number of nodes is inferred from the maximum node id in s and t.

source
GNNGraphs.add_nodesMethod
add_nodes(g::GNNGraph, n; [ndata])

Add n new nodes to graph g. In the new graph, these nodes will have indexes from g.num_nodes + 1 to g.num_nodes + n.

source
GNNGraphs.add_self_loopsMethod
add_self_loops(g::GNNGraph)

Return a graph with the same features as g but also adding edges connecting the nodes to themselves.

Nodes with already existing self-loops will obtain a second self-loop.

If the graphs has edge weights, the new edges will have weight 1.

source
GNNGraphs.add_self_loopsMethod
add_self_loops(g::GNNHeteroGraph, edge_t::EType)
-add_self_loops(g::GNNHeteroGraph)

If the source node type is the same as the destination node type in edge_t, return a graph with the same features as g but also add self-loops of the specified type, edge_t. Otherwise, it returns g unchanged.

Nodes with already existing self-loops of type edge_t will obtain a second set of self-loops of the same type.

If the graph has edge weights for edges of type edge_t, the new edges will have weight 1.

If no edges of type edge_t exist, or all existing edges have no weight, then all new self loops will have no weight.

If edge_t is not passed as argument, for the entire graph self-loop is added to each node for every edge type in the graph where the source and destination node types are the same. This iterates over all edge types present in the graph, applying the self-loop addition logic to each applicable edge type.

source
GNNGraphs.getgraphMethod
getgraph(g::GNNGraph, i; nmap=false)

Return the subgraph of g induced by those nodes j for which g.graph_indicator[j] == i or, if i is a collection, g.graph_indicator[j] ∈ i. In other words, it extract the component graphs from a batched graph.

If nmap=true, return also a vector v mapping the new nodes to the old ones. The node i in the subgraph will correspond to the node v[i] in g.

source
GNNGraphs.negative_sampleMethod
negative_sample(g::GNNGraph; 
+add_edges(g::GNNHeteroGraph, edge_t => (s, t, w); [edata, num_nodes])

Add to heterograph g edges of type edge_t with source node vector s and target node vector t. Optionally, pass the edge weights w or the features edata for the new edges. edge_t is a triplet of symbols (src_t, rel_t, dst_t).

If the edge type is not already present in the graph, it is added. If it involves new node types, they are added to the graph as well. In this case, a dictionary or named tuple of num_nodes can be passed to specify the number of nodes of the new types, otherwise the number of nodes is inferred from the maximum node id in s and t.

source
GNNGraphs.add_nodesMethod
add_nodes(g::GNNGraph, n; [ndata])

Add n new nodes to graph g. In the new graph, these nodes will have indexes from g.num_nodes + 1 to g.num_nodes + n.

source
GNNGraphs.add_self_loopsMethod
add_self_loops(g::GNNGraph)

Return a graph with the same features as g but also adding edges connecting the nodes to themselves.

Nodes with already existing self-loops will obtain a second self-loop.

If the graphs has edge weights, the new edges will have weight 1.

source
GNNGraphs.add_self_loopsMethod
add_self_loops(g::GNNHeteroGraph, edge_t::EType)
+add_self_loops(g::GNNHeteroGraph)

If the source node type is the same as the destination node type in edge_t, return a graph with the same features as g but also add self-loops of the specified type, edge_t. Otherwise, it returns g unchanged.

Nodes with already existing self-loops of type edge_t will obtain a second set of self-loops of the same type.

If the graph has edge weights for edges of type edge_t, the new edges will have weight 1.

If no edges of type edge_t exist, or all existing edges have no weight, then all new self loops will have no weight.

If edge_t is not passed as argument, for the entire graph self-loop is added to each node for every edge type in the graph where the source and destination node types are the same. This iterates over all edge types present in the graph, applying the self-loop addition logic to each applicable edge type.

source
GNNGraphs.getgraphMethod
getgraph(g::GNNGraph, i; nmap=false)

Return the subgraph of g induced by those nodes j for which g.graph_indicator[j] == i or, if i is a collection, g.graph_indicator[j] ∈ i. In other words, it extract the component graphs from a batched graph.

If nmap=true, return also a vector v mapping the new nodes to the old ones. The node i in the subgraph will correspond to the node v[i] in g.

source
GNNGraphs.negative_sampleMethod
negative_sample(g::GNNGraph; 
                 num_neg_edges = g.num_edges, 
-                bidirected = is_bidirected(g))

Return a graph containing random negative edges (i.e. non-edges) from graph g as edges.

If bidirected=true, the output graph will be bidirected and there will be no leakage from the origin graph.

See also is_bidirected.

source
GNNGraphs.perturb_edgesMethod
perturb_edges([rng], g::GNNGraph, perturb_ratio)

Return a new graph obtained from g by adding random edges, based on a specified perturb_ratio. The perturb_ratio determines the fraction of new edges to add relative to the current number of edges in the graph. These new edges are added without creating self-loops.

The function returns a new GNNGraph instance that shares some of the underlying data with g but includes the additional edges. The nodes for the new edges are selected randomly, and no edge data (edata) or weights (w) are assigned to these new edges.

Arguments

  • g::GNNGraph: The graph to be perturbed.
  • perturb_ratio: The ratio of the number of new edges to add relative to the current number of edges in the graph. For example, a perturb_ratio of 0.1 means that 10% of the current number of edges will be added as new random edges.
  • rng: An optionalrandom number generator to ensure reproducible results.

Examples

julia> g = GNNGraph((s, t, w))
+                bidirected = is_bidirected(g))

Return a graph containing random negative edges (i.e. non-edges) from graph g as edges.

If bidirected=true, the output graph will be bidirected and there will be no leakage from the origin graph.

See also is_bidirected.

source
GNNGraphs.perturb_edgesMethod
perturb_edges([rng], g::GNNGraph, perturb_ratio)

Return a new graph obtained from g by adding random edges, based on a specified perturb_ratio. The perturb_ratio determines the fraction of new edges to add relative to the current number of edges in the graph. These new edges are added without creating self-loops.

The function returns a new GNNGraph instance that shares some of the underlying data with g but includes the additional edges. The nodes for the new edges are selected randomly, and no edge data (edata) or weights (w) are assigned to these new edges.

Arguments

  • g::GNNGraph: The graph to be perturbed.
  • perturb_ratio: The ratio of the number of new edges to add relative to the current number of edges in the graph. For example, a perturb_ratio of 0.1 means that 10% of the current number of edges will be added as new random edges.
  • rng: An optionalrandom number generator to ensure reproducible results.

Examples

julia> g = GNNGraph((s, t, w))
 GNNGraph:
   num_nodes: 4
   num_edges: 5
@@ -114,7 +114,7 @@
 julia> perturbed_g = perturb_edges(g, 0.2)
 GNNGraph:
   num_nodes: 4
-  num_edges: 6
source
GNNGraphs.ppr_diffusionMethod
ppr_diffusion(g::GNNGraph{<:COO_T}, alpha =0.85f0) -> GNNGraph

Calculates the Personalized PageRank (PPR) diffusion based on the edge weight matrix of a GNNGraph and updates the graph with new edge weights derived from the PPR matrix. References paper: The pagerank citation ranking: Bringing order to the web

The function performs the following steps:

  1. Constructs a modified adjacency matrix A using the graph's edge weights, where A is adjusted by (α - 1) * A + I, with α being the damping factor (alpha_f32) and I the identity matrix.
  2. Normalizes A to ensure each column sums to 1, representing transition probabilities.
  3. Applies the PPR formula α * (I + (α - 1) * A)^-1 to compute the diffusion matrix.
  4. Updates the original edge weights of the graph based on the PPR diffusion matrix, assigning new weights for each edge from the PPR matrix.

Arguments

  • g::GNNGraph: The input graph for which PPR diffusion is to be calculated. It should have edge weights available.
  • alpha_f32::Float32: The damping factor used in PPR calculation, controlling the teleport probability in the random walk. Defaults to 0.85f0.

Returns

  • A new GNNGraph instance with the same structure as g but with updated edge weights according to the PPR diffusion calculation.
source
GNNGraphs.rand_edge_splitMethod
rand_edge_split(g::GNNGraph, frac; bidirected=is_bidirected(g)) -> g1, g2

Randomly partition the edges in g to form two graphs, g1 and g2. Both will have the same number of nodes as g. g1 will contain a fraction frac of the original edges, while g2 wil contain the rest.

If bidirected = true makes sure that an edge and its reverse go into the same split. This option is supported only for bidirected graphs with no self-loops and multi-edges.

rand_edge_split is tipically used to create train/test splits in link prediction tasks.

source
GNNGraphs.ppr_diffusionMethod
ppr_diffusion(g::GNNGraph{<:COO_T}, alpha =0.85f0) -> GNNGraph

Calculates the Personalized PageRank (PPR) diffusion based on the edge weight matrix of a GNNGraph and updates the graph with new edge weights derived from the PPR matrix. References paper: The pagerank citation ranking: Bringing order to the web

The function performs the following steps:

  1. Constructs a modified adjacency matrix A using the graph's edge weights, where A is adjusted by (α - 1) * A + I, with α being the damping factor (alpha_f32) and I the identity matrix.
  2. Normalizes A to ensure each column sums to 1, representing transition probabilities.
  3. Applies the PPR formula α * (I + (α - 1) * A)^-1 to compute the diffusion matrix.
  4. Updates the original edge weights of the graph based on the PPR diffusion matrix, assigning new weights for each edge from the PPR matrix.

Arguments

  • g::GNNGraph: The input graph for which PPR diffusion is to be calculated. It should have edge weights available.
  • alpha_f32::Float32: The damping factor used in PPR calculation, controlling the teleport probability in the random walk. Defaults to 0.85f0.

Returns

  • A new GNNGraph instance with the same structure as g but with updated edge weights according to the PPR diffusion calculation.
source
GNNGraphs.rand_edge_splitMethod
rand_edge_split(g::GNNGraph, frac; bidirected=is_bidirected(g)) -> g1, g2

Randomly partition the edges in g to form two graphs, g1 and g2. Both will have the same number of nodes as g. g1 will contain a fraction frac of the original edges, while g2 wil contain the rest.

If bidirected = true makes sure that an edge and its reverse go into the same split. This option is supported only for bidirected graphs with no self-loops and multi-edges.

rand_edge_split is tipically used to create train/test splits in link prediction tasks.

source
GNNGraphs.remove_edgesMethod
remove_edges(g::GNNGraph, edges_to_remove::AbstractVector{<:Integer})
 remove_edges(g::GNNGraph, p=0.5)

Remove specified edges from a GNNGraph, either by specifying edge indices or by randomly removing edges with a given probability.

Arguments

  • g: The input graph from which edges will be removed.
  • edges_to_remove: Vector of edge indices to be removed. This argument is only required for the first method.
  • p: Probability of removing each edge. This argument is only required for the second method and defaults to 0.5.

Returns

A new GNNGraph with the specified edges removed.

Example

julia> using GraphNeuralNetworks
 
 # Construct a GNNGraph
@@ -137,7 +137,7 @@
 julia> g_new
 GNNGraph:
   num_nodes: 3
-  num_edges: 2
source
GNNGraphs.remove_nodesMethod
remove_nodes(g::GNNGraph, p)

Returns a new graph obtained by dropping nodes from g with independent probabilities p.

Examples

julia> g = GNNGraph([1, 1, 2, 2, 3, 4], [1, 2, 3, 1, 3, 1])
+  num_edges: 2
source
GNNGraphs.remove_nodesMethod
remove_nodes(g::GNNGraph, p)

Returns a new graph obtained by dropping nodes from g with independent probabilities p.

Examples

julia> g = GNNGraph([1, 1, 2, 2, 3, 4], [1, 2, 3, 1, 3, 1])
 GNNGraph:
   num_nodes: 4
   num_edges: 6
@@ -145,7 +145,7 @@
 julia> g_new = remove_nodes(g, 0.5)
 GNNGraph:
   num_nodes: 2
-  num_edges: 2
source
GNNGraphs.remove_nodesMethod
remove_nodes(g::GNNGraph, nodes_to_remove::AbstractVector)

Remove specified nodes, and their associated edges, from a GNNGraph. This operation reindexes the remaining nodes to maintain a continuous sequence of node indices, starting from 1. Similarly, edges are reindexed to account for the removal of edges connected to the removed nodes.

Arguments

  • g: The input graph from which nodes (and their edges) will be removed.
  • nodes_to_remove: Vector of node indices to be removed.

Returns

A new GNNGraph with the specified nodes and all edges associated with these nodes removed.

Example

using GraphNeuralNetworks
+  num_edges: 2
source
GNNGraphs.remove_nodesMethod
remove_nodes(g::GNNGraph, nodes_to_remove::AbstractVector)

Remove specified nodes, and their associated edges, from a GNNGraph. This operation reindexes the remaining nodes to maintain a continuous sequence of node indices, starting from 1. Similarly, edges are reindexed to account for the removal of edges connected to the removed nodes.

Arguments

  • g: The input graph from which nodes (and their edges) will be removed.
  • nodes_to_remove: Vector of node indices to be removed.

Returns

A new GNNGraph with the specified nodes and all edges associated with these nodes removed.

Example

using GraphNeuralNetworks
 
 g = GNNGraph([1, 1, 2, 2, 3], [2, 3, 1, 3, 1])
 
@@ -153,7 +153,7 @@
 g_new = remove_nodes(g, [2, 3])
 
 # g_new now does not contain nodes 2 and 3, and any edges that were connected to these nodes.
-println(g_new)
source
GNNGraphs.to_bidirectedMethod
to_bidirected(g)

Adds a reverse edge for each edge in the graph, then calls remove_multi_edges with mean aggregation to simplify the graph.

See also is_bidirected.

Examples

julia> s, t = [1, 2, 3, 3, 4], [2, 3, 4, 4, 4];
 
 julia> w = [1.0, 2.0, 3.0, 4.0, 5.0];
 
@@ -194,7 +194,7 @@
  20.0
  35.0
  35.0
- 50.0
source
GNNGraphs.to_unidirectedMethod
to_unidirected(g::GNNGraph)

Return a graph that for each multiple edge between two nodes in g keeps only an edge in one direction.

source
MLUtils.batchMethod
batch(gs::Vector{<:GNNGraph})

Batch together multiple GNNGraphs into a single one containing the total number of original nodes and edges.

Equivalent to SparseArrays.blockdiag. See also MLUtils.unbatch.

Examples

julia> g1 = rand_graph(4, 6, ndata=ones(8, 4))
+ 50.0
source
GNNGraphs.to_unidirectedMethod
to_unidirected(g::GNNGraph)

Return a graph that for each multiple edge between two nodes in g keeps only an edge in one direction.

source
MLUtils.batchMethod
batch(gs::Vector{<:GNNGraph})

Batch together multiple GNNGraphs into a single one containing the total number of original nodes and edges.

Equivalent to SparseArrays.blockdiag. See also MLUtils.unbatch.

Examples

julia> g1 = rand_graph(4, 6, ndata=ones(8, 4))
 GNNGraph:
     num_nodes = 4
     num_edges = 6
@@ -225,7 +225,7 @@
  1.0  1.0  1.0  1.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0
  1.0  1.0  1.0  1.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0
  1.0  1.0  1.0  1.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0
- 1.0  1.0  1.0  1.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0
source
MLUtils.unbatchMethod
unbatch(g::GNNGraph)

Opposite of the MLUtils.batch operation, returns an array of the individual graphs batched together in g.

See also MLUtils.batch and getgraph.

Examples

julia> gbatched = MLUtils.batch([rand_graph(5, 6), rand_graph(10, 8), rand_graph(4,2)])
+ 1.0  1.0  1.0  1.0  0.0  0.0  0.0  0.0  0.0  0.0  0.0
source
MLUtils.unbatchMethod
unbatch(g::GNNGraph)

Opposite of the MLUtils.batch operation, returns an array of the individual graphs batched together in g.

See also MLUtils.batch and getgraph.

Examples

julia> gbatched = MLUtils.batch([rand_graph(5, 6), rand_graph(10, 8), rand_graph(4,2)])
 GNNGraph:
     num_nodes = 19
     num_edges = 16
@@ -243,8 +243,8 @@
 
  GNNGraph:
     num_nodes = 4
-    num_edges = 2
source

Utils

GNNGraphs.sort_edge_indexFunction
sort_edge_index(ei::Tuple) -> u', v'
-sort_edge_index(u, v) -> u', v'

Return a sorted version of the tuple of vectors ei = (u, v), applying a common permutation to u and v. The sorting is lexycographic, that is the pairs (ui, vi) are sorted first according to the ui and then according to vi.

source
GNNGraphs.color_refinementFunction
color_refinement(g::GNNGraph, [x0]) -> x, num_colors, niters

The color refinement algorithm for graph coloring. Given a graph g and an initial coloring x0, the algorithm iteratively refines the coloring until a fixed point is reached.

At each iteration the algorithm computes a hash of the coloring and the sorted list of colors of the neighbors of each node. This hash is used to determine if the coloring has changed.

math x_i' = hashmap((x_i, sort([x_j for j \in N(i)]))).`

This algorithm is related to the 1-Weisfeiler-Lehman algorithm for graph isomorphism testing.

Arguments

  • g::GNNGraph: The graph to color.
  • x0::AbstractVector{<:Integer}: The initial coloring. If not provided, all nodes are colored with 1.

Returns

  • x::AbstractVector{<:Integer}: The final coloring.
  • num_colors::Int: The number of colors used.
  • niters::Int: The number of iterations until convergence.
source

Generate

Utils

GNNGraphs.sort_edge_indexFunction
sort_edge_index(ei::Tuple) -> u', v'
+sort_edge_index(u, v) -> u', v'

Return a sorted version of the tuple of vectors ei = (u, v), applying a common permutation to u and v. The sorting is lexycographic, that is the pairs (ui, vi) are sorted first according to the ui and then according to vi.

source
GNNGraphs.color_refinementFunction
color_refinement(g::GNNGraph, [x0]) -> x, num_colors, niters

The color refinement algorithm for graph coloring. Given a graph g and an initial coloring x0, the algorithm iteratively refines the coloring until a fixed point is reached.

At each iteration the algorithm computes a hash of the coloring and the sorted list of colors of the neighbors of each node. This hash is used to determine if the coloring has changed.

math x_i' = hashmap((x_i, sort([x_j for j \in N(i)]))).`

This algorithm is related to the 1-Weisfeiler-Lehman algorithm for graph isomorphism testing.

Arguments

  • g::GNNGraph: The graph to color.
  • x0::AbstractVector{<:Integer}: The initial coloring. If not provided, all nodes are colored with 1.

Returns

  • x::AbstractVector{<:Integer}: The final coloring.
  • num_colors::Int: The number of colors used.
  • niters::Int: The number of iterations until convergence.
source

Generate

GNNGraphs.knn_graphMethod
knn_graph(points::AbstractMatrix, 
           k::Int; 
           graph_indicator = nothing,
           self_loops = false, 
@@ -265,7 +265,7 @@
     num_nodes = 10
     num_edges = 30
     num_graphs = 2
-
source
GNNGraphs.rand_bipartite_heterographMethod
rand_bipartite_heterograph([rng,] 
                            (n1, n2), (m12, m21); 
                            bidirected = true, 
                            node_t = (:A, :B), 
@@ -299,7 +299,7 @@
 julia> g = rand_bipartite_heterograph((10, 15), (20, 0), node_t=(:user, :item), edge_t=:-, bidirected=false)
 GNNHeteroGraph:
   num_nodes: Dict(:item => 15, :user => 10)
-  num_edges: Dict((:item, :-, :user) => 0, (:user, :-, :item) => 20)
source
GNNGraphs.rand_graphMethod
rand_graph([rng,] n, m; bidirected=true, edge_weight = nothing, kws...)

Generate a random (Erdós-Renyi) GNNGraph with n nodes and m edges.

If bidirected=true the reverse edge of each edge will be present. If bidirected=false instead, m unrelated edges are generated. In any case, the output graph will contain no self-loops or multi-edges.

A vector can be passed as edge_weight. Its length has to be equal to m in the directed case, and m÷2 in the bidirected one.

Pass a random number generator as the first argument to make the generation reproducible.

Additional keyword arguments will be passed to the GNNGraph constructor.

Examples

julia> g = rand_graph(5, 4, bidirected=false)
+  num_edges: Dict((:item, :-, :user) => 0, (:user, :-, :item) => 20)
source
GNNGraphs.rand_graphMethod
rand_graph([rng,] n, m; bidirected=true, edge_weight = nothing, kws...)

Generate a random (Erdós-Renyi) GNNGraph with n nodes and m edges.

If bidirected=true the reverse edge of each edge will be present. If bidirected=false instead, m unrelated edges are generated. In any case, the output graph will contain no self-loops or multi-edges.

A vector can be passed as edge_weight. Its length has to be equal to m in the directed case, and m÷2 in the bidirected one.

Pass a random number generator as the first argument to make the generation reproducible.

Additional keyword arguments will be passed to the GNNGraph constructor.

Examples

julia> g = rand_graph(5, 4, bidirected=false)
 GNNGraph:
     num_nodes = 5
     num_edges = 4
@@ -317,11 +317,11 @@
 
 # Each edge has a reverse
 julia> edge_index(g)
-([1, 3, 3, 4], [3, 4, 1, 3])
source
GNNGraphs.rand_heterographFunction
rand_heterograph([rng,] n, m; bidirected=false, kws...)

Construct an GNNHeteroGraph with random edges and with number of nodes and edges specified by n and m respectively. n and m can be any iterable of pairs specifing node/edge types and their numbers.

Pass a random number generator as a first argument to make the generation reproducible.

Setting bidirected=true will generate a bidirected graph, i.e. each edge will have a reverse edge. Therefore, for each edge type (:A, :rel, :B) a corresponding reverse edge type (:B, :rel, :A) will be generated.

Additional keyword arguments will be passed to the GNNHeteroGraph constructor.

Examples

julia> g = rand_heterograph((:user => 10, :movie => 20),
+([1, 3, 3, 4], [3, 4, 1, 3])
source
GNNGraphs.rand_heterographFunction
rand_heterograph([rng,] n, m; bidirected=false, kws...)

Construct an GNNHeteroGraph with random edges and with number of nodes and edges specified by n and m respectively. n and m can be any iterable of pairs specifing node/edge types and their numbers.

Pass a random number generator as a first argument to make the generation reproducible.

Setting bidirected=true will generate a bidirected graph, i.e. each edge will have a reverse edge. Therefore, for each edge type (:A, :rel, :B) a corresponding reverse edge type (:B, :rel, :A) will be generated.

Additional keyword arguments will be passed to the GNNHeteroGraph constructor.

Examples

julia> g = rand_heterograph((:user => 10, :movie => 20),
                             (:user, :rate, :movie) => 30)
 GNNHeteroGraph:
   num_nodes: (:user => 10, :movie => 20)         
-  num_edges: ((:user, :rate, :movie) => 30,)
source

Operators

Base.intersectFunction

" intersect(g1::GNNGraph, g2::GNNGraph)

Intersect two graphs by keeping only the common edges.

source

Sampling

GNNGraphs.sample_neighborsFunction
sample_neighbors(g, nodes, K=-1; dir=:in, replace=false, dropnodes=false)

Sample neighboring edges of the given nodes and return the induced subgraph. For each node, a number of inbound (or outbound when dir = :out) edges will be randomly chosen. Ifdropnodes=false`, the graph returned will then contain all the nodes in the original graph, but only the sampled edges.

The returned graph will contain an edge feature EID corresponding to the id of the edge in the original graph. If dropnodes=true, it will also contain a node feature NID with the node ids in the original graph.

Arguments

  • g. The graph.
  • nodes. A list of node IDs to sample neighbors from.
  • K. The maximum number of edges to be sampled for each node. If -1, all the neighboring edges will be selected.
  • dir. Determines whether to sample inbound (:in) or outbound (`:out) edges (Default :in).
  • replace. If true, sample with replacement.
  • dropnodes. If true, the resulting subgraph will contain only the nodes involved in the sampled edges.

Examples

julia> g = rand_graph(20, 100)
+  num_edges: ((:user, :rate, :movie) => 30,)
source

Operators

Base.intersectFunction

" intersect(g1::GNNGraph, g2::GNNGraph)

Intersect two graphs by keeping only the common edges.

source

Sampling

GNNGraphs.sample_neighborsFunction
sample_neighbors(g, nodes, K=-1; dir=:in, replace=false, dropnodes=false)

Sample neighboring edges of the given nodes and return the induced subgraph. For each node, a number of inbound (or outbound when dir = :out) edges will be randomly chosen. Ifdropnodes=false`, the graph returned will then contain all the nodes in the original graph, but only the sampled edges.

The returned graph will contain an edge feature EID corresponding to the id of the edge in the original graph. If dropnodes=true, it will also contain a node feature NID with the node ids in the original graph.

Arguments

  • g. The graph.
  • nodes. A list of node IDs to sample neighbors from.
  • K. The maximum number of edges to be sampled for each node. If -1, all the neighboring edges will be selected.
  • dir. Determines whether to sample inbound (:in) or outbound (`:out) edges (Default :in).
  • replace. If true, sample with replacement.
  • dropnodes. If true, the resulting subgraph will contain only the nodes involved in the sampled edges.

Examples

julia> g = rand_graph(20, 100)
 GNNGraph:
     num_nodes = 20
     num_edges = 100
@@ -360,7 +360,7 @@
     num_nodes = 20
     num_edges = 10
     edata:
-        EID => (10,)
source
Graphs.induced_subgraphMethod
induced_subgraph(graph, nodes)

Generates a subgraph from the original graph using the provided nodes. The function includes the nodes' neighbors and creates edges between nodes that are connected in the original graph. If a node has no neighbors, an isolated node will be added to the subgraph. Returns A new GNNGraph containing the subgraph with the specified nodes and their features.

Arguments

  • graph. The original GNNGraph containing nodes, edges, and node features.
  • nodes`. A vector of node indices to include in the subgraph.

Examples

julia> s = [1, 2]
+        EID => (10,)
source
Graphs.induced_subgraphMethod
induced_subgraph(graph, nodes)

Generates a subgraph from the original graph using the provided nodes. The function includes the nodes' neighbors and creates edges between nodes that are connected in the original graph. If a node has no neighbors, an isolated node will be added to the subgraph. Returns A new GNNGraph containing the subgraph with the specified nodes and their features.

Arguments

  • graph. The original GNNGraph containing nodes, edges, and node features.
  • nodes`. A vector of node indices to include in the subgraph.

Examples

julia> s = [1, 2]
 2-element Vector{Int64}:
  1
  2
@@ -393,4 +393,4 @@
         y = 2-element Vector{Float32}
         x = 32×2 Matrix{Float32}
   edata:
-        e = 1-element Vector{Float32}
source
\ No newline at end of file + e = 1-element Vector{Float32}
source
\ No newline at end of file diff --git a/gnngraphs/api/heterograph/index.html b/gnngraphs/api/heterograph/index.html index 16aee3356..91b5a8833 100644 --- a/gnngraphs/api/heterograph/index.html +++ b/gnngraphs/api/heterograph/index.html @@ -39,7 +39,7 @@ julia> hg.ndata[:A].x 2×10 Matrix{Float64}: 0.825882 0.0797502 0.245813 0.142281 0.231253 0.685025 0.821457 0.888838 0.571347 0.53165 - 0.631286 0.316292 0.705325 0.239211 0.533007 0.249233 0.473736 0.595475 0.0623298 0.159307

See also GNNGraph for a homogeneous graph type and rand_heterograph for a function to generate random heterographs.

source
GNNGraphs.edge_type_subgraphMethod
edge_type_subgraph(g::GNNHeteroGraph, edge_ts)

Return a subgraph of g that contains only the edges of type edge_ts. Edge types can be specified as a single edge type (i.e. a tuple containing 3 symbols) or a vector of edge types.

source
GNNGraphs.num_edge_typesMethod
num_edge_types(g)

Return the number of edge types in the graph. For GNNGraphs, this is always 1. For GNNHeteroGraphs, this is the number of unique edge types.

source
GNNGraphs.num_node_typesMethod
num_node_types(g)

Return the number of node types in the graph. For GNNGraphs, this is always 1. For GNNHeteroGraphs, this is the number of unique node types.

source
Graphs.has_edgeMethod
has_edge(g::GNNHeteroGraph, edge_t, i, j)

Return true if there is an edge of type edge_t from node i to node j in g.

Examples

julia> g = rand_bipartite_heterograph((2, 2), (4, 0), bidirected=false)
+    0.631286  0.316292   0.705325  0.239211  0.533007  0.249233  0.473736  0.595475  0.0623298  0.159307

See also GNNGraph for a homogeneous graph type and rand_heterograph for a function to generate random heterographs.

source
GNNGraphs.edge_type_subgraphMethod
edge_type_subgraph(g::GNNHeteroGraph, edge_ts)

Return a subgraph of g that contains only the edges of type edge_ts. Edge types can be specified as a single edge type (i.e. a tuple containing 3 symbols) or a vector of edge types.

source
GNNGraphs.num_edge_typesMethod
num_edge_types(g)

Return the number of edge types in the graph. For GNNGraphs, this is always 1. For GNNHeteroGraphs, this is the number of unique edge types.

source
GNNGraphs.num_node_typesMethod
num_node_types(g)

Return the number of node types in the graph. For GNNGraphs, this is always 1. For GNNHeteroGraphs, this is the number of unique node types.

source
Graphs.has_edgeMethod
has_edge(g::GNNHeteroGraph, edge_t, i, j)

Return true if there is an edge of type edge_t from node i to node j in g.

Examples

julia> g = rand_bipartite_heterograph((2, 2), (4, 0), bidirected=false)
 GNNHeteroGraph:
   num_nodes: (:A => 2, :B => 2)
   num_edges: ((:A, :to, :B) => 4, (:B, :to, :A) => 0)
@@ -48,4 +48,4 @@
 true
 
 julia> has_edge(g, (:B,:to,:A), 1, 1)
-false
source
\ No newline at end of file +falsesource \ No newline at end of file diff --git a/gnngraphs/api/temporalgraph/index.html b/gnngraphs/api/temporalgraph/index.html index f79ead63f..28e5af44d 100644 --- a/gnngraphs/api/temporalgraph/index.html +++ b/gnngraphs/api/temporalgraph/index.html @@ -16,7 +16,7 @@ num_edges: [20, 20, 20, 20, 20] num_snapshots: 5 tgdata: - x = 4-element Vector{Float64}source
GNNGraphs.add_snapshotMethod
add_snapshot(tg::TemporalSnapshotsGNNGraph, t::Int, g::GNNGraph)

Return a TemporalSnapshotsGNNGraph created starting from tg by adding the snapshot g at time index t.

Examples

julia> using GraphNeuralNetworks
+        x = 4-element Vector{Float64}
source
GNNGraphs.add_snapshotMethod
add_snapshot(tg::TemporalSnapshotsGNNGraph, t::Int, g::GNNGraph)

Return a TemporalSnapshotsGNNGraph created starting from tg by adding the snapshot g at time index t.

Examples

julia> using GraphNeuralNetworks
 
 julia> snapshots = [rand_graph(10, 20) for i in 1:5];
 
@@ -30,7 +30,7 @@
 TemporalSnapshotsGNNGraph:
   num_nodes: [10, 10, 10, 10, 10, 10]
   num_edges: [20, 20, 16, 20, 20, 20]
-  num_snapshots: 6
source
GNNGraphs.remove_snapshotMethod
remove_snapshot(tg::TemporalSnapshotsGNNGraph, t::Int)

Return a TemporalSnapshotsGNNGraph created starting from tg by removing the snapshot at time index t.

Examples

julia> using GraphNeuralNetworks
+  num_snapshots: 6
source
GNNGraphs.remove_snapshotMethod
remove_snapshot(tg::TemporalSnapshotsGNNGraph, t::Int)

Return a TemporalSnapshotsGNNGraph created starting from tg by removing the snapshot at time index t.

Examples

julia> using GraphNeuralNetworks
 
 julia> snapshots = [rand_graph(10,20), rand_graph(10,14), rand_graph(10,22)];
 
@@ -44,7 +44,7 @@
 TemporalSnapshotsGNNGraph:
   num_nodes: [10, 10]
   num_edges: [20, 22]
-  num_snapshots: 2
source

TemporalSnapshotsGNNGraph random generators

GNNGraphs.rand_temporal_radius_graphFunction
rand_temporal_radius_graph(number_nodes::Int, 
+  num_snapshots: 2
source

TemporalSnapshotsGNNGraph random generators

GNNGraphs.rand_temporal_radius_graphFunction
rand_temporal_radius_graph(number_nodes::Int, 
                            number_snapshots::Int,
                            speed::AbstractFloat,
                            r::AbstractFloat;
@@ -56,7 +56,7 @@
 TemporalSnapshotsGNNGraph:
   num_nodes: [10, 10, 10, 10, 10]
   num_edges: [90, 90, 90, 90, 90]
-  num_snapshots: 5
source
GNNGraphs.rand_temporal_hyperbolic_graphFunction
rand_temporal_hyperbolic_graph(number_nodes::Int, 
+  num_snapshots: 5
source
GNNGraphs.rand_temporal_hyperbolic_graphFunction
rand_temporal_hyperbolic_graph(number_nodes::Int, 
                                number_snapshots::Int;
                                α::Real,
                                R::Real,
@@ -69,4 +69,4 @@
 TemporalSnapshotsGNNGraph:
   num_nodes: [10, 10, 10, 10, 10]
   num_edges: [44, 46, 48, 42, 38]
-  num_snapshots: 5

References

Section D of the paper Dynamic Hidden-Variable Network Models and the paper Hyperbolic Geometry of Complex Networks

source
\ No newline at end of file + num_snapshots: 5

References

Section D of the paper Dynamic Hidden-Variable Network Models and the paper Hyperbolic Geometry of Complex Networks

source \ No newline at end of file diff --git a/gnngraphs/datasets/index.html b/gnngraphs/datasets/index.html index 2ada219c0..90be28a1d 100644 --- a/gnngraphs/datasets/index.html +++ b/gnngraphs/datasets/index.html @@ -9,4 +9,4 @@ targets => 2708-element Vector{Int64} train_mask => 2708-element BitVector val_mask => 2708-element BitVector - test_mask => 2708-element BitVectorsource \ No newline at end of file + test_mask => 2708-element BitVectorsource \ No newline at end of file diff --git a/gnngraphs/gnngraph/index.html b/gnngraphs/gnngraph/index.html index 12896eae6..395533458 100644 --- a/gnngraphs/gnngraph/index.html +++ b/gnngraphs/gnngraph/index.html @@ -166,4 +166,4 @@ julia> GNNGraph(gd) GNNGraph: num_nodes: 10 - num_edges: 20 \ No newline at end of file + num_edges: 20 \ No newline at end of file diff --git a/gnngraphs/heterograph/index.html b/gnngraphs/heterograph/index.html index 9373cc10b..9068452ff 100644 --- a/gnngraphs/heterograph/index.html +++ b/gnngraphs/heterograph/index.html @@ -80,4 +80,4 @@ @assert g.num_nodes[:A] == 80 @assert size(g.ndata[:A].x) == (3, 80) # ... -end

Graph convolutions on heterographs

See HeteroGraphConv for how to perform convolutions on heterogeneous graphs.

\ No newline at end of file +end

Graph convolutions on heterographs

See HeteroGraphConv for how to perform convolutions on heterogeneous graphs.

\ No newline at end of file diff --git a/gnngraphs/index.html b/gnngraphs/index.html index 94933b4e9..c063dc802 100644 --- a/gnngraphs/index.html +++ b/gnngraphs/index.html @@ -1 +1 @@ -Home · GNNGraphs.jl

GNNGraphs.jl

GNNGraphs.jl is a package that provides graph data structures and helper functions specifically designed for working with graph neural networks. This package allows to store not only the graph structure, but also features associated with nodes, edges, and the graph itself. It is the core foundation for the GNNlib.jl, GraphNeuralNetworks.jl, and GNNLux.jl packages.

It supports three types of graphs:

  • Static graph is the basic graph type represented by GNNGraph, where each node and edge can have associated features. This type of graph is used in typical graph neural network applications, where neural networks operate on both the structure of the graph and the features stored in it. It can be used to represent a graph where the structure does not change over time, but the features of the nodes and edges can change over time.

  • Heterogeneous graph is a graph that supports multiple types of nodes and edges, and is represented by GNNHeteroGraph. Each type can have its own properties and relationships. This is useful in scenarios with different entities and interactions, such as in citation graphs or multi-relational data.

  • Temporal graph is a graph that changes over time, and is represented by TemporalSnapshotsGNNGraph. Edges and features can change dynamically. This type of graph is useful for applications that involve tracking time-dependent relationships, such as social networks.

This package depends on the package Graphs.jl.

Installation

The package can be installed with the Julia package manager. From the Julia REPL, type ] to enter the Pkg REPL mode and run:

pkg> add GNNGraphs
\ No newline at end of file +Home · GNNGraphs.jl

GNNGraphs.jl

GNNGraphs.jl is a package that provides graph data structures and helper functions specifically designed for working with graph neural networks. This package allows to store not only the graph structure, but also features associated with nodes, edges, and the graph itself. It is the core foundation for the GNNlib.jl, GraphNeuralNetworks.jl, and GNNLux.jl packages.

It supports three types of graphs:

  • Static graph is the basic graph type represented by GNNGraph, where each node and edge can have associated features. This type of graph is used in typical graph neural network applications, where neural networks operate on both the structure of the graph and the features stored in it. It can be used to represent a graph where the structure does not change over time, but the features of the nodes and edges can change over time.

  • Heterogeneous graph is a graph that supports multiple types of nodes and edges, and is represented by GNNHeteroGraph. Each type can have its own properties and relationships. This is useful in scenarios with different entities and interactions, such as in citation graphs or multi-relational data.

  • Temporal graph is a graph that changes over time, and is represented by TemporalSnapshotsGNNGraph. Edges and features can change dynamically. This type of graph is useful for applications that involve tracking time-dependent relationships, such as social networks.

This package depends on the package Graphs.jl.

Installation

The package can be installed with the Julia package manager. From the Julia REPL, type ] to enter the Pkg REPL mode and run:

pkg> add GNNGraphs
\ No newline at end of file diff --git a/gnngraphs/temporalgraph/index.html b/gnngraphs/temporalgraph/index.html index 99aab2f26..355e558cf 100644 --- a/gnngraphs/temporalgraph/index.html +++ b/gnngraphs/temporalgraph/index.html @@ -93,4 +93,4 @@ julia> output = m(tg, tg.ndata.x); julia> size(output[1]) -(1, 10) \ No newline at end of file +(1, 10) \ No newline at end of file diff --git a/gnnlib/.documenter-siteinfo.json b/gnnlib/.documenter-siteinfo.json index 1232433d9..b2a9ffaa7 100644 --- a/gnnlib/.documenter-siteinfo.json +++ b/gnnlib/.documenter-siteinfo.json @@ -1 +1 @@ -{"documenter":{"julia_version":"1.10.5","generation_timestamp":"2024-11-08T08:44:43","documenter_version":"1.7.0"}} \ No newline at end of file +{"documenter":{"julia_version":"1.10.5","generation_timestamp":"2024-11-09T14:47:21","documenter_version":"1.7.0"}} \ No newline at end of file diff --git a/gnnlib/api/messagepassing/index.html b/gnnlib/api/messagepassing/index.html index 2db6cc97e..478c3e56d 100644 --- a/gnnlib/api/messagepassing/index.html +++ b/gnnlib/api/messagepassing/index.html @@ -25,4 +25,4 @@ end l = GNNConv(10 => 20) -l(g, x)

See also apply_edges and aggregate_neighbors.

source

Built-in message functions

GNNlib.copy_xiFunction
copy_xi(xi, xj, e) = xi
source
GNNlib.copy_xjFunction
copy_xj(xi, xj, e) = xj
source
GNNlib.xi_dot_xjFunction
xi_dot_xj(xi, xj, e) = sum(xi .* xj, dims=1)
source
GNNlib.xi_sub_xjFunction
xi_sub_xj(xi, xj, e) = xi .- xj
source
GNNlib.xj_sub_xiFunction
xj_sub_xi(xi, xj, e) = xj .- xi
source
GNNlib.e_mul_xjFunction
e_mul_xj(xi, xj, e) = reshape(e, (...)) .* xj

Reshape e into broadcast compatible shape with xj (by prepending singleton dimensions) then perform broadcasted multiplication.

source
GNNlib.w_mul_xjFunction
w_mul_xj(xi, xj, w) = reshape(w, (...)) .* xj

Similar to e_mul_xj but specialized on scalar edge features (weights).

source
\ No newline at end of file +l(g, x)

See also apply_edges and aggregate_neighbors.

source

Built-in message functions

GNNlib.copy_xiFunction
copy_xi(xi, xj, e) = xi
source
GNNlib.copy_xjFunction
copy_xj(xi, xj, e) = xj
source
GNNlib.xi_dot_xjFunction
xi_dot_xj(xi, xj, e) = sum(xi .* xj, dims=1)
source
GNNlib.xi_sub_xjFunction
xi_sub_xj(xi, xj, e) = xi .- xj
source
GNNlib.xj_sub_xiFunction
xj_sub_xi(xi, xj, e) = xj .- xi
source
GNNlib.e_mul_xjFunction
e_mul_xj(xi, xj, e) = reshape(e, (...)) .* xj

Reshape e into broadcast compatible shape with xj (by prepending singleton dimensions) then perform broadcasted multiplication.

source
GNNlib.w_mul_xjFunction
w_mul_xj(xi, xj, w) = reshape(w, (...)) .* xj

Similar to e_mul_xj but specialized on scalar edge features (weights).

source
\ No newline at end of file diff --git a/gnnlib/api/utils/index.html b/gnnlib/api/utils/index.html index 6da07ca52..07314a891 100644 --- a/gnnlib/api/utils/index.html +++ b/gnnlib/api/utils/index.html @@ -1,2 +1,2 @@ Utils · GNNlib.jl

Utility Functions

Index

Docs

Graph-wise operations

GNNlib.reduce_nodesFunction
reduce_nodes(aggr, g, x)

For a batched graph g, return the graph-wise aggregation of the node features x. The aggregation operator aggr can be +, mean, max, or min. The returned array will have last dimension g.num_graphs.

See also: reduce_edges.

source
reduce_nodes(aggr, indicator::AbstractVector, x)

Return the graph-wise aggregation of the node features x given the graph indicator indicator. The aggregation operator aggr can be +, mean, max, or min.

See also graph_indicator.

source
GNNlib.reduce_edgesFunction
reduce_edges(aggr, g, e)

For a batched graph g, return the graph-wise aggregation of the edge features e. The aggregation operator aggr can be +, mean, max, or min. The returned array will have last dimension g.num_graphs.

source
GNNlib.broadcast_nodesFunction
broadcast_nodes(g, x)

Graph-wise broadcast array x of size (*, g.num_graphs) to size (*, g.num_nodes).

source
GNNlib.broadcast_edgesFunction
broadcast_edges(g, x)

Graph-wise broadcast array x of size (*, g.num_graphs) to size (*, g.num_edges).

source

Neighborhood operations

GNNlib.softmax_edge_neighborsFunction
softmax_edge_neighbors(g, e)

Softmax over each node's neighborhood of the edge features e.

\[\mathbf{e}'_{j\to i} = \frac{e^{\mathbf{e}_{j\to i}}} - {\sum_{j'\in N(i)} e^{\mathbf{e}_{j'\to i}}}.\]

source

NNlib

Primitive functions implemented in NNlib.jl:

\ No newline at end of file + {\sum_{j'\in N(i)} e^{\mathbf{e}_{j'\to i}}}.\]

source

NNlib

Primitive functions implemented in NNlib.jl:

\ No newline at end of file diff --git a/gnnlib/index.html b/gnnlib/index.html index 2544f330b..4c58a7b05 100644 --- a/gnnlib/index.html +++ b/gnnlib/index.html @@ -1 +1 @@ -Home · GNNlib.jl

GNNlib.jl

GNNlib.jl is a package that provides the implementation of the basic message passing functions and functional implementation of graph convolutional layers, which are used to build graph neural networks in both the Flux.jl and Lux.jl machine learning frameworks, created in the GraphNeuralNetworks.jl and GNNLux.jl packages, respectively.

This package depends on GNNGraphs.jl and NNlib.jl, and is primarily intended for developers looking to create new GNN architectures. For most users, the higher-level GraphNeuralNetworks.jl and GNNLux.jl packages are recommended.

Installation

The package can be installed with the Julia package manager. From the Julia REPL, type ] to enter the Pkg REPL mode and run:

pkg> add GNNlib
\ No newline at end of file +Home · GNNlib.jl

GNNlib.jl

GNNlib.jl is a package that provides the implementation of the basic message passing functions and functional implementation of graph convolutional layers, which are used to build graph neural networks in both the Flux.jl and Lux.jl machine learning frameworks, created in the GraphNeuralNetworks.jl and GNNLux.jl packages, respectively.

This package depends on GNNGraphs.jl and NNlib.jl, and is primarily intended for developers looking to create new GNN architectures. For most users, the higher-level GraphNeuralNetworks.jl and GNNLux.jl packages are recommended.

Installation

The package can be installed with the Julia package manager. From the Julia REPL, type ] to enter the Pkg REPL mode and run:

pkg> add GNNlib
\ No newline at end of file diff --git a/gnnlib/messagepassing/index.html b/gnnlib/messagepassing/index.html index f7a8b6ff9..246df4cd3 100644 --- a/gnnlib/messagepassing/index.html +++ b/gnnlib/messagepassing/index.html @@ -75,4 +75,4 @@ x = propagate(message, g, +, xj=x) return l.σ.(l.weight * x .+ l.bias) -end

See the GATConv implementation here for a more complex example.

Built-in message functions

In order to exploit optimized specializations of the propagate, it is recommended to use built-in message functions such as copy_xj whenever possible.

\ No newline at end of file +end

See the GATConv implementation here for a more complex example.

Built-in message functions

In order to exploit optimized specializations of the propagate, it is recommended to use built-in message functions such as copy_xj whenever possible.

\ No newline at end of file diff --git a/gnnlux/.documenter-siteinfo.json b/gnnlux/.documenter-siteinfo.json index b4a6aeaa9..99669c6f7 100644 --- a/gnnlux/.documenter-siteinfo.json +++ b/gnnlux/.documenter-siteinfo.json @@ -1 +1 @@ -{"documenter":{"julia_version":"1.10.5","generation_timestamp":"2024-11-08T08:45:16","documenter_version":"1.7.0"}} \ No newline at end of file +{"documenter":{"julia_version":"1.10.5","generation_timestamp":"2024-11-09T14:48:11","documenter_version":"1.7.0"}} \ No newline at end of file diff --git a/gnnlux/api/basic/index.html b/gnnlux/api/basic/index.html index cc8ff8fe2..d3229e4ab 100644 --- a/gnnlux/api/basic/index.html +++ b/gnnlux/api/basic/index.html @@ -1,4 +1,4 @@ -Basic · GNNLux.jl

GNNLayer

GNNLux.GNNLayerType
abstract type GNNLayer <: AbstractLuxLayer end

An abstract type from which graph neural network layers are derived. It is derived from Lux's AbstractLuxLayer type.

See also GNNLux.GNNChain.

source
GNNLux.GNNChainType
GNNChain(layers...)
+Basic · GNNLux.jl

GNNLayer

GNNLux.GNNLayerType
abstract type GNNLayer <: AbstractLuxLayer end

An abstract type from which graph neural network layers are derived. It is derived from Lux's AbstractLuxLayer type.

See also GNNLux.GNNChain.

source
GNNLux.GNNChainType
GNNChain(layers...)
 GNNChain(name = layer, ...)

Collects multiple layers / functions to be called in sequence on given input graph and input node features.

It allows to compose layers in a sequential fashion as Lux.Chain does, propagating the output of each layer to the next one. In addition, GNNChain handles the input graph as well, providing it as a first argument only to layers subtyping the GNNLayer abstract type.

GNNChain supports indexing and slicing, m[2] or m[1:end-1], and if names are given, m[:name] == m[1] etc.

Examples

julia> using Lux, GNNLux, Random
 
 julia> rng = Random.default_rng();
@@ -17,4 +17,4 @@
 julia> ps, st = LuxCore.setup(rng, m);
 
 julia> m(g, x, ps, st)     # First entry is the output, second entry is the state of the model
-(Float32[-0.15594329 -0.15594329 -0.15594329; 0.93431795 0.93431795 0.93431795; 0.27568763 0.27568763 0.27568763; 0.12568939 0.12568939 0.12568939], (layer_1 = NamedTuple(), layer_2 = NamedTuple(), layer_3 = NamedTuple()))
source
\ No newline at end of file +(Float32[-0.15594329 -0.15594329 -0.15594329; 0.93431795 0.93431795 0.93431795; 0.27568763 0.27568763 0.27568763; 0.12568939 0.12568939 0.12568939], (layer_1 = NamedTuple(), layer_2 = NamedTuple(), layer_3 = NamedTuple()))
source
\ No newline at end of file diff --git a/gnnlux/api/conv/index.html b/gnnlux/api/conv/index.html index e128a16dd..9e64a6b85 100644 --- a/gnnlux/api/conv/index.html +++ b/gnnlux/api/conv/index.html @@ -1,6 +1,174 @@ -Convolutional Layers · GNNLux.jl

Convolutional Layers

Many different types of graphs convolutional layers have been proposed in the literature. Choosing the right layer for your application could involve a lot of exploration. Multiple graph convolutional layers are typically stacked together to create a graph neural network model (see GNNChain).

The table below lists all graph convolutional layers implemented in the GNNLux.jl. It also highlights the presence of some additional capabilities with respect to basic message passing:

  • Sparse Ops: implements message passing as multiplication by sparse adjacency matrix instead of the gather/scatter mechanism. This can lead to better CPU performances but it is not supported on GPU yet.
  • Edge Weight: supports scalar weights (or equivalently scalar features) on edges.
  • Edge Features: supports feature vectors on edges.
  • Heterograph: supports heterogeneous graphs (see GNNHeteroGraph).
  • TemporalSnapshotsGNNGraphs: supports temporal graphs (see TemporalSnapshotsGNNGraph) by applying the convolution layers to each snapshot independently.

| Layer |Sparse Ops|Edge Weight|Edge Features| Heterograph | TemporalSnapshotsGNNGraphs | | :–––– | :–-: |:–-: |:–-: | :–-: | :–-: | ✓ | | GCNConv | ✓ | ✓ | | ✓ | |

Docs

GNNLux.GCNConvType
GCNConv(in => out, σ=identity; [init_weight, init_bias, use_bias, add_self_loops, use_edge_weight])

Graph convolutional layer from paper Semi-supervised Classification with Graph Convolutional Networks.

Performs the operation

\[\mathbf{x}'_i = \sum_{j\in N(i)} a_{ij} W \mathbf{x}_j\]

where $a_{ij} = 1 / \sqrt{|N(i)||N(j)|}$ is a normalization factor computed from the node degrees.

If the input graph has weighted edges and use_edge_weight=true, than $a_{ij}$ will be computed as

\[a_{ij} = \frac{e_{j\to i}}{\sqrt{\sum_{j \in N(i)} e_{j\to i}} \sqrt{\sum_{i \in N(j)} e_{i\to j}}}\]

Arguments

  • in: Number of input features.
  • out: Number of output features.
  • σ: Activation function. Default identity.
  • init_weight: Weights' initializer. Default glorot_uniform.
  • init_bias: Bias initializer. Default zeros32.
  • use_bias: Add learnable bias. Default true.
  • add_self_loops: Add self loops to the graph before performing the convolution. Default false.
  • use_edge_weight: If true, consider the edge weights in the input graph (if available). If add_self_loops=true the new weights will be set to 1. This option is ignored if the edge_weight is explicitly provided in the forward pass. Default false.

Forward

(::GCNConv)(g, x, [edge_weight], ps, st; norm_fn = d -> 1 ./ sqrt.(d), conv_weight=nothing)

Takes as input a graph g, a node feature matrix x of size [in, num_nodes], optionally an edge weight vector and the parameter and state of the layer. Returns a node feature matrix of size [out, num_nodes].

The norm_fn parameter allows for custom normalization of the graph convolution operation by passing a function as argument. By default, it computes $\frac{1}{\sqrt{d}}$ i.e the inverse square root of the degree (d) of each node in the graph. If conv_weight is an AbstractMatrix of size [out, in], then the convolution is performed using that weight matrix.

Examples

using GNNLux, Lux, Random
+Convolutional layers · GNNLux.jl

Convolutional Layers

Many different types of graphs convolutional layers have been proposed in the literature. Choosing the right layer for your application could involve a lot of exploration. Multiple graph convolutional layers are typically stacked together to create a graph neural network model (see GNNChain).

The table below lists all graph convolutional layers implemented in the GNNLux.jl. It also highlights the presence of some additional capabilities with respect to basic message passing:

  • Sparse Ops: implements message passing as multiplication by sparse adjacency matrix instead of the gather/scatter mechanism. This can lead to better CPU performances but it is not supported on GPU yet.
  • Edge Weight: supports scalar weights (or equivalently scalar features) on edges.
  • Edge Features: supports feature vectors on edges.
  • Heterograph: supports heterogeneous graphs (see GNNHeteroGraph).
  • TemporalSnapshotsGNNGraphs: supports temporal graphs (see TemporalSnapshotsGNNGraph) by applying the convolution layers to each snapshot independently.
LayerSparse OpsEdge WeightEdge FeaturesHeterographTemporalSnapshotsGNNGraphs
AGNNConv
CGConv
ChebConv
EGNNConv
EdgeConv
GATConv
GATv2Conv
GatedGraphConv
GCNConv
GINConv
GMMConv
GraphConv
MEGNetConv
NNConv
ResGatedGraphConv
SAGEConv
SGConv

Docs

GNNLux.AGNNConvType
AGNNConv(; init_beta=1.0f0, trainable=true, add_self_loops=true)

Attention-based Graph Neural Network layer from paper Attention-based Graph Neural Network for Semi-Supervised Learning.

The forward pass is given by

\[\mathbf{x}_i' = \sum_{j \in N(i)} \alpha_{ij} \mathbf{x}_j\]

where the attention coefficients $\alpha_{ij}$ are given by

\[\alpha_{ij} =\frac{e^{\beta \cos(\mathbf{x}_i, \mathbf{x}_j)}} + {\sum_{j'}e^{\beta \cos(\mathbf{x}_i, \mathbf{x}_{j'})}}\]

with the cosine distance defined by

\[\cos(\mathbf{x}_i, \mathbf{x}_j) = + \frac{\mathbf{x}_i \cdot \mathbf{x}_j}{\lVert\mathbf{x}_i\rVert \lVert\mathbf{x}_j\rVert}\]

and $\beta$ a trainable parameter if trainable=true.

Arguments

  • init_beta: The initial value of $\beta$. Default 1.0f0.
  • trainable: If true, $\beta$ is trainable. Default true.
  • add_self_loops: Add self loops to the graph before performing the convolution. Default true.

Examples:

using GNNLux, Lux, Random
+
+# initialize random number generator
+rng = Random.default_rng()
+
+# create data
+s = [1,1,2,3]
+t = [2,3,1,1]
+g = GNNGraph(s, t)
+
+# create layer
+l = AGNNConv(init_beta=2.0f0)
+
+# setup layer
+ps, st = LuxCore.setup(rng, l)
+
+# forward pass
+y, st = l(g, x, ps, st)   
source
GNNLux.CGConvType
CGConv((in, ein) => out, act = identity; residual = false,
+            use_bias = true, init_weight = glorot_uniform, init_bias = zeros32)
+CGConv(in => out, ...)

The crystal graph convolutional layer from the paper Crystal Graph Convolutional Neural Networks for an Accurate and Interpretable Prediction of Material Properties. Performs the operation

\[\mathbf{x}_i' = \mathbf{x}_i + \sum_{j\in N(i)}\sigma(W_f \mathbf{z}_{ij} + \mathbf{b}_f)\, act(W_s \mathbf{z}_{ij} + \mathbf{b}_s)\]

where $\mathbf{z}_{ij}$ is the node and edge features concatenation $[\mathbf{x}_i; \mathbf{x}_j; \mathbf{e}_{j\to i}]$ and $\sigma$ is the sigmoid function. The residual $\mathbf{x}_i$ is added only if residual=true and the output size is the same as the input size.

Arguments

  • in: The dimension of input node features.
  • ein: The dimension of input edge features.

If ein is not given, assumes that no edge features are passed as input in the forward pass.

  • out: The dimension of output node features.
  • act: Activation function.
  • residual: Add a residual connection.
  • init_weight: Weights' initializer. Default glorot_uniform.
  • init_bias: Bias initializer. Default zeros32.
  • use_bias: Add learnable bias. Default true.

Examples

using GNNLux, Lux, Random
+
+# initialize random number generator
+rng = Random.default_rng()
+
+# create random graph
+g = rand_graph(rng, 5, 6)
+x = rand(rng, Float32, 2, g.num_nodes)
+e = rand(rng, Float32, 3, g.num_edges)
+
+l = CGConv((2, 3) => 4, tanh)
+
+# setup layer
+ps, st = LuxCore.setup(rng, l)
+
+# forward pass
+y, st = l(g, x, e, ps, st)    # size: (4, num_nodes)
+
+# No edge features
+l = CGConv(2 => 4, tanh)
+ps, st = LuxCore.setup(rng, l)
+y, st = l(g, x, ps, st)    # size: (4, num_nodes)
source
GNNLux.ChebConvType
ChebConv(in => out, k; init_weight = glorot_uniform, init_bias = zeros32, use_bias = true)

Chebyshev spectral graph convolutional layer from paper Convolutional Neural Networks on Graphs with Fast Localized Spectral Filtering.

Implements

\[X' = \sum^{K-1}_{k=0} W^{(k)} Z^{(k)}\]

where $Z^{(k)}$ is the $k$-th term of Chebyshev polynomials, and can be calculated by the following recursive form:

\[\begin{aligned} +Z^{(0)} &= X \\ +Z^{(1)} &= \hat{L} X \\ +Z^{(k)} &= 2 \hat{L} Z^{(k-1)} - Z^{(k-2)} +\end{aligned}\]

with $\hat{L}$ the scaled_laplacian.

Arguments

  • in: The dimension of input features.
  • out: The dimension of output features.
  • k: The order of Chebyshev polynomial.
  • init_weight: Weights' initializer. Default glorot_uniform.
  • init_bias: Bias initializer. Default zeros32.
  • use_bias: Add learnable bias. Default true.

Examples

using GNNLux, Lux, Random
+
+# initialize random number generator
+rng = Random.default_rng()
+
+# create data
+s = [1,1,2,3]
+t = [2,3,1,1]
+g = GNNGraph(s, t)
+x = randn(rng, Float32, 3, g.num_nodes)
+
+# create layer
+l = ChebConv(3 => 5, 5)
+
+# setup layer
+ps, st = LuxCore.setup(rng, l)
+
+# forward pass
+y, st = l(g, x, ps, st)       # size of the output y:  5 × num_nodes
source
GNNLux.DConvType
DConv(in => out, k; init_weight = glorot_uniform, init_bias = zeros32, use_bias = true)

Diffusion convolution layer from the paper Diffusion Convolutional Recurrent Neural Networks: Data-Driven Traffic Forecasting.

Arguments

  • in: The dimension of input features.
  • out: The dimension of output features.
  • k: Number of diffusion steps.
  • init_weight: Weights' initializer. Default glorot_uniform.
  • init_bias: Bias initializer. Default zeros32.
  • use_bias: Add learnable bias. Default true.

Examples

using GNNLux, Lux, Random
+
+# initialize random number generator
+rng = Random.default_rng()
+
+# create random graph
+g = GNNGraph(rand(rng, 10, 10), ndata = rand(rng, Float32, 2, 10))
+
+dconv = DConv(2 => 4, 4)
+
+# setup layer
+ps, st = LuxCore.setup(rng, dconv)
+
+# forward pass
+y, st = dconv(g, g.ndata.x, ps, st)   # size: (4, num_nodes)
source
GNNLux.EGNNConvType
EGNNConv((in, ein) => out; hidden_size=2in, residual=false)
+EGNNConv(in => out; hidden_size=2in, residual=false)

Equivariant Graph Convolutional Layer from E(n) Equivariant Graph Neural Networks.

The layer performs the following operation:

\[\begin{aligned} +\mathbf{m}_{j\to i} &=\phi_e(\mathbf{h}_i, \mathbf{h}_j, \lVert\mathbf{x}_i-\mathbf{x}_j\rVert^2, \mathbf{e}_{j\to i}),\\ +\mathbf{x}_i' &= \mathbf{x}_i + C_i\sum_{j\in\mathcal{N}(i)}(\mathbf{x}_i-\mathbf{x}_j)\phi_x(\mathbf{m}_{j\to i}),\\ +\mathbf{m}_i &= C_i\sum_{j\in\mathcal{N}(i)} \mathbf{m}_{j\to i},\\ +\mathbf{h}_i' &= \mathbf{h}_i + \phi_h(\mathbf{h}_i, \mathbf{m}_i) +\end{aligned}\]

where $\mathbf{h}_i$, $\mathbf{x}_i$, $\mathbf{e}_{j\to i}$ are invariant node features, equivariant node features, and edge features respectively. $\phi_e$, $\phi_h$, and $\phi_x$ are two-layer MLPs. C is a constant for normalization, computed as $1/|\mathcal{N}(i)|$.

Constructor Arguments

  • in: Number of input features for h.
  • out: Number of output features for h.
  • ein: Number of input edge features.
  • hidden_size: Hidden representation size.
  • residual: If true, add a residual connection. Only possible if in == out. Default false.

Forward Pass

l(g, x, h, e=nothing, ps, st)

Forward Pass Arguments:

  • g : The graph.
  • x : Matrix of equivariant node coordinates.
  • h : Matrix of invariant node features.
  • e : Matrix of invariant edge features. Default nothing.
  • ps : Parameters.
  • st : State.

Returns updated h and x.

Examples

using GNNLux, Lux, Random
+
+# initialize random number generator
+rng = Random.default_rng()
+
+# create random graph
+g = rand_graph(rng, 10, 10)
+h = randn(rng, Float32, 5, g.num_nodes)
+x = randn(rng, Float32, 3, g.num_nodes)
+
+egnn = EGNNConv(5 => 6, 10)
+
+# setup layer
+ps, st = LuxCore.setup(rng, egnn)
+
+# forward pass
+(hnew, xnew), st = egnn(g, h, x, ps, st)
source
GNNLux.EdgeConvType
EdgeConv(nn; aggr=max)

Edge convolutional layer from paper Dynamic Graph CNN for Learning on Point Clouds.

Performs the operation

\[\mathbf{x}_i' = \square_{j \in N(i)}\, nn([\mathbf{x}_i; \mathbf{x}_j - \mathbf{x}_i])\]

where nn generally denotes a learnable function, e.g. a linear layer or a multi-layer perceptron.

Arguments

  • nn: A (possibly learnable) function.
  • aggr: Aggregation operator for the incoming messages (e.g. +, *, max, min, and mean).

Examples:

using GNNLux, Lux, Random
+
 # initialize random number generator
 rng = Random.default_rng()
+
+# create data
+s = [1,1,2,3]
+t = [2,3,1,1]
+in_channel = 3
+out_channel = 5
+g = GNNGraph(s, t)
+x = rand(rng, Float32, in_channel, g.num_nodes)
+
+# create layer
+l = EdgeConv(Dense(2 * in_channel, out_channel), aggr = +)
+
+# setup layer
+ps, st = LuxCore.setup(rng, l)
+
+# forward pass
+y, st = l(g, x, ps, st)
source
GNNLux.GATConvType
GATConv(in => out, σ = identity; heads = 1, concat = true, negative_slope = 0.2, init_weight = glorot_uniform, init_bias = zeros32, use_bias = true, add_self_loops = true, dropout=0.0)
+GATConv((in, ein) => out, ...)

Graph attentional layer from the paper Graph Attention Networks.

Implements the operation

\[\mathbf{x}_i' = \sum_{j \in N(i) \cup \{i\}} \alpha_{ij} W \mathbf{x}_j\]

where the attention coefficients $\alpha_{ij}$ are given by

\[\alpha_{ij} = \frac{1}{z_i} \exp(LeakyReLU(\mathbf{a}^T [W \mathbf{x}_i; W \mathbf{x}_j]))\]

with $z_i$ a normalization factor.

In case ein > 0 is given, edge features of dimension ein will be expected in the forward pass and the attention coefficients will be calculated as

\[\alpha_{ij} = \frac{1}{z_i} \exp(LeakyReLU(\mathbf{a}^T [W_e \mathbf{e}_{j\to i}; W \mathbf{x}_i; W \mathbf{x}_j]))\]

Arguments

  • in: The dimension of input node features.
  • ein: The dimension of input edge features. Default 0 (i.e. no edge features passed in the forward).
  • out: The dimension of output node features.
  • σ: Activation function. Default identity.
  • heads: Number attention heads. Default 1.
  • concat: Concatenate layer output or not. If not, layer output is averaged over the heads. Default true.
  • negative_slope: The parameter of LeakyReLU.Default 0.2.
  • init_weight: Weights' initializer. Default glorot_uniform.
  • init_bias: Bias initializer. Default zeros32.
  • use_bias: Add learnable bias. Default true.
  • add_self_loops: Add self loops to the graph before performing the convolution. Default true.
  • dropout: Dropout probability on the normalized attention coefficient. Default 0.0.

Examples

using GNNLux, Lux, Random
+
+# initialize random number generator
+rng = Random.default_rng()
+
+# create data
+s = [1,1,2,3]
+t = [2,3,1,1]
+in_channel = 3
+out_channel = 5
+g = GNNGraph(s, t)
+x = randn(rng, Float32, 3, g.num_nodes)
+
+# create layer
+l = GATConv(in_channel => out_channel; add_self_loops = false, use_bias = false, heads=2, concat=true)
+
+# setup layer
+ps, st = LuxCore.setup(rng, l)
+
+# forward pass
+y, st = l(g, x, ps, st)       
source
GNNLux.GATv2ConvType
GATv2Conv(in => out, σ = identity; heads = 1, concat = true, negative_slope = 0.2, init_weight = glorot_uniform, init_bias = zeros32, use_bias = true, add_self_loops = true, dropout=0.0)
+GATv2Conv((in, ein) => out, ...)

GATv2 attentional layer from the paper How Attentive are Graph Attention Networks?.

Implements the operation

\[\mathbf{x}_i' = \sum_{j \in N(i) \cup \{i\}} \alpha_{ij} W_1 \mathbf{x}_j\]

where the attention coefficients $\alpha_{ij}$ are given by

\[\alpha_{ij} = \frac{1}{z_i} \exp(\mathbf{a}^T LeakyReLU(W_2 \mathbf{x}_i + W_1 \mathbf{x}_j))\]

with $z_i$ a normalization factor.

In case ein > 0 is given, edge features of dimension ein will be expected in the forward pass and the attention coefficients will be calculated as

\[\alpha_{ij} = \frac{1}{z_i} \exp(\mathbf{a}^T LeakyReLU(W_3 \mathbf{e}_{j\to i} + W_2 \mathbf{x}_i + W_1 \mathbf{x}_j)).\]

Arguments

  • in: The dimension of input node features.
  • ein: The dimension of input edge features. Default 0 (i.e. no edge features passed in the forward).
  • out: The dimension of output node features.
  • σ: Activation function. Default identity.
  • heads: Number attention heads. Default 1.
  • concat: Concatenate layer output or not. If not, layer output is averaged over the heads. Default true.
  • negative_slope: The parameter of LeakyReLU.Default 0.2.
  • add_self_loops: Add self loops to the graph before performing the convolution. Default true.
  • dropout: Dropout probability on the normalized attention coefficient. Default 0.0.
  • init_weight: Weights' initializer. Default glorot_uniform.
  • init_bias: Bias initializer. Default zeros32.
  • use_bias: Add learnable bias. Default true.

Examples

using GNNLux, Lux, Random
+
+# initialize random number generator
+rng = Random.default_rng()
+
+# create data
+s = [1,1,2,3]
+t = [2,3,1,1]
+in_channel = 3
+out_channel = 5
+ein = 3
+g = GNNGraph(s, t)
+x = randn(rng, Float32, 3, g.num_nodes)
+
+# create layer
+l = GATv2Conv((in_channel, ein) => out_channel, add_self_loops = false)
+
+# setup layer
+ps, st = LuxCore.setup(rng, l)
+
+# edge features
+e = randn(rng, Float32, ein, length(s))
+
+# forward pass
+y, st = l(g, x, e, ps, st)    
source
GNNLux.GCNConvType
GCNConv(in => out, σ=identity; [init_weight, init_bias, use_bias, add_self_loops, use_edge_weight])

Graph convolutional layer from paper Semi-supervised Classification with Graph Convolutional Networks.

Performs the operation

\[\mathbf{x}'_i = \sum_{j\in N(i)} a_{ij} W \mathbf{x}_j\]

where $a_{ij} = 1 / \sqrt{|N(i)||N(j)|}$ is a normalization factor computed from the node degrees.

If the input graph has weighted edges and use_edge_weight=true, than $a_{ij}$ will be computed as

\[a_{ij} = \frac{e_{j\to i}}{\sqrt{\sum_{j \in N(i)} e_{j\to i}} \sqrt{\sum_{i \in N(j)} e_{i\to j}}}\]

Arguments

  • in: Number of input features.
  • out: Number of output features.
  • σ: Activation function. Default identity.
  • init_weight: Weights' initializer. Default glorot_uniform.
  • init_bias: Bias initializer. Default zeros32.
  • use_bias: Add learnable bias. Default true.
  • add_self_loops: Add self loops to the graph before performing the convolution. Default false.
  • use_edge_weight: If true, consider the edge weights in the input graph (if available). If add_self_loops=true the new weights will be set to 1. This option is ignored if the edge_weight is explicitly provided in the forward pass. Default false.

Forward

(::GCNConv)(g, x, [edge_weight], ps, st; norm_fn = d -> 1 ./ sqrt.(d), conv_weight=nothing)

Takes as input a graph g, a node feature matrix x of size [in, num_nodes], optionally an edge weight vector and the parameter and state of the layer. Returns a node feature matrix of size [out, num_nodes].

The norm_fn parameter allows for custom normalization of the graph convolution operation by passing a function as argument. By default, it computes $\frac{1}{\sqrt{d}}$ i.e the inverse square root of the degree (d) of each node in the graph. If conv_weight is an AbstractMatrix of size [out, in], then the convolution is performed using that weight matrix.

Examples

using GNNLux, Lux, Random
+
+# initialize random number generator
+rng = Random.default_rng()
+
 # create data
 s = [1,1,2,3]
 t = [2,3,1,1]
@@ -25,4 +193,205 @@
 g = GNNGraph(s, t, w)
 l = GCNConv(3 => 5, use_edge_weight=true)
 ps, st = Lux.setup(rng, l)
-y = l(g, x, ps, st) # same as l(g, x, w) 
source
\ No newline at end of file +y = l(g, x, ps, st) # same as l(g, x, w)
source
GNNLux.GINConvType
GINConv(f, ϵ; aggr=+)

Graph Isomorphism convolutional layer from paper How Powerful are Graph Neural Networks?.

Implements the graph convolution

\[\mathbf{x}_i' = f_\Theta\left((1 + \epsilon) \mathbf{x}_i + \sum_{j \in N(i)} \mathbf{x}_j \right)\]

where $f_\Theta$ typically denotes a learnable function, e.g. a linear layer or a multi-layer perceptron.

Arguments

  • f: A (possibly learnable) function acting on node features.
  • ϵ: Weighting factor.

Examples:

using GNNLux, Lux, Random
+
+# initialize random number generator
+rng = Random.default_rng()
+
+# create data
+s = [1,1,2,3]
+t = [2,3,1,1]
+in_channel = 3
+out_channel = 5
+g = GNNGraph(s, t)
+x = randn(rng, Float32, in_channel, g.num_nodes)
+
+# create dense layer
+nn = Dense(in_channel, out_channel)
+
+# create layer
+l = GINConv(nn, 0.01f0, aggr = mean)
+
+# setup layer
+ps, st = LuxCore.setup(rng, l)
+
+# forward pass
+y, st = l(g, x, ps, st)       # size:  out_channel × num_nodes
source
GNNLux.GMMConvType
GMMConv((in, ein) => out, σ=identity; K = 1, residual = false init_weight = glorot_uniform, init_bias = zeros32, use_bias = true)

Graph mixture model convolution layer from the paper Geometric deep learning on graphs and manifolds using mixture model CNNs Performs the operation

\[\mathbf{x}_i' = \mathbf{x}_i + \frac{1}{|N(i)|} \sum_{j\in N(i)}\frac{1}{K}\sum_{k=1}^K \mathbf{w}_k(\mathbf{e}_{j\to i}) \odot \Theta_k \mathbf{x}_j\]

where $w^a_{k}(e^a)$ for feature a and kernel k is given by

\[w^a_{k}(e^a) = \exp(-\frac{1}{2}(e^a - \mu^a_k)^T (\Sigma^{-1})^a_k(e^a - \mu^a_k))\]

$\Theta_k, \mu^a_k, (\Sigma^{-1})^a_k$ are learnable parameters.

The input to the layer is a node feature array x of size (num_features, num_nodes) and edge pseudo-coordinate array e of size (num_features, num_edges) The residual $\mathbf{x}_i$ is added only if residual=true and the output size is the same as the input size.

Arguments

  • in: Number of input node features.
  • ein: Number of input edge features.
  • out: Number of output features.
  • σ: Activation function. Default identity.
  • K: Number of kernels. Default 1.
  • residual: Residual conncetion. Default false.
  • init_weight: Weights' initializer. Default glorot_uniform.
  • init_bias: Bias initializer. Default zeros32.
  • use_bias: Add learnable bias. Default true.

Examples

using GNNLux, Lux, Random
+
+# initialize random number generator
+rng = Random.default_rng()
+
+# create data
+s = [1,1,2,3]
+t = [2,3,1,1]
+g = GNNGraph(s,t)
+nin, ein, out, K = 4, 10, 7, 8 
+x = randn(rng, Float32, nin, g.num_nodes)
+e = randn(rng, Float32, ein, g.num_edges)
+
+# create layer
+l = GMMConv((nin, ein) => out, K=K)
+
+# setup layer
+ps, st = LuxCore.setup(rng, l)
+
+# forward pass
+y, st = l(g, x, e, ps, st)       # size:  out × num_nodes
source
GNNLux.GatedGraphConvType
GatedGraphConv(out, num_layers; 
+        aggr = +, init_weight = glorot_uniform)

Gated graph convolution layer from Gated Graph Sequence Neural Networks.

Implements the recursion

\[\begin{aligned} +\mathbf{h}^{(0)}_i &= [\mathbf{x}_i; \mathbf{0}] \\ +\mathbf{h}^{(l)}_i &= GRU(\mathbf{h}^{(l-1)}_i, \square_{j \in N(i)} W \mathbf{h}^{(l-1)}_j) +\end{aligned}\]

where $\mathbf{h}^{(l)}_i$ denotes the $l$-th hidden variables passing through GRU. The dimension of input $\mathbf{x}_i$ needs to be less or equal to out.

Arguments

  • out: The dimension of output features.
  • num_layers: The number of recursion steps.
  • aggr: Aggregation operator for the incoming messages (e.g. +, *, max, min, and mean).
  • init_weight: Weights' initializer. Default glorot_uniform.

Examples:

using GNNLux, Lux, Random
+
+# initialize random number generator
+rng = Random.default_rng()
+
+# create data
+s = [1,1,2,3]
+t = [2,3,1,1]
+out_channel = 5
+num_layers = 3
+g = GNNGraph(s, t)
+
+# create layer
+l = GatedGraphConv(out_channel, num_layers)
+
+# setup layer
+ps, st = LuxCore.setup(rng, l)
+
+# forward pass
+y, st = l(g, x, ps, st)       # size:  out_channel × num_nodes  
source
GNNLux.GraphConvType
GraphConv(in => out, σ = identity; aggr = +, init_weight = glorot_uniform,init_bias = zeros32, use_bias = true)

Graph convolution layer from Reference: Weisfeiler and Leman Go Neural: Higher-order Graph Neural Networks.

Performs:

\[\mathbf{x}_i' = W_1 \mathbf{x}_i + \square_{j \in \mathcal{N}(i)} W_2 \mathbf{x}_j\]

where the aggregation type is selected by aggr.

Arguments

  • in: The dimension of input features.
  • out: The dimension of output features.
  • σ: Activation function.
  • aggr: Aggregation operator for the incoming messages (e.g. +, *, max, min, and mean).
  • init_weight: Weights' initializer. Default glorot_uniform.
  • init_bias: Bias initializer. Default zeros32.
  • use_bias: Add learnable bias. Default true.

Examples

using GNNLux, Lux, Random
+
+# initialize random number generator
+rng = Random.default_rng()
+
+# create data
+s = [1,1,2,3]
+t = [2,3,1,1]
+in_channel = 3
+out_channel = 5
+g = GNNGraph(s, t)
+x = randn(rng, Float32, 3, g.num_nodes)
+
+# create layer
+l = GraphConv(in_channel => out_channel, relu, use_bias = false, aggr = mean)
+
+# setup layer
+ps, st = LuxCore.setup(rng, l)
+
+# forward pass
+y, st = l(g, x, ps, st)       # size of the output y:  5 × num_nodes
source
GNNLux.MEGNetConvType
MEGNetConv(ϕe, ϕv; aggr=mean)
+MEGNetConv(in => out; aggr=mean)

Convolution from Graph Networks as a Universal Machine Learning Framework for Molecules and Crystals paper. In the forward pass, takes as inputs node features x and edge features e and returns updated features x' and e' according to

\[\begin{aligned} +\mathbf{e}_{i\to j}' = \phi_e([\mathbf{x}_i;\, \mathbf{x}_j;\, \mathbf{e}_{i\to j}]),\\ +\mathbf{x}_{i}' = \phi_v([\mathbf{x}_i;\, \square_{j\in \mathcal{N}(i)}\,\mathbf{e}_{j\to i}']). +\end{aligned}\]

aggr defines the aggregation to be performed.

If the neural networks ϕe and ϕv are not provided, they will be constructed from the in and out arguments instead as multi-layer perceptron with one hidden layer and relu activations.

Examples

using GNNLux, Lux, Random
+
+# initialize random number generator
+rng = Random.default_rng()
+
+# create a random graph
+g = rand_graph(rng, 10, 30)
+x = randn(rng, Float32, 3, 10)
+e = randn(rng, Float32, 3, 30)
+
+# create a MEGNetConv layer
+m = MEGNetConv(3 => 3)
+
+# setup layer
+ps, st = LuxCore.setup(rng, m)
+
+# forward pass
+(x′, e′), st = m(g, x, e, ps, st)
source
GNNLux.NNConvType
NNConv(in => out, f, σ=identity; aggr=+, init_bias = zeros32, use_bias = true, init_weight = glorot_uniform)

The continuous kernel-based convolutional operator from the Neural Message Passing for Quantum Chemistry paper. This convolution is also known as the edge-conditioned convolution from the Dynamic Edge-Conditioned Filters in Convolutional Neural Networks on Graphs paper.

Performs the operation

\[\mathbf{x}_i' = W \mathbf{x}_i + \square_{j \in N(i)} f_\Theta(\mathbf{e}_{j\to i})\,\mathbf{x}_j\]

where $f_\Theta$ denotes a learnable function (e.g. a linear layer or a multi-layer perceptron). Given an input of batched edge features e of size (num_edge_features, num_edges), the function f will return an batched matrices array whose size is (out, in, num_edges). For convenience, also functions returning a single (out*in, num_edges) matrix are allowed.

Arguments

  • in: The dimension of input node features.
  • out: The dimension of output node features.
  • f: A (possibly learnable) function acting on edge features.
  • aggr: Aggregation operator for the incoming messages (e.g. +, *, max, min, and mean).
  • σ: Activation function.
  • init_weight: Weights' initializer. Default glorot_uniform.
  • init_bias: Bias initializer. Default zeros32.
  • use_bias: Add learnable bias. Default true.

Examples:

using GNNLux, Lux, Random
+
+# initialize random number generator
+rng = Random.default_rng()
+
+# create data
+n_in = 3
+n_in_edge = 10
+n_out = 5
+
+s = [1,1,2,3]
+t = [2,3,1,1]
+g = GNNGraph(s, t)
+x = randn(rng, Float32, n_in, g.num_nodes)
+e = randn(rng, Float32, n_in_edge, g.num_edges)
+
+# create dense layer
+nn = Dense(n_in_edge => n_out * n_in)
+
+# create layer
+l = NNConv(n_in => n_out, nn, tanh, use_bias = true, aggr = +)
+
+# setup layer
+ps, st = LuxCore.setup(rng, l)
+
+# forward pass
+y, st = l(g, x, e, ps, st)       # size:  n_out × num_nodes 
source
GNNLux.ResGatedGraphConvType
ResGatedGraphConv(in => out, act=identity; init_weight = glorot_uniform, init_bias = zeros32, use_bias = true)

The residual gated graph convolutional operator from the Residual Gated Graph ConvNets paper.

The layer's forward pass is given by

\[\mathbf{x}_i' = act\big(U\mathbf{x}_i + \sum_{j \in N(i)} \eta_{ij} V \mathbf{x}_j\big),\]

where the edge gates $\eta_{ij}$ are given by

\[\eta_{ij} = sigmoid(A\mathbf{x}_i + B\mathbf{x}_j).\]

Arguments

  • in: The dimension of input features.
  • out: The dimension of output features.
  • act: Activation function.
  • init_weight: Weights' initializer. Default glorot_uniform.
  • init_bias: Bias initializer. Default zeros32.
  • use_bias: Add learnable bias. Default true.

Examples:

using GNNLux, Lux, Random
+
+# initialize random number generator
+rng = Random.default_rng()
+
+# create data
+s = [1,1,2,3]
+t = [2,3,1,1]
+in_channel = 3
+out_channel = 5
+g = GNNGraph(s, t)
+x = randn(rng, Float32, in_channel, g.num_nodes)
+
+# create layer
+l = ResGatedGraphConv(in_channel => out_channel, tanh, use_bias = true)
+
+# setup layer
+ps, st = LuxCore.setup(rng, l)
+
+# forward pass
+y, st = l(g, x, ps, st)       # size:  out_channel × num_nodes  
source
GNNLux.SAGEConvType
SAGEConv(in => out, σ=identity; aggr=mean, init_weight = glorot_uniform, init_bias = zeros32, use_bias=true)

GraphSAGE convolution layer from paper Inductive Representation Learning on Large Graphs.

Performs:

\[\mathbf{x}_i' = W \cdot [\mathbf{x}_i; \square_{j \in \mathcal{N}(i)} \mathbf{x}_j]\]

where the aggregation type is selected by aggr.

Arguments

  • in: The dimension of input features.
  • out: The dimension of output features.
  • σ: Activation function.
  • aggr: Aggregation operator for the incoming messages (e.g. +, *, max, min, and mean).
  • init_bias: Bias initializer. Default zeros32.
  • use_bias: Add learnable bias. Default true.

Examples:

using GNNLux, Lux, Random
+
+# initialize random number generator
+rng = Random.default_rng()
+
+# create data
+s = [1,1,2,3]
+t = [2,3,1,1]
+in_channel = 3
+out_channel = 5
+g = GNNGraph(s, t)
+x = rand(rng, Float32, in_channel, g.num_nodes)
+
+# create layer
+l = SAGEConv(in_channel => out_channel, tanh, use_bias = false, aggr = +)
+
+# setup layer
+ps, st = LuxCore.setup(rng, l)
+
+# forward pass
+y, st = l(g, x, ps, st)       # size:  out_channel × num_nodes   
source
GNNLux.SGConvType
SGConv(int => out, k = 1; init_weight = glorot_uniform, init_bias = zeros32, use_bias = true, add_self_loops = true,use_edge_weight = false)

SGC layer from Simplifying Graph Convolutional Networks Performs operation

\[H^{K} = (\tilde{D}^{-1/2} \tilde{A} \tilde{D}^{-1/2})^K X \Theta\]

where $\tilde{A}$ is $A + I$.

Arguments

  • in: Number of input features.
  • out: Number of output features.
  • k : Number of hops k. Default 1.
  • add_self_loops: Add self loops to the graph before performing the convolution. Default false.
  • use_edge_weight: If true, consider the edge weights in the input graph (if available). If add_self_loops=true the new weights will be set to 1. Default false.
  • init_weight: Weights' initializer. Default glorot_uniform.
  • init_bias: Bias initializer. Default zeros32.
  • use_bias: Add learnable bias. Default true.

Examples

using GNNLux, Lux, Random
+
+# initialize random number generator
+rng = Random.default_rng()
+
+# create data
+s = [1,1,2,3]
+t = [2,3,1,1]
+g = GNNGraph(s, t)
+x = randn(rng, Float32, 3, g.num_nodes)
+
+# create layer
+l = SGConv(3 => 5; add_self_loops = true) 
+
+# setup layer
+ps, st = LuxCore.setup(rng, l)
+
+# forward pass
+y, st = l(g, x, ps, st)       # size:  5 × num_nodes
+
+# convolution with edge weights
+w = [1.1, 0.1, 2.3, 0.5]
+y = l(g, x, w, ps, st)
+
+# Edge weights can also be embedded in the graph.
+g = GNNGraph(s, t, w)
+l = SGConv(3 => 5, add_self_loops = true, use_edge_weight=true) 
+ps, st = LuxCore.setup(rng, l)
+y, st = l(g, x, ps, st) # same as l(g, x, w) 
source
\ No newline at end of file diff --git a/gnnlux/index.html b/gnnlux/index.html index 1bfebc6f4..9cf250f5c 100644 --- a/gnnlux/index.html +++ b/gnnlux/index.html @@ -1 +1 @@ -Home · GNNLux.jl

GNNLux.jl

GNNLux.jl is a work-in-progress package that implements stateless graph convolutional layers, fully compatible with the Lux.jl machine learning framework. It is built on top of the GNNGraphs.jl, GNNlib.jl, and Lux.jl packages.

The full documentation will be available soon.

\ No newline at end of file +Home · GNNLux.jl

GNNLux.jl

GNNLux.jl is a work-in-progress package that implements stateless graph convolutional layers, fully compatible with the Lux.jl machine learning framework. It is built on top of the GNNGraphs.jl, GNNlib.jl, and Lux.jl packages.

The full documentation will be available soon.

\ No newline at end of file diff --git a/gnnlux/objects.inv b/gnnlux/objects.inv index 2afab68a9..93156573a 100644 Binary files a/gnnlux/objects.inv and b/gnnlux/objects.inv differ diff --git a/gnnlux/search_index.js b/gnnlux/search_index.js index 1d8e42fdc..ddb309fb3 100644 --- a/gnnlux/search_index.js +++ b/gnnlux/search_index.js @@ -1,3 +1,3 @@ var documenterSearchIndex = {"docs": -[{"location":"api/basic/","page":"Basic","title":"Basic","text":"CurrentModule = GNNLux","category":"page"},{"location":"api/basic/#GNNLayer","page":"Basic","title":"GNNLayer","text":"","category":"section"},{"location":"api/basic/","page":"Basic","title":"Basic","text":"GNNLayer\nGNNChain","category":"page"},{"location":"api/basic/#GNNLux.GNNLayer","page":"Basic","title":"GNNLux.GNNLayer","text":"abstract type GNNLayer <: AbstractLuxLayer end\n\nAn abstract type from which graph neural network layers are derived. It is derived from Lux's AbstractLuxLayer type.\n\nSee also GNNLux.GNNChain.\n\n\n\n\n\n","category":"type"},{"location":"api/basic/#GNNLux.GNNChain","page":"Basic","title":"GNNLux.GNNChain","text":"GNNChain(layers...)\nGNNChain(name = layer, ...)\n\nCollects multiple layers / functions to be called in sequence on given input graph and input node features. \n\nIt allows to compose layers in a sequential fashion as Lux.Chain does, propagating the output of each layer to the next one. In addition, GNNChain handles the input graph as well, providing it as a first argument only to layers subtyping the GNNLayer abstract type. \n\nGNNChain supports indexing and slicing, m[2] or m[1:end-1], and if names are given, m[:name] == m[1] etc.\n\nExamples\n\njulia> using Lux, GNNLux, Random\n\njulia> rng = Random.default_rng();\n\njulia> m = GNNChain(GCNConv(2=>5), \n x -> relu.(x), \n Dense(5=>4))\n\njulia> x = randn(rng, Float32, 2, 3);\n\njulia> g = rand_graph(rng, 3, 6)\nGNNGraph:\n num_nodes: 3\n num_edges: 6\n\njulia> ps, st = LuxCore.setup(rng, m);\n\njulia> m(g, x, ps, st) # First entry is the output, second entry is the state of the model\n(Float32[-0.15594329 -0.15594329 -0.15594329; 0.93431795 0.93431795 0.93431795; 0.27568763 0.27568763 0.27568763; 0.12568939 0.12568939 0.12568939], (layer_1 = NamedTuple(), layer_2 = NamedTuple(), layer_3 = NamedTuple()))\n\n\n\n\n\n","category":"type"},{"location":"api/conv/","page":"Convolutional Layers","title":"Convolutional Layers","text":"CurrentModule = GNNLux","category":"page"},{"location":"api/conv/#Convolutional-Layers","page":"Convolutional Layers","title":"Convolutional Layers","text":"","category":"section"},{"location":"api/conv/","page":"Convolutional Layers","title":"Convolutional Layers","text":"Many different types of graphs convolutional layers have been proposed in the literature. Choosing the right layer for your application could involve a lot of exploration. Multiple graph convolutional layers are typically stacked together to create a graph neural network model (see GNNChain).","category":"page"},{"location":"api/conv/","page":"Convolutional Layers","title":"Convolutional Layers","text":"The table below lists all graph convolutional layers implemented in the GNNLux.jl. It also highlights the presence of some additional capabilities with respect to basic message passing:","category":"page"},{"location":"api/conv/","page":"Convolutional Layers","title":"Convolutional Layers","text":"Sparse Ops: implements message passing as multiplication by sparse adjacency matrix instead of the gather/scatter mechanism. This can lead to better CPU performances but it is not supported on GPU yet. \nEdge Weight: supports scalar weights (or equivalently scalar features) on edges. \nEdge Features: supports feature vectors on edges.\nHeterograph: supports heterogeneous graphs (see GNNHeteroGraph).\nTemporalSnapshotsGNNGraphs: supports temporal graphs (see TemporalSnapshotsGNNGraph) by applying the convolution layers to each snapshot independently.","category":"page"},{"location":"api/conv/","page":"Convolutional Layers","title":"Convolutional Layers","text":"| Layer |Sparse Ops|Edge Weight|Edge Features| Heterograph | TemporalSnapshotsGNNGraphs | | :–––– | :–-: |:–-: |:–-: | :–-: | :–-: | ✓ | | GCNConv | ✓ | ✓ | | ✓ | |","category":"page"},{"location":"api/conv/#Docs","page":"Convolutional Layers","title":"Docs","text":"","category":"section"},{"location":"api/conv/","page":"Convolutional Layers","title":"Convolutional Layers","text":"Modules = [GNNLux]\nPages = [\"layers/conv.jl\"]\nPrivate = false","category":"page"},{"location":"api/conv/#GNNLux.GCNConv","page":"Convolutional Layers","title":"GNNLux.GCNConv","text":"GCNConv(in => out, σ=identity; [init_weight, init_bias, use_bias, add_self_loops, use_edge_weight])\n\nGraph convolutional layer from paper Semi-supervised Classification with Graph Convolutional Networks.\n\nPerforms the operation\n\nmathbfx_i = sum_jin N(i) a_ij W mathbfx_j\n\nwhere a_ij = 1 sqrtN(i)N(j) is a normalization factor computed from the node degrees. \n\nIf the input graph has weighted edges and use_edge_weight=true, than a_ij will be computed as\n\na_ij = frace_jto isqrtsum_j in N(i) e_jto i sqrtsum_i in N(j) e_ito j\n\nArguments\n\nin: Number of input features.\nout: Number of output features.\nσ: Activation function. Default identity.\ninit_weight: Weights' initializer. Default glorot_uniform.\ninit_bias: Bias initializer. Default zeros32.\nuse_bias: Add learnable bias. Default true.\nadd_self_loops: Add self loops to the graph before performing the convolution. Default false.\nuse_edge_weight: If true, consider the edge weights in the input graph (if available). If add_self_loops=true the new weights will be set to 1. This option is ignored if the edge_weight is explicitly provided in the forward pass. Default false.\n\nForward\n\n(::GCNConv)(g, x, [edge_weight], ps, st; norm_fn = d -> 1 ./ sqrt.(d), conv_weight=nothing)\n\nTakes as input a graph g, a node feature matrix x of size [in, num_nodes], optionally an edge weight vector and the parameter and state of the layer. Returns a node feature matrix of size [out, num_nodes].\n\nThe norm_fn parameter allows for custom normalization of the graph convolution operation by passing a function as argument. By default, it computes frac1sqrtd i.e the inverse square root of the degree (d) of each node in the graph. If conv_weight is an AbstractMatrix of size [out, in], then the convolution is performed using that weight matrix.\n\nExamples\n\nusing GNNLux, Lux, Random\n# initialize random number generator\nrng = Random.default_rng()\n# create data\ns = [1,1,2,3]\nt = [2,3,1,1]\ng = GNNGraph(s, t)\nx = randn(rng, Float32, 3, g.num_nodes)\n\n# create layer\nl = GCNConv(3 => 5) \n\n# setup layer\nps, st = LuxCore.setup(rng, l)\n\n# forward pass\ny = l(g, x, ps, st) # size of the output first entry: 5 × num_nodes\n\n# convolution with edge weights and custom normalization function\nw = [1.1, 0.1, 2.3, 0.5]\ncustom_norm_fn(d) = 1 ./ sqrt.(d + 1) # Custom normalization function\ny = l(g, x, w, ps, st; norm_fn = custom_norm_fn)\n\n# Edge weights can also be embedded in the graph.\ng = GNNGraph(s, t, w)\nl = GCNConv(3 => 5, use_edge_weight=true)\nps, st = Lux.setup(rng, l)\ny = l(g, x, ps, st) # same as l(g, x, w) \n\n\n\n\n\n","category":"type"},{"location":"#GNNLux.jl","page":"Home","title":"GNNLux.jl","text":"","category":"section"},{"location":"","page":"Home","title":"Home","text":"GNNLux.jl is a work-in-progress package that implements stateless graph convolutional layers, fully compatible with the Lux.jl machine learning framework. It is built on top of the GNNGraphs.jl, GNNlib.jl, and Lux.jl packages.","category":"page"},{"location":"","page":"Home","title":"Home","text":"The full documentation will be available soon.","category":"page"}] +[{"location":"api/basic/","page":"Basic","title":"Basic","text":"CurrentModule = GNNLux","category":"page"},{"location":"api/basic/#GNNLayer","page":"Basic","title":"GNNLayer","text":"","category":"section"},{"location":"api/basic/","page":"Basic","title":"Basic","text":"GNNLayer\nGNNChain","category":"page"},{"location":"api/basic/#GNNLux.GNNLayer","page":"Basic","title":"GNNLux.GNNLayer","text":"abstract type GNNLayer <: AbstractLuxLayer end\n\nAn abstract type from which graph neural network layers are derived. It is derived from Lux's AbstractLuxLayer type.\n\nSee also GNNLux.GNNChain.\n\n\n\n\n\n","category":"type"},{"location":"api/basic/#GNNLux.GNNChain","page":"Basic","title":"GNNLux.GNNChain","text":"GNNChain(layers...)\nGNNChain(name = layer, ...)\n\nCollects multiple layers / functions to be called in sequence on given input graph and input node features. \n\nIt allows to compose layers in a sequential fashion as Lux.Chain does, propagating the output of each layer to the next one. In addition, GNNChain handles the input graph as well, providing it as a first argument only to layers subtyping the GNNLayer abstract type. \n\nGNNChain supports indexing and slicing, m[2] or m[1:end-1], and if names are given, m[:name] == m[1] etc.\n\nExamples\n\njulia> using Lux, GNNLux, Random\n\njulia> rng = Random.default_rng();\n\njulia> m = GNNChain(GCNConv(2=>5), \n x -> relu.(x), \n Dense(5=>4))\n\njulia> x = randn(rng, Float32, 2, 3);\n\njulia> g = rand_graph(rng, 3, 6)\nGNNGraph:\n num_nodes: 3\n num_edges: 6\n\njulia> ps, st = LuxCore.setup(rng, m);\n\njulia> m(g, x, ps, st) # First entry is the output, second entry is the state of the model\n(Float32[-0.15594329 -0.15594329 -0.15594329; 0.93431795 0.93431795 0.93431795; 0.27568763 0.27568763 0.27568763; 0.12568939 0.12568939 0.12568939], (layer_1 = NamedTuple(), layer_2 = NamedTuple(), layer_3 = NamedTuple()))\n\n\n\n\n\n","category":"type"},{"location":"api/conv/","page":"Convolutional layers","title":"Convolutional layers","text":"CurrentModule = GNNLux","category":"page"},{"location":"api/conv/#Convolutional-Layers","page":"Convolutional layers","title":"Convolutional Layers","text":"","category":"section"},{"location":"api/conv/","page":"Convolutional layers","title":"Convolutional layers","text":"Many different types of graphs convolutional layers have been proposed in the literature. Choosing the right layer for your application could involve a lot of exploration. Multiple graph convolutional layers are typically stacked together to create a graph neural network model (see GNNChain).","category":"page"},{"location":"api/conv/","page":"Convolutional layers","title":"Convolutional layers","text":"The table below lists all graph convolutional layers implemented in the GNNLux.jl. It also highlights the presence of some additional capabilities with respect to basic message passing:","category":"page"},{"location":"api/conv/","page":"Convolutional layers","title":"Convolutional layers","text":"Sparse Ops: implements message passing as multiplication by sparse adjacency matrix instead of the gather/scatter mechanism. This can lead to better CPU performances but it is not supported on GPU yet. \nEdge Weight: supports scalar weights (or equivalently scalar features) on edges. \nEdge Features: supports feature vectors on edges.\nHeterograph: supports heterogeneous graphs (see GNNHeteroGraph).\nTemporalSnapshotsGNNGraphs: supports temporal graphs (see TemporalSnapshotsGNNGraph) by applying the convolution layers to each snapshot independently.","category":"page"},{"location":"api/conv/","page":"Convolutional layers","title":"Convolutional layers","text":"Layer Sparse Ops Edge Weight Edge Features Heterograph TemporalSnapshotsGNNGraphs\nAGNNConv ✓ \nCGConv ✓ ✓ ✓\nChebConv ✓\nEGNNConv ✓ \nEdgeConv ✓ \nGATConv ✓ ✓ ✓\nGATv2Conv ✓ ✓ ✓\nGatedGraphConv ✓ ✓\nGCNConv ✓ ✓ ✓ \nGINConv ✓ ✓ ✓\nGMMConv ✓ \nGraphConv ✓ ✓ ✓\nMEGNetConv ✓ \nNNConv ✓ \nResGatedGraphConv ✓ ✓\nSAGEConv ✓ ✓ ✓\nSGConv ✓ ✓","category":"page"},{"location":"api/conv/#Docs","page":"Convolutional layers","title":"Docs","text":"","category":"section"},{"location":"api/conv/","page":"Convolutional layers","title":"Convolutional layers","text":"Modules = [GNNLux]\nPages = [\"layers/conv.jl\"]\nPrivate = false","category":"page"},{"location":"api/conv/#GNNLux.AGNNConv","page":"Convolutional layers","title":"GNNLux.AGNNConv","text":"AGNNConv(; init_beta=1.0f0, trainable=true, add_self_loops=true)\n\nAttention-based Graph Neural Network layer from paper Attention-based Graph Neural Network for Semi-Supervised Learning.\n\nThe forward pass is given by\n\nmathbfx_i = sum_j in N(i) alpha_ij mathbfx_j\n\nwhere the attention coefficients alpha_ij are given by\n\nalpha_ij =frace^beta cos(mathbfx_i mathbfx_j)\n sum_je^beta cos(mathbfx_i mathbfx_j)\n\nwith the cosine distance defined by\n\ncos(mathbfx_i mathbfx_j) = \n fracmathbfx_i cdot mathbfx_jlVertmathbfx_irVert lVertmathbfx_jrVert\n\nand beta a trainable parameter if trainable=true.\n\nArguments\n\ninit_beta: The initial value of beta. Default 1.0f0.\ntrainable: If true, beta is trainable. Default true.\nadd_self_loops: Add self loops to the graph before performing the convolution. Default true.\n\nExamples:\n\nusing GNNLux, Lux, Random\n\n# initialize random number generator\nrng = Random.default_rng()\n\n# create data\ns = [1,1,2,3]\nt = [2,3,1,1]\ng = GNNGraph(s, t)\n\n# create layer\nl = AGNNConv(init_beta=2.0f0)\n\n# setup layer\nps, st = LuxCore.setup(rng, l)\n\n# forward pass\ny, st = l(g, x, ps, st) \n\n\n\n\n\n","category":"type"},{"location":"api/conv/#GNNLux.CGConv","page":"Convolutional layers","title":"GNNLux.CGConv","text":"CGConv((in, ein) => out, act = identity; residual = false,\n use_bias = true, init_weight = glorot_uniform, init_bias = zeros32)\nCGConv(in => out, ...)\n\nThe crystal graph convolutional layer from the paper Crystal Graph Convolutional Neural Networks for an Accurate and Interpretable Prediction of Material Properties. Performs the operation\n\nmathbfx_i = mathbfx_i + sum_jin N(i)sigma(W_f mathbfz_ij + mathbfb_f) act(W_s mathbfz_ij + mathbfb_s)\n\nwhere mathbfz_ij is the node and edge features concatenation mathbfx_i mathbfx_j mathbfe_jto i and sigma is the sigmoid function. The residual mathbfx_i is added only if residual=true and the output size is the same as the input size.\n\nArguments\n\nin: The dimension of input node features.\nein: The dimension of input edge features. \n\nIf ein is not given, assumes that no edge features are passed as input in the forward pass.\n\nout: The dimension of output node features.\nact: Activation function.\nresidual: Add a residual connection.\ninit_weight: Weights' initializer. Default glorot_uniform.\ninit_bias: Bias initializer. Default zeros32.\nuse_bias: Add learnable bias. Default true.\n\nExamples\n\nusing GNNLux, Lux, Random\n\n# initialize random number generator\nrng = Random.default_rng()\n\n# create random graph\ng = rand_graph(rng, 5, 6)\nx = rand(rng, Float32, 2, g.num_nodes)\ne = rand(rng, Float32, 3, g.num_edges)\n\nl = CGConv((2, 3) => 4, tanh)\n\n# setup layer\nps, st = LuxCore.setup(rng, l)\n\n# forward pass\ny, st = l(g, x, e, ps, st) # size: (4, num_nodes)\n\n# No edge features\nl = CGConv(2 => 4, tanh)\nps, st = LuxCore.setup(rng, l)\ny, st = l(g, x, ps, st) # size: (4, num_nodes)\n\n\n\n\n\n","category":"type"},{"location":"api/conv/#GNNLux.ChebConv","page":"Convolutional layers","title":"GNNLux.ChebConv","text":"ChebConv(in => out, k; init_weight = glorot_uniform, init_bias = zeros32, use_bias = true)\n\nChebyshev spectral graph convolutional layer from paper Convolutional Neural Networks on Graphs with Fast Localized Spectral Filtering.\n\nImplements\n\nX = sum^K-1_k=0 W^(k) Z^(k)\n\nwhere Z^(k) is the k-th term of Chebyshev polynomials, and can be calculated by the following recursive form:\n\nbeginaligned\nZ^(0) = X \nZ^(1) = hatL X \nZ^(k) = 2 hatL Z^(k-1) - Z^(k-2)\nendaligned\n\nwith hatL the scaled_laplacian.\n\nArguments\n\nin: The dimension of input features.\nout: The dimension of output features.\nk: The order of Chebyshev polynomial.\ninit_weight: Weights' initializer. Default glorot_uniform.\ninit_bias: Bias initializer. Default zeros32.\nuse_bias: Add learnable bias. Default true.\n\nExamples\n\nusing GNNLux, Lux, Random\n\n# initialize random number generator\nrng = Random.default_rng()\n\n# create data\ns = [1,1,2,3]\nt = [2,3,1,1]\ng = GNNGraph(s, t)\nx = randn(rng, Float32, 3, g.num_nodes)\n\n# create layer\nl = ChebConv(3 => 5, 5)\n\n# setup layer\nps, st = LuxCore.setup(rng, l)\n\n# forward pass\ny, st = l(g, x, ps, st) # size of the output y: 5 × num_nodes\n\n\n\n\n\n","category":"type"},{"location":"api/conv/#GNNLux.DConv","page":"Convolutional layers","title":"GNNLux.DConv","text":"DConv(in => out, k; init_weight = glorot_uniform, init_bias = zeros32, use_bias = true)\n\nDiffusion convolution layer from the paper Diffusion Convolutional Recurrent Neural Networks: Data-Driven Traffic Forecasting.\n\nArguments\n\nin: The dimension of input features.\nout: The dimension of output features.\nk: Number of diffusion steps.\ninit_weight: Weights' initializer. Default glorot_uniform.\ninit_bias: Bias initializer. Default zeros32.\nuse_bias: Add learnable bias. Default true.\n\nExamples\n\nusing GNNLux, Lux, Random\n\n# initialize random number generator\nrng = Random.default_rng()\n\n# create random graph\ng = GNNGraph(rand(rng, 10, 10), ndata = rand(rng, Float32, 2, 10))\n\ndconv = DConv(2 => 4, 4)\n\n# setup layer\nps, st = LuxCore.setup(rng, dconv)\n\n# forward pass\ny, st = dconv(g, g.ndata.x, ps, st) # size: (4, num_nodes)\n\n\n\n\n\n","category":"type"},{"location":"api/conv/#GNNLux.EGNNConv","page":"Convolutional layers","title":"GNNLux.EGNNConv","text":"EGNNConv((in, ein) => out; hidden_size=2in, residual=false)\nEGNNConv(in => out; hidden_size=2in, residual=false)\n\nEquivariant Graph Convolutional Layer from E(n) Equivariant Graph Neural Networks.\n\nThe layer performs the following operation:\n\nbeginaligned\nmathbfm_jto i =phi_e(mathbfh_i mathbfh_j lVertmathbfx_i-mathbfx_jrVert^2 mathbfe_jto i)\nmathbfx_i = mathbfx_i + C_isum_jinmathcalN(i)(mathbfx_i-mathbfx_j)phi_x(mathbfm_jto i)\nmathbfm_i = C_isum_jinmathcalN(i) mathbfm_jto i\nmathbfh_i = mathbfh_i + phi_h(mathbfh_i mathbfm_i)\nendaligned\n\nwhere mathbfh_i, mathbfx_i, mathbfe_jto i are invariant node features, equivariant node features, and edge features respectively. phi_e, phi_h, and phi_x are two-layer MLPs. C is a constant for normalization, computed as 1mathcalN(i).\n\nConstructor Arguments\n\nin: Number of input features for h.\nout: Number of output features for h.\nein: Number of input edge features.\nhidden_size: Hidden representation size.\nresidual: If true, add a residual connection. Only possible if in == out. Default false.\n\nForward Pass\n\nl(g, x, h, e=nothing, ps, st)\n\nForward Pass Arguments:\n\ng : The graph.\nx : Matrix of equivariant node coordinates.\nh : Matrix of invariant node features.\ne : Matrix of invariant edge features. Default nothing.\nps : Parameters.\nst : State.\n\nReturns updated h and x.\n\nExamples\n\nusing GNNLux, Lux, Random\n\n# initialize random number generator\nrng = Random.default_rng()\n\n# create random graph\ng = rand_graph(rng, 10, 10)\nh = randn(rng, Float32, 5, g.num_nodes)\nx = randn(rng, Float32, 3, g.num_nodes)\n\negnn = EGNNConv(5 => 6, 10)\n\n# setup layer\nps, st = LuxCore.setup(rng, egnn)\n\n# forward pass\n(hnew, xnew), st = egnn(g, h, x, ps, st)\n\n\n\n\n\n","category":"type"},{"location":"api/conv/#GNNLux.EdgeConv","page":"Convolutional layers","title":"GNNLux.EdgeConv","text":"EdgeConv(nn; aggr=max)\n\nEdge convolutional layer from paper Dynamic Graph CNN for Learning on Point Clouds.\n\nPerforms the operation\n\nmathbfx_i = square_j in N(i) nn(mathbfx_i mathbfx_j - mathbfx_i)\n\nwhere nn generally denotes a learnable function, e.g. a linear layer or a multi-layer perceptron.\n\nArguments\n\nnn: A (possibly learnable) function. \naggr: Aggregation operator for the incoming messages (e.g. +, *, max, min, and mean).\n\nExamples:\n\nusing GNNLux, Lux, Random\n\n# initialize random number generator\nrng = Random.default_rng()\n\n# create data\ns = [1,1,2,3]\nt = [2,3,1,1]\nin_channel = 3\nout_channel = 5\ng = GNNGraph(s, t)\nx = rand(rng, Float32, in_channel, g.num_nodes)\n\n# create layer\nl = EdgeConv(Dense(2 * in_channel, out_channel), aggr = +)\n\n# setup layer\nps, st = LuxCore.setup(rng, l)\n\n# forward pass\ny, st = l(g, x, ps, st)\n\n\n\n\n\n","category":"type"},{"location":"api/conv/#GNNLux.GATConv","page":"Convolutional layers","title":"GNNLux.GATConv","text":"GATConv(in => out, σ = identity; heads = 1, concat = true, negative_slope = 0.2, init_weight = glorot_uniform, init_bias = zeros32, use_bias = true, add_self_loops = true, dropout=0.0)\nGATConv((in, ein) => out, ...)\n\nGraph attentional layer from the paper Graph Attention Networks.\n\nImplements the operation\n\nmathbfx_i = sum_j in N(i) cup i alpha_ij W mathbfx_j\n\nwhere the attention coefficients alpha_ij are given by\n\nalpha_ij = frac1z_i exp(LeakyReLU(mathbfa^T W mathbfx_i W mathbfx_j))\n\nwith z_i a normalization factor. \n\nIn case ein > 0 is given, edge features of dimension ein will be expected in the forward pass and the attention coefficients will be calculated as \n\nalpha_ij = frac1z_i exp(LeakyReLU(mathbfa^T W_e mathbfe_jto i W mathbfx_i W mathbfx_j))\n\nArguments\n\nin: The dimension of input node features.\nein: The dimension of input edge features. Default 0 (i.e. no edge features passed in the forward).\nout: The dimension of output node features.\nσ: Activation function. Default identity.\nheads: Number attention heads. Default 1.\nconcat: Concatenate layer output or not. If not, layer output is averaged over the heads. Default true.\nnegative_slope: The parameter of LeakyReLU.Default 0.2.\ninit_weight: Weights' initializer. Default glorot_uniform.\ninit_bias: Bias initializer. Default zeros32.\nuse_bias: Add learnable bias. Default true.\nadd_self_loops: Add self loops to the graph before performing the convolution. Default true.\ndropout: Dropout probability on the normalized attention coefficient. Default 0.0.\n\nExamples\n\nusing GNNLux, Lux, Random\n\n# initialize random number generator\nrng = Random.default_rng()\n\n# create data\ns = [1,1,2,3]\nt = [2,3,1,1]\nin_channel = 3\nout_channel = 5\ng = GNNGraph(s, t)\nx = randn(rng, Float32, 3, g.num_nodes)\n\n# create layer\nl = GATConv(in_channel => out_channel; add_self_loops = false, use_bias = false, heads=2, concat=true)\n\n# setup layer\nps, st = LuxCore.setup(rng, l)\n\n# forward pass\ny, st = l(g, x, ps, st) \n\n\n\n\n\n","category":"type"},{"location":"api/conv/#GNNLux.GATv2Conv","page":"Convolutional layers","title":"GNNLux.GATv2Conv","text":"GATv2Conv(in => out, σ = identity; heads = 1, concat = true, negative_slope = 0.2, init_weight = glorot_uniform, init_bias = zeros32, use_bias = true, add_self_loops = true, dropout=0.0)\nGATv2Conv((in, ein) => out, ...)\n\nGATv2 attentional layer from the paper How Attentive are Graph Attention Networks?.\n\nImplements the operation\n\nmathbfx_i = sum_j in N(i) cup i alpha_ij W_1 mathbfx_j\n\nwhere the attention coefficients alpha_ij are given by\n\nalpha_ij = frac1z_i exp(mathbfa^T LeakyReLU(W_2 mathbfx_i + W_1 mathbfx_j))\n\nwith z_i a normalization factor.\n\nIn case ein > 0 is given, edge features of dimension ein will be expected in the forward pass and the attention coefficients will be calculated as \n\nalpha_ij = frac1z_i exp(mathbfa^T LeakyReLU(W_3 mathbfe_jto i + W_2 mathbfx_i + W_1 mathbfx_j))\n\nArguments\n\nin: The dimension of input node features.\nein: The dimension of input edge features. Default 0 (i.e. no edge features passed in the forward).\nout: The dimension of output node features.\nσ: Activation function. Default identity.\nheads: Number attention heads. Default 1.\nconcat: Concatenate layer output or not. If not, layer output is averaged over the heads. Default true.\nnegative_slope: The parameter of LeakyReLU.Default 0.2.\nadd_self_loops: Add self loops to the graph before performing the convolution. Default true.\ndropout: Dropout probability on the normalized attention coefficient. Default 0.0.\ninit_weight: Weights' initializer. Default glorot_uniform.\ninit_bias: Bias initializer. Default zeros32.\nuse_bias: Add learnable bias. Default true.\n\nExamples\n\nusing GNNLux, Lux, Random\n\n# initialize random number generator\nrng = Random.default_rng()\n\n# create data\ns = [1,1,2,3]\nt = [2,3,1,1]\nin_channel = 3\nout_channel = 5\nein = 3\ng = GNNGraph(s, t)\nx = randn(rng, Float32, 3, g.num_nodes)\n\n# create layer\nl = GATv2Conv((in_channel, ein) => out_channel, add_self_loops = false)\n\n# setup layer\nps, st = LuxCore.setup(rng, l)\n\n# edge features\ne = randn(rng, Float32, ein, length(s))\n\n# forward pass\ny, st = l(g, x, e, ps, st) \n\n\n\n\n\n","category":"type"},{"location":"api/conv/#GNNLux.GCNConv","page":"Convolutional layers","title":"GNNLux.GCNConv","text":"GCNConv(in => out, σ=identity; [init_weight, init_bias, use_bias, add_self_loops, use_edge_weight])\n\nGraph convolutional layer from paper Semi-supervised Classification with Graph Convolutional Networks.\n\nPerforms the operation\n\nmathbfx_i = sum_jin N(i) a_ij W mathbfx_j\n\nwhere a_ij = 1 sqrtN(i)N(j) is a normalization factor computed from the node degrees. \n\nIf the input graph has weighted edges and use_edge_weight=true, than a_ij will be computed as\n\na_ij = frace_jto isqrtsum_j in N(i) e_jto i sqrtsum_i in N(j) e_ito j\n\nArguments\n\nin: Number of input features.\nout: Number of output features.\nσ: Activation function. Default identity.\ninit_weight: Weights' initializer. Default glorot_uniform.\ninit_bias: Bias initializer. Default zeros32.\nuse_bias: Add learnable bias. Default true.\nadd_self_loops: Add self loops to the graph before performing the convolution. Default false.\nuse_edge_weight: If true, consider the edge weights in the input graph (if available). If add_self_loops=true the new weights will be set to 1. This option is ignored if the edge_weight is explicitly provided in the forward pass. Default false.\n\nForward\n\n(::GCNConv)(g, x, [edge_weight], ps, st; norm_fn = d -> 1 ./ sqrt.(d), conv_weight=nothing)\n\nTakes as input a graph g, a node feature matrix x of size [in, num_nodes], optionally an edge weight vector and the parameter and state of the layer. Returns a node feature matrix of size [out, num_nodes].\n\nThe norm_fn parameter allows for custom normalization of the graph convolution operation by passing a function as argument. By default, it computes frac1sqrtd i.e the inverse square root of the degree (d) of each node in the graph. If conv_weight is an AbstractMatrix of size [out, in], then the convolution is performed using that weight matrix.\n\nExamples\n\nusing GNNLux, Lux, Random\n\n# initialize random number generator\nrng = Random.default_rng()\n\n# create data\ns = [1,1,2,3]\nt = [2,3,1,1]\ng = GNNGraph(s, t)\nx = randn(rng, Float32, 3, g.num_nodes)\n\n# create layer\nl = GCNConv(3 => 5) \n\n# setup layer\nps, st = LuxCore.setup(rng, l)\n\n# forward pass\ny = l(g, x, ps, st) # size of the output first entry: 5 × num_nodes\n\n# convolution with edge weights and custom normalization function\nw = [1.1, 0.1, 2.3, 0.5]\ncustom_norm_fn(d) = 1 ./ sqrt.(d + 1) # Custom normalization function\ny = l(g, x, w, ps, st; norm_fn = custom_norm_fn)\n\n# Edge weights can also be embedded in the graph.\ng = GNNGraph(s, t, w)\nl = GCNConv(3 => 5, use_edge_weight=true)\nps, st = Lux.setup(rng, l)\ny = l(g, x, ps, st) # same as l(g, x, w) \n\n\n\n\n\n","category":"type"},{"location":"api/conv/#GNNLux.GINConv","page":"Convolutional layers","title":"GNNLux.GINConv","text":"GINConv(f, ϵ; aggr=+)\n\nGraph Isomorphism convolutional layer from paper How Powerful are Graph Neural Networks?.\n\nImplements the graph convolution\n\nmathbfx_i = f_Thetaleft((1 + epsilon) mathbfx_i + sum_j in N(i) mathbfx_j right)\n\nwhere f_Theta typically denotes a learnable function, e.g. a linear layer or a multi-layer perceptron.\n\nArguments\n\nf: A (possibly learnable) function acting on node features. \nϵ: Weighting factor.\n\nExamples:\n\nusing GNNLux, Lux, Random\n\n# initialize random number generator\nrng = Random.default_rng()\n\n# create data\ns = [1,1,2,3]\nt = [2,3,1,1]\nin_channel = 3\nout_channel = 5\ng = GNNGraph(s, t)\nx = randn(rng, Float32, in_channel, g.num_nodes)\n\n# create dense layer\nnn = Dense(in_channel, out_channel)\n\n# create layer\nl = GINConv(nn, 0.01f0, aggr = mean)\n\n# setup layer\nps, st = LuxCore.setup(rng, l)\n\n# forward pass\ny, st = l(g, x, ps, st) # size: out_channel × num_nodes\n\n\n\n\n\n","category":"type"},{"location":"api/conv/#GNNLux.GMMConv","page":"Convolutional layers","title":"GNNLux.GMMConv","text":"GMMConv((in, ein) => out, σ=identity; K = 1, residual = false init_weight = glorot_uniform, init_bias = zeros32, use_bias = true)\n\nGraph mixture model convolution layer from the paper Geometric deep learning on graphs and manifolds using mixture model CNNs Performs the operation\n\nmathbfx_i = mathbfx_i + frac1N(i) sum_jin N(i)frac1Ksum_k=1^K mathbfw_k(mathbfe_jto i) odot Theta_k mathbfx_j\n\nwhere w^a_k(e^a) for feature a and kernel k is given by\n\nw^a_k(e^a) = exp(-frac12(e^a - mu^a_k)^T (Sigma^-1)^a_k(e^a - mu^a_k))\n\nTheta_k mu^a_k (Sigma^-1)^a_k are learnable parameters.\n\nThe input to the layer is a node feature array x of size (num_features, num_nodes) and edge pseudo-coordinate array e of size (num_features, num_edges) The residual mathbfx_i is added only if residual=true and the output size is the same as the input size.\n\nArguments\n\nin: Number of input node features.\nein: Number of input edge features.\nout: Number of output features.\nσ: Activation function. Default identity.\nK: Number of kernels. Default 1.\nresidual: Residual conncetion. Default false.\ninit_weight: Weights' initializer. Default glorot_uniform.\ninit_bias: Bias initializer. Default zeros32.\nuse_bias: Add learnable bias. Default true.\n\nExamples\n\nusing GNNLux, Lux, Random\n\n# initialize random number generator\nrng = Random.default_rng()\n\n# create data\ns = [1,1,2,3]\nt = [2,3,1,1]\ng = GNNGraph(s,t)\nnin, ein, out, K = 4, 10, 7, 8 \nx = randn(rng, Float32, nin, g.num_nodes)\ne = randn(rng, Float32, ein, g.num_edges)\n\n# create layer\nl = GMMConv((nin, ein) => out, K=K)\n\n# setup layer\nps, st = LuxCore.setup(rng, l)\n\n# forward pass\ny, st = l(g, x, e, ps, st) # size: out × num_nodes\n\n\n\n\n\n","category":"type"},{"location":"api/conv/#GNNLux.GatedGraphConv","page":"Convolutional layers","title":"GNNLux.GatedGraphConv","text":"GatedGraphConv(out, num_layers; \n aggr = +, init_weight = glorot_uniform)\n\nGated graph convolution layer from Gated Graph Sequence Neural Networks.\n\nImplements the recursion\n\nbeginaligned\nmathbfh^(0)_i = mathbfx_i mathbf0 \nmathbfh^(l)_i = GRU(mathbfh^(l-1)_i square_j in N(i) W mathbfh^(l-1)_j)\nendaligned\n\nwhere mathbfh^(l)_i denotes the l-th hidden variables passing through GRU. The dimension of input mathbfx_i needs to be less or equal to out.\n\nArguments\n\nout: The dimension of output features.\nnum_layers: The number of recursion steps.\naggr: Aggregation operator for the incoming messages (e.g. +, *, max, min, and mean).\ninit_weight: Weights' initializer. Default glorot_uniform.\n\nExamples:\n\nusing GNNLux, Lux, Random\n\n# initialize random number generator\nrng = Random.default_rng()\n\n# create data\ns = [1,1,2,3]\nt = [2,3,1,1]\nout_channel = 5\nnum_layers = 3\ng = GNNGraph(s, t)\n\n# create layer\nl = GatedGraphConv(out_channel, num_layers)\n\n# setup layer\nps, st = LuxCore.setup(rng, l)\n\n# forward pass\ny, st = l(g, x, ps, st) # size: out_channel × num_nodes \n\n\n\n\n\n","category":"type"},{"location":"api/conv/#GNNLux.GraphConv","page":"Convolutional layers","title":"GNNLux.GraphConv","text":"GraphConv(in => out, σ = identity; aggr = +, init_weight = glorot_uniform,init_bias = zeros32, use_bias = true)\n\nGraph convolution layer from Reference: Weisfeiler and Leman Go Neural: Higher-order Graph Neural Networks.\n\nPerforms:\n\nmathbfx_i = W_1 mathbfx_i + square_j in mathcalN(i) W_2 mathbfx_j\n\nwhere the aggregation type is selected by aggr.\n\nArguments\n\nin: The dimension of input features.\nout: The dimension of output features.\nσ: Activation function.\naggr: Aggregation operator for the incoming messages (e.g. +, *, max, min, and mean).\ninit_weight: Weights' initializer. Default glorot_uniform.\ninit_bias: Bias initializer. Default zeros32.\nuse_bias: Add learnable bias. Default true.\n\nExamples\n\nusing GNNLux, Lux, Random\n\n# initialize random number generator\nrng = Random.default_rng()\n\n# create data\ns = [1,1,2,3]\nt = [2,3,1,1]\nin_channel = 3\nout_channel = 5\ng = GNNGraph(s, t)\nx = randn(rng, Float32, 3, g.num_nodes)\n\n# create layer\nl = GraphConv(in_channel => out_channel, relu, use_bias = false, aggr = mean)\n\n# setup layer\nps, st = LuxCore.setup(rng, l)\n\n# forward pass\ny, st = l(g, x, ps, st) # size of the output y: 5 × num_nodes\n\n\n\n\n\n","category":"type"},{"location":"api/conv/#GNNLux.MEGNetConv","page":"Convolutional layers","title":"GNNLux.MEGNetConv","text":"MEGNetConv(ϕe, ϕv; aggr=mean)\nMEGNetConv(in => out; aggr=mean)\n\nConvolution from Graph Networks as a Universal Machine Learning Framework for Molecules and Crystals paper. In the forward pass, takes as inputs node features x and edge features e and returns updated features x' and e' according to \n\nbeginaligned\nmathbfe_ito j = phi_e(mathbfx_i mathbfx_j mathbfe_ito j)\nmathbfx_i = phi_v(mathbfx_i square_jin mathcalN(i)mathbfe_jto i)\nendaligned\n\naggr defines the aggregation to be performed.\n\nIf the neural networks ϕe and ϕv are not provided, they will be constructed from the in and out arguments instead as multi-layer perceptron with one hidden layer and relu activations.\n\nExamples\n\nusing GNNLux, Lux, Random\n\n# initialize random number generator\nrng = Random.default_rng()\n\n# create a random graph\ng = rand_graph(rng, 10, 30)\nx = randn(rng, Float32, 3, 10)\ne = randn(rng, Float32, 3, 30)\n\n# create a MEGNetConv layer\nm = MEGNetConv(3 => 3)\n\n# setup layer\nps, st = LuxCore.setup(rng, m)\n\n# forward pass\n(x′, e′), st = m(g, x, e, ps, st)\n\n\n\n\n\n","category":"type"},{"location":"api/conv/#GNNLux.NNConv","page":"Convolutional layers","title":"GNNLux.NNConv","text":"NNConv(in => out, f, σ=identity; aggr=+, init_bias = zeros32, use_bias = true, init_weight = glorot_uniform)\n\nThe continuous kernel-based convolutional operator from the Neural Message Passing for Quantum Chemistry paper. This convolution is also known as the edge-conditioned convolution from the Dynamic Edge-Conditioned Filters in Convolutional Neural Networks on Graphs paper.\n\nPerforms the operation\n\nmathbfx_i = W mathbfx_i + square_j in N(i) f_Theta(mathbfe_jto i)mathbfx_j\n\nwhere f_Theta denotes a learnable function (e.g. a linear layer or a multi-layer perceptron). Given an input of batched edge features e of size (num_edge_features, num_edges), the function f will return an batched matrices array whose size is (out, in, num_edges). For convenience, also functions returning a single (out*in, num_edges) matrix are allowed.\n\nArguments\n\nin: The dimension of input node features.\nout: The dimension of output node features.\nf: A (possibly learnable) function acting on edge features.\naggr: Aggregation operator for the incoming messages (e.g. +, *, max, min, and mean).\nσ: Activation function.\ninit_weight: Weights' initializer. Default glorot_uniform.\ninit_bias: Bias initializer. Default zeros32.\nuse_bias: Add learnable bias. Default true.\n\nExamples:\n\nusing GNNLux, Lux, Random\n\n# initialize random number generator\nrng = Random.default_rng()\n\n# create data\nn_in = 3\nn_in_edge = 10\nn_out = 5\n\ns = [1,1,2,3]\nt = [2,3,1,1]\ng = GNNGraph(s, t)\nx = randn(rng, Float32, n_in, g.num_nodes)\ne = randn(rng, Float32, n_in_edge, g.num_edges)\n\n# create dense layer\nnn = Dense(n_in_edge => n_out * n_in)\n\n# create layer\nl = NNConv(n_in => n_out, nn, tanh, use_bias = true, aggr = +)\n\n# setup layer\nps, st = LuxCore.setup(rng, l)\n\n# forward pass\ny, st = l(g, x, e, ps, st) # size: n_out × num_nodes \n\n\n\n\n\n","category":"type"},{"location":"api/conv/#GNNLux.ResGatedGraphConv","page":"Convolutional layers","title":"GNNLux.ResGatedGraphConv","text":"ResGatedGraphConv(in => out, act=identity; init_weight = glorot_uniform, init_bias = zeros32, use_bias = true)\n\nThe residual gated graph convolutional operator from the Residual Gated Graph ConvNets paper.\n\nThe layer's forward pass is given by\n\nmathbfx_i = actbig(Umathbfx_i + sum_j in N(i) eta_ij V mathbfx_jbig)\n\nwhere the edge gates eta_ij are given by\n\neta_ij = sigmoid(Amathbfx_i + Bmathbfx_j)\n\nArguments\n\nin: The dimension of input features.\nout: The dimension of output features.\nact: Activation function.\ninit_weight: Weights' initializer. Default glorot_uniform.\ninit_bias: Bias initializer. Default zeros32.\nuse_bias: Add learnable bias. Default true.\n\nExamples:\n\nusing GNNLux, Lux, Random\n\n# initialize random number generator\nrng = Random.default_rng()\n\n# create data\ns = [1,1,2,3]\nt = [2,3,1,1]\nin_channel = 3\nout_channel = 5\ng = GNNGraph(s, t)\nx = randn(rng, Float32, in_channel, g.num_nodes)\n\n# create layer\nl = ResGatedGraphConv(in_channel => out_channel, tanh, use_bias = true)\n\n# setup layer\nps, st = LuxCore.setup(rng, l)\n\n# forward pass\ny, st = l(g, x, ps, st) # size: out_channel × num_nodes \n\n\n\n\n\n","category":"type"},{"location":"api/conv/#GNNLux.SAGEConv","page":"Convolutional layers","title":"GNNLux.SAGEConv","text":"SAGEConv(in => out, σ=identity; aggr=mean, init_weight = glorot_uniform, init_bias = zeros32, use_bias=true)\n\nGraphSAGE convolution layer from paper Inductive Representation Learning on Large Graphs.\n\nPerforms:\n\nmathbfx_i = W cdot mathbfx_i square_j in mathcalN(i) mathbfx_j\n\nwhere the aggregation type is selected by aggr.\n\nArguments\n\nin: The dimension of input features.\nout: The dimension of output features.\nσ: Activation function.\naggr: Aggregation operator for the incoming messages (e.g. +, *, max, min, and mean).\ninit_bias: Bias initializer. Default zeros32.\nuse_bias: Add learnable bias. Default true.\n\nExamples:\n\nusing GNNLux, Lux, Random\n\n# initialize random number generator\nrng = Random.default_rng()\n\n# create data\ns = [1,1,2,3]\nt = [2,3,1,1]\nin_channel = 3\nout_channel = 5\ng = GNNGraph(s, t)\nx = rand(rng, Float32, in_channel, g.num_nodes)\n\n# create layer\nl = SAGEConv(in_channel => out_channel, tanh, use_bias = false, aggr = +)\n\n# setup layer\nps, st = LuxCore.setup(rng, l)\n\n# forward pass\ny, st = l(g, x, ps, st) # size: out_channel × num_nodes \n\n\n\n\n\n","category":"type"},{"location":"api/conv/#GNNLux.SGConv","page":"Convolutional layers","title":"GNNLux.SGConv","text":"SGConv(int => out, k = 1; init_weight = glorot_uniform, init_bias = zeros32, use_bias = true, add_self_loops = true,use_edge_weight = false)\n\nSGC layer from Simplifying Graph Convolutional Networks Performs operation\n\nH^K = (tildeD^-12 tildeA tildeD^-12)^K X Theta\n\nwhere tildeA is A + I.\n\nArguments\n\nin: Number of input features.\nout: Number of output features.\nk : Number of hops k. Default 1.\nadd_self_loops: Add self loops to the graph before performing the convolution. Default false.\nuse_edge_weight: If true, consider the edge weights in the input graph (if available). If add_self_loops=true the new weights will be set to 1. Default false.\ninit_weight: Weights' initializer. Default glorot_uniform.\ninit_bias: Bias initializer. Default zeros32.\nuse_bias: Add learnable bias. Default true.\n\nExamples\n\nusing GNNLux, Lux, Random\n\n# initialize random number generator\nrng = Random.default_rng()\n\n# create data\ns = [1,1,2,3]\nt = [2,3,1,1]\ng = GNNGraph(s, t)\nx = randn(rng, Float32, 3, g.num_nodes)\n\n# create layer\nl = SGConv(3 => 5; add_self_loops = true) \n\n# setup layer\nps, st = LuxCore.setup(rng, l)\n\n# forward pass\ny, st = l(g, x, ps, st) # size: 5 × num_nodes\n\n# convolution with edge weights\nw = [1.1, 0.1, 2.3, 0.5]\ny = l(g, x, w, ps, st)\n\n# Edge weights can also be embedded in the graph.\ng = GNNGraph(s, t, w)\nl = SGConv(3 => 5, add_self_loops = true, use_edge_weight=true) \nps, st = LuxCore.setup(rng, l)\ny, st = l(g, x, ps, st) # same as l(g, x, w) \n\n\n\n\n\n","category":"type"},{"location":"#GNNLux.jl","page":"Home","title":"GNNLux.jl","text":"","category":"section"},{"location":"","page":"Home","title":"Home","text":"GNNLux.jl is a work-in-progress package that implements stateless graph convolutional layers, fully compatible with the Lux.jl machine learning framework. It is built on top of the GNNGraphs.jl, GNNlib.jl, and Lux.jl packages.","category":"page"},{"location":"","page":"Home","title":"Home","text":"The full documentation will be available soon.","category":"page"}] } diff --git a/graphneuralnetworks/.documenter-siteinfo.json b/graphneuralnetworks/.documenter-siteinfo.json index f8bf75f4a..24fbd6cb0 100644 --- a/graphneuralnetworks/.documenter-siteinfo.json +++ b/graphneuralnetworks/.documenter-siteinfo.json @@ -1 +1 @@ -{"documenter":{"julia_version":"1.10.5","generation_timestamp":"2024-11-08T08:45:48","documenter_version":"1.7.0"}} \ No newline at end of file +{"documenter":{"julia_version":"1.10.5","generation_timestamp":"2024-11-09T14:49:15","documenter_version":"1.7.0"}} \ No newline at end of file diff --git a/graphneuralnetworks/api/basic/index.html b/graphneuralnetworks/api/basic/index.html index 60e979795..b1d4d3724 100644 --- a/graphneuralnetworks/api/basic/index.html +++ b/graphneuralnetworks/api/basic/index.html @@ -8,7 +8,7 @@ julia> dotdec(g, rand(2, 5)) 1×6 Matrix{Float64}: - 0.345098 0.458305 0.106353 0.345098 0.458305 0.106353source
GraphNeuralNetworks.GNNChainType
GNNChain(layers...)
+ 0.345098  0.458305  0.106353  0.345098  0.458305  0.106353
source
GraphNeuralNetworks.GNNChainType
GNNChain(layers...)
 GNNChain(name = layer, ...)

Collects multiple layers / functions to be called in sequence on given input graph and input node features.

It allows to compose layers in a sequential fashion as Flux.Chain does, propagating the output of each layer to the next one. In addition, GNNChain handles the input graph as well, providing it as a first argument only to layers subtyping the GNNLayer abstract type.

GNNChain supports indexing and slicing, m[2] or m[1:end-1], and if names are given, m[:name] == m[1] etc.

Examples

julia> using Flux, GraphNeuralNetworks
 
 julia> m = GNNChain(GCNConv(2=>5), 
@@ -40,7 +40,7 @@
  2.90053  2.90053  2.90053  2.90053  2.90053  2.90053
 
 julia> m2[:enc](g, x) == m(g, x)
-true
source
GraphNeuralNetworks.GNNLayerType
abstract type GNNLayer end

An abstract type from which graph neural network layers are derived.

See also GNNChain.

source
GraphNeuralNetworks.WithGraphType
WithGraph(model, g::GNNGraph; traingraph=false)

A type wrapping the model and tying it to the graph g. In the forward pass, can only take feature arrays as inputs, returning model(g, x...; kws...).

If traingraph=false, the graph's parameters won't be part of the trainable parameters in the gradient updates.

Examples

g = GNNGraph([1,2,3], [2,3,1])
+true
source
GraphNeuralNetworks.GNNLayerType
abstract type GNNLayer end

An abstract type from which graph neural network layers are derived.

See also GNNChain.

source
GraphNeuralNetworks.WithGraphType
WithGraph(model, g::GNNGraph; traingraph=false)

A type wrapping the model and tying it to the graph g. In the forward pass, can only take feature arrays as inputs, returning model(g, x...; kws...).

If traingraph=false, the graph's parameters won't be part of the trainable parameters in the gradient updates.

Examples

g = GNNGraph([1,2,3], [2,3,1])
 x = rand(Float32, 2, 3)
 model = SAGEConv(2 => 3)
 wg = WithGraph(model, g)
@@ -50,4 +50,4 @@
 g2 = GNNGraph([1,1,2,3], [2,4,1,1])
 x2 = rand(Float32, 2, 4)
 # WithGraph will ignore the internal graph if fed with a new one. 
-@assert wg(g2, x2) == model(g2, x2)
source
\ No newline at end of file +@assert wg(g2, x2) == model(g2, x2)source \ No newline at end of file diff --git a/graphneuralnetworks/api/conv/index.html b/graphneuralnetworks/api/conv/index.html index 8f54a1f65..e98d32587 100644 --- a/graphneuralnetworks/api/conv/index.html +++ b/graphneuralnetworks/api/conv/index.html @@ -9,7 +9,7 @@ l = AGNNConv(init_beta=2.0f0) # forward pass -y = l(g, x) source
GraphNeuralNetworks.CGConvType
CGConv((in, ein) => out, act=identity; bias=true, init=glorot_uniform, residual=false)
+y = l(g, x)   
source
GraphNeuralNetworks.CGConvType
CGConv((in, ein) => out, act=identity; bias=true, init=glorot_uniform, residual=false)
 CGConv(in => out, ...)

The crystal graph convolutional layer from the paper Crystal Graph Convolutional Neural Networks for an Accurate and Interpretable Prediction of Material Properties. Performs the operation

\[\mathbf{x}_i' = \mathbf{x}_i + \sum_{j\in N(i)}\sigma(W_f \mathbf{z}_{ij} + \mathbf{b}_f)\, act(W_s \mathbf{z}_{ij} + \mathbf{b}_s)\]

where $\mathbf{z}_{ij}$ is the node and edge features concatenation $[\mathbf{x}_i; \mathbf{x}_j; \mathbf{e}_{j\to i}]$ and $\sigma$ is the sigmoid function. The residual $\mathbf{x}_i$ is added only if residual=true and the output size is the same as the input size.

Arguments

  • in: The dimension of input node features.
  • ein: The dimension of input edge features.

If ein is not given, assumes that no edge features are passed as input in the forward pass.

  • out: The dimension of output node features.
  • act: Activation function.
  • bias: Add learnable bias.
  • init: Weights' initializer.
  • residual: Add a residual connection.

Examples

g = rand_graph(5, 6)
 x = rand(Float32, 2, g.num_nodes)
 e = rand(Float32, 3, g.num_edges)
@@ -19,7 +19,7 @@
 
 # No edge features
 l = CGConv(2 => 4, tanh)
-y = l(g, x)    # size: (4, num_nodes)
source
GraphNeuralNetworks.ChebConvType
ChebConv(in => out, k; bias=true, init=glorot_uniform)

Chebyshev spectral graph convolutional layer from paper Convolutional Neural Networks on Graphs with Fast Localized Spectral Filtering.

Implements

\[X' = \sum^{K-1}_{k=0} W^{(k)} Z^{(k)}\]

where $Z^{(k)}$ is the $k$-th term of Chebyshev polynomials, and can be calculated by the following recursive form:

\[\begin{aligned} +y = l(g, x) # size: (4, num_nodes)

source
GraphNeuralNetworks.ChebConvType
ChebConv(in => out, k; bias=true, init=glorot_uniform)

Chebyshev spectral graph convolutional layer from paper Convolutional Neural Networks on Graphs with Fast Localized Spectral Filtering.

Implements

\[X' = \sum^{K-1}_{k=0} W^{(k)} Z^{(k)}\]

where $Z^{(k)}$ is the $k$-th term of Chebyshev polynomials, and can be calculated by the following recursive form:

\[\begin{aligned} Z^{(0)} &= X \\ Z^{(1)} &= \hat{L} X \\ Z^{(k)} &= 2 \hat{L} Z^{(k-1)} - Z^{(k-2)} @@ -33,7 +33,7 @@ l = ChebConv(3 => 5, 5) # forward pass -y = l(g, x) # size: 5 × num_nodes

source
GraphNeuralNetworks.DConvType
DConv(ch::Pair{Int, Int}, k::Int; init = glorot_uniform, bias = true)

Diffusion convolution layer from the paper Diffusion Convolutional Recurrent Neural Networks: Data-Driven Traffic Forecasting.

Arguments

  • ch: Pair of input and output dimensions.
  • k: Number of diffusion steps.
  • init: Weights' initializer. Default glorot_uniform.
  • bias: Add learnable bias. Default true.

Examples

julia> g = GNNGraph(rand(10, 10), ndata = rand(Float32, 2, 10));
+y = l(g, x)       # size:  5 × num_nodes
source
GraphNeuralNetworks.DConvType
DConv(ch::Pair{Int, Int}, k::Int; init = glorot_uniform, bias = true)

Diffusion convolution layer from the paper Diffusion Convolutional Recurrent Neural Networks: Data-Driven Traffic Forecasting.

Arguments

  • ch: Pair of input and output dimensions.
  • k: Number of diffusion steps.
  • init: Weights' initializer. Default glorot_uniform.
  • bias: Add learnable bias. Default true.

Examples

julia> g = GNNGraph(rand(10, 10), ndata = rand(Float32, 2, 10));
 
 julia> dconv = DConv(2 => 4, 4)
 DConv(2 => 4, 4)
@@ -41,7 +41,7 @@
 julia> y = dconv(g, g.ndata.x);
 
 julia> size(y)
-(4, 10)
source
GraphNeuralNetworks.EGNNConvType
EGNNConv((in, ein) => out; hidden_size=2in, residual=false)
+(4, 10)
source
GraphNeuralNetworks.EGNNConvType
EGNNConv((in, ein) => out; hidden_size=2in, residual=false)
 EGNNConv(in => out; hidden_size=2in, residual=false)

Equivariant Graph Convolutional Layer from E(n) Equivariant Graph Neural Networks.

The layer performs the following operation:

\[\begin{aligned} \mathbf{m}_{j\to i} &=\phi_e(\mathbf{h}_i, \mathbf{h}_j, \lVert\mathbf{x}_i-\mathbf{x}_j\rVert^2, \mathbf{e}_{j\to i}),\\ \mathbf{x}_i' &= \mathbf{x}_i + C_i\sum_{j\in\mathcal{N}(i)}(\mathbf{x}_i-\mathbf{x}_j)\phi_x(\mathbf{m}_{j\to i}),\\ @@ -51,7 +51,7 @@ h = randn(Float32, 5, g.num_nodes) x = randn(Float32, 3, g.num_nodes) egnn = EGNNConv(5 => 6, 10) -hnew, xnew = egnn(g, h, x)

source
GraphNeuralNetworks.EdgeConvType
EdgeConv(nn; aggr=max)

Edge convolutional layer from paper Dynamic Graph CNN for Learning on Point Clouds.

Performs the operation

\[\mathbf{x}_i' = \square_{j \in N(i)}\, nn([\mathbf{x}_i; \mathbf{x}_j - \mathbf{x}_i])\]

where nn generally denotes a learnable function, e.g. a linear layer or a multi-layer perceptron.

Arguments

  • nn: A (possibly learnable) function.
  • aggr: Aggregation operator for the incoming messages (e.g. +, *, max, min, and mean).

Examples:

# create data
+hnew, xnew = egnn(g, h, x)
source
GraphNeuralNetworks.EdgeConvType
EdgeConv(nn; aggr=max)

Edge convolutional layer from paper Dynamic Graph CNN for Learning on Point Clouds.

Performs the operation

\[\mathbf{x}_i' = \square_{j \in N(i)}\, nn([\mathbf{x}_i; \mathbf{x}_j - \mathbf{x}_i])\]

where nn generally denotes a learnable function, e.g. a linear layer or a multi-layer perceptron.

Arguments

  • nn: A (possibly learnable) function.
  • aggr: Aggregation operator for the incoming messages (e.g. +, *, max, min, and mean).

Examples:

# create data
 s = [1,1,2,3]
 t = [2,3,1,1]
 in_channel = 3
@@ -62,7 +62,7 @@
 l = EdgeConv(Dense(2 * in_channel, out_channel), aggr = +)
 
 # forward pass
-y = l(g, x)
source
GraphNeuralNetworks.GATConvType
GATConv(in => out, [σ; heads, concat, init, bias, negative_slope, add_self_loops])
+y = l(g, x)
source
GraphNeuralNetworks.GATConvType
GATConv(in => out, [σ; heads, concat, init, bias, negative_slope, add_self_loops])
 GATConv((in, ein) => out, ...)

Graph attentional layer from the paper Graph Attention Networks.

Implements the operation

\[\mathbf{x}_i' = \sum_{j \in N(i) \cup \{i\}} \alpha_{ij} W \mathbf{x}_j\]

where the attention coefficients $\alpha_{ij}$ are given by

\[\alpha_{ij} = \frac{1}{z_i} \exp(LeakyReLU(\mathbf{a}^T [W \mathbf{x}_i; W \mathbf{x}_j]))\]

with $z_i$ a normalization factor.

In case ein > 0 is given, edge features of dimension ein will be expected in the forward pass and the attention coefficients will be calculated as

\[\alpha_{ij} = \frac{1}{z_i} \exp(LeakyReLU(\mathbf{a}^T [W_e \mathbf{e}_{j\to i}; W \mathbf{x}_i; W \mathbf{x}_j]))\]

Arguments

  • in: The dimension of input node features.
  • ein: The dimension of input edge features. Default 0 (i.e. no edge features passed in the forward).
  • out: The dimension of output node features.
  • σ: Activation function. Default identity.
  • bias: Learn the additive bias if true. Default true.
  • heads: Number attention heads. Default 1.
  • concat: Concatenate layer output or not. If not, layer output is averaged over the heads. Default true.
  • negative_slope: The parameter of LeakyReLU.Default 0.2.
  • add_self_loops: Add self loops to the graph before performing the convolution. Default true.
  • dropout: Dropout probability on the normalized attention coefficient. Default 0.0.

Examples

# create data
 s = [1,1,2,3]
 t = [2,3,1,1]
@@ -75,7 +75,7 @@
 l = GATConv(in_channel => out_channel, add_self_loops = false, bias = false; heads=2, concat=true)
 
 # forward pass
-y = l(g, x)       
source
GraphNeuralNetworks.GATv2ConvType
GATv2Conv(in => out, [σ; heads, concat, init, bias, negative_slope, add_self_loops])
+y = l(g, x)       
source
GraphNeuralNetworks.GATv2ConvType
GATv2Conv(in => out, [σ; heads, concat, init, bias, negative_slope, add_self_loops])
 GATv2Conv((in, ein) => out, ...)

GATv2 attentional layer from the paper How Attentive are Graph Attention Networks?.

Implements the operation

\[\mathbf{x}_i' = \sum_{j \in N(i) \cup \{i\}} \alpha_{ij} W_1 \mathbf{x}_j\]

where the attention coefficients $\alpha_{ij}$ are given by

\[\alpha_{ij} = \frac{1}{z_i} \exp(\mathbf{a}^T LeakyReLU(W_2 \mathbf{x}_i + W_1 \mathbf{x}_j))\]

with $z_i$ a normalization factor.

In case ein > 0 is given, edge features of dimension ein will be expected in the forward pass and the attention coefficients will be calculated as

\[\alpha_{ij} = \frac{1}{z_i} \exp(\mathbf{a}^T LeakyReLU(W_3 \mathbf{e}_{j\to i} + W_2 \mathbf{x}_i + W_1 \mathbf{x}_j)).\]

Arguments

  • in: The dimension of input node features.
  • ein: The dimension of input edge features. Default 0 (i.e. no edge features passed in the forward).
  • out: The dimension of output node features.
  • σ: Activation function. Default identity.
  • bias: Learn the additive bias if true. Default true.
  • heads: Number attention heads. Default 1.
  • concat: Concatenate layer output or not. If not, layer output is averaged over the heads. Default true.
  • negative_slope: The parameter of LeakyReLU.Default 0.2.
  • add_self_loops: Add self loops to the graph before performing the convolution. Default true.
  • dropout: Dropout probability on the normalized attention coefficient. Default 0.0.

Examples

# create data
 s = [1,1,2,3]
 t = [2,3,1,1]
@@ -92,7 +92,7 @@
 e = randn(Float32, ein, length(s))
 
 # forward pass
-y = l(g, x, e)    
source
GraphNeuralNetworks.GCNConvType
GCNConv(in => out, σ=identity; [bias, init, add_self_loops, use_edge_weight])

Graph convolutional layer from paper Semi-supervised Classification with Graph Convolutional Networks.

Performs the operation

\[\mathbf{x}'_i = \sum_{j\in N(i)} a_{ij} W \mathbf{x}_j\]

where $a_{ij} = 1 / \sqrt{|N(i)||N(j)|}$ is a normalization factor computed from the node degrees.

If the input graph has weighted edges and use_edge_weight=true, than $a_{ij}$ will be computed as

\[a_{ij} = \frac{e_{j\to i}}{\sqrt{\sum_{j \in N(i)} e_{j\to i}} \sqrt{\sum_{i \in N(j)} e_{i\to j}}}\]

The input to the layer is a node feature array X of size (num_features, num_nodes) and optionally an edge weight vector.

Arguments

  • in: Number of input features.
  • out: Number of output features.
  • σ: Activation function. Default identity.
  • bias: Add learnable bias. Default true.
  • init: Weights' initializer. Default glorot_uniform.
  • add_self_loops: Add self loops to the graph before performing the convolution. Default false.
  • use_edge_weight: If true, consider the edge weights in the input graph (if available). If add_self_loops=true the new weights will be set to 1. This option is ignored if the edge_weight is explicitly provided in the forward pass. Default false.

Forward

(::GCNConv)(g::GNNGraph, x, edge_weight = nothing; norm_fn = d -> 1 ./ sqrt.(d), conv_weight = nothing) -> AbstractMatrix

Takes as input a graph g, a node feature matrix x of size [in, num_nodes], and optionally an edge weight vector. Returns a node feature matrix of size [out, num_nodes].

The norm_fn parameter allows for custom normalization of the graph convolution operation by passing a function as argument. By default, it computes $\frac{1}{\sqrt{d}}$ i.e the inverse square root of the degree (d) of each node in the graph. If conv_weight is an AbstractMatrix of size [out, in], then the convolution is performed using that weight matrix instead of the weights stored in the model.

Examples

# create data
+y = l(g, x, e)    
source
GraphNeuralNetworks.GCNConvType
GCNConv(in => out, σ=identity; [bias, init, add_self_loops, use_edge_weight])

Graph convolutional layer from paper Semi-supervised Classification with Graph Convolutional Networks.

Performs the operation

\[\mathbf{x}'_i = \sum_{j\in N(i)} a_{ij} W \mathbf{x}_j\]

where $a_{ij} = 1 / \sqrt{|N(i)||N(j)|}$ is a normalization factor computed from the node degrees.

If the input graph has weighted edges and use_edge_weight=true, than $a_{ij}$ will be computed as

\[a_{ij} = \frac{e_{j\to i}}{\sqrt{\sum_{j \in N(i)} e_{j\to i}} \sqrt{\sum_{i \in N(j)} e_{i\to j}}}\]

The input to the layer is a node feature array X of size (num_features, num_nodes) and optionally an edge weight vector.

Arguments

  • in: Number of input features.
  • out: Number of output features.
  • σ: Activation function. Default identity.
  • bias: Add learnable bias. Default true.
  • init: Weights' initializer. Default glorot_uniform.
  • add_self_loops: Add self loops to the graph before performing the convolution. Default false.
  • use_edge_weight: If true, consider the edge weights in the input graph (if available). If add_self_loops=true the new weights will be set to 1. This option is ignored if the edge_weight is explicitly provided in the forward pass. Default false.

Forward

(::GCNConv)(g::GNNGraph, x, edge_weight = nothing; norm_fn = d -> 1 ./ sqrt.(d), conv_weight = nothing) -> AbstractMatrix

Takes as input a graph g, a node feature matrix x of size [in, num_nodes], and optionally an edge weight vector. Returns a node feature matrix of size [out, num_nodes].

The norm_fn parameter allows for custom normalization of the graph convolution operation by passing a function as argument. By default, it computes $\frac{1}{\sqrt{d}}$ i.e the inverse square root of the degree (d) of each node in the graph. If conv_weight is an AbstractMatrix of size [out, in], then the convolution is performed using that weight matrix instead of the weights stored in the model.

Examples

# create data
 s = [1,1,2,3]
 t = [2,3,1,1]
 g = GNNGraph(s, t)
@@ -112,7 +112,7 @@
 # Edge weights can also be embedded in the graph.
 g = GNNGraph(s, t, w)
 l = GCNConv(3 => 5, use_edge_weight=true) 
-y = l(g, x) # same as l(g, x, w) 
source
GraphNeuralNetworks.GINConvType
GINConv(f, ϵ; aggr=+)

Graph Isomorphism convolutional layer from paper How Powerful are Graph Neural Networks?.

Implements the graph convolution

\[\mathbf{x}_i' = f_\Theta\left((1 + \epsilon) \mathbf{x}_i + \sum_{j \in N(i)} \mathbf{x}_j \right)\]

where $f_\Theta$ typically denotes a learnable function, e.g. a linear layer or a multi-layer perceptron.

Arguments

  • f: A (possibly learnable) function acting on node features.
  • ϵ: Weighting factor.

Examples:

# create data
+y = l(g, x) # same as l(g, x, w) 
source
GraphNeuralNetworks.GINConvType
GINConv(f, ϵ; aggr=+)

Graph Isomorphism convolutional layer from paper How Powerful are Graph Neural Networks?.

Implements the graph convolution

\[\mathbf{x}_i' = f_\Theta\left((1 + \epsilon) \mathbf{x}_i + \sum_{j \in N(i)} \mathbf{x}_j \right)\]

where $f_\Theta$ typically denotes a learnable function, e.g. a linear layer or a multi-layer perceptron.

Arguments

  • f: A (possibly learnable) function acting on node features.
  • ϵ: Weighting factor.

Examples:

# create data
 s = [1,1,2,3]
 t = [2,3,1,1]
 in_channel = 3
@@ -126,7 +126,7 @@
 l = GINConv(nn, 0.01f0, aggr = mean)
 
 # forward pass
-y = l(g, x)  
source
GraphNeuralNetworks.GMMConvType
GMMConv((in, ein) => out, σ=identity; K=1, bias=true, init=glorot_uniform, residual=false)

Graph mixture model convolution layer from the paper Geometric deep learning on graphs and manifolds using mixture model CNNs Performs the operation

\[\mathbf{x}_i' = \mathbf{x}_i + \frac{1}{|N(i)|} \sum_{j\in N(i)}\frac{1}{K}\sum_{k=1}^K \mathbf{w}_k(\mathbf{e}_{j\to i}) \odot \Theta_k \mathbf{x}_j\]

where $w^a_{k}(e^a)$ for feature a and kernel k is given by

\[w^a_{k}(e^a) = \exp(-\frac{1}{2}(e^a - \mu^a_k)^T (\Sigma^{-1})^a_k(e^a - \mu^a_k))\]

$\Theta_k, \mu^a_k, (\Sigma^{-1})^a_k$ are learnable parameters.

The input to the layer is a node feature array x of size (num_features, num_nodes) and edge pseudo-coordinate array e of size (num_features, num_edges) The residual $\mathbf{x}_i$ is added only if residual=true and the output size is the same as the input size.

Arguments

  • in: Number of input node features.
  • ein: Number of input edge features.
  • out: Number of output features.
  • σ: Activation function. Default identity.
  • K: Number of kernels. Default 1.
  • bias: Add learnable bias. Default true.
  • init: Weights' initializer. Default glorot_uniform.
  • residual: Residual conncetion. Default false.

Examples

# create data
+y = l(g, x)  
source
GraphNeuralNetworks.GMMConvType
GMMConv((in, ein) => out, σ=identity; K=1, bias=true, init=glorot_uniform, residual=false)

Graph mixture model convolution layer from the paper Geometric deep learning on graphs and manifolds using mixture model CNNs Performs the operation

\[\mathbf{x}_i' = \mathbf{x}_i + \frac{1}{|N(i)|} \sum_{j\in N(i)}\frac{1}{K}\sum_{k=1}^K \mathbf{w}_k(\mathbf{e}_{j\to i}) \odot \Theta_k \mathbf{x}_j\]

where $w^a_{k}(e^a)$ for feature a and kernel k is given by

\[w^a_{k}(e^a) = \exp(-\frac{1}{2}(e^a - \mu^a_k)^T (\Sigma^{-1})^a_k(e^a - \mu^a_k))\]

$\Theta_k, \mu^a_k, (\Sigma^{-1})^a_k$ are learnable parameters.

The input to the layer is a node feature array x of size (num_features, num_nodes) and edge pseudo-coordinate array e of size (num_features, num_edges) The residual $\mathbf{x}_i$ is added only if residual=true and the output size is the same as the input size.

Arguments

  • in: Number of input node features.
  • ein: Number of input edge features.
  • out: Number of output features.
  • σ: Activation function. Default identity.
  • K: Number of kernels. Default 1.
  • bias: Add learnable bias. Default true.
  • init: Weights' initializer. Default glorot_uniform.
  • residual: Residual conncetion. Default false.

Examples

# create data
 s = [1,1,2,3]
 t = [2,3,1,1]
 g = GNNGraph(s,t)
@@ -138,7 +138,7 @@
 l = GMMConv((nin, ein) => out, K=K)
 
 # forward pass
-l(g, x, e)
source
GraphNeuralNetworks.GatedGraphConvType
GatedGraphConv(out, num_layers; aggr=+, init=glorot_uniform)

Gated graph convolution layer from Gated Graph Sequence Neural Networks.

Implements the recursion

\[\begin{aligned} +l(g, x, e)

source
GraphNeuralNetworks.GatedGraphConvType
GatedGraphConv(out, num_layers; aggr=+, init=glorot_uniform)

Gated graph convolution layer from Gated Graph Sequence Neural Networks.

Implements the recursion

\[\begin{aligned} \mathbf{h}^{(0)}_i &= [\mathbf{x}_i; \mathbf{0}] \\ \mathbf{h}^{(l)}_i &= GRU(\mathbf{h}^{(l-1)}_i, \square_{j \in N(i)} W \mathbf{h}^{(l-1)}_j) \end{aligned}\]

where $\mathbf{h}^{(l)}_i$ denotes the $l$-th hidden variables passing through GRU. The dimension of input $\mathbf{x}_i$ needs to be less or equal to out.

Arguments

  • out: The dimension of output features.
  • num_layers: The number of recursion steps.
  • aggr: Aggregation operator for the incoming messages (e.g. +, *, max, min, and mean).
  • init: Weight initialization function.

Examples:

# create data
@@ -152,7 +152,7 @@
 l = GatedGraphConv(out_channel, num_layers)
 
 # forward pass
-y = l(g, x)   
source
GraphNeuralNetworks.GraphConvType
GraphConv(in => out, σ=identity; aggr=+, bias=true, init=glorot_uniform)

Graph convolution layer from Reference: Weisfeiler and Leman Go Neural: Higher-order Graph Neural Networks.

Performs:

\[\mathbf{x}_i' = W_1 \mathbf{x}_i + \square_{j \in \mathcal{N}(i)} W_2 \mathbf{x}_j\]

where the aggregation type is selected by aggr.

Arguments

  • in: The dimension of input features.
  • out: The dimension of output features.
  • σ: Activation function.
  • aggr: Aggregation operator for the incoming messages (e.g. +, *, max, min, and mean).
  • bias: Add learnable bias.
  • init: Weights' initializer.

Examples

# create data
+y = l(g, x)   
source
GraphNeuralNetworks.GraphConvType
GraphConv(in => out, σ=identity; aggr=+, bias=true, init=glorot_uniform)

Graph convolution layer from Reference: Weisfeiler and Leman Go Neural: Higher-order Graph Neural Networks.

Performs:

\[\mathbf{x}_i' = W_1 \mathbf{x}_i + \square_{j \in \mathcal{N}(i)} W_2 \mathbf{x}_j\]

where the aggregation type is selected by aggr.

Arguments

  • in: The dimension of input features.
  • out: The dimension of output features.
  • σ: Activation function.
  • aggr: Aggregation operator for the incoming messages (e.g. +, *, max, min, and mean).
  • bias: Add learnable bias.
  • init: Weights' initializer.

Examples

# create data
 s = [1,1,2,3]
 t = [2,3,1,1]
 in_channel = 3
@@ -164,7 +164,7 @@
 l = GraphConv(in_channel => out_channel, relu, bias = false, aggr = mean)
 
 # forward pass
-y = l(g, x)       
source
GraphNeuralNetworks.MEGNetConvType
MEGNetConv(ϕe, ϕv; aggr=mean)
+y = l(g, x)       
source
GraphNeuralNetworks.MEGNetConvType
MEGNetConv(ϕe, ϕv; aggr=mean)
 MEGNetConv(in => out; aggr=mean)

Convolution from Graph Networks as a Universal Machine Learning Framework for Molecules and Crystals paper. In the forward pass, takes as inputs node features x and edge features e and returns updated features x' and e' according to

\[\begin{aligned} \mathbf{e}_{i\to j}' = \phi_e([\mathbf{x}_i;\, \mathbf{x}_j;\, \mathbf{e}_{i\to j}]),\\ \mathbf{x}_{i}' = \phi_v([\mathbf{x}_i;\, \square_{j\in \mathcal{N}(i)}\,\mathbf{e}_{j\to i}']). @@ -172,7 +172,7 @@ x = randn(Float32, 3, 10) e = randn(Float32, 3, 30) m = MEGNetConv(3 => 3) -x′, e′ = m(g, x, e)

source
GraphNeuralNetworks.NNConvType
NNConv(in => out, f, σ=identity; aggr=+, bias=true, init=glorot_uniform)

The continuous kernel-based convolutional operator from the Neural Message Passing for Quantum Chemistry paper. This convolution is also known as the edge-conditioned convolution from the Dynamic Edge-Conditioned Filters in Convolutional Neural Networks on Graphs paper.

Performs the operation

\[\mathbf{x}_i' = W \mathbf{x}_i + \square_{j \in N(i)} f_\Theta(\mathbf{e}_{j\to i})\,\mathbf{x}_j\]

where $f_\Theta$ denotes a learnable function (e.g. a linear layer or a multi-layer perceptron). Given an input of batched edge features e of size (num_edge_features, num_edges), the function f will return an batched matrices array whose size is (out, in, num_edges). For convenience, also functions returning a single (out*in, num_edges) matrix are allowed.

Arguments

  • in: The dimension of input node features.
  • out: The dimension of output node features.
  • f: A (possibly learnable) function acting on edge features.
  • aggr: Aggregation operator for the incoming messages (e.g. +, *, max, min, and mean).
  • σ: Activation function.
  • bias: Add learnable bias.
  • init: Weights' initializer.

Examples:

n_in = 3
+x′, e′ = m(g, x, e)
source
GraphNeuralNetworks.NNConvType
NNConv(in => out, f, σ=identity; aggr=+, bias=true, init=glorot_uniform)

The continuous kernel-based convolutional operator from the Neural Message Passing for Quantum Chemistry paper. This convolution is also known as the edge-conditioned convolution from the Dynamic Edge-Conditioned Filters in Convolutional Neural Networks on Graphs paper.

Performs the operation

\[\mathbf{x}_i' = W \mathbf{x}_i + \square_{j \in N(i)} f_\Theta(\mathbf{e}_{j\to i})\,\mathbf{x}_j\]

where $f_\Theta$ denotes a learnable function (e.g. a linear layer or a multi-layer perceptron). Given an input of batched edge features e of size (num_edge_features, num_edges), the function f will return an batched matrices array whose size is (out, in, num_edges). For convenience, also functions returning a single (out*in, num_edges) matrix are allowed.

Arguments

  • in: The dimension of input node features.
  • out: The dimension of output node features.
  • f: A (possibly learnable) function acting on edge features.
  • aggr: Aggregation operator for the incoming messages (e.g. +, *, max, min, and mean).
  • σ: Activation function.
  • bias: Add learnable bias.
  • init: Weights' initializer.

Examples:

n_in = 3
 n_in_edge = 10
 n_out = 5
 
@@ -191,7 +191,7 @@
 e = randn(Float32, n_in_edge, g.num_edges)
 
 # forward pass
-y = l(g, x, e)  
source
GraphNeuralNetworks.ResGatedGraphConvType
ResGatedGraphConv(in => out, act=identity; init=glorot_uniform, bias=true)

The residual gated graph convolutional operator from the Residual Gated Graph ConvNets paper.

The layer's forward pass is given by

\[\mathbf{x}_i' = act\big(U\mathbf{x}_i + \sum_{j \in N(i)} \eta_{ij} V \mathbf{x}_j\big),\]

where the edge gates $\eta_{ij}$ are given by

\[\eta_{ij} = sigmoid(A\mathbf{x}_i + B\mathbf{x}_j).\]

Arguments

  • in: The dimension of input features.
  • out: The dimension of output features.
  • act: Activation function.
  • init: Weight matrices' initializing function.
  • bias: Learn an additive bias if true.

Examples:

# create data
+y = l(g, x, e)  
source
GraphNeuralNetworks.ResGatedGraphConvType
ResGatedGraphConv(in => out, act=identity; init=glorot_uniform, bias=true)

The residual gated graph convolutional operator from the Residual Gated Graph ConvNets paper.

The layer's forward pass is given by

\[\mathbf{x}_i' = act\big(U\mathbf{x}_i + \sum_{j \in N(i)} \eta_{ij} V \mathbf{x}_j\big),\]

where the edge gates $\eta_{ij}$ are given by

\[\eta_{ij} = sigmoid(A\mathbf{x}_i + B\mathbf{x}_j).\]

Arguments

  • in: The dimension of input features.
  • out: The dimension of output features.
  • act: Activation function.
  • init: Weight matrices' initializing function.
  • bias: Learn an additive bias if true.

Examples:

# create data
 s = [1,1,2,3]
 t = [2,3,1,1]
 in_channel = 3
@@ -202,7 +202,7 @@
 l = ResGatedGraphConv(in_channel => out_channel, tanh, bias = true)
 
 # forward pass
-y = l(g, x)  
source
GraphNeuralNetworks.SAGEConvType
SAGEConv(in => out, σ=identity; aggr=mean, bias=true, init=glorot_uniform)

GraphSAGE convolution layer from paper Inductive Representation Learning on Large Graphs.

Performs:

\[\mathbf{x}_i' = W \cdot [\mathbf{x}_i; \square_{j \in \mathcal{N}(i)} \mathbf{x}_j]\]

where the aggregation type is selected by aggr.

Arguments

  • in: The dimension of input features.
  • out: The dimension of output features.
  • σ: Activation function.
  • aggr: Aggregation operator for the incoming messages (e.g. +, *, max, min, and mean).
  • bias: Add learnable bias.
  • init: Weights' initializer.

Examples:

# create data
+y = l(g, x)  
source
GraphNeuralNetworks.SAGEConvType
SAGEConv(in => out, σ=identity; aggr=mean, bias=true, init=glorot_uniform)

GraphSAGE convolution layer from paper Inductive Representation Learning on Large Graphs.

Performs:

\[\mathbf{x}_i' = W \cdot [\mathbf{x}_i; \square_{j \in \mathcal{N}(i)} \mathbf{x}_j]\]

where the aggregation type is selected by aggr.

Arguments

  • in: The dimension of input features.
  • out: The dimension of output features.
  • σ: Activation function.
  • aggr: Aggregation operator for the incoming messages (e.g. +, *, max, min, and mean).
  • bias: Add learnable bias.
  • init: Weights' initializer.

Examples:

# create data
 s = [1,1,2,3]
 t = [2,3,1,1]
 in_channel = 3
@@ -213,7 +213,7 @@
 l = SAGEConv(in_channel => out_channel, tanh, bias = false, aggr = +)
 
 # forward pass
-y = l(g, x)   
source
GraphNeuralNetworks.SGConvType
SGConv(int => out, k=1; [bias, init, add_self_loops, use_edge_weight])

SGC layer from Simplifying Graph Convolutional Networks Performs operation

\[H^{K} = (\tilde{D}^{-1/2} \tilde{A} \tilde{D}^{-1/2})^K X \Theta\]

where $\tilde{A}$ is $A + I$.

Arguments

  • in: Number of input features.
  • out: Number of output features.
  • k : Number of hops k. Default 1.
  • bias: Add learnable bias. Default true.
  • init: Weights' initializer. Default glorot_uniform.
  • add_self_loops: Add self loops to the graph before performing the convolution. Default false.
  • use_edge_weight: If true, consider the edge weights in the input graph (if available). If add_self_loops=true the new weights will be set to 1. Default false.

Examples

# create data
+y = l(g, x)   
source
GraphNeuralNetworks.SGConvType
SGConv(int => out, k=1; [bias, init, add_self_loops, use_edge_weight])

SGC layer from Simplifying Graph Convolutional Networks Performs operation

\[H^{K} = (\tilde{D}^{-1/2} \tilde{A} \tilde{D}^{-1/2})^K X \Theta\]

where $\tilde{A}$ is $A + I$.

Arguments

  • in: Number of input features.
  • out: Number of output features.
  • k : Number of hops k. Default 1.
  • bias: Add learnable bias. Default true.
  • init: Weights' initializer. Default glorot_uniform.
  • add_self_loops: Add self loops to the graph before performing the convolution. Default false.
  • use_edge_weight: If true, consider the edge weights in the input graph (if available). If add_self_loops=true the new weights will be set to 1. Default false.

Examples

# create data
 s = [1,1,2,3]
 t = [2,3,1,1]
 g = GNNGraph(s, t)
@@ -232,7 +232,7 @@
 # Edge weights can also be embedded in the graph.
 g = GNNGraph(s, t, w)
 l = SGConv(3 => 5, add_self_loops = true, use_edge_weight=true) 
-y = l(g, x) # same as l(g, x, w) 
source
GraphNeuralNetworks.TAGConvType
TAGConv(in => out, k=3; bias=true, init=glorot_uniform, add_self_loops=true, use_edge_weight=false)

TAGConv layer from Topology Adaptive Graph Convolutional Networks. This layer extends the idea of graph convolutions by applying filters that adapt to the topology of the data. It performs the operation:

\[H^{K} = {\sum}_{k=0}^K (D^{-1/2} A D^{-1/2})^{k} X {\Theta}_{k}\]

where A is the adjacency matrix of the graph, D is the degree matrix, X is the input feature matrix, and ${\Theta}_{k}$ is a unique weight matrix for each hop k.

Arguments

  • in: Number of input features.
  • out: Number of output features.
  • k: Maximum number of hops to consider. Default is 3.
  • bias: Whether to include a learnable bias term. Default is true.
  • init: Initialization function for the weights. Default is glorot_uniform.
  • add_self_loops: Whether to add self-loops to the adjacency matrix. Default is true.
  • use_edge_weight: If true, edge weights are considered in the computation (if available). Default is false.

Examples

# Example graph data
+y = l(g, x) # same as l(g, x, w) 
source
GraphNeuralNetworks.TAGConvType
TAGConv(in => out, k=3; bias=true, init=glorot_uniform, add_self_loops=true, use_edge_weight=false)

TAGConv layer from Topology Adaptive Graph Convolutional Networks. This layer extends the idea of graph convolutions by applying filters that adapt to the topology of the data. It performs the operation:

\[H^{K} = {\sum}_{k=0}^K (D^{-1/2} A D^{-1/2})^{k} X {\Theta}_{k}\]

where A is the adjacency matrix of the graph, D is the degree matrix, X is the input feature matrix, and ${\Theta}_{k}$ is a unique weight matrix for each hop k.

Arguments

  • in: Number of input features.
  • out: Number of output features.
  • k: Maximum number of hops to consider. Default is 3.
  • bias: Whether to include a learnable bias term. Default is true.
  • init: Initialization function for the weights. Default is glorot_uniform.
  • add_self_loops: Whether to add self-loops to the adjacency matrix. Default is true.
  • use_edge_weight: If true, edge weights are considered in the computation (if available). Default is false.

Examples

# Example graph data
 s = [1, 1, 2, 3]
 t = [2, 3, 1, 1]
 g = GNNGraph(s, t)  # Create a graph
@@ -242,7 +242,7 @@
 l = TAGConv(3 => 5, k=3; add_self_loops=true)
 
 # Apply the TAGConv layer
-y = l(g, x)  # Output size: 5 × num_nodes
source
GraphNeuralNetworks.TransformerConvType
TransformerConv((in, ein) => out; [heads, concat, init, add_self_loops, bias_qkv,
+y = l(g, x)  # Output size: 5 × num_nodes
source
GraphNeuralNetworks.TransformerConvType
TransformerConv((in, ein) => out; [heads, concat, init, add_self_loops, bias_qkv,
     bias_root, root_weight, gating, skip_connection, batch_norm, ff_channels]))

The transformer-like multi head attention convolutional operator from the Masked Label Prediction: Unified Message Passing Model for Semi-Supervised Classification paper, which also considers edge features. It further contains options to also be configured as the transformer-like convolutional operator from the Attention, Learn to Solve Routing Problems! paper, including a successive feed-forward network as well as skip layers and batch normalization.

The layer's basic forward pass is given by

\[x_i' = W_1x_i + \sum_{j\in N(i)} \alpha_{ij} (W_2 x_j + W_6e_{ij})\]

where the attention scores are

\[\alpha_{ij} = \mathrm{softmax}\left(\frac{(W_3x_i)^T(W_4x_j+ W_6e_{ij})}{\sqrt{d}}\right).\]

Optionally, a combination of the aggregated value with transformed root node features by a gating mechanism via

\[x'_i = \beta_i W_1 x_i + (1 - \beta_i) \underbrace{\left(\sum_{j \in \mathcal{N}(i)} \alpha_{i,j} W_2 x_j \right)}_{=m_i}\]

with

\[\beta_i = \textrm{sigmoid}(W_5^{\top} [ W_1 x_i, m_i, W_1 x_i - m_i ]).\]

can be performed.

Arguments

  • in: Dimension of input features, which also corresponds to the dimension of the output features.
  • ein: Dimension of the edge features; if 0, no edge features will be used.
  • out: Dimension of the output.
  • heads: Number of heads in output. Default 1.
  • concat: Concatenate layer output or not. If not, layer output is averaged over the heads. Default true.
  • init: Weight matrices' initializing function. Default glorot_uniform.
  • add_self_loops: Add self loops to the input graph. Default false.
  • bias_qkv: If set, bias is used in the key, query and value transformations for nodes. Default true.
  • bias_root: If set, the layer will also learn an additive bias for the root when root weight is used. Default true.
  • root_weight: If set, the layer will add the transformed root node features to the output. Default true.
  • gating: If set, will combine aggregation and transformed root node features by a gating mechanism. Default false.
  • skip_connection: If set, a skip connection will be made from the input and added to the output. Default false.
  • batch_norm: If set, a batch normalization will be applied to the output. Default false.
  • ff_channels: If positive, a feed-forward NN is appended, with the first having the given number of hidden nodes; this NN also gets a skip connection and batch normalization if the respective parameters are set. Default: 0.

Examples

N, in_channel, out_channel = 4, 3, 5
@@ -251,4 +251,4 @@
 l = TransformerConv((in_channel, ein) => in_channel; heads, gating = true, bias_qkv = true)
 x = rand(Float32, in_channel, N)
 e = rand(Float32, ein, g.num_edges)
-l(g, x, e)
source
\ No newline at end of file +l(g, x, e)source \ No newline at end of file diff --git a/graphneuralnetworks/api/heteroconv/index.html b/graphneuralnetworks/api/heteroconv/index.html index 736ba58ae..04f3a23a6 100644 --- a/graphneuralnetworks/api/heteroconv/index.html +++ b/graphneuralnetworks/api/heteroconv/index.html @@ -12,4 +12,4 @@ julia> y = layer(g, x); # output is a named tuple julia> size(y.A) == (32, 10) && size(y.B) == (32, 15) -truesource \ No newline at end of file +truesource \ No newline at end of file diff --git a/graphneuralnetworks/api/pool/index.html b/graphneuralnetworks/api/pool/index.html index 962a48e14..37ba56b80 100644 --- a/graphneuralnetworks/api/pool/index.html +++ b/graphneuralnetworks/api/pool/index.html @@ -12,7 +12,7 @@ u = pool(g, g.ndata.x) -@assert size(u) == (chout, g.num_graphs)source
GraphNeuralNetworks.GlobalPoolType
GlobalPool(aggr)

Global pooling layer for graph neural networks. Takes a graph and feature nodes as inputs and performs the operation

\[\mathbf{u}_V = \square_{i \in V} \mathbf{x}_i\]

where $V$ is the set of nodes of the input graph and the type of aggregation represented by $\square$ is selected by the aggr argument. Commonly used aggregations are mean, max, and +.

See also reduce_nodes.

Examples

using Flux, GraphNeuralNetworks, Graphs
+@assert size(u) == (chout, g.num_graphs)
source
GraphNeuralNetworks.GlobalPoolType
GlobalPool(aggr)

Global pooling layer for graph neural networks. Takes a graph and feature nodes as inputs and performs the operation

\[\mathbf{u}_V = \square_{i \in V} \mathbf{x}_i\]

where $V$ is the set of nodes of the input graph and the type of aggregation represented by $\square$ is selected by the aggr argument. Commonly used aggregations are mean, max, and +.

See also reduce_nodes.

Examples

using Flux, GraphNeuralNetworks, Graphs
 
 pool = GlobalPool(mean)
 
@@ -23,7 +23,7 @@
 
 g = Flux.batch([GNNGraph(erdos_renyi(10, 4)) for _ in 1:5])
 X = rand(32, 50)
-pool(g, X) # => 32x5 matrix
source
GraphNeuralNetworks.Set2SetType
Set2Set(n_in, n_iters, n_layers = 1)

Set2Set layer from the paper Order Matters: Sequence to sequence for sets.

For each graph in the batch, the layer computes an output vector of size 2*n_in by iterating the following steps n_iters times:

\[\mathbf{q} = \mathrm{LSTM}(\mathbf{q}_{t-1}^*) +pool(g, X) # => 32x5 matrix

source
GraphNeuralNetworks.Set2SetType
Set2Set(n_in, n_iters, n_layers = 1)

Set2Set layer from the paper Order Matters: Sequence to sequence for sets.

For each graph in the batch, the layer computes an output vector of size 2*n_in by iterating the following steps n_iters times:

\[\mathbf{q} = \mathrm{LSTM}(\mathbf{q}_{t-1}^*) \alpha_{i} = \frac{\exp(\mathbf{q}^T \mathbf{x}_i)}{\sum_{j=1}^N \exp(\mathbf{q}^T \mathbf{x}_j)} \mathbf{r} = \sum_{i=1}^N \alpha_{i} \mathbf{x}_i -\mathbf{q}^*_t = [\mathbf{q}; \mathbf{r}]\]

where N is the number of nodes in the graph, LSTM is a Long-Short-Term-Memory network with n_layers layers, input size 2*n_in and output size n_in.

Given a batch of graphs g and node features x, the layer returns a matrix of size (2*n_in, n_graphs). ```

source
GraphNeuralNetworks.TopKPoolType
TopKPool(adj, k, in_channel)

Top-k pooling layer.

Arguments

  • adj: Adjacency matrix of a graph.
  • k: Top-k nodes are selected to pool together.
  • in_channel: The dimension of input channel.
source
\ No newline at end of file +\mathbf{q}^*_t = [\mathbf{q}; \mathbf{r}]\]

where N is the number of nodes in the graph, LSTM is a Long-Short-Term-Memory network with n_layers layers, input size 2*n_in and output size n_in.

Given a batch of graphs g and node features x, the layer returns a matrix of size (2*n_in, n_graphs). ```

source
GraphNeuralNetworks.TopKPoolType
TopKPool(adj, k, in_channel)

Top-k pooling layer.

Arguments

  • adj: Adjacency matrix of a graph.
  • k: Top-k nodes are selected to pool together.
  • in_channel: The dimension of input channel.
source
\ No newline at end of file diff --git a/graphneuralnetworks/api/samplers/index.html b/graphneuralnetworks/api/samplers/index.html index 2c6763bd2..529242984 100644 --- a/graphneuralnetworks/api/samplers/index.html +++ b/graphneuralnetworks/api/samplers/index.html @@ -3,4 +3,4 @@ julia> batch_counter = 0 julia> for mini_batch_gnn in loader batch_counter += 1 - println("Batch ", batch_counter, ": Nodes in mini-batch graph: ", nv(mini_batch_gnn))source \ No newline at end of file + println("Batch ", batch_counter, ": Nodes in mini-batch graph: ", nv(mini_batch_gnn))source \ No newline at end of file diff --git a/graphneuralnetworks/api/temporalconv/index.html b/graphneuralnetworks/api/temporalconv/index.html index 53289d407..db234e94c 100644 --- a/graphneuralnetworks/api/temporalconv/index.html +++ b/graphneuralnetworks/api/temporalconv/index.html @@ -13,7 +13,7 @@ julia> y = a3tgcn(rand_graph(5, 10), rand(Float32, 2, 5, 20)); julia> size(y) -(6, 5)
Batch size changes

Failing to call reset! when the input batch size changes can lead to unexpected behavior.

source
GraphNeuralNetworks.EvolveGCNOType
EvolveGCNO(ch; bias = true, init = glorot_uniform, init_state = Flux.zeros32)

Evolving Graph Convolutional Network (EvolveGCNO) layer from the paper EvolveGCN: Evolving Graph Convolutional Networks for Dynamic Graphs.

Perfoms a Graph Convolutional layer with parameters derived from a Long Short-Term Memory (LSTM) layer across the snapshots of the temporal graph.

Arguments

  • in: Number of input features.
  • out: Number of output features.
  • bias: Add learnable bias. Default true.
  • init: Weights' initializer. Default glorot_uniform.
  • init_state: Initial state of the hidden stat of the LSTM layer. Default zeros32.

Examples

julia> tg = TemporalSnapshotsGNNGraph([rand_graph(10,20; ndata = rand(4,10)), rand_graph(10,14; ndata = rand(4,10)), rand_graph(10,22; ndata = rand(4,10))])
+(6, 5)
Batch size changes

Failing to call reset! when the input batch size changes can lead to unexpected behavior.

source
GraphNeuralNetworks.EvolveGCNOType
EvolveGCNO(ch; bias = true, init = glorot_uniform, init_state = Flux.zeros32)

Evolving Graph Convolutional Network (EvolveGCNO) layer from the paper EvolveGCN: Evolving Graph Convolutional Networks for Dynamic Graphs.

Perfoms a Graph Convolutional layer with parameters derived from a Long Short-Term Memory (LSTM) layer across the snapshots of the temporal graph.

Arguments

  • in: Number of input features.
  • out: Number of output features.
  • bias: Add learnable bias. Default true.
  • init: Weights' initializer. Default glorot_uniform.
  • init_state: Initial state of the hidden stat of the LSTM layer. Default zeros32.

Examples

julia> tg = TemporalSnapshotsGNNGraph([rand_graph(10,20; ndata = rand(4,10)), rand_graph(10,14; ndata = rand(4,10)), rand_graph(10,22; ndata = rand(4,10))])
 TemporalSnapshotsGNNGraph:
   num_nodes: [10, 10, 10]
   num_edges: [20, 14, 22]
@@ -26,7 +26,7 @@
 (3,)
 
 julia> size(ev(tg, tg.ndata.x)[1])
-(5, 10)
source
GraphNeuralNetworks.DCGRUMethod
DCGRU(in => out, k, n; [bias, init, init_state])

Diffusion Convolutional Recurrent Neural Network (DCGRU) layer from the paper Diffusion Convolutional Recurrent Neural Network: Data-driven Traffic Forecasting.

Performs a Diffusion Convolutional layer to model spatial dependencies, followed by a Gated Recurrent Unit (GRU) cell to model temporal dependencies.

Arguments

  • in: Number of input features.
  • out: Number of output features.
  • k: Diffusion step.
  • n: Number of nodes in the graph.
  • bias: Add learnable bias. Default true.
  • init: Weights' initializer. Default glorot_uniform.
  • init_state: Initial state of the hidden stat of the LSTM layer. Default zeros32.

Examples

julia> g1, x1 = rand_graph(5, 10), rand(Float32, 2, 5);
+(5, 10)
source
GraphNeuralNetworks.DCGRUMethod
DCGRU(in => out, k, n; [bias, init, init_state])

Diffusion Convolutional Recurrent Neural Network (DCGRU) layer from the paper Diffusion Convolutional Recurrent Neural Network: Data-driven Traffic Forecasting.

Performs a Diffusion Convolutional layer to model spatial dependencies, followed by a Gated Recurrent Unit (GRU) cell to model temporal dependencies.

Arguments

  • in: Number of input features.
  • out: Number of output features.
  • k: Diffusion step.
  • n: Number of nodes in the graph.
  • bias: Add learnable bias. Default true.
  • init: Weights' initializer. Default glorot_uniform.
  • init_state: Initial state of the hidden stat of the LSTM layer. Default zeros32.

Examples

julia> g1, x1 = rand_graph(5, 10), rand(Float32, 2, 5);
 
 julia> dcgru = DCGRU(2 => 5, 2, g1.num_nodes);
 
@@ -40,7 +40,7 @@
 julia> z = dcgru(g2, x2);
 
 julia> size(z)
-(5, 5, 30)
source
GraphNeuralNetworks.GConvGRUMethod
GConvGRU(in => out, k, n; [bias, init, init_state])

Graph Convolutional Gated Recurrent Unit (GConvGRU) recurrent layer from the paper Structured Sequence Modeling with Graph Convolutional Recurrent Networks.

Performs a layer of ChebConv to model spatial dependencies, followed by a Gated Recurrent Unit (GRU) cell to model temporal dependencies.

Arguments

  • in: Number of input features.
  • out: Number of output features.
  • k: Chebyshev polynomial order.
  • n: Number of nodes in the graph.
  • bias: Add learnable bias. Default true.
  • init: Weights' initializer. Default glorot_uniform.
  • init_state: Initial state of the hidden stat of the GRU layer. Default zeros32.

Examples

julia> g1, x1 = rand_graph(5, 10), rand(Float32, 2, 5);
+(5, 5, 30)
source
GraphNeuralNetworks.GConvGRUMethod
GConvGRU(in => out, k, n; [bias, init, init_state])

Graph Convolutional Gated Recurrent Unit (GConvGRU) recurrent layer from the paper Structured Sequence Modeling with Graph Convolutional Recurrent Networks.

Performs a layer of ChebConv to model spatial dependencies, followed by a Gated Recurrent Unit (GRU) cell to model temporal dependencies.

Arguments

  • in: Number of input features.
  • out: Number of output features.
  • k: Chebyshev polynomial order.
  • n: Number of nodes in the graph.
  • bias: Add learnable bias. Default true.
  • init: Weights' initializer. Default glorot_uniform.
  • init_state: Initial state of the hidden stat of the GRU layer. Default zeros32.

Examples

julia> g1, x1 = rand_graph(5, 10), rand(Float32, 2, 5);
 
 julia> ggru = GConvGRU(2 => 5, 2, g1.num_nodes);
 
@@ -54,7 +54,7 @@
 julia> z = ggru(g2, x2);
 
 julia> size(z)
-(5, 5, 30)
source
GraphNeuralNetworks.GConvLSTMMethod
GConvLSTM(in => out, k, n; [bias, init, init_state])

Graph Convolutional Long Short-Term Memory (GConvLSTM) recurrent layer from the paper Structured Sequence Modeling with Graph Convolutional Recurrent Networks.

Performs a layer of ChebConv to model spatial dependencies, followed by a Long Short-Term Memory (LSTM) cell to model temporal dependencies.

Arguments

  • in: Number of input features.
  • out: Number of output features.
  • k: Chebyshev polynomial order.
  • n: Number of nodes in the graph.
  • bias: Add learnable bias. Default true.
  • init: Weights' initializer. Default glorot_uniform.
  • init_state: Initial state of the hidden stat of the LSTM layer. Default zeros32.

Examples

julia> g1, x1 = rand_graph(5, 10), rand(Float32, 2, 5);
+(5, 5, 30)
source
GraphNeuralNetworks.GConvLSTMMethod
GConvLSTM(in => out, k, n; [bias, init, init_state])

Graph Convolutional Long Short-Term Memory (GConvLSTM) recurrent layer from the paper Structured Sequence Modeling with Graph Convolutional Recurrent Networks.

Performs a layer of ChebConv to model spatial dependencies, followed by a Long Short-Term Memory (LSTM) cell to model temporal dependencies.

Arguments

  • in: Number of input features.
  • out: Number of output features.
  • k: Chebyshev polynomial order.
  • n: Number of nodes in the graph.
  • bias: Add learnable bias. Default true.
  • init: Weights' initializer. Default glorot_uniform.
  • init_state: Initial state of the hidden stat of the LSTM layer. Default zeros32.

Examples

julia> g1, x1 = rand_graph(5, 10), rand(Float32, 2, 5);
 
 julia> gclstm = GConvLSTM(2 => 5, 2, g1.num_nodes);
 
@@ -68,7 +68,7 @@
 julia> z = gclstm(g2, x2);
 
 julia> size(z)
-(5, 5, 30)
source
GraphNeuralNetworks.TGCNMethod
TGCN(in => out; [bias, init, init_state, add_self_loops, use_edge_weight])

Temporal Graph Convolutional Network (T-GCN) recurrent layer from the paper T-GCN: A Temporal Graph Convolutional Network for Traffic Prediction.

Performs a layer of GCNConv to model spatial dependencies, followed by a Gated Recurrent Unit (GRU) cell to model temporal dependencies.

Arguments

  • in: Number of input features.
  • out: Number of output features.
  • bias: Add learnable bias. Default true.
  • init: Weights' initializer. Default glorot_uniform.
  • init_state: Initial state of the hidden stat of the GRU layer. Default zeros32.
  • add_self_loops: Add self loops to the graph before performing the convolution. Default false.
  • use_edge_weight: If true, consider the edge weights in the input graph (if available). If add_self_loops=true the new weights will be set to 1. This option is ignored if the edge_weight is explicitly provided in the forward pass. Default false.

Examples

julia> tgcn = TGCN(2 => 6)
+(5, 5, 30)
source
GraphNeuralNetworks.TGCNMethod
TGCN(in => out; [bias, init, init_state, add_self_loops, use_edge_weight])

Temporal Graph Convolutional Network (T-GCN) recurrent layer from the paper T-GCN: A Temporal Graph Convolutional Network for Traffic Prediction.

Performs a layer of GCNConv to model spatial dependencies, followed by a Gated Recurrent Unit (GRU) cell to model temporal dependencies.

Arguments

  • in: Number of input features.
  • out: Number of output features.
  • bias: Add learnable bias. Default true.
  • init: Weights' initializer. Default glorot_uniform.
  • init_state: Initial state of the hidden stat of the GRU layer. Default zeros32.
  • add_self_loops: Add self loops to the graph before performing the convolution. Default false.
  • use_edge_weight: If true, consider the edge weights in the input graph (if available). If add_self_loops=true the new weights will be set to 1. This option is ignored if the edge_weight is explicitly provided in the forward pass. Default false.

Examples

julia> tgcn = TGCN(2 => 6)
 Recur(
   TGCNCell(
     GCNConv(2 => 6, σ),                 # 18 parameters
@@ -90,4 +90,4 @@
 julia> Flux.reset!(tgcn);
 
 julia> tgcn(rand_graph(5, 10), rand(Float32, 2, 5, 20)) |> size # batch size of 20
-(6, 5, 20)
Batch size changes

Failing to call reset! when the input batch size changes can lead to unexpected behavior.

source
\ No newline at end of file +(6, 5, 20)
Batch size changes

Failing to call reset! when the input batch size changes can lead to unexpected behavior.

source \ No newline at end of file diff --git a/graphneuralnetworks/datasets/index.html b/graphneuralnetworks/datasets/index.html index 1f2c6b71a..3b22afed0 100644 --- a/graphneuralnetworks/datasets/index.html +++ b/graphneuralnetworks/datasets/index.html @@ -1 +1 @@ -Datasets · GraphNeuralNetworks.jl
\ No newline at end of file +Datasets · GraphNeuralNetworks.jl
\ No newline at end of file diff --git a/graphneuralnetworks/dev/index.html b/graphneuralnetworks/dev/index.html index 08cf4c0e9..e6fa06ade 100644 --- a/graphneuralnetworks/dev/index.html +++ b/graphneuralnetworks/dev/index.html @@ -23,4 +23,4 @@ julia> @load "perf_pr_20210803_mymachine.jld2" julia> compare(dfpr, dfmaster)

Caching tutorials

Tutorials in GraphNeuralNetworks.jl are written in Pluto and rendered using DemoCards.jl and PlutoStaticHTML.jl. Rendering a Pluto notebook is time and resource-consuming, especially in a CI environment. So we use the caching functionality provided by PlutoStaticHTML.jl to reduce CI time.

If you are contributing a new tutorial or making changes to the existing notebook, generate the docs locally before committing/pushing. For caching to work, the cache environment(your local) and the documenter CI should have the same Julia version (e.g. "v1.9.1", also the patch number must match). So use the documenter CI Julia version for generating docs locally.

julia --version # check julia version before generating docs
-julia --project=docs docs/make.jl

Note: Use juliaup for easy switching of Julia versions.

During the doc generation process, DemoCards.jl stores the cache notebooks in docs/pluto_output. So add any changes made in this folder in your git commit. Remember that every file in this folder is machine-generated and should not be edited manually.

git add docs/pluto_output # add generated cache

Check the documenter CI logs to ensure that it used the local cache:

\ No newline at end of file +julia --project=docs docs/make.jl

Note: Use juliaup for easy switching of Julia versions.

During the doc generation process, DemoCards.jl stores the cache notebooks in docs/pluto_output. So add any changes made in this folder in your git commit. Remember that every file in this folder is machine-generated and should not be edited manually.

git add docs/pluto_output # add generated cache

Check the documenter CI logs to ensure that it used the local cache:

\ No newline at end of file diff --git a/graphneuralnetworks/gsoc/index.html b/graphneuralnetworks/gsoc/index.html index d888954ad..6d4a0bb1f 100644 --- a/graphneuralnetworks/gsoc/index.html +++ b/graphneuralnetworks/gsoc/index.html @@ -1 +1 @@ -Google Summer of Code · GraphNeuralNetworks.jl
\ No newline at end of file +Google Summer of Code · GraphNeuralNetworks.jl
\ No newline at end of file diff --git a/graphneuralnetworks/home/index.html b/graphneuralnetworks/home/index.html index d4d8ec510..561947f7d 100644 --- a/graphneuralnetworks/home/index.html +++ b/graphneuralnetworks/home/index.html @@ -36,4 +36,4 @@ end @info (; epoch, train_loss=loss(model, train_loader), test_loss=loss(model, test_loader)) -end \ No newline at end of file +end \ No newline at end of file diff --git a/graphneuralnetworks/index.html b/graphneuralnetworks/index.html index 3a4a9735f..4fe8d1d7d 100644 --- a/graphneuralnetworks/index.html +++ b/graphneuralnetworks/index.html @@ -3,4 +3,4 @@ title = {GraphNeuralNetworks.jl: a geometric deep learning library for the Julia programming language}, year = 2021, url = {https://github.com/JuliaGraphs/GraphNeuralNetworks.jl} -}

Acknowledgments

GraphNeuralNetworks.jl is largely inspired by PyTorch Geometric, Deep Graph Library, and GeometricFlux.jl.

\ No newline at end of file +}

Acknowledgments

GraphNeuralNetworks.jl is largely inspired by PyTorch Geometric, Deep Graph Library, and GeometricFlux.jl.

\ No newline at end of file diff --git a/graphneuralnetworks/models/index.html b/graphneuralnetworks/models/index.html index 8e3f4fc8b..963d3e635 100644 --- a/graphneuralnetworks/models/index.html +++ b/graphneuralnetworks/models/index.html @@ -65,4 +65,4 @@ X = randn(Float32, din, 10) # Pass only X as input, the model already contains the graph. -y = model(X)

An example of WithGraph usage is given in the graph neural ODE script in the examples folder.

\ No newline at end of file +y = model(X)

An example of WithGraph usage is given in the graph neural ODE script in the examples folder.

\ No newline at end of file diff --git a/tutorials/.documenter-siteinfo.json b/tutorials/.documenter-siteinfo.json index 2b7090bcc..ec783e202 100644 --- a/tutorials/.documenter-siteinfo.json +++ b/tutorials/.documenter-siteinfo.json @@ -1 +1 @@ -{"documenter":{"julia_version":"1.10.5","generation_timestamp":"2024-11-08T08:46:09","documenter_version":"1.7.0"}} \ No newline at end of file +{"documenter":{"julia_version":"1.10.5","generation_timestamp":"2024-11-09T14:50:11","documenter_version":"1.7.0"}} \ No newline at end of file diff --git a/tutorials/index.html b/tutorials/index.html index c3368cedb..cabff421c 100644 --- a/tutorials/index.html +++ b/tutorials/index.html @@ -1 +1 @@ -Home · Tutorials

Tutorials

Introductory tutorials

Here are some introductory tutorials to get you started:

Temporal graph neural networks tutorials

Here some tutorials on temporal graph neural networks:

Contributions

If you have a suggestion on adding new tutorials, feel free to create a new issue here. Users are invited to contribute demonstrations of their own. If you want to contribute new tutorials and looking for inspiration, checkout these tutorials from PyTorch Geometric. Please check out existing tutorials for more details.

\ No newline at end of file +Home · Tutorials

Tutorials

Introductory tutorials

Here are some introductory tutorials to get you started:

Temporal graph neural networks tutorials

Here some tutorials on temporal graph neural networks:

Contributions

If you have a suggestion on adding new tutorials, feel free to create a new issue here. Users are invited to contribute demonstrations of their own. If you want to contribute new tutorials and looking for inspiration, checkout these tutorials from PyTorch Geometric. Please check out existing tutorials for more details.

\ No newline at end of file diff --git a/tutorials/pluto_output/gnn_intro_pluto/index.html b/tutorials/pluto_output/gnn_intro_pluto/index.html index 5ce0ad2ac..89dd1913f 100644 --- a/tutorials/pluto_output/gnn_intro_pluto/index.html +++ b/tutorials/pluto_output/gnn_intro_pluto/index.html @@ -152,4 +152,4 @@ end end
ŷ, emb_final = model(g, g.ndata.x)
(Float32[-8.871021 -6.288402 … 7.8817716 7.3984337; 7.873129 5.5748186 … -8.054153 -7.562167; 0.6939411 2.6538918 … 0.1978332 0.633129; 0.42380208 -1.7143326 … -0.14687762 -0.5542332], Float32[-0.99049056 -0.9905237 … 0.99305063 0.87260294; -0.9905631 -0.40585023 … 0.9999852 0.99999404])
# train accuracy
 mean(onecold(ŷ[:, train_mask]) .== onecold(y[:, train_mask]))
1.0
# test accuracy
-mean(onecold(ŷ[:, .!train_mask]) .== onecold(y[:, .!train_mask]))
0.8
visualize_embeddings(emb_final, colors = labels)

As one can see, our 3-layer GCN model manages to linearly separating the communities and classifying most of the nodes correctly.

Furthermore, we did this all with a few lines of code, thanks to the GraphNeuralNetworks.jl which helped us out with data handling and GNN implementations.

\ No newline at end of file +mean(onecold(ŷ[:, .!train_mask]) .== onecold(y[:, .!train_mask]))
0.8
visualize_embeddings(emb_final, colors = labels)

As one can see, our 3-layer GCN model manages to linearly separating the communities and classifying most of the nodes correctly.

Furthermore, we did this all with a few lines of code, thanks to the GraphNeuralNetworks.jl which helped us out with data handling and GNN implementations.

\ No newline at end of file diff --git a/tutorials/pluto_output/graph_classification_pluto/index.html b/tutorials/pluto_output/graph_classification_pluto/index.html index 81c7c4416..a3c5b234b 100644 --- a/tutorials/pluto_output/graph_classification_pluto/index.html +++ b/tutorials/pluto_output/graph_classification_pluto/index.html @@ -119,4 +119,4 @@ nout = 2 model = create_model(nin, nh, nout) train!(model) -end

As one can see, our model reaches around 74% test accuracy. Reasons for the fluctuations in accuracy can be explained by the rather small dataset (only 38 test graphs), and usually disappear once one applies GNNs to larger datasets.

(Optional) Exercise

Can we do better than this? As multiple papers pointed out (Xu et al. (2018), Morris et al. (2018)), applying neighborhood normalization decreases the expressivity of GNNs in distinguishing certain graph structures. An alternative formulation (Morris et al. (2018)) omits neighborhood normalization completely and adds a simple skip-connection to the GNN layer in order to preserve central node information:

$$\mathbf{x}_i^{(\ell+1)} = \mathbf{W}^{(\ell + 1)}_1 \mathbf{x}_i^{(\ell)} + \mathbf{W}^{(\ell + 1)}_2 \sum_{j \in \mathcal{N}(i)} \mathbf{x}_j^{(\ell)}$$

This layer is implemented under the name GraphConv in GraphNeuralNetworks.jl.

As an exercise, you are invited to complete the following code to the extent that it makes use of GraphConv rather than GCNConv. This should bring you close to 82% test accuracy.

Conclusion

In this chapter, you have learned how to apply GNNs to the task of graph classification. You have learned how graphs can be batched together for better GPU utilization, and how to apply readout layers for obtaining graph embeddings rather than node embeddings.

\ No newline at end of file +end

As one can see, our model reaches around 74% test accuracy. Reasons for the fluctuations in accuracy can be explained by the rather small dataset (only 38 test graphs), and usually disappear once one applies GNNs to larger datasets.

(Optional) Exercise

Can we do better than this? As multiple papers pointed out (Xu et al. (2018), Morris et al. (2018)), applying neighborhood normalization decreases the expressivity of GNNs in distinguishing certain graph structures. An alternative formulation (Morris et al. (2018)) omits neighborhood normalization completely and adds a simple skip-connection to the GNN layer in order to preserve central node information:

$$\mathbf{x}_i^{(\ell+1)} = \mathbf{W}^{(\ell + 1)}_1 \mathbf{x}_i^{(\ell)} + \mathbf{W}^{(\ell + 1)}_2 \sum_{j \in \mathcal{N}(i)} \mathbf{x}_j^{(\ell)}$$

This layer is implemented under the name GraphConv in GraphNeuralNetworks.jl.

As an exercise, you are invited to complete the following code to the extent that it makes use of GraphConv rather than GCNConv. This should bring you close to 82% test accuracy.

Conclusion

In this chapter, you have learned how to apply GNNs to the task of graph classification. You have learned how graphs can be batched together for better GPU utilization, and how to apply readout layers for obtaining graph embeddings rather than node embeddings.

\ No newline at end of file diff --git a/tutorials/pluto_output/node_classification_pluto/index.html b/tutorials/pluto_output/node_classification_pluto/index.html index 7bf23bb9d..6e17b4343 100644 --- a/tutorials/pluto_output/node_classification_pluto/index.html +++ b/tutorials/pluto_output/node_classification_pluto/index.html @@ -177,4 +177,4 @@ out_trained = gcn(g, x) |> transpose visualize_tsne(out_trained, g.ndata.targets) -end

(Optional) Exercises

  1. To achieve better model performance and to avoid overfitting, it is usually a good idea to select the best model based on an additional validation set. The Cora dataset provides a validation node set as g.ndata.val_mask, but we haven't used it yet. Can you modify the code to select and test the model with the highest validation performance? This should bring test performance to 82% accuracy.

  2. How does GCN behave when increasing the hidden feature dimensionality or the number of layers? Does increasing the number of layers help at all?

  3. You can try to use different GNN layers to see how model performance changes. What happens if you swap out all GCNConv instances with GATConv layers that make use of attention? Try to write a 2-layer GAT model that makes use of 8 attention heads in the first layer and 1 attention head in the second layer, uses a dropout ratio of 0.6 inside and outside each GATConv call, and uses a hidden_channels dimensions of 8 per head.

Conclusion

In this tutorial, we have seen how to apply GNNs to real-world problems, and, in particular, how they can effectively be used for boosting a model's performance. In the next tutorial, we will look into how GNNs can be used for the task of graph classification.

\ No newline at end of file +end

(Optional) Exercises

  1. To achieve better model performance and to avoid overfitting, it is usually a good idea to select the best model based on an additional validation set. The Cora dataset provides a validation node set as g.ndata.val_mask, but we haven't used it yet. Can you modify the code to select and test the model with the highest validation performance? This should bring test performance to 82% accuracy.

  2. How does GCN behave when increasing the hidden feature dimensionality or the number of layers? Does increasing the number of layers help at all?

  3. You can try to use different GNN layers to see how model performance changes. What happens if you swap out all GCNConv instances with GATConv layers that make use of attention? Try to write a 2-layer GAT model that makes use of 8 attention heads in the first layer and 1 attention head in the second layer, uses a dropout ratio of 0.6 inside and outside each GATConv call, and uses a hidden_channels dimensions of 8 per head.

Conclusion

In this tutorial, we have seen how to apply GNNs to real-world problems, and, in particular, how they can effectively be used for boosting a model's performance. In the next tutorial, we will look into how GNNs can be used for the task of graph classification.

\ No newline at end of file diff --git a/tutorials/pluto_output/temporal_graph_classification_pluto/index.html b/tutorials/pluto_output/temporal_graph_classification_pluto/index.html index 9224809c6..57df3f29c 100644 --- a/tutorials/pluto_output/temporal_graph_classification_pluto/index.html +++ b/tutorials/pluto_output/temporal_graph_classification_pluto/index.html @@ -119,4 +119,4 @@ end return model end; -
train(brain_dataset; usecuda = true)
GenderPredictionModel(GINConv(Chain(Dense(103 => 128, relu), Dense(128 => 128, relu)), 0.5), Chain(Dense(103 => 128, relu), Dense(128 => 128, relu)), GlobalPool{typeof(mean)}(Statistics.mean), var"#4#5"(), Dense(128 => 2))  # 30_082 parameters, plus 29_824 non-trainable

We set up the training on the GPU because training takes a lot of time, especially when working on the CPU.

Conclusions

In this tutorial, we implemented a very simple architecture to classify temporal graphs in the context of gender classification using brain data. We then trained the model on the GPU for 100 epochs on the TemporalBrains dataset. The accuracy of the model is approximately 75-80%, but can be improved by fine-tuning the parameters and training on more data.

\ No newline at end of file +
train(brain_dataset; usecuda = true)
GenderPredictionModel(GINConv(Chain(Dense(103 => 128, relu), Dense(128 => 128, relu)), 0.5), Chain(Dense(103 => 128, relu), Dense(128 => 128, relu)), GlobalPool{typeof(mean)}(Statistics.mean), var"#4#5"(), Dense(128 => 2))  # 30_082 parameters, plus 29_824 non-trainable

We set up the training on the GPU because training takes a lot of time, especially when working on the CPU.

Conclusions

In this tutorial, we implemented a very simple architecture to classify temporal graphs in the context of gender classification using brain data. We then trained the model on the GPU for 100 epochs on the TemporalBrains dataset. The accuracy of the model is approximately 75-80%, but can be improved by fine-tuning the parameters and training on more data.

\ No newline at end of file diff --git a/tutorials/pluto_output/traffic_prediction/index.html b/tutorials/pluto_output/traffic_prediction/index.html index dd26f18da..608e37ff7 100644 --- a/tutorials/pluto_output/traffic_prediction/index.html +++ b/tutorials/pluto_output/traffic_prediction/index.html @@ -85,4 +85,4 @@ plot!(p, collect(1:length(features)), grand_truth, color = :blue, label = "Grand Truth", xticks =([i for i in 0:50:250], ["$(i)" for i in 0:4:24])) plot!(p, collect(1:length(features)), prediction, color = :red, label= "Prediction") return p -end
plot_predicted_data (generic function with 1 method)
plot_predicted_data(graph,features[301:588],targets[301:588], 1)
accuracy(ŷ, y) = 1 - Statistics.norm(y-ŷ)/Statistics.norm(y)
accuracy (generic function with 1 method)
mean([accuracy(model(graph,x), y) for (x, y) in test_loader])
0.47803628f0

The accuracy is not very good but can be improved by training using more data. We used a small subset of the dataset for this tutorial because of the computational cost of training the model. From the plot of the predictions, we can see that the model is able to capture the general trend of the traffic speed, but it is not able to capture the peaks of the traffic.

Conclusion

In this tutorial, we learned how to use a recurrent temporal graph convolutional network to predict traffic in a spatio-temporal setting. We used the TGCN model, which consists of a graph convolutional network (GCN) and a gated recurrent unit (GRU). We then trained the model for 100 epochs on a small subset of the METR-LA dataset. The accuracy of the model is not very good, but it can be improved by training on more data.

\ No newline at end of file +end
plot_predicted_data (generic function with 1 method)
plot_predicted_data(graph,features[301:588],targets[301:588], 1)
accuracy(ŷ, y) = 1 - Statistics.norm(y-ŷ)/Statistics.norm(y)
accuracy (generic function with 1 method)
mean([accuracy(model(graph,x), y) for (x, y) in test_loader])
0.47803628f0

The accuracy is not very good but can be improved by training using more data. We used a small subset of the dataset for this tutorial because of the computational cost of training the model. From the plot of the predictions, we can see that the model is able to capture the general trend of the traffic speed, but it is not able to capture the peaks of the traffic.

Conclusion

In this tutorial, we learned how to use a recurrent temporal graph convolutional network to predict traffic in a spatio-temporal setting. We used the TGCN model, which consists of a graph convolutional network (GCN) and a gated recurrent unit (GRU). We then trained the model for 100 epochs on a small subset of the METR-LA dataset. The accuracy of the model is not very good, but it can be improved by training on more data.

\ No newline at end of file