Advanced Campaign Configuration
Custom objectives, constraints, convergence criteria, and multi-objective strategies.
Apr 10, 20267 min read
tutorial
campaign
advanced
optimization
pareto
Advanced Campaign Configuration
This tutorial covers advanced optimization campaign features for users who want fine-grained control over the discovery process.
Custom Objective Functions
Beyond the built-in domain objectives, you can define custom Python functions:
python
from materia import Campaign, Material, Objective
def thermal_stability_score(params):
"""Custom objective combining multiple factors."""
temp = params["max_service_temp"]
oxidation = params["oxidation_resistance"]
creep = params["creep_strength"]
return 0.4 * temp / 1500 + 0.3 * oxidation + 0.3 * creep
material = Material.from_yaml("my_material.yaml")
material.add_objective(Objective(
name="thermal_score",
function=thermal_stability_score,
direction="maximize"
))Complex Constraints
Define nonlinear constraints using Python expressions:
yaml
constraints:
# Linear: component fractions sum to 1
- expression: "x_A + x_B + x_C == 1.0"
type: equality
# Nonlinear: minimum solubility requirement
- expression: "x_A * x_B > 0.01"
type: inequality
# Conditional: if using additive, concentration must exceed threshold
- expression: "additive_conc >= 0.05 if additive_type != 'none'"
type: conditionalConvergence Criteria
Control when the campaign stops:
yaml
optimizer:
method: cma-es
budget: 500
convergence:
# Stop if hypervolume improvement < threshold for N iterations
hypervolume_patience: 10
hypervolume_threshold: 0.001
# Stop if best objective does not improve
objective_patience: 15
objective_threshold: 0.01
# Minimum iterations before convergence check
min_iterations: 20Surrogate Model Selection
Choose different surrogate architectures based on your problem:
yaml
optimizer:
surrogate: mlp # Default: multi-layer perceptron
# surrogate: gp # Gaussian Process (better for < 100 points)
# surrogate: rf # Random Forest (robust, fast)
# surrogate: ensemble # Ensemble of all three (most accurate, slowest)
surrogate_config:
hidden_layers: [128, 64, 32]
dropout: 0.1
learning_rate: 0.001
epochs: 200Acquisition Functions
Control the exploration-exploitation balance:
yaml
optimizer:
acquisition: ei # Expected Improvement (default)
# acquisition: ucb # Upper Confidence Bound
# acquisition: pi # Probability of Improvement
# acquisition: thompson # Thompson Sampling
acquisition_config:
# For UCB: higher kappa = more exploration
kappa: 2.0
# For EI: xi adds exploration bonus
xi: 0.01Multi-Objective Strategies
For problems with 3+ objectives:
yaml
optimizer:
multi_objective:
method: nsga2 # NSGA-II for Pareto front
# method: parego # ParEGO (scalarization approach)
# method: ehvi # Expected Hypervolume Improvement
# Reference point for hypervolume calculation
reference_point: [0, 0, 100]
# Pareto front size target
pareto_size: 50Warm-Starting from Previous Campaigns
Resume or build on prior results:
python
from materia import Campaign
# Load previous campaign data
campaign = Campaign.from_yaml("campaign.yaml")
campaign.load_data("previous_results.csv")
# The surrogate starts pre-trained on existing data
campaign.run()Parallel Evaluation
For computationally expensive evaluations:
yaml
optimizer:
batch_size: 20 # Evaluate 20 candidates in parallel
n_workers: 4 # Use 4 parallel processes
batch_strategy: cl # Constant Liar for batch selectionMonitoring Callbacks
Add custom monitoring logic:
python
def on_iteration(campaign, iteration, results):
best = results.best_objectives()
print(f"Iter {iteration}: capacity={best['capacity']:.1f}, cost={best['cost']:.2f}")
if best["capacity"] > 200:
campaign.stop("Target capacity reached")
campaign.add_callback("on_iteration", on_iteration)