/ AI Models / Graph Neural Networks: Learning from Structured Data
AI Models 5 min read

Graph Neural Networks: Learning from Structured Data

How graph neural networks enable deep learning on connected data structures, from social networks to molecular systems.

Graph Neural Networks: Learning from Structured Data - Complete AI Models guide and tutorial

Traditional neural networks excel at processing Euclidean data—images, text, audio. But much of the world's data exists in non-Euclidean forms: social networks, molecular structures, transportation systems, and knowledge graphs. Graph Neural Networks (GNNs) provide a principled approach to learning from these connected data structures. This article explores GNN architectures, applications, and implementation patterns.

Introduction

Consider these data structures:

  • Social networks: Users connected by friendships, followers, interactions
  • Molecules: Atoms bonded together in complex 3D configurations
  • Transportation: Cities connected by roads, flights, rail lines
  • Knowledge graphs: Entities with typed relationships
  • Financial networks: Transactions between accounts

Traditional deep learning models expect data in regular formats—vectors, matrices, or tensors. Graphs break these assumptions: variable numbers of nodes, arbitrary connectivity, no inherent ordering.

Graph Neural Networks solve this problem by learning representations that respect graph structure.

Understanding Graph Representations

Graph Components

A graph G = (V, E) consists of:

  • Vertices (V): Nodes representing entities
  • Edges (E): Connections between entities
  • Optional features: Attributes on nodes and edges

Types of Graphs

Type Description Examples
Directed Edges have direction Web links, follower relationships
Undirected Edges symmetric Social friendships
Weighted Edges have scores Road distances, bond strengths
Typed Multiple edge types Knowledge graph relations
Heterogeneous Different node types Different user account types

Representing Graphs for Neural Networks

Graphs must be encoded as tensors for processing:

# Node features: (num_nodes, feature_dim)
node_features = torch.randn(num_nodes, feature_dim)

# Edge index: (2, num_edges)
edge_index = torch.tensor([[0, 1, 2],
                          [1, 2, 0]])

# Optional edge features: (num_edges, edge_feature_dim)
edge_features = torch.randn(num_edges, edge_feature_dim)

Graph Neural Network Architectures

Message Passing Neural Networks

The foundational GNN framework:

For each layer l = 1 to L:
    For each node v:
        Aggregate messages from neighbors
        Update node representation

Message passing equation:

def message_passing(node_features, edge_index):
    # For each edge, compute message from source to target
    messages = compute_message(source_features, target_features, edge_attr)

    # Aggregate messages to each node
    aggregated = scatter_sum(messages, target_node)

    # Update node representation
    new_features = update_function(aggregated)

    return new_features

GraphSAGE: Scalable Inductive Learning

GraphSAGE introduces sampling and aggregation:

class GraphSAGE(nn.Module):
    def __init__(self, input_dim, hidden_dim, output_dim):
        self.aggregate = MeanAggregator()
        self.update = nn.Linear(hidden_dim * 2, hidden_dim)
        self.transform = nn.Linear(input_dim, hidden_dim)

    def forward(self, x, edge_index):
        # Sample neighbors (for scalability)
        neighbors = sample_neighbors(edge_index, num_samples=5)

        # Aggregate neighbor features
        aggregated = self.aggregate(x, neighbors)

        # Concatenate with self features
        combined = torch.cat([x, aggregated], dim=-1)

        # Update
        return self.update(combined)

Graph Attention Networks (GAT)

GAT adds attention mechanisms:

class GraphAttentionLayer(nn.Module):
    def __init__(self, in_dim, out_dim, heads=4):
        self.heads = heads
        self.W = nn.Linear(in_dim, out_dim * heads)
        self.att = nn.Linear(out_dim * 2, 1)

    def forward(self, x, edge_index):
        # Transform features
        h = self.W(x).view(-1, self.heads, out_dim)

        # Compute attention scores
        source, target = h[edge_index[0]], h[edge_index[1]]
        e = self.att(torch.cat([source, target], dim=-1))
        a = softmax(e, edge_index[1])

        # Weighted aggregation
        out = scatter_add(a * source, edge_index[1])
        return out

Comparative Analysis

Architecture Inductive Scalable Attention Best For
GCn No Moderate No Small transductive
GraphSAGE Yes Yes No Large-scale inductive
GAT Yes Moderate Yes Attention-weighted
Transformer-G Yes Moderate Yes State-of-the-art

Applications of Graph Neural Networks

1. Molecular Property Prediction

GNNs excel at molecular analysis:

  • Drug discovery: Predict binding affinity
  • Material design: Predict material properties
  • Toxicity prediction: Assess safety profiles
Molecule → GNN → Property prediction
[Atom features, Bond features] → [Learn representation] → [Binding affinity, IC50, etc.]

2. Social Network Analysis

  • Recommendation: Friend/content recommendations
  • Fraud detection: Anomalous account patterns
  • Influence modeling: Identify key influencers

3. Knowledge Graph Reasoning

  • Entity resolution: Link prediction
  • Question answering: Multi-hop reasoning
  • Recommendation: Knowledge-enhanced recommendations

4. Transportation and Logistics

  • Traffic prediction: Flow forecasting
  • Route optimization: Path planning
  • Delivery scheduling: Logistics optimization

Implementation with PyTorch Geometric

Basic GNN Implementation

import torch
from torch_geometric.nn import GCNConv, global_mean_pool

class GNN(torch.nn.Module):
    def __init__(self, input_dim, hidden_dim, output_dim, num_layers):
        super().__init__()
        self.convs = nn.ModuleList()
        self.convs.append(GCNConv(input_dim, hidden_dim))
        for _ in range(num_layers - 2):
            self.convs.append(GCNConv(hidden_dim, hidden_dim))
        self.convs.append(GCNConv(hidden_dim, output_dim))
        self.dropout = nn.Dropout(0.5)

    def forward(self, x, edge_index, batch=None):
        for conv in self.convs[:-1]:
            x = conv(x, edge_index)
            x = F.relu(x)
            x = self.dropout(x)

        x = self.convs[-1](x, edge_index)

        # Graph-level pooling
        if batch is not None:
            x = global_mean_pool(x, batch)

        return x

Training Loop

def train(model, data, optimizer, criterion):
    model.train()
    optimizer.zero_grad()

    out = model(data.x, data.edge_index, data.batch)
    loss = criterion(out[data.train_mask], data.y[data.train_mask])

    loss.backward()
    optimizer.step()

    return loss.item()

Challenges and Future Directions

Current Challenges

Challenge Description Mitigation
Scalability Large graphs Sampling, clustering
Over-smoothing Deep GNNs merge Skip connections, identity
Expressiveness WL test limitations Higher-order neighborhoods
Heterogeneity Diverse node types Heterogeneous GNNs

Emerging Research

  1. Graph Transformers: Attention over graph structure
  2. Continuous GNNs: Diffusion-based methods
  3. Temporal Graphs: Dynamic graph evolution
  4. Causal GNNs: Incorporating causal structure

Conclusion

Graph Neural Networks unlock deep learning capabilities on structured data that traditional models cannot handle. From molecular discovery to social network analysis, GNNs provide a principled approach to learning from connected data.

The field continues to evolve rapidly, with new architectures pushing the boundaries of what's possible. For practitioners, understanding GNNs opens doors to applications across science, industry, and social systems that depend on structured relationships.