用于低功耗自主部署的卫星异常响应操作的概率图神经推理
Source: Dev.to
引言:来自太空边缘的嘈杂信号
凌晨 3 点,我正盯着实验室里一颗 CubeSat 原型的遥测数据流。卫星仿真在一块 Raspberry Pi 4 上运行,特意限制功耗以模拟轨道环境。突然,推进模块的温度传感器读数开始剧烈振荡——虽然不足以触发传统阈值报警,却足以暗示出现了问题。机载的基于规则的系统保持沉默。
当我手动追踪系统之间的依赖关系时,我意识到自己看到的是什么:一次级联异常在卫星互联子系统中传播。这一瞬间凝练出一个根本性的洞见:在复杂的自主系统中,异常不是孤立事件,而是网络现象。
通过研究分布式卫星星座及其失效模式,我了解到传统的异常检测方法会失效,因为它们把传感器视为相互独立。实际上,电源系统的热异常可能表现为通信延迟,进而影响姿态控制。图神经网络(GNN)能够捕捉这些关系,但标准 GNN 缺乏对不确定性的量化,而不确定性对低功耗环境中的自主决策至关重要——在这种环境下误报会带来严重后果。
技术背景:从确定性图到概率推理
图表示问题
最具挑战性的并不是检测异常,而是以一种能够捕获结构和时间依赖性的方式来表示系统。卫星不仅仅是一堆传感器;它是一个动态网络,其中:
- 物理连接(电源总线、数据总线、热通道)形成硬性依赖。
- 功能依赖(姿态控制需要电源,通信需要热稳定性)形成软约束。
- 时间模式(轨道周期、热循环、通信窗口)产生时变关系。
传统的贝叶斯网络在处理高维、时间序列遥测数据时捉襟见肘。马尔可夫逻辑网络提供了更大的灵活性,但在边缘硬件上进行实时推理时计算成本难以接受。
概率图神经网络登场
概率图神经网络(Probabilistic Graph Neural Networks,PGNN)将 GNN 的表征能力与概率模型的不确定性量化相结合。两类不确定性尤为重要:
- Aleatoric 不确定性——观测本身的噪声(传感器噪声、宇宙辐射影响)。
- Epistemic 不确定性——模型因训练数据有限而产生的不确定性(在稀有异常场景中尤为关键)。
Monte Carlo Dropout 虽然计算效率高,却常在太空操作中常见的分布外情形下低估不确定性。这促使我们探索适用于图结构的贝叶斯神经网络方法。
实现细节:为卫星运营构建 PGNN
从遥测数据构建图
每个子系统成为一个节点,节点特征包括当前传感器读数(归一化后)、滑动窗口内的历史统计量(均值、方差)、运行模式标志以及自上次维护以来的时间。边缘依据物理连通矩阵、从历史数据中学习到的相关模式以及已知的功能依赖进行构建。
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))
概率图神经网络架构
PGNN 将确定性特征提取与概率不确定性估计分离,在保持表达能力的同时兼顾低功耗部署的计算效率。
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
这些组件构成了能够在边缘硬件上实时进行异常推理的 PGNN 核心,为安全的自主卫星运行提供了预测结果以及经过校准的不确定性估计。