GCN layer (message passing)Medium

GCN layer (message passing)

Background

A Graph Convolutional Network (GCN) layer updates each node's features by mixing in its neighbors'. Kipf & Welling's formulation uses the symmetrically normalized adjacency with self-loops: A^=D~1/2A~D~1/2\hat A = \tilde D^{-1/2}\tilde A\,\tilde D^{-1/2} where A~=A+I\tilde A = A + I. One layer is then H=σ(A^HW)H' = \sigma(\hat A H W) — propagate (aggregate neighbors), transform (linear), activate.

Problem statement

Implement gcn_layer(A, H, W) for one GCN propagation step (no activation):

A~=A+I,D~ii=jA~ij,A^=D~1/2A~D~1/2,H=A^HW\tilde A = A + I, \quad \tilde D_{ii} = \sum_j \tilde A_{ij}, \quad \hat A = \tilde D^{-1/2}\tilde A\,\tilde D^{-1/2}, \quad H' = \hat A H W

Input

  • A — adjacency matrix (n, n) (0/1, symmetric, no self-loops).
  • H — node features (n, f_in).
  • W — weight matrix (f_in, f_out).

Output

An np.ndarray (n, f_out): the propagated, transformed node features.

Examples

Example 1

Input:  A = [[0,1],[1,0]] (two connected nodes), H = [[1],[3]], W = [[1]]
Output: [[2.0], [2.0]]

Explanation: with self-loops each node has degree 2, so A^=[[0.5,0.5],[0.5,0.5]]\hat A = [[0.5,0.5],[0.5,0.5]]. Each node's new feature is the average of both, (1+3)/2=2(1+3)/2 = 2, then multiplied by W=1W=1.

Constraints

  • Add self-loops (A~=A+I\tilde A = A + I) before normalizing.
  • Use symmetric normalization D~1/2A~D~1/2\tilde D^{-1/2}\tilde A\,\tilde D^{-1/2}, not row normalization.
  • Apply the linear transform W after propagation (no activation here).

Notes

  • Self-loops ensure a node keeps its own features; without them a node would see only its neighbors.
  • Symmetric normalization keeps the scale of features stable across nodes of very different degree, avoiding exploding/vanishing signals in deep GCNs.
Python
Loading...

This problem ships 5 hidden tests. They run in your browser via Pyodide — no backend, no submission queue. Press ▶ Run tests to execute.

  • Reference: two connected nodes average their features
  • Isolated node keeps its own (self-loop normalized) feature
  • Normalized adjacency rows/cols are symmetric and degree-aware
  • Output shape is (n, f_out)
  • W = identity reduces to pure neighbor aggregation