pyagc.encoders

The pyagc.encoders package provides the Representation Encoding module in the Encode-Cluster-Optimize framework. The encoder \(\mathcal{E}\) fuses structural topology and node attributes into a latent representation space \(\mathbf{Z} \in \mathbb{R}^{N \times H}\):

\[\mathbf{Z} = \mathcal{E}(\mathbf{A}, \mathbf{X}; \Theta_{\mathcal{E}})\]

Beyond classical graph encoders, pyagc.encoders also supports tabular-feature-aware graph encoding, where node attributes are represented as structured tabular data instead of plain dense tensors. This may be useful for real-world datasets with heterogeneous feature types (e.g., numerical, categorical, timestamp), commonly seen in recommendation systems and relational data.

Following the “Classic GNNs are Strong Baselines” paper (Luo et al., NeurIPS 2024), we provide TunedGNN — enhanced implementations of standard GNNs with critical improvements including residual connections, pre-linear transformations, flexible normalization, and optimized dropout strategies. These encoders support both full-batch processing for small graphs and neighbor-sampling-based mini-batching for massive graphs.

In addition, we re-export standard GNN backbones from PyTorch Geometric, including GCN, GraphSAGE, GAT, and GIN. We also implement graph transformer architectures such as SGFormer and Polynormer.

This design allows any clustering head from pyagc.clusters to be easily paired with varying encoder backbones without code duplication — simply change the encoder specification in the configuration file.

from pyagc.encoders import TunedGCN, TunedGAT, create_tuned_gnn

# Create a tuned GCN encoder directly:
encoder = TunedGCN(
    in_channels=1433,
    hidden_channels=256,
    num_layers=3,
    out_channels=128,
    dropout=0.5,
    norm="batch_norm",
    residual=True,
)

# Or use the factory function for convenience:
encoder = create_tuned_gnn(
    "gcn",
    in_channels=1433,
    hidden_channels=256,
    num_layers=3,
    out_channels=128,
    dropout=0.5,
    norm="batch_norm",
    residual=True,
)

# Create a tuned GAT with multiple attention heads:
encoder = create_tuned_gnn(
    "gat",
    in_channels=1433,
    hidden_channels=256,
    num_layers=3,
    out_channels=128,
    heads=4,
    concat=True,
    dropout=0.6,
    norm="layer_norm",
)

# Incompatible parameters are automatically filtered:
encoder = create_tuned_gnn(
    "gcn",
    in_channels=1433,
    hidden_channels=256,
    num_layers=3,
    heads=4,  # ignored for GCN, with a warning
)

Tuned GNN Models

The TunedGNN family provides enhanced versions of standard GNN architectures with hyperparameters tuned for optimal node-level performance. Key improvements over vanilla PyG implementations include:

  • Residual connections — especially beneficial for heterophilous graphs and deeper networks.

  • Pre-linear transformation — optional linear layer before the first GNN layer.

  • Flexible normalization — supports "batch_norm" (recommended for large graphs) and "layer_norm" (for smaller graphs).

  • Optimized dropout — applied at configurable positions in the network.

  • Jumping Knowledge — optional aggregation across layers ("last", "cat", "max", "lstm").

TunedGNN

An enhanced GNN model with tuned hyperparameters based on "Classic GNNs are Strong Baselines: Reassessing GNNs for Node Classification" paper (Luo et al., NeurIPS 2024).

TunedGCN

Tuned Graph Convolutional Network based on "Classic GNNs are Strong Baselines: Reassessing GNNs for Node Classification" paper (Luo et al., NeurIPS 2024).

TunedGraphSAGE

Tuned GraphSAGE Network based on "Classic GNNs are Strong Baselines: Reassessing GNNs for Node Classification" paper (Luo et al., NeurIPS 2024).

TunedGAT

Tuned Graph Attention Network based on "Classic GNNs are Strong Baselines: Reassessing GNNs for Node Classification" paper (Luo et al., NeurIPS 2024).

TunedGIN

Tuned Graph Isomorphism Network based on "Classic GNNs are Strong Baselines: Reassessing GNNs for Node Classification" paper (Luo et al., NeurIPS 2024).

TunedPNA

Tuned Principal Neighbourhood Aggregation Network based on "Classic GNNs are Strong Baselines: Reassessing GNNs for Node Classification" paper (Luo et al., NeurIPS 2024).

TunedEdgeCNN

Tuned EdgeCNN (Dynamic Graph CNN) based on "Classic GNNs are Strong Baselines: Reassessing GNNs for Node Classification" paper (Luo et al., NeurIPS 2024).

Factory Function

The create_tuned_gnn() factory function provides a convenient way to instantiate any tuned GNN model by name. It automatically inspects the target model’s signature and filters out incompatible parameters, so you can safely pass all hyperparameters without worrying about compatibility across different GNN types.

create_tuned_gnn

Factory function to create tuned GNN models with recommended defaults.

create_tuned_gnn(gnn_type: str, in_channels: int, hidden_channels: int, num_layers: int, out_channels: Optional[int] = None, dropout: float = 0.0, act: Optional[Union[str, Callable]] = 'relu', act_first: bool = False, act_last: bool = False, act_kwargs: Optional[Dict[str, Any]] = None, norm: Optional[Union[str, Callable]] = None, norm_kwargs: Optional[Dict[str, Any]] = None, residual: bool = False, pre_linear: bool = False, jk: Optional[str] = None, **kwargs) TunedGNN[source]

Factory function to create tuned GNN models with recommended defaults.

This function provides an easy way to create tuned GNN models with hyperparameters optimized based on empirical findings from the “Classic GNNs are Strong Baselines: Reassessing GNNs for Node Classification” paper (Luo et al., NeurIPS 2024).

The function automatically filters out incompatible parameters for each GNN type by inspecting the model’s signature, so you can safely pass all parameters without worrying about compatibility.

Parameters:
  • gnn_type (str) – Type of GNN. Options: "gcn", "sage", "gat", "gatv2", "gin", "pna", "edgecnn".

  • in_channels (int) – Size of each input sample.

  • hidden_channels (int) – Size of each hidden sample.

  • num_layers (int) – Number of message passing layers. Recommendation: 2-6 for homophilous graphs, 6-15 for heterophilous.

  • out_channels (int, optional) – Output size. If not set, will use hidden_channels. (default: None)

  • dropout (float, optional) – Dropout probability. Paper findings suggest 0.2-0.7 range works well. (default: 0.0)

  • act (str or Callable, optional) – The non-linear activation function to use. (default: "relu")

  • act_first (bool, optional) – If set to True, activation is applied before normalization. (default: False)

  • act_last (bool, optional) – If set to True, applies activation function to the final output. Useful for tasks requiring non-linear final representations. (default: False)

  • act_kwargs (Dict[str, Any], optional) – Arguments passed to the respective activation function defined by act. (default: None)

  • norm (str or Callable, optional) – Normalization type. Options: "batch_norm", "layer_norm". Paper recommends BatchNorm for large graphs, LayerNorm for smaller graphs. (default: None)

  • norm_kwargs (Dict[str, Any], optional) – Arguments passed to the respective normalization function defined by norm. (default: None)

  • residual (bool, optional) – If set to True, applies residual connections. Especially beneficial for heterophilous graphs and deeper networks. (default: False)

  • pre_linear (bool, optional) – If set to True, applies a linear transformation before the first GNN layer. (default: False)

  • jk (str, optional) – Jumping Knowledge mode. Options: None, "last", "cat", "max", "lstm". Paper shows this is optional but can help in some cases. (default: None)

  • **kwargs

    Additional GNN-specific arguments. These will be automatically filtered based on the GNN type. Common options include:

    • heads (int): Number of attention heads (GAT/GATv2 only)

    • concat (bool): Concatenate attention heads (GAT/GATv2 only)

    • v2 (bool): Use GATv2 variant (GAT only, auto-set for gatv2)

    • add_self_loops (bool): Add self-loops to adjacency matrix

    • normalize (bool): Apply normalization (GCN only)

    • improved (bool): Use improved GCN formulation (GCN only)

    • cached (bool): Cache normalized edge weights (GCN only)

    • bias (bool): Add bias parameters

    • aggr (str): Aggregation scheme (e.g., “mean”, “max”, “add”)

    • aggregators (List[str]): Aggregation functions (PNA only)

    • scalers (List[str]): Scaling functions (PNA only)

    • deg (Tensor): Degree histogram for normalization (PNA only)

    • edge_dim (int): Edge feature dimensionality (GAT/GATv2/EdgeCNN)

    • fill_value (float or str): Value for self-loops

Returns:

The initialized tuned GNN model.

Return type:

TunedGNN

Examples

>>> # Create a tuned GCN for homophilous graphs
>>> model = create_tuned_gnn(
...     'gcn', in_channels=128, hidden_channels=256,
...     num_layers=3, out_channels=10, dropout=0.5,
...     norm='batch_norm'
... )
>>> # Create a tuned GCN for heterophilous graphs (deeper + residual)
>>> model = create_tuned_gnn(
...     'gcn', in_channels=128, hidden_channels=256,
...     num_layers=10, out_channels=10, dropout=0.5,
...     norm='batch_norm', residual=True, pre_linear=True
... )
>>> # Create a tuned GAT with multiple attention heads
>>> model = create_tuned_gnn(
...     'gat', in_channels=128, hidden_channels=256,
...     num_layers=3, out_channels=10, heads=4, concat=True,
...     dropout=0.6, norm='layer_norm'
... )
>>> # Create a tuned model with custom activation
>>> model = create_tuned_gnn(
...     'sage', in_channels=128, hidden_channels=256,
...     num_layers=3, act='elu', act_first=True,
...     norm='batch_norm', residual=True
... )
>>> # Create a model with Jumping Knowledge
>>> model = create_tuned_gnn(
...     'gcn', in_channels=128, hidden_channels=256,
...     num_layers=4, out_channels=10, jk='cat',
...     norm='layer_norm'
... )
>>> # Pass all parameters - incompatible ones are automatically filtered
>>> model = create_tuned_gnn(
...     'gcn', in_channels=128, hidden_channels=256,
...     num_layers=3, heads=4  # 'heads' will be ignored for GCN
... )

Tabular & Tabular-Graph Encoders

To better support heterogeneous node attributes, we introduce encoders based on PyTorch Frame, enabling structured tabular data processing within graph learning pipelines.

These encoders are especially useful when node features are not simple dense tensors, but structured rows with mixed feature types.

TabularEncoder

Encodes a single torch_frame.TensorFrame into dense embeddings:

\[\mathbf{H} = \mathcal{E}_{tab}(\mathbf{T})\]

This module leverages TorchFrame models (e.g., ResNet-style encoders) to process column-wise heterogeneous features.

TabularGraphEncoder

A two-stage encoder for tabular graphs:

\[\mathbf{Z} = \mathcal{E}_{graph}(\mathcal{E}_{tab}(\mathbf{T}), \mathbf{A})\]

It first encodes tabular node attributes, then applies a graph encoder (e.g., GCN, GAT) to incorporate structural information.

from pyagc.encoders import TabularEncoder, TabularGraphEncoder, GCN

tab_encoder = TabularEncoder(...)
gnn = GCN(in_channels=128, hidden_channels=256, num_layers=2)

encoder = TabularGraphEncoder(
    tabular_encoder=tab_encoder,
    graph_encoder=gnn,
)

TabularEncoder

Tabular encoder using PyTorch Frame.

TabularGraphEncoder

A two-stage encoder for Tabular Graphs:

PyG Backbone Re-exports

For convenience, pyagc.encoders also re-exports the following standard GNN models from PyTorch Geometric. These can be used as drop-in encoder backbones within the ECO framework:

from pyagc.encoders import GCN, GraphSAGE, GAT, GIN

# Use a standard PyG GCN as encoder:
encoder = GCN(
    in_channels=1433,
    hidden_channels=256,
    num_layers=2,
    out_channels=128,
)

Standard GNNs:

GCN

The Graph Neural Network from the "Semi-supervised Classification with Graph Convolutional Networks" paper, using the GCNConv operator for message passing.

GraphSAGE

The Graph Neural Network from the "Inductive Representation Learning on Large Graphs" paper, using the SAGEConv operator for message passing.

GAT

The Graph Neural Network from "Graph Attention Networks" or "How Attentive are Graph Attention Networks?" papers, using the GATConv or GATv2Conv operator for message passing, respectively.

GIN

The Graph Neural Network from the "How Powerful are Graph Neural Networks?" paper, using the GINConv operator for message passing.

PNA

The Graph Neural Network from the "Principal Neighbourhood Aggregation for Graph Nets" paper, using the PNAConv operator for message passing.

EdgeCNN

The Graph Neural Network from the "Dynamic Graph CNN for Learning on Point Clouds" paper, using the EdgeConv operator for message passing.

Note

These classes are imported directly from torch_geometric.nn.models. See the PyG documentation for full API details.

Graph Transformers

In addition to standard message-passing GNNs, pyagc.encoders provides graph transformer architectures implemented within this library, designed for capturing long-range dependencies and global structural patterns.

These models follow transformer-style designs adapted to graph domains, and are particularly effective for graphs where locality assumptions of GNNs break down.

SGFormer

The sgformer module from the "SGFormer: Simplifying and Empowering Transformers for Large-Graph Representations" paper.

Polynormer

The polynormer module from the "Polynormer: polynomial-expressive graph transformer in linear time" paper.