Paper · 2021-10-15 · cs.LG
Graph Neural Networks with Learnable Structural and Positional Representations
Adds a separate, learnable positional vector to each node of message-passing and Transformer GNNs (LSPE). Positions start from random-walk return probabilities (RWPE) and are updated at every layer; an optional Laplacian loss regularises them. Author-reported: GatedGCN-LSPE reaches test MAE 0.090 on ZINC versus 0.251 without positional encoding.
Graph neural networkPositional encodingGraph transformerMolecular representation learninggraph-neural-networkspositional-encodinggraph-transformersmolecular-property-prediction
arXivPDFCodeMarkdown19 min read
AI-compiled by claude-haiku-5-5 on 2026-10-19, not yet reviewed by a human. Every claim cites its source; check it when a detail matters.
In plain words
Graph neural networks (GNNs) learn from data shaped like networks, such as molecules, where atoms are nodes and bonds are edges. Most of them update each node by looking only at its neighbours. Two atoms with the same neighbourhood then look identical to the network, even when they sit in different places in the molecule. A common fix is to give every node a position-like tag. Fixed tags have known limits, so this paper gives each node a small vector of position values that the network learns alongside its normal features and refines at every layer. The starting values come from a simple random-walk calculation. The authors show that this helps several different GNN designs, and the largest gains are on molecular benchmarks.
TL;DR
- Adds a learnable positional vector per node, kept separate from the structural features and updated in every layer (LSPE).
- Initial positions are random-walk return probabilities (RWPE) or Laplacian eigenvectors (LapPE); RWPE has no sign ambiguity.
- Applied to two sparse GNNs (GatedGCN, PNA) and two fully connected Transformer GNNs (SAN, GraphiT).
- Author-reported: GatedGCN-LSPE test MAE 0.090 on ZINC against 0.251 without positional encoding tab. 1. On the two OGB datasets the authors report results comparable to SOTA, not clear wins §4.2 tab. 2.
- Code is public (MIT). The Laplacian-loss term is implemented with a detached tensor, so it does not train as written in the paper (Paper vs code).
Problem
- Message-passing GNNs (MP-GNNs) build node states from local neighbourhoods. They cannot tell apart two nodes with the same 1-hop structure, and their expressivity is bounded by the 1-WL test §1 §2.
- Stacking layers can spread information over more hops, but suffers from over-squashing for distant nodes §1.
- Higher-order WL-style GNNs are more expensive; they are not linear in the number of nodes §1 §2.
- Existing positional encodings have limits: index encodings need permutation training; Laplacian eigenvectors have sign ambiguity (2^k sign patterns for k vectors) and can be unstable under eigenvalue multiplicities; anchor-set embeddings do not generalise inductively §2.
- Existing MP-GNN-PE models concatenate a fixed PE to the input features only, so the positional representation cannot adapt during training §3.1.
- Fully connected Transformer GNNs use non-learnable PEs, or learned PEs built on Laplacian eigenvectors and therefore inherit the sign ambiguity §2.
Method
The paper keeps two streams per node: structural features h and positional
features p. Both are updated at every layer. The structural update reads
the concatenation [h; p]; the positional update is its own message-passing
function §3.1 eq. 7 eq. 8 eq. 9. Positional features are not used as
fixed inputs.
- Standard MP-GNN layer. Node and edge updates are functions of neighbours and edge features §3.1 eq. 1 eq. 2. Transformers are a special case of MP-GNNs with fully connected graphs and no edge features §3.1.
- Baseline MP-GNN-PE. The PE is concatenated with the input node features and passed through one linear map; the layers do not update it §3.1 eq. 3 eq. 4 eq. 5 eq. 6.
- LSPE layer. Each layer updates
h,eandp§3.1 eq. 7 eq. 8 eq. 9. Thepupdate usestanhso that coordinates can be positive or negative §3.1. - Input projection. The initial PE
p_i^PE(length k) is mapped to the model width d by a learnable linear layer §3.1 eq. 11. - Initial PE. Two choices §3.1:
- LapPE: the eigenvectors
U_i1 .. U_ikof the Laplacian §3.1. Sign ambiguity needs random sign flips during training §3.1. - RWPE: the return probabilities
RW_ii, RW_ii^2, ..., RW_ii^kwithRW = A D^-1§3.1 eq. 10. Only the diagonal of each power is kept, unlike Distance Encoding, which uses pairwise return probabilities §4.3 app. A.1. RWPE is precomputed before training app. A.
- LapPE: the eigenvectors
- Positional loss (optional). A Laplacian-eigenvector term on the final
positional features
p^L§3.1 eq. 12. The finalp^Lis required to be centred and of unit norm per column §3.1. The Laplacian isΔ = I - D^-1/2 A D^-1/2app. B.2. - Readout. The final positional features are concatenated with the
structural features before pooling; Table 3 reports this as
[h^L, p^L]§4.3 tab. 3.
GatedGCN-LSPE (the instance with the best reported numbers)
The authors write the gated convolution with the concatenated stream as
§3.2 eq. 13 eq. 14 eq. 15 eq. 16. The gate for edge (i, j) is a
sigmoid of a linear function of both endpoints and the edge, normalised over
the incoming edges of i §3.2.
# GatedGCN-LSPE layer [§3.2] [eq. 13-16]
# Input: h (n, d), p (n, d), e (E, d); src[E], dst[E] are edge endpoints
# Output: h, p, e for the next layer
def gatedgcn_lspe_layer(h, p, e, src, dst):
# Gate logit per edge: B1 h_i + B2 h_j + B3 e_ij [§3.2]
gate_logit = B1(h)[dst] + B2(h)[src] + B3(e) # (E, d)
# Sigmoid gate, normalised over the incoming edges of each node [§3.2]
# eps is not stated in the paper
# Code uses 1e-6 [code: layers/gatedgcn_lspe_layer.py#L51]
gate = sigmoid(gate_logit)
gate = gate / (sum_over_dst(gate) + eps) # (E, d)
# Structural update: A1 [h; p] plus gated sum of A2 [h_j; p_j] [eq. 14]
hp = concat(h, p) # (n, 2d)
h_new = A1(hp) + sum_over_dst(gate * A2(hp)[src])
# Code only: scale by graph-size normaliser before BN
# [code: layers/gatedgcn_lspe_layer.py#L104]
h_new = h_new * node_norm
# Edge update: residual + ReLU(BN(gate logit)) [eq. 15]
e_new = e + relu(batch_norm(gate_logit))
# Positional update: C1 p_i plus gated sum of C2 p_j [eq. 16]
# tanh and residual follow in the next lines
p_new = C1(p) + sum_over_dst(gate * C2(p)[src])
p_out = p + tanh(p_new) # no BatchNorm on p [§3.2]
h_out = h + relu(batch_norm(h_new)) # residual [eq. 14]
return h_out, p_out, e_newPositional head (RWPE only in the code)
The code applies the following to the final positional features only when the initial PE is RWPE gatedgcn_net.py.
# Final positional features before readout [§3.1]
# [code: nets/ZINC_graph_regression/gatedgcn_net.py#L67-L115]
# Input: h (n, d), p (n, d), graph ids per node
# Output: node features (n, d) for pooling
def positional_head(h, p, graph_ids):
# Linear map from model width to k [code: gatedgcn_net.py#L67]
p = linear_p_out(p) # (n, k)
# Centre each column within each graph
# [§3.1] [code: gatedgcn_net.py#L98-L103]
p = p - mean_per_graph(p, graph_ids)
# Scale each column of each graph to unit L2 norm
# [§3.1] [code: gatedgcn_net.py#L105-L111]
p = p / norm_per_graph(p, graph_ids)
# Fuse structure and position with a linear map
# [code: gatedgcn_net.py#L115]
return linear_Whp(concat(h, p)) # (n, d)Initial PEs
# Random-walk PE (RWPE), precomputed once per graph [§3.1] [eq. 10]
# Input: adjacency (n, n), degrees (n,), k steps
# Output: pe (n, k)
def rwpe(adjacency, degrees, k):
# Random-walk operator RW = A D^-1; degrees clipped to at least 1
# [code: data/molecules.py#L182-L184]
walk = adjacency @ diag(1 / max(degrees, 1)) # (n, n)
# Return probability of each node to itself after 1 .. k steps [eq. 10]
power = walk
columns = [diagonal(power)]
for _ in range(k - 1):
power = power @ walk
columns.append(diagonal(power))
return stack(columns, axis=1) # (n, k)# Laplacian-eigenvector PE (LapPE) [§3.1]
# [code: data/molecules.py#L153-L162]
# Input: adjacency (n, n), degrees (n,), k
# Output: pe (n, k)
def lap_pe(adjacency, degrees, k):
# Symmetric normalised Laplacian [app. B.2]
d_half = diag(1 / sqrt(max(degrees, 1)))
laplacian = identity(n) - d_half @ adjacency @ d_half
# Eigenvectors sorted by ascending eigenvalue
values, vectors = eig(laplacian)
# The code drops the first (trivial) eigenvector; the paper does not say so
return vectors[:, 1 : k + 1] # (n, k)# Training-time sign flip for LapPE only [§3.1]
# [code: train/train_ZINC_graph_regression.py#L35-L37]
# Input: pe (n_total, k)
def flip_signs(pe):
# One random sign per column, shared by every node in the batch
signs = where(uniform(k) >= 0.5, 1.0, -1.0) # (k,)
return pe * signsLaplacian-eigenvector loss (optional)
The paper defines the total loss as a task loss plus alpha times a
Laplacian term over the final positional features §3.1 eq. 12. The
Laplacian term has a trace (smoothness) part and a Frobenius orthogonality
part with weight lambda §3.1.
\mathcal{L} = \mathcal{L}_{\text{task}}\big(h^L, p^L\big) + \alpha\,\mathcal{L}_{\text{LapEig}}\big(p^L\big) \qquad \text{[eq. 12]}
\mathcal{L}_{\text{LapEig}}(p) = \frac{1}{k}\operatorname{tr}\big(p^\top \Delta p\big) + \frac{\lambda}{k}\,\big\|p^\top p - I_k\big\|_F^2 \qquad \text{[§3.1]}
The code computes the same two terms with a different normalisation, and the orthogonality term is detached. See Paper vs code.
SAN-LSPE and GraphiT-LSPE (Transformer GNNs)
- SAN-LSPE. The attention over all node pairs is split into existing and
non-existing edges, weighted by a balance scalar
gammaapp. C.2.1. The authors makegammalearnable and clip it to [0, 1] app. C.2.1. The positional stream has its own query, key and value projections and atanhupdate app. C.2.1. The code clipsgammato [0, 1] in the attention layer san_gt_lspe_layer.py. - GraphiT-LSPE. Attention weights are multiplied by a diffusion kernel
K = (I - beta Δ)^p, with separate parameters for edges and non-edges app. C.2.2. The authors givebetain [0.25, 0.50] app. C.2.2. The ZINC config usesbeta = 0.25andp = 16GraphiT_ZINC_LSPE.json molecules.py. - PNA-LSPE applies the same two-stream update with PNA's principal aggregators app. C.1.2. Its layer code was not compared line by line (see Paper vs code).
Hyperparameters
| Name | Value | Where | Notes |
|---|---|---|---|
| Layers L | ZINC: GatedGCN and PNA 16, SAN and GraphiT 10. MOLTOX21: 8 (GatedGCN, PNA), 10 (SAN, GraphiT). MOLPCBA: 8 (GatedGCN), 4 (PNA) | tab. 1 | Full list in Table 1 below |
| Positional dimension k (= RWPE steps) | ZINC: GatedGCN 20, PNA 16, SAN 16, GraphiT 16 | tab. 5 app. E | Text: k = 20 for ZINC GatedGCN and k = 16 for MOLTOX21 PNA §4.3 |
| LapPE k | ZINC: GatedGCN 8; MOLTOX21 and MOLPCBA GatedGCN 3 | tab. 5 | Baseline LapPE rows |
| alpha, lambda (PosLoss) | GatedGCN ZINC: alpha 1, lambda 0.1; PNA MOLTOX21: alpha 0.1, lambda 100 | tab. 5 | PosLoss only in these two rows |
| Positional-loss weight in code | ZINC GatedGCN config: alpha 1, lambda 0.1 | GatedGCN_ZINC_LSPE_withLapEigLoss.json | Same values as tab. 5 |
| Learning rate (init) | 1e-3 (GatedGCN, PNA ZINC); 3e-4 or 7e-4 (SAN, GraphiT); 5e-4 (PNA MOLTOX21, MOLPCBA) | tab. 5 | Exact value per row in tab. 5 |
| LR schedule | reduce on plateau; factor 0.5 (0.8 for PNA on MOLTOX21 and MOLPCBA); patience 25 (10 or 4 for PNA) | tab. 5 | Min LR 1e-6 (ZINC), 1e-5 or 2e-5 (MOLTOX21), 1e-4 or 2e-5 (MOLPCBA) |
| GraphiT beta, p | beta 0.25, p 16 | tab. 5 | "beta" is named gamma in the code GraphiT_ZINC_LSPE.json |
| Optimiser | Adam; ReduceLROnPlateau, mode min | not stated in paper | main_ZINC_graph_regression.py |
| Weight decay | 0.0 | not stated in paper | GatedGCN_ZINC_LSPE_withLapEigLoss.json |
| Dropout | 0.0 (input and hidden) | not stated in paper | GatedGCN_ZINC_LSPE_withLapEigLoss.json |
| Batch size | ZINC 128; MOLTOX21 256 | not stated in paper | GatedGCN_ZINC_LSPE_withLapEigLoss.json GatedGCN_MOLTOX21_LSPE.json |
| Hidden width | ZINC GatedGCN 59; MOLTOX21 GatedGCN 118 | not stated in paper | GatedGCN_ZINC_LSPE_withLapEigLoss.json GatedGCN_MOLTOX21_LSPE.json |
| Max epochs | 1000 (config); max_time 12 | not stated in paper | GatedGCN_ZINC_LSPE_withLapEigLoss.json GatedGCN_ZINC_LSPE_withLapEigLoss.json |
| Seeds | 4 seeds per result | tab. 1 caption | Code default seed 41 GatedGCN_ZINC_LSPE_withLapEigLoss.json |
| Gate normalisation epsilon | not stated in paper | §3.2 | Code: 1e-6 gatedgcn_lspe_layer.py |
| Framework | PyTorch and DGL | §4.1 | |
| Hardware | Intel Xeon E5-2690 v4, 4 × GTX 1080 Ti | app. E | |
| Dataset sizes | ZINC 12K subset; MOLTOX21 7,831 graphs; MOLPCBA 437,929 graphs | §4.1 | ZINC split from benchmarking GNNs; OGB scaffold splits |
Results
Author-reported. Setup: ZINC (12K subset, MAE, lower is better, about 500k parameters); OGBG-MOLTOX21 (ROC-AUC, higher is better); OGBG-MOLPCBA (AP, higher is better); all scores are means over 4 seeds §4.1 tab. 1. Parameter counts for OGB models are larger, following OGB leaderboard practice §4.1.
Headline numbers:
- GatedGCN-LSPE with PosLoss: test MAE 0.090 ± 0.001 on ZINC, against 0.251 ± 0.009 without PE. The paper reports a 64.14% gain §4.2 tab. 1.
- PNA-LSPE: test MAE 0.095 ± 0.002 on ZINC, against 0.141 ± 0.004 for PNA; a 32.62% gain §4.2 tab. 1.
- Against SOTA on ZINC (MAE 0.139 for SAN, 0.122 for Graphormer), GatedGCN-LSPE improves by 35.25% and 26.23% §4.2 tab. 2.
- On MOLTOX21, GatedGCN-LSPE reaches test ROC-AUC 0.7754 against 0.7757 for GIN-VN, i.e. comparable §4.2 tab. 2.
- On MOLPCBA, PNA-LSPE reaches AP 0.2840 against 0.2838 for PNA and 0.2947 for PHC-GNN §4.2 tab. 2.
- Non-molecular graphs (GatedGCN): accuracy rises on IMDB-B, IMDB-M and CIFAR10 app. D tab. 4. The IMDB gains are smaller than the standard deviations tab. 4.
Table 1: All instances (ZINC, OGBG-MOLTOX21, OGBG-MOLPCBA) tab. 1
Timing columns (Epoch/Total time) are dropped here because they depend on hardware. The paper bolds the best results; those marks are omitted here.
ZINC (test MAE, lower is better)
| Model | Init PE | LSPE | PosLoss | L | #Param | Test MAE ± s.d. | Train MAE ± s.d. | Epochs |
|---|---|---|---|---|---|---|---|---|
| GatedGCN | x | x | x | 16 | 504309 | 0.251 ± 0.009 | 0.025 ± 0.005 | 440.25 |
| GatedGCN | LapPE | x | x | 16 | 505011 | 0.202 ± 0.006 | 0.033 ± 0.003 | 426.00 |
| GatedGCN | RWPE | ✓ | x | 16 | 522870 | 0.093 ± 0.003 | 0.014 ± 0.003 | 440.75 |
| GatedGCN | RWPE | ✓ | ✓ | 16 | 522870 | 0.090 ± 0.001 | 0.013 ± 0.004 | 460.50 |
| PNA | x | x | x | 16 | 369235 | 0.141 ± 0.004 | 0.020 ± 0.003 | 451.25 |
| PNA | RWPE | ✓ | x | 16 | 503061 | 0.095 ± 0.002 | 0.022 ± 0.002 | 462.25 |
| SAN | x | x | x | 10 | 501314 | 0.181 ± 0.004 | 0.017 ± 0.004 | 433.50 |
| SAN | RWPE | ✓ | x | 10 | 588066 | 0.104 ± 0.004 | 0.016 ± 0.002 | 462.50 |
| GraphiT | x | x | x | 10 | 501313 | 0.181 ± 0.006 | 0.021 ± 0.003 | 493.25 |
| GraphiT | RWPE | ✓ | x | 10 | 588065 | 0.106 ± 0.002 | 0.028 ± 0.002 | 420.50 |
OGBG-MOLTOX21 (test ROC-AUC, higher is better)
| Model | Init PE | LSPE | PosLoss | L | #Param | Test AUC ± s.d. | Train AUC ± s.d. | Epochs |
|---|---|---|---|---|---|---|---|---|
| GatedGCN | x | x | x | 8 | 1003739 | 0.772 ± 0.006 | 0.933 ± 0.010 | 304.25 |
| GatedGCN | LapPE | x | x | 8 | 1004355 | 0.774 ± 0.007 | 0.921 ± 0.006 | 275.50 |
| GatedGCN | RWPE | ✓ | x | 8 | 1063821 | 0.775 ± 0.003 | 0.906 ± 0.003 | 246.50 |
| PNA | x | x | x | 8 | 5244849 | 0.755 ± 0.008 | 0.876 ± 0.014 | 214.75 |
| PNA | RWPE | ✓ | x | 8 | 5357393 | 0.761 ± 0.007 | 0.871 ± 0.009 | 215.50 |
| PNA | RWPE | ✓ | ✓ | 8 | 5357393 | 0.758 ± 0.003 | 0.875 ± 0.012 | 194.25 |
| SAN | x | x | x | 10 | 957871 | 0.744 ± 0.007 | 0.915 ± 0.015 | 279.75 |
| SAN | RWPE | ✓ | x | 10 | 1051017 | 0.744 ± 0.008 | 0.918 ± 0.018 | 281.75 |
| GraphiT | x | x | x | 10 | 957870 | 0.743 ± 0.003 | 0.919 ± 0.023 | 276.50 |
| GraphiT | RWPE | ✓ | x | 10 | 1051788 | 0.746 ± 0.010 | 0.934 ± 0.016 | 279.75 |
OGBG-MOLPCBA (test AP, higher is better)
| Model | Init PE | LSPE | PosLoss | L | #Param | Test AP ± s.d. | Train AP ± s.d. | Epochs |
|---|---|---|---|---|---|---|---|---|
| GatedGCN | x | x | x | 8 | 1008263 | 0.262 ± 0.001 | 0.401 ± 0.057 | 190.50 |
| GatedGCN | LapPE | x | x | 8 | 1008879 | 0.266 ± 0.002 | 0.391 ± 0.003 | 177.00 |
| GatedGCN | RWPE | ✓ | x | 8 | 1068721 | 0.267 ± 0.002 | 0.403 ± 0.006 | 181.00 |
| PNA | x | x | x | 4 | 6550839 | 0.279 ± 0.003 | 0.448 ± 0.004 | 129.25 |
| PNA | RWPE | ✓ | x | 4 | 6521029 | 0.284 ± 0.002 | 0.383 ± 0.005 | 320.00 |
Table 2: Comparison with baselines and SOTA (best LSPE per dataset) tab. 2
ZINC: models with about 500k parameters. OGBG-MOLTOX21 and OGBG-MOLPCBA baselines are taken from the OGB leaderboards, and their parameter counts differ tab. 2 caption.
| ZINC model | Test MAE |
|---|---|
| GCN | 0.367 ± 0.011 |
| GAT | 0.384 ± 0.007 |
| GatedGCN-LapPE | 0.202 ± 0.006 |
| GT | 0.226 ± 0.014 |
| SAN | 0.139 ± 0.006 |
| Graphormer | 0.122 ± 0.006 |
| GatedGCN-LSPE | 0.090 ± 0.001 |
| MOLTOX21 model | Test ROC-AUC |
|---|---|
| GCN | 0.7529 ± 0.0069 |
| GCN-VN | 0.7746 ± 0.0086 |
| GIN | 0.7491 ± 0.0051 |
| GIN-VN | 0.7757 ± 0.0062 |
| GatedGCN-LapPE | 0.7743 ± 0.0073 |
| GatedGCN-LSPE | 0.7754 ± 0.0032 |
| MOLPCBA model | Test AP |
|---|---|
| GIN | 0.2266 ± 0.0028 |
| GIN-VN | 0.2703 ± 0.0023 |
| DeeperGCN-VN | 0.2781 ± 0.0038 |
| PNA | 0.2838 ± 0.0035 |
| DGN | 0.2885 ± 0.0030 |
| PHC-GNN | 0.2947 ± 0.0026 |
| PNA-LSPE | 0.2840 ± 0.0021 |
The paper excludes Graphormer's MOLPCBA score, which uses 3.8M pre-training graphs, from this comparison §4.2.
Table 3: Ablation on ZINC with GatedGCN tab. 3
| Input PE | Positional updates | Readout | Layers | Parameters | Test MAE ± s.d. | Train MAE ± s.d. | Epochs |
|---|---|---|---|---|---|---|---|
| x | x | h^L | 16 | 504309 | 0.251 ± 0.009 | 0.025 ± 0.005 | 440.25 |
| LapPE | x | h^L | 16 | 505011 | 0.202 ± 0.006 | 0.033 ± 0.003 | 426.00 |
| RWPE | x | h^L | 16 | 505947 | 0.122 ± 0.003 | 0.013 ± 0.003 | 436.25 |
| x | x | [h^L, RWPE] | 16 | 515249 | 0.249 ± 0.012 | 0.024 ± 0.002 | 437.50 |
| LapPE | ✓ | h^L | 16 | 516722 | 0.202 ± 0.008 | 0.032 ± 0.005 | 405.25 |
| LapPE | ✓ | [h^L, p^L] | 16 | 520734 | 0.196 ± 0.008 | 0.023 ± 0.004 | 454.00 |
| RWPE | ✓ | h^L | 16 | 518150 | 0.100 ± 0.006 | 0.018 ± 0.012 | 395.00 |
| RWPE | ✓ | [h^L, p^L] | 16 | 522870 | 0.093 ± 0.003 | 0.014 ± 0.003 | 440.75 |
The paper's text says that injecting RWPE at the final layer instead of the input performs poorly §4.3. No row in Table 3 tests that injection alone; the closest row, concatenating RWPE at the output without LSPE, gives 0.249 tab. 3.
Table 4: Non-molecular graphs (GatedGCN, accuracy) tab. 4
Baseline CIFAR10 values are taken from the benchmarking paper (†) tab. 4 caption. IMDB uses 10-fold cross-validation per seed tab. 4 caption.
| Dataset | Init PE | LSPE | L | #Param | Test Acc ± s.d. | Train Acc ± s.d. | Epochs |
|---|---|---|---|---|---|---|---|
| IMDB-B | x | x | 4 | 87122 | 66.050 ± 6.631 | 67.769 ± 4.675 | 115.85 |
| IMDB-B | RWPE | ✓ | 4 | 91470 | 70.025 ± 5.147 | 72.166 ± 1.706 | 111.17 |
| IMDB-M | x | x | 4 | 87139 | 45.767 ± 4.906 | 47.725 ± 1.803 | 109.18 |
| IMDB-M | RWPE | ✓ | 4 | 91483 | 46.467 ± 3.997 | 48.781 ± 1.568 | 100.55 |
| CIFAR10 | x | x | 4 | 104357 | 67.312 ± 0.311 | 94.553 ± 1.018 | 97.00 |
| CIFAR10 | RWPE | ✓ | 4 | 107237 | 70.858 ± 0.631 | 78.616 ± 1.006 | 185.00 |
Table 5: Hyperparameters per model tab. 5 app. E
Columns follow the paper. beta and p apply to GraphiT only. alpha and lambda apply with PosLoss only. Dashes mean not applicable.
| Dataset | Model | Init PE | LSPE | PosLoss | k | beta | p | Init lr | Patience | Factor | Min lr | alpha | lambda |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| ZINC | GatedGCN | x | x | x | - | - | - | 1e-3 | 25 | 0.5 | 1e-6 | - | - |
| ZINC | GatedGCN | LapPE | x | x | 8 | - | - | 1e-3 | 25 | 0.5 | 1e-6 | - | - |
| ZINC | GatedGCN | RWPE | ✓ | x | 20 | - | - | 1e-3 | 25 | 0.5 | 1e-6 | - | - |
| ZINC | GatedGCN | RWPE | ✓ | ✓ | 20 | - | - | 1e-3 | 25 | 0.5 | 1e-6 | 1 | 1e-1 |
| ZINC | PNA | x | x | x | - | - | - | 1e-3 | 25 | 0.5 | 1e-6 | - | - |
| ZINC | PNA | RWPE | ✓ | x | 16 | - | - | 1e-3 | 25 | 0.5 | 1e-6 | - | - |
| ZINC | SAN | x | x | x | - | - | - | 3e-4 | 25 | 0.5 | 1e-6 | - | - |
| ZINC | SAN | RWPE | ✓ | x | 16 | - | - | 7e-4 | 25 | 0.5 | 1e-6 | - | - |
| ZINC | GraphiT | x | x | x | - | 0.25 | 16 | 3e-4 | 25 | 0.5 | 1e-6 | - | - |
| ZINC | GraphiT | RWPE | ✓ | x | 16 | 0.25 | 16 | 7e-4 | 25 | 0.5 | 1e-6 | - | - |
| MOLTOX21 | GatedGCN | x | x | x | - | - | - | 1e-3 | 25 | 0.5 | 1e-5 | - | - |
| MOLTOX21 | GatedGCN | LapPE | x | x | 3 | - | - | 1e-3 | 25 | 0.5 | 1e-5 | - | - |
| MOLTOX21 | GatedGCN | RWPE | ✓ | x | 16 | - | - | 1e-3 | 25 | 0.5 | 1e-5 | - | - |
| MOLTOX21 | PNA | x | x | x | - | - | - | 5e-4 | 10 | 0.8 | 2e-5 | - | - |
| MOLTOX21 | PNA | RWPE | ✓ | x | 16 | - | - | 5e-4 | 10 | 0.8 | 2e-5 | - | - |
| MOLTOX21 | PNA | RWPE | ✓ | ✓ | 16 | - | - | 5e-4 | 10 | 0.8 | 2e-5 | 1e-1 | 100 |
| MOLTOX21 | SAN | x | x | x | - | - | - | 7e-4 | 25 | 0.5 | 1e-6 | - | - |
| MOLTOX21 | SAN | RWPE | ✓ | x | 12 | - | - | 7e-4 | 25 | 0.5 | 1e-6 | - | - |
| MOLTOX21 | GraphiT | x | x | x | - | 0.25 | 16 | 7e-4 | 25 | 0.5 | 1e-6 | - | - |
| MOLTOX21 | GraphiT | RWPE | ✓ | x | 16 | 0.25 | 16 | 7e-4 | 25 | 0.5 | 1e-6 | - | - |
| MOLPCBA | GatedGCN | x | x | x | - | - | - | 1e-3 | 25 | 0.5 | 1e-4 | - | - |
| MOLPCBA | GatedGCN | LapPE | x | x | 3 | - | - | 1e-3 | 25 | 0.5 | 1e-4 | - | - |
| MOLPCBA | GatedGCN | RWPE | ✓ | x | 16 | - | - | 1e-3 | 25 | 0.5 | 1e-4 | - | - |
| MOLPCBA | PNA | x | x | x | - | - | - | 5e-4 | 4 | 0.8 | 2e-5 | - | - |
| MOLPCBA | PNA | RWPE | ✓ | x | 16 | - | - | 5e-4 | 10 | 0.8 | 2e-5 | - | - |
Paper vs code
Code: https://github.com/vijaydwivedi75/gnn-lspe at 6b38443677befd4726cc0e5c20e9c88073fbc2ed
(MIT, LICENSE file). The repository is linked from the abstract's footnote.
I checked the ZINC GatedGCN path (model, RWPE, LapPE, loss, configs), the
GraphiT kernel parameters and SAN's gamma clamp. I did not compare the PNA layer, the
SAN and GraphiT layer bodies, or the non-molecular runs line by line.
- Laplacian loss: orthogonality term has no gradient. The code converts
each graph's positional features to NumPy with
.detach()before computing the Frobenius term, then wraps the result in a newtorch.tensor. The term adds a constant to the loss value and does not change the gradient gatedgcn_net.py. The paper's Eq. 12 treats it as a differentiable term §3.1 eq. 12. Of the two Laplacian-loss terms, only the trace term gives gradients. - Laplacian loss: normalisation differs. The paper's
Loss_LapEighas a1/kfactor only §3.1. The code divides the sum byk × B × n, whereBis the number of graphs andnthe number of nodes in the batch gatedgcn_net.py. So the effectivealphadepends on batch size and graph size. The paper does not state this. - Laplacian matrix. The code uses
I - D^-1/2 A D^-1/2gatedgcn_net.py, the same matrix as app. B.2. - Positional head adds layers not in the paper text. The code applies a
linear map
d → ktopbefore centring and normalising gatedgcn_net.py and a linear fusion[h; p] → dbefore pooling gatedgcn_net.py gatedgcn_net.py. Table 3 writes the fusion as concatenation[h^L, p^L]tab. 3. - Centring and normalisation apply to RWPE only. The code runs them only
when
pe_init == 'rand_walk'gatedgcn_net.py. The paper states the constraint forp^Lgenerally §3.1. - LapPE + LSPE is not in the code path. For
pe_init == 'lap_pe'the forward pass adds the LapPE tohand setsp = Nonegatedgcn_net.py. The configs directory has no LapPE + LSPE config. The LapPE + LSPE rows of tab. 3 are therefore not reproducible from the repository as I read it. - Extra h scaling. The code multiplies
hby a graph-size normalisersnorm_nbefore batch norm gatedgcn_lspe_layer.py. The paper does not mention this step. - Gate epsilon. The code uses
1e-6in the gate denominator gatedgcn_lspe_layer.py. The paper writesepsilonwithout a value §3.2. - LapPE drops the trivial eigenvector. The code keeps eigenvectors
1 .. kafter sorting by eigenvalue and drops index 0 molecules.py. The paper does not say this. - Sign flips. The code draws one random sign per column for the whole mini-batch at each training step train_ZINC_graph_regression.py. The paper says only "random sign flipping during training" §3.1.
- GraphiT naming. The code's
gammais GraphiT's diffusion parameterbetaGraphiT_ZINC_LSPE.json. The SAN balance scalar is also calledgammabut is a different quantity SAN_ZINC_LSPE.json. - SAN gamma. The code clamps
gammato [0, 1] in the attention layer san_gt_lspe_layer.py, as app. C.2.1 states. The initial value 0.1 is set in the config SAN_ZINC_LSPE.json and is not stated in the paper.
Pitfalls
- Abstract range is inconsistent with the results. The abstract says the gains range "from 1.79% up to 64.14%". The MOLTOX21 PNA-LSPE gain in the text is 0.79% (0.761 vs 0.755) §4.2 tab. 1. The 1.79% figure is for MOLPCBA §4.2. Do not use 1.79% as the lower bound.
- The Laplacian loss gain does not come from the orthogonality term in the code. The text says the loss moves the best ZINC score from 0.093 to 0.090 §4.2. In the code, the orthogonality part is constant (see Paper vs code). In the code, any gain from the loss can only come from the trace term and the normalisation. An implementer who wants the paper's loss must decide which one to build and say so.
- Positional features are not unique per node. The authors report that most
nodes in ZINC molecules get unique RWPE vectors for
k ≥ 24§3.1. Two example molecules have 100% and 71.43% unique RWPEs §3.1. Appendix A.3 reports that 30 validation graphs with 24 nodes have 21 unique RWPEs, 87.5% of nodes app. A.3. The authors call RWPE uniqueness an approximation app. A.3. - RWPE and symmetry. For strongly regular graphs (for example CSL), all nodes get the same RWPE, but distinct graph classes get distinct values §3.1 app. A.1.
- LapPE sign ambiguity. The paper's explanation is
2^ksign patterns forkeigenvectors §2. The code's sign flip is one sign per column for the whole batch train_ZINC_graph_regression.py. - Parameter counts change across rows. LSPE adds parameters in the layers. For GatedGCN on ZINC, 504309 → 522870 tab. 1. For SAN, 501314 → 588066 tab. 1. The paper targets about 500k parameters on ZINC §4.1.
- OGB baselines are not matched on parameters. Table 2 notes that the OGB baselines have different parameter counts tab. 2 caption. Read the MOLTOX21 and MOLPCBA gains as comparable, not as wins §4.2.
- Non-molecular gains are within noise on IMDB. IMDB-B goes from 66.05 ± 6.63 to 70.03 ± 5.15, and IMDB-M from 45.77 ± 4.91 to 46.47 ± 4.00 tab. 4. Only CIFAR10 has a gap larger than its spread tab. 4.
- Cost of Transformer variants. The sparse GNNs train faster than the Transformer GNNs on the same hardware §4.2; the epoch timings are in tab. 1. Full attention scales quadratically with the number of nodes §2 §4.2.
- RWPE precomputation cost. The paper states that RWPE is precomputed before training app. A. The cost of the
kmatrix products per graph is not stated. The code performs them with sparse matrices once per graph at data load molecules.py.
Lineage
- Builds on: GatedGCN, arXiv:1711.07553 (no card); PNA (Corso et al., NeurIPS 2020; no arXiv id in the source); SAN, arXiv:2106.03893 (no card); GraphiT, arXiv:2106.05667 (no card).
- Related positional encoding: Distance Encoding (Li et al., NeurIPS 2020; no arXiv id in the source). The paper says RWPE is close to it, but uses only the diagonal and larger
kthan the k = 3 or 4 used there app. A.1 §4.3. - Compared against: Graphormer, arXiv:2106.05234; the benchmarking protocol, arXiv:2003.00982 (no card).
- Superseded by: not known from this card.
Source and license
Adapted from “Graph Neural Networks with Learnable Structural and Positional Representations” by Vijay Prakash Dwivedi, Anh Tuan Luu, Thomas Laurent, Yoshua Bengio, Xavier Bresson (arXiv:2110.07875), used under CC BY 4.0. Changes: condensed and restructured for implementation, with tables, equations and algorithms taken from the paper and its code, each cited to its source. Not affiliated with or endorsed by the authors. Code citations refer to https://github.com/vijaydwivedi75/gnn-lspe at commit 6b38443677be (MIT). Any quoted code is shown under that license.