Probabilistic Graph Neural Inference for satellite anomaly response operations for low-power autonomous deployments

Published: (December 14, 2025 at 04:28 AM EST)
4 min read
Source: Dev.to

Source: Dev.to

Probabilistic Graph Neural Inference for Satellite Anomaly Response

Introduction: A Noisy Signal from the Edge of Space

It was 3 AM, and I was staring at a stream of telemetry data from a CubeSat prototype in my lab. The satellite simulation was running on a Raspberry Pi 4, deliberately power‑constrained to mimic orbital conditions. Suddenly, the temperature sensor readings from the propulsion module began oscillating wildly—not enough to trigger traditional threshold alarms, but enough to suggest something was wrong. The onboard rule‑based system remained silent.

As I manually traced the dependencies between systems, I realized what I was seeing: a cascading anomaly propagating through the satellite’s interconnected subsystems. This moment crystallized a fundamental insight: in complex autonomous systems, anomalies aren’t isolated events—they’re network phenomena.

Through studying distributed satellite constellations and their failure modes, I learned that traditional anomaly detection approaches fail because they treat sensors as independent. In reality, a thermal anomaly in the power system might manifest as communication latency, which then affects attitude control. Graph neural networks (GNNs) can capture these relationships, but standard GNNs lack the uncertainty quantification crucial for autonomous decision‑making in low‑power environments where false positives carry severe consequences.

Technical Background: From Deterministic Graphs to Probabilistic Inference

The Graph Representation Problem

The most challenging aspect wasn’t detecting anomalies—it was representing the system in a way that captured both structural and temporal dependencies. A satellite isn’t just a collection of sensors; it’s a dynamic network where:

  • Physical connections (power buses, data buses, thermal paths) create hard dependencies.
  • Functional dependencies (attitude control needing power, communication needing thermal stability) create soft constraints.
  • Temporal patterns (orbital periods, thermal cycles, communication windows) create time‑varying relationships.

Traditional Bayesian networks struggled with the high‑dimensional, time‑series nature of telemetry data. Markov logic networks offered more flexibility but became computationally intractable for real‑time inference on edge hardware.

Enter Probabilistic Graph Neural Networks

Probabilistic Graph Neural Networks (PGNNs) combine the representational power of GNNs with the uncertainty quantification of probabilistic models. Two types of uncertainty are relevant:

  • Aleatoric uncertainty – inherent noise in observations (sensor noise, cosmic radiation effects).
  • Epistemic uncertainty – model uncertainty due to limited training data (especially important for rare anomalies).

Monte Carlo Dropout, while computationally efficient, often underestimates uncertainty in out‑of‑distribution scenarios common in space operations. This motivated the exploration of Bayesian neural network approaches adapted for graph structures.

Implementation Details: Building a PGNN for Satellite Operations

Graph Construction from Telemetry Data

Each subsystem becomes a node with features such as current sensor readings (normalized), historical statistics (mean, variance over sliding windows), operational mode flags, and time since last maintenance event. Edges are constructed from physical connectivity matrices, correlation patterns learned from historical data, and known functional dependencies.

import torch
import torch.nn as nn
import torch.nn.functional as F
from torch_geometric.nn import GCNConv, MessagePassing
from torch_geometric.data import Data
import numpy as np

class SatelliteGraphBuilder:
    """Constructs dynamic graph from satellite telemetry"""

    def __init__(self, n_subsystems, history_window=100):
        self.n_subsystems = n_subsystems
        self.history_window = history_window
        self.physical_adjacency = self.load_physical_connectivity()

    def telemetry_to_graph(self, telemetry_batch):
        """Convert time‑series telemetry to graph representation"""
        # Node features: [current_value, mean_10s, std_10s, trend]
        node_features = []

        for subsystem_id in range(self.n_subsystems):
            current = telemetry_batch[subsystem_id, -1]
            history = telemetry_batch[subsystem_id, -self.history_window:]

            features = [
                current,
                np.mean(history),
                np.std(history),
                self.calculate_trend(history)
            ]
            node_features.append(features)

        # Dynamic edge weights based on correlation
        edge_index, edge_attr = self.compute_dynamic_edges(telemetry_batch)

        return Data(
            x=torch.tensor(node_features, dtype=torch.float32),
            edge_index=edge_index,
            edge_attr=edge_attr
        )

    def compute_dynamic_edges(self, telemetry_batch):
        """Compute edges based on recent correlations"""
        correlations = np.corrcoef(telemetry_batch)

        edge_index = []
        edge_weights = []

        for i in range(self.n_subsystems):
            for j in range(i + 1, self.n_subsystems):
                if abs(correlations[i, j]) > 0.7:  # Strong correlation threshold
                    edge_index.append([i, j])
                    edge_index.append([j, i])  # Undirected graph

                    weight = (self.physical_adjacency[i, j] * 0.3 +
                              abs(correlations[i, j]) * 0.7)
                    edge_weights.extend([weight, weight])

        return (torch.tensor(edge_index, dtype=torch.long).t().contiguous(),
                torch.tensor(edge_weights, dtype=torch.float32))

Probabilistic Graph Neural Network Architecture

The PGNN separates deterministic feature extraction from probabilistic uncertainty estimation, balancing expressiveness with computational efficiency for low‑power deployments.

class ProbabilisticGNNLayer(MessagePassing):
    """Single layer of probabilistic graph neural network"""

    def __init__(self, in_channels, out_channels, dropout_rate=0.1):
        super().__init__(aggr='mean')

        # Deterministic transformation
        self.deterministic_lin = nn.Linear(in_channels, out_channels)

        # Probabilistic components
        self.mu_lin = nn.Linear(in_channels, out_channels)
        self.log_var_lin = nn.Linear(in_channels, out_channels)

        self.dropout = nn.Dropout(dropout_rate)
        self.activation = nn.ReLU()

    def forward(self, x, edge_index, edge_weight=None):
        # Message passing (aggregation)
        aggregated = self.propagate(edge_index, x=x, edge_weight=edge_weight)

        # Deterministic path
        det_out = self.deterministic_lin(aggregated)

        # Probabilistic path (mean and variance)
        mu = self.mu_lin(aggregated)
        log_var = self.log_var_lin(aggregated)

        # Apply dropout and activation
        det_out = self.dropout(self.activation(det_out))
        mu = self.dropout(self.activation(mu))
        log_var = self.dropout(self.activation(log_var))

        return det_out, mu, log_var

These components form the core of a PGNN capable of real‑time anomaly inference on edge hardware, providing both predictions and calibrated uncertainty estimates for safe autonomous satellite operations.

Back to Blog

Related posts

Read more »