Status: Needs Review
This page has not been reviewed for accuracy and completeness. Content may be outdated or contain errors.
Pipeline Configuration Schema¶
Complete reference for pipeline YAML structure, fields, validation rules, and examples.
Overview¶
Pipeline configurations define the computational graph for hyperspectral image processing:
- metadata: Pipeline identification and documentation
- nodes: Processing components with parameters
- connections: Data flow between nodes
- frozen_nodes: Nodes excluded from training
File location: configs/pipeline/
Usage: Referenced in trainrun configs via Hydra composition
Quick Reference¶
Minimal Pipeline¶
metadata:
name: My_Pipeline
description: Pipeline description
author: cuvis.ai
nodes:
- name: data_loader
class: cuvis_ai.node.data.LentilsAnomalyDataNode
params:
normal_class_ids: [0, 1]
- name: detector
class: cuvis_ai.anomaly.rx_detector.RXGlobal
params:
num_channels: 61
eps: 1.0e-06
connections:
- from: data_loader.outputs.cube
to: detector.inputs.data
frozen_nodes: []
Complete Pipeline Structure¶
metadata:
name: string # Required
description: string # Required
created: string # Optional
tags: [...] # Optional
author: string # Required
version: string # Optional
cuvis_ai_version: string # Optional
nodes:
- name: string # Required, unique
class: string # Required, importable Python path
params: {} # Optional, node-specific parameters
connections:
- from: node.outputs.port # Required
to: node.inputs.port # Required
frozen_nodes: [] # Optional, list of node names
Metadata Section¶
Required Fields¶
name (string) - Pipeline identifier - Used in logs and saved models - Should be descriptive and unique
description (string) - Brief description of pipeline purpose - Helps identify pipelines in multi-experiment setups
author (string) - Creator or organization name - Used for tracking and attribution
Optional Fields¶
created (string) - Creation timestamp - Format: ISO 8601 or any consistent format
tags (list of strings)
- Classification tags for filtering and search
- Common tags: statistical, gradient, anomaly, classification
version (string)
- Pipeline version for tracking changes
- Use semantic versioning: major.minor.patch
cuvis_ai_version (string) - Framework version used to create pipeline - Helps with compatibility tracking
Complete Metadata Example¶
metadata:
name: DRCNN_AdaClip_Gradient
description: DRCNN channel mixer with AdaClip anomaly detection
created: '2026-02-04T10:30:00'
tags:
- gradient
- drcnn
- adaclip
- anomaly
author: cuvis.ai
version: '2.1.0'
cuvis_ai_version: '0.1.5.post26'
Nodes Section¶
Node Structure¶
Each node has three components:
name (string, required)¶
- Unique identifier within the pipeline
- Used in connections to reference the node
- Case-sensitive
- Must be valid Python identifier (no spaces, special chars)
Good names:
Avoid:
name: node1 # Not descriptive
name: my node # Contains space
name: detector-rx # Contains dash (not Python identifier)
class (string, required)¶
- Fully qualified Python class path
- Must be importable from Python path
- Format:
module.submodule.ClassName
Common node classes:
Data nodes:
Preprocessing nodes:
class: cuvis_ai.node.normalization.MinMaxNormalizer
class: cuvis_ai.node.normalization.StandardScaler
class: cuvis_ai.node.preprocessing.PCANode
Detection nodes:
class: cuvis_ai.anomaly.rx_detector.RXGlobal
class: cuvis_ai.anomaly.lad_detector.LADDetector
class: cuvis_ai.node.conversion.ScoreToLogit
Decision nodes:
Loss nodes:
Metric nodes:
Monitoring nodes:
class: cuvis_ai.node.monitor.TensorBoardMonitorNode
class: cuvis_ai.node.visualizations.AnomalyMask
class: cuvis_ai.node.visualizations.ScoreHeatmapVisualizer
params (dict, optional)¶
Node-specific configuration parameters. Each node class defines its own parameters.
Example: Data node parameters
- name: LentilsAnomalyDataNode
class: cuvis_ai.node.data.LentilsAnomalyDataNode
params:
normal_class_ids: [0, 1]
Example: Normalization parameters
- name: MinMaxNormalizer
class: cuvis_ai.node.normalization.MinMaxNormalizer
params:
eps: 1.0e-06
use_running_stats: true
Example: Detector parameters
- name: RXGlobal
class: cuvis_ai.anomaly.rx_detector.RXGlobal
params:
num_channels: 61
eps: 1.0e-06
cache_inverse: true
Example: Complex node with many parameters
- name: concrete_selector
class: cuvis_ai.node.concrete_selector.ConcreteBandSelector
params:
input_channels: 61
output_channels: 3
tau_start: 10.0
tau_end: 0.1
max_epochs: 20
use_hard_inference: true
eps: 1.0e-06
Example: Node with no parameters
Or simply omit params:
Complete Node Examples¶
Statistical RX Pipeline Nodes:
nodes:
- name: LentilsAnomalyDataNode
class: cuvis_ai.node.data.LentilsAnomalyDataNode
params:
normal_class_ids: [0, 1]
- name: MinMaxNormalizer
class: cuvis_ai.node.normalization.MinMaxNormalizer
params:
eps: 1.0e-06
use_running_stats: true
- name: RXGlobal
class: cuvis_ai.anomaly.rx_detector.RXGlobal
params:
num_channels: 61
eps: 1.0e-06
- name: ScoreToLogit
class: cuvis_ai.node.conversion.ScoreToLogit
params:
init_scale: 1.0
init_bias: 0.0
- name: BinaryDecider
class: cuvis_ai.deciders.binary_decider.BinaryDecider
params:
threshold: 0.5
- name: metrics_anomaly
class: cuvis_ai.node.metrics.AnomalyDetectionMetrics
Connections Section¶
Connection Structure¶
Connections define data flow between nodes using port references:
connections:
- from: <source_node>.<port_type>.<port_name>
to: <target_node>.<port_type>.<port_name>
Port types:
- outputs - Source ports (produce data)
- inputs - Target ports (consume data)
Connection Syntax¶
Pattern:
Components:
1. node_name: Must match a node name defined in nodes section
2. port_type: Either outputs (source) or inputs (target)
3. port_name: Port identifier defined by the node class
Valid connection:
Invalid connections:
# Wrong: Using inputs as source
- from: normalizer.inputs.data
to: detector.inputs.data
# Wrong: Using outputs as target
- from: data_loader.outputs.cube
to: normalizer.outputs.normalized
# Wrong: Mismatched port names
- from: data_loader.outputs.cube
to: normalizer.inputs.wrong_port_name
Common Port Names¶
Data node outputs:
LentilsAnomalyDataNode.outputs.cube # Hyperspectral cube
LentilsAnomalyDataNode.outputs.mask # Ground truth mask
LentilsAnomalyDataNode.outputs.wavelengths # Wavelength array
Normalizer ports:
Detector ports:
RXGlobal.inputs.data # Input hyperspectral data
RXGlobal.outputs.scores # Anomaly scores
RXGlobal.outputs.mean # Computed mean (statistical nodes)
RXGlobal.outputs.covariance # Computed covariance (statistical nodes)
Decision ports:
BinaryDecider.inputs.logits # Input logits or scores
BinaryDecider.outputs.decisions # Binary decisions
Metric ports:
AnomalyDetectionMetrics.inputs.decisions # Binary predictions
AnomalyDetectionMetrics.inputs.targets # Ground truth
AnomalyDetectionMetrics.inputs.logits # Optional scores
AnomalyDetectionMetrics.outputs.metrics # Computed metrics
Monitor ports:
TensorBoardMonitorNode.inputs.metrics # Metric objects
TensorBoardMonitorNode.inputs.artifacts # Visualization artifacts
Connection Patterns¶
Linear flow:
connections:
- from: data_loader.outputs.cube
to: normalizer.inputs.data
- from: normalizer.outputs.normalized
to: detector.inputs.data
- from: detector.outputs.scores
to: decider.inputs.scores
Multi-branch flow:
connections:
# Main flow
- from: data_loader.outputs.cube
to: normalizer.inputs.data
- from: normalizer.outputs.normalized
to: detector.inputs.data
# Branch 1: Metrics
- from: decider.outputs.decisions
to: metrics.inputs.decisions
- from: data_loader.outputs.mask
to: metrics.inputs.targets
# Branch 2: Visualization
- from: decider.outputs.decisions
to: viz.inputs.decisions
- from: data_loader.outputs.cube
to: viz.inputs.cube
Fan-out pattern (one source → multiple targets):
connections:
# RX scores go to multiple destinations
- from: detector.outputs.scores
to: decider.inputs.scores
- from: detector.outputs.scores
to: score_viz.inputs.scores
- from: detector.outputs.scores
to: metrics.inputs.logits
Convergence pattern (multiple sources → one target):
connections:
# Monitoring receives from multiple sources
- from: metrics.outputs.metrics
to: monitor.inputs.metrics
- from: viz_mask.outputs.artifacts
to: monitor.inputs.artifacts
- from: score_viz.outputs.artifacts
to: monitor.inputs.artifacts
Complete Connection Examples¶
RX Statistical Pipeline:
connections:
- from: LentilsAnomalyDataNode.outputs.cube
to: MinMaxNormalizer.inputs.data
- from: LentilsAnomalyDataNode.outputs.mask
to: metrics_anomaly.inputs.targets
- from: LentilsAnomalyDataNode.outputs.mask
to: mask.inputs.mask
- from: LentilsAnomalyDataNode.outputs.cube
to: mask.inputs.cube
- from: MinMaxNormalizer.outputs.normalized
to: RXGlobal.inputs.data
- from: RXGlobal.outputs.scores
to: ScoreToLogit.inputs.scores
- from: ScoreToLogit.outputs.logits
to: BinaryDecider.inputs.logits
- from: BinaryDecider.outputs.decisions
to: metrics_anomaly.inputs.decisions
- from: BinaryDecider.outputs.decisions
to: mask.inputs.decisions
- from: metrics_anomaly.outputs.metrics
to: TensorBoardMonitorNode.inputs.metrics
- from: mask.outputs.artifacts
to: TensorBoardMonitorNode.inputs.artifacts
DRCNN + AdaClip Pipeline (multi-branch):
connections:
# Data loading
- from: LentilsAnomalyDataNode.outputs.cube
to: MinMaxNormalizer.inputs.data
# Main processing
- from: MinMaxNormalizer.outputs.normalized
to: channel_mixer.inputs.data
- from: channel_mixer.outputs.output
to: adaclip.inputs.image
# Loss computation
- from: adaclip.outputs.scores
to: iou_loss.inputs.predictions
- from: LentilsAnomalyDataNode.outputs.mask
to: iou_loss.inputs.targets
# Decisions
- from: adaclip.outputs.scores
to: decider.inputs.logits
# Metrics
- from: decider.outputs.decisions
to: metrics_anomaly.inputs.decisions
- from: LentilsAnomalyDataNode.outputs.mask
to: metrics_anomaly.inputs.targets
- from: adaclip.outputs.scores
to: metrics_anomaly.inputs.logits
# Monitoring
- from: metrics_anomaly.outputs.metrics
to: TensorBoardMonitorNode.inputs.metrics
Frozen Nodes Section¶
Purpose¶
The frozen_nodes list specifies nodes that should not be updated during training.
Use cases: - Data loaders (always frozen) - Statistical nodes after initialization - Pretrained components that should remain fixed
Syntax¶
Or:
Examples¶
Statistical training (no gradient training):
Gradient training with selective unfreezing:
# In trainrun config (not pipeline)
freeze_nodes: [data_loader, normalizer]
unfreeze_nodes: [channel_selector, rx_detector]
Note: The frozen_nodes field in pipeline configs is typically empty. Freezing/unfreezing is controlled by freeze_nodes and unfreeze_nodes in trainrun configs.
Complete Pipeline Examples¶
Example 1: Statistical RX Pipeline¶
metadata:
name: RX_Statistical
description: RX anomaly detector with statistical initialization
tags:
- statistical
- rx
author: cuvis.ai
nodes:
- name: LentilsAnomalyDataNode
class: cuvis_ai.node.data.LentilsAnomalyDataNode
params:
normal_class_ids: [0, 1]
- name: MinMaxNormalizer
class: cuvis_ai.node.normalization.MinMaxNormalizer
params:
eps: 1.0e-06
use_running_stats: true
- name: RXGlobal
class: cuvis_ai.anomaly.rx_detector.RXGlobal
params:
num_channels: 61
eps: 1.0e-06
- name: ScoreToLogit
class: cuvis_ai.node.conversion.ScoreToLogit
params:
init_scale: 1.0
init_bias: 0.0
- name: BinaryDecider
class: cuvis_ai.deciders.binary_decider.BinaryDecider
params:
threshold: 0.5
- name: metrics_anomaly
class: cuvis_ai.node.metrics.AnomalyDetectionMetrics
- name: TensorBoardMonitorNode
class: cuvis_ai.node.monitor.TensorBoardMonitorNode
params:
output_dir: outputs/rx_statistical/tensorboard
run_name: RX_Statistical
connections:
- from: LentilsAnomalyDataNode.outputs.cube
to: MinMaxNormalizer.inputs.data
- from: MinMaxNormalizer.outputs.normalized
to: RXGlobal.inputs.data
- from: RXGlobal.outputs.scores
to: ScoreToLogit.inputs.scores
- from: ScoreToLogit.outputs.logits
to: BinaryDecider.inputs.logits
- from: BinaryDecider.outputs.decisions
to: metrics_anomaly.inputs.decisions
- from: LentilsAnomalyDataNode.outputs.mask
to: metrics_anomaly.inputs.targets
- from: metrics_anomaly.outputs.metrics
to: TensorBoardMonitorNode.inputs.metrics
frozen_nodes: []
Example 2: Channel Selector Gradient Pipeline¶
metadata:
name: Channel_Selector
description: Learnable channel selection with RX detection
tags:
- gradient
- channel_selection
- rx
author: cuvis.ai
version: '1.0.0'
nodes:
- name: LentilsAnomalyDataNode
class: cuvis_ai.node.data.LentilsAnomalyDataNode
params:
normal_class_ids: [0, 1]
- name: MinMaxNormalizer
class: cuvis_ai.node.normalization.MinMaxNormalizer
params:
eps: 1.0e-06
use_running_stats: true
- name: selector
class: cuvis_ai.node.channel_selection.ChannelSelector
params:
num_channels: 61
tau_start: 8.0
tau_end: 0.05
- name: rx_global
class: cuvis_ai.anomaly.rx_detector.RXGlobal
params:
num_channels: 61
eps: 1.0e-06
- name: logit_head
class: cuvis_ai.node.conversion.ScoreToLogit
params:
init_scale: 1.0
init_bias: 0.0
- name: decider
class: cuvis_ai.deciders.binary_decider.BinaryDecider
params:
threshold: 0.5
- name: bce_loss
class: cuvis_ai.anomaly.bce_loss.AnomalyBCEWithLogits
params:
weight: 1.0
- name: entropy_loss
class: cuvis_ai.anomaly.entropy_loss.SelectorEntropyLoss
params:
weight: 0.001
- name: metrics_anomaly
class: cuvis_ai.node.metrics.AnomalyDetectionMetrics
connections:
# Data flow
- from: LentilsAnomalyDataNode.outputs.cube
to: MinMaxNormalizer.inputs.data
- from: MinMaxNormalizer.outputs.normalized
to: selector.inputs.data
- from: selector.outputs.selected
to: rx_global.inputs.data
- from: rx_global.outputs.scores
to: logit_head.inputs.scores
- from: logit_head.outputs.logits
to: decider.inputs.logits
# Loss computation
- from: logit_head.outputs.logits
to: bce_loss.inputs.predictions
- from: LentilsAnomalyDataNode.outputs.mask
to: bce_loss.inputs.targets
- from: selector.outputs.weights
to: entropy_loss.inputs.weights
# Metrics
- from: decider.outputs.decisions
to: metrics_anomaly.inputs.decisions
- from: LentilsAnomalyDataNode.outputs.mask
to: metrics_anomaly.inputs.targets
frozen_nodes: []
Example 3: Deep SVDD Pipeline¶
metadata:
name: Deep_SVDD
description: Deep Support Vector Data Description for anomaly detection
tags:
- gradient
- deep_learning
- svdd
author: cuvis.ai
nodes:
- name: LentilsAnomalyDataNode
class: cuvis_ai.node.data.LentilsAnomalyDataNode
params:
normal_class_ids: [0, 1]
- name: normalizer
class: cuvis_ai.node.normalization.MinMaxNormalizer
params:
eps: 1.0e-06
use_running_stats: true
- name: projection
class: cuvis_ai.node.deep_svdd.ProjectionNetwork
params:
input_dim: 61
hidden_dims: [128, 64, 32]
output_dim: 16
- name: deepsvdd_loss
class: cuvis_ai.anomaly.deep_svdd_loss.DeepSVDDLoss
params:
radius: 0.0
nu: 0.1
- name: metrics_anomaly
class: cuvis_ai.node.metrics.AnomalyDetectionMetrics
connections:
- from: LentilsAnomalyDataNode.outputs.cube
to: normalizer.inputs.data
- from: normalizer.outputs.normalized
to: projection.inputs.data
- from: projection.outputs.embeddings
to: deepsvdd_loss.inputs.embeddings
- from: deepsvdd_loss.outputs.scores
to: metrics_anomaly.inputs.logits
- from: LentilsAnomalyDataNode.outputs.mask
to: metrics_anomaly.inputs.targets
frozen_nodes: []
Validation Rules¶
1. Node Name Uniqueness¶
All node names must be unique within a pipeline.
Valid:
nodes:
- name: normalizer_1
class: cuvis_ai.node.normalization.MinMaxNormalizer
- name: normalizer_2
class: cuvis_ai.node.normalization.MinMaxNormalizer
Invalid:
nodes:
- name: normalizer
class: cuvis_ai.node.normalization.MinMaxNormalizer
- name: normalizer # ✗ Duplicate name
class: cuvis_ai.node.normalization.StandardScaler
2. Class Importability¶
All node classes must be importable from Python path.
Valid:
Invalid:
3. Connection Validity¶
Source must be output port:
# Valid
- from: detector.outputs.scores
to: decider.inputs.scores
# Invalid
- from: detector.inputs.data # ✗ Can't use input as source
to: decider.inputs.scores
Target must be input port:
# Valid
- from: detector.outputs.scores
to: decider.inputs.scores
# Invalid
- from: detector.outputs.scores
to: decider.outputs.decisions # ✗ Can't use output as target
Referenced nodes must exist:
# Valid
nodes:
- name: detector
...
connections:
- from: detector.outputs.scores
to: decider.inputs.scores
# Invalid
connections:
- from: nonexistent_node.outputs.data # ✗ Node not defined
to: decider.inputs.scores
4. Parameter Types¶
Node parameters must match expected types.
Valid:
params:
num_channels: 61 # int
eps: 1.0e-06 # float
use_running_stats: true # bool
normal_class_ids: [0, 1] # list
Invalid:
params:
num_channels: "61" # ✗ String instead of int
eps: true # ✗ Bool instead of float
normal_class_ids: 0 # ✗ Int instead of list
Best Practices¶
1. Descriptive Node Names¶
Good:
Avoid:
2. Consistent Naming Convention¶
Pick a style and stick to it:
# snake_case (recommended)
name: data_loader
name: rx_detector
name: score_visualizer
# PascalCase (alternative)
name: DataLoader
name: RXDetector
name: ScoreVisualizer
3. Organized Connections¶
Group connections by purpose:
connections:
# Main processing flow
- from: data_loader.outputs.cube
to: normalizer.inputs.data
- from: normalizer.outputs.normalized
to: detector.inputs.data
# Loss computation
- from: detector.outputs.scores
to: loss.inputs.predictions
# Metrics and monitoring
- from: metrics.outputs.metrics
to: monitor.inputs.metrics
4. Comments for Complex Pipelines¶
nodes:
# Data loading and preprocessing
- name: data_loader
...
- name: normalizer
...
# Feature extraction
- name: channel_selector
...
- name: pca
...
# Anomaly detection
- name: rx_detector
...
- name: threshold_decider
...
5. Parameter Documentation¶
- name: concrete_selector
class: cuvis_ai.node.concrete_selector.ConcreteBandSelector
params:
input_channels: 61
output_channels: 3
tau_start: 10.0 # Initial temperature for Gumbel-Softmax
tau_end: 0.1 # Final temperature after annealing
max_epochs: 20 # Epochs for temperature schedule
use_hard_inference: true # Use hard selection during inference
See Also¶
- Configuration Guides:
- Config Groups - Organizing pipeline configs
- TrainRun Schema - Complete experiment configuration
- Hydra Composition - Composition patterns
- How-To Guides:
- Build Pipelines in YAML - Creating pipeline configs
- Build Pipelines in Python - Programmatic construction
- Add Builtin Node - Creating custom nodes
- Node Catalog:
- Data Nodes - Available data loading nodes
- Processing Nodes - Normalization, PCA, etc.
- Statistical Nodes - Anomaly detector implementations
- Loss & Metrics Nodes - Loss and metric computations