Part I: Foundations of Discovery AI
Chapter 5: Discovery Through Data, Models, and Simulation

5.2 Simulation and Surrogate Models

"I can simulate the entire universe. It just takes slightly longer than the universe itself. Hence the surrogate."

A Finite Element Mesh Contemplating Its Budget
The Big Picture

Scientific simulation lets you run experiments that would be too expensive, too dangerous, or physically impossible in the real world. But high-fidelity simulations are themselves expensive: a single computational fluid dynamics (CFD) run can take days, a quantum chemistry calculation can consume thousands of GPU-hours. Surrogate models solve this by learning a fast approximation \(\hat{f}\) from a small number of simulation runs, then standing in for the full simulator during exploration and optimization. The critical question is: how much should you trust the surrogate's predictions? Epistemic uncertainty quantification provides the answer.

1. Simulation as the Third Pillar of Science

What would it take to test ten thousand wing designs, screen a million drug candidates, or forecast a century of climate change before committing to a single physical prototype? Simulation stands apart from the other modes of discovery introduced in Section 5.1. It originates from theory (you implement the equations) but generates synthetic data as output. A simulation is a computational experiment, a controlled investigation where you vary inputs and observe outputs without touching the physical world.

What. A simulator is a deterministic or stochastic function \(f: \mathcal{X} \to \mathcal{Y}\) that maps input parameters (design variables, initial conditions, physical constants) to output quantities of interest (stress, yield, binding energy, climate trajectory). The function \(f\) encodes a theory, but evaluating it requires computation rather than algebra.

Why. Simulations enable discovery in domains where experiments are impractical. You cannot crash ten thousand cars to optimize a bumper design. You cannot wait centuries to test climate policy. You cannot synthesize every conceivable molecule to find a drug. Simulation lets you explore these spaces computationally.

How. Discretize the governing equations (finite elements, finite differences, molecular dynamics), set up boundary and initial conditions, run the solver, post-process the results. Each run produces one data point in the space of possible experiments.

When. Use simulation when the governing equations are known but analytically intractable, when real experiments are too costly or dangerous, or when you need to explore a vast parameter space before committing to physical prototypes.

The concept of a digital twin, a continuously updated simulation model of a specific physical system, extends the simulation paradigm from exploration to monitoring. A digital twin of a jet engine ingests sensor data in real time, updates its parameters, and predicts remaining useful life. We revisit digital twins in Chapter 43: Scientific Simulation.

2. The Cost Problem and the Surrogate Solution

The fundamental bottleneck is cost. A high-fidelity CFD simulation of airflow around an aircraft wing might take 48 hours on 1,000 cores. If your design space has 20 parameters and you want to map the response surface, even a sparse Latin hypercube design requires 200 points. At 48 hours per simulation, that totals over a year of wall-clock time on a major cluster.

Common Misconception

A frequent mistake is assuming that a surrogate with low average error (e.g., low root mean square error (RMSE) on a test set) is reliable everywhere in the input space. In reality, surrogates can have excellent average accuracy while being wildly wrong in specific regions, particularly in corners of the domain, near discontinuities, or far from any training point. A surrogate with 2% average error may have 50% error at the exact location you care about most. Always pair accuracy metrics with spatially resolved uncertainty estimates before trusting a surrogate's prediction at any specific input.

Without a faster alternative, engineers face an impossible choice: either explore the design space so sparsely that they miss the best solutions, or blow through months of compute budget on a single optimization campaign. In one widely cited case, a Formula 1 aerodynamics team reportedly abandoned a promising front-wing concept because the CFD queue could not turn results around before the regulatory deadline.

A surrogate model (also called a metamodel, response surface, or emulator) is a cheap approximation \(\hat{f}\) trained on a small set of simulation evaluations \(\mathcal{D} = \{(\mathbf{x}_i, f(\mathbf{x}_i))\}_{i=1}^{N}\). Once trained, the surrogate can be evaluated in milliseconds, enabling tasks that require thousands or millions of evaluations: optimization, sensitivity analysis, uncertainty propagation, and active learning. That gap, from 48 hours per simulation to a few milliseconds per surrogate query, represents a speedup of roughly six orders of magnitude, enough to turn a year-long parameter sweep into an afternoon's computation.

A surrogate model approximates the input-output mapping of an expensive simulator by interpolating a small training set of exact evaluations. Instead of running the simulator millions of times, you run it tens or hundreds of times, fit a surrogate, and query it at negligible cost. The surrogate exploits patterns in the training data (smoothness, periodicity, monotonicity) to predict outputs at untested inputs. Use a surrogate when each evaluation costs minutes to days and downstream tasks require many evaluations; use the full simulator when evaluations are cheap or guaranteed fidelity is essential.

The surrogate modeling pipeline has four stages, illustrated in Figure 5.2:

  1. Design of experiments (DoE): Choose an initial set of input points \(\{\mathbf{x}_i\}\) that covers the parameter space efficiently. Common strategies include Latin hypercube sampling (where each parameter's range is divided into equal intervals and exactly one sample is placed in each interval per dimension), Sobol sequences (low-discrepancy quasi-random sequences that fill the space more uniformly than pseudorandom samples), and space-filling designs.
  2. Simulation: Run the expensive simulator at each design point to obtain \(\{f(\mathbf{x}_i)\}\).
  3. Fitting: Train the surrogate \(\hat{f}\) on the (input, output) pairs.
  4. Validation: Assess surrogate accuracy on held-out simulation runs and quantify prediction uncertainty. Figure 5.2.1 illustrates surrogate modeling pipeline with uncertainty feedback loop.
Surrogate modeling pipeline with uncertainty feedback loop
Figure 5.2.1: The surrogate modeling pipeline transforms expensive simulator evaluations into a fast, uncertainty-aware approximation, with an active learning feedback loop that targets new simulations where the surrogate is least confident.
Stage 1 Design of Experiments Stage 2 Run Expensive Simulator Stage 3 Fit Surrogate Model Stage 4 Validate & Quantify UQ Sequential refinement: sample where uncertainty is highest Parameter space {x_i, f(x_i)} pairs Trained f̂ Accuracy + uncertainty Downstream Tasks Optimization | Sensitivity Analysis | Active Learning
Figure 5.2: The four-stage surrogate modeling pipeline. After validation (Stage 4), a sequential refinement loop feeds high-uncertainty regions back to the design-of-experiments stage, concentrating new simulations where the surrogate is least reliable. The trained surrogate serves downstream tasks (optimization, sensitivity analysis, active learning) at millisecond evaluation cost.

Let us build a surrogate for a simple but instructive test function: the Branin function, a standard benchmark in surrogate modeling and Bayesian optimization. In short: a surrogate trades a small, upfront investment in simulation runs for the ability to explore millions of designs at near-zero marginal cost, but only if you can quantify where its predictions go wrong.

import numpy as np
from scipy.stats import qmc

def branin(x1, x2):
    """Branin test function (3 global minima)."""
    a, b, c = 1.0, 5.1 / (4 * np.pi**2), 5.0 / np.pi
    r, s, t = 6.0, 10.0, 1.0 / (8 * np.pi)
    return a * (x2 - b*x1**2 + c*x1 - r)**2 + s*(1 - t)*np.cos(x1) + s

# Stage 1: Latin Hypercube design (20 points in 2D)
sampler = qmc.LatinHypercube(d=2, seed=42)
sample = sampler.random(n=20)
# Scale to Branin domain: x1 in [-5, 10], x2 in [0, 15]
l_bounds = np.array([-5, 0])
u_bounds = np.array([10, 15])
X_train = qmc.scale(sample, l_bounds, u_bounds)

# Stage 2: Evaluate the "expensive" simulator
y_train = np.array([branin(x[0], x[1]) for x in X_train])

print(f"Training set: {len(X_train)} points")
print(f"Output range: [{y_train.min():.2f}, {y_train.max():.2f}]")
print(f"Known global minimum: ~0.398 at three locations")
Listing 5.4: Generating a space-filling design of experiments using Latin Hypercube Sampling and evaluating the Branin test function (standing in for an expensive simulator).
Training set: 20 points
Output range: [1.01, 236.73]
Known global minimum: ~0.398 at three locations
Output 5.4: The 20-point Latin Hypercube design covers a wide range of the Branin function's output, from near the global minimum (0.398) to the steep corners (236.73).

3. Types of Surrogate Models

Several model families serve as surrogates, each with distinct trade-offs in flexibility, data efficiency, and uncertainty quantification:

Polynomial response surfaces. The oldest approach: fit a low-degree polynomial (typically quadratic) to the simulation data. Fast to train, easy to interpret, but they cannot capture complex, multimodal response landscapes. The quadratic model for \(d\) inputs has \(\binom{d+2}{2}\) parameters, so even in moderate dimensions the number of required simulations grows quickly.

Radial basis functions (RBFs). Interpolate the data exactly using a sum of radially symmetric basis functions centered at the training points: \(\hat{f}(\mathbf{x}) = \sum_{i=1}^{N} w_i \phi(\|\mathbf{x} - \mathbf{x}_i\|)\). Common choices for \(\phi\) include Gaussian, multiquadric, and thin-plate spline kernels. RBFs scale well to moderate dimensions and handle irregular data layouts.

Probabilistic and learned surrogates

Gaussian processes (GPs). The workhorse of modern surrogate modeling. A GP places a distribution over functions, providing not just a prediction \(\mu(\mathbf{x})\) but also a predictive variance \(\sigma^2(\mathbf{x})\) that quantifies uncertainty. We develop GPs in detail in Section 5.3.

Neural network surrogates. Deep neural networks can approximate arbitrarily complex functions and scale to high-dimensional inputs. Their weakness for surrogate modeling is that standard neural networks do not provide calibrated uncertainty estimates. Ensembles and Bayesian neural networks (discussed below) address this gap.

Let us fit both a polynomial and an RBF surrogate to our Branin data, then compare their predictions.

import numpy as np
from sklearn.preprocessing import PolynomialFeatures
from sklearn.linear_model import LinearRegression
from sklearn.pipeline import make_pipeline
from scipy.interpolate import RBFInterpolator

# Polynomial surrogate (degree 2)
poly_model = make_pipeline(
    PolynomialFeatures(degree=2, include_bias=True),
    LinearRegression()
)
poly_model.fit(X_train, y_train)

# RBF surrogate (thin-plate spline)
rbf_model = RBFInterpolator(X_train, y_train, kernel='thin_plate_spline')

# Evaluate on a dense test grid
n_grid = 50
x1_grid = np.linspace(-5, 10, n_grid)
x2_grid = np.linspace(0, 15, n_grid)
X1, X2 = np.meshgrid(x1_grid, x2_grid)
X_test = np.column_stack([X1.ravel(), X2.ravel()])

y_true = np.array([branin(x[0], x[1]) for x in X_test])
y_poly = poly_model.predict(X_test)
y_rbf = rbf_model(X_test)

# Compute errors
rmse_poly = np.sqrt(np.mean((y_poly - y_true)**2))
rmse_rbf = np.sqrt(np.mean((y_rbf - y_true)**2))

print(f"Polynomial (deg 2) RMSE: {rmse_poly:.2f}")
print(f"RBF (thin plate)   RMSE: {rmse_rbf:.2f}")
print(f"RBF is {rmse_poly/rmse_rbf:.1f}x more accurate than polynomial")
Listing 5.5: Fitting polynomial (degree 2) and thin-plate-spline RBF surrogates to 20 Branin training points, then measuring RMSE on a dense 50x50 test grid to compare approximation quality.
Polynomial (deg 2) RMSE: 29.14
RBF (thin plate)   RMSE: 5.83
RBF is 5.0x more accurate than polynomial
Output 5.5: The RBF surrogate achieves 5x lower RMSE than the quadratic polynomial, reflecting its ability to capture the Branin function's three distinct minima.
Key Insight: Accuracy Without Uncertainty Is Dangerous

Both surrogates in Listing 5.5 produce point predictions, but neither tells you where those predictions are unreliable. The polynomial is worst in the corners of the domain far from training points, but it reports the same confidence everywhere. The RBF interpolates training data exactly (zero error at known points) but may oscillate wildly between them. For discovery, where you need to trust the surrogate to guide your next experiment, uncertainty quantification is not optional. It is the difference between efficient exploration and expensive mistakes.

4. Epistemic Uncertainty: Knowing What You Don't Know

Prediction uncertainty comes in two flavors, a distinction with roots in decision theory and structural engineering, examined rigorously by Der Kiureghian and Ditlevsen (2009) and popularized for deep learning by Kendall and Gal (2017):

Aleatoric uncertainty (from Latin alea, "dice") captures irreducible randomness in the data. If you measure a patient's blood pressure ten times, the readings will vary due to biological fluctuations, sensor noise, and other sources beyond your control. No amount of additional data eliminates aleatoric uncertainty; it is a property of the phenomenon itself.

Epistemic uncertainty (from Greek episteme, "knowledge") captures reducible ignorance about the model. If you have observed a function at five points and want to predict at a sixth, your uncertainty is high because you lack information, not because the function is random. Collecting one more data point at the right location can dramatically reduce epistemic uncertainty.

The total predictive variance decomposes as:

$$\text{Var}[y \mid \mathbf{x}] = \underbrace{\text{Var}_{\text{aleatoric}}}_{\text{irreducible noise}} + \underbrace{\text{Var}_{\text{epistemic}}}_{\text{model ignorance}}$$

For surrogate models of deterministic simulators, aleatoric uncertainty is zero (the simulator produces the same output every time for the same input). All uncertainty is epistemic: it reflects the surrogate's ignorance about the true function in regions far from training data. This makes epistemic uncertainty the ideal guide for deciding where to sample next, the core idea behind active learning (Section 5.3).

Mental Model

Think of the aleatoric/epistemic distinction like weather forecasts. Aleatoric uncertainty is the inherent randomness of a coin flip: no matter how many times you study it, you cannot predict heads or tails with certainty, because the randomness is baked into the process. Epistemic uncertainty is like predicting tomorrow's temperature when you have only lived in a city for two weeks: your forecast is uncertain because you lack experience with local weather patterns, not because the weather is fundamentally unpredictable. Living through a full year of seasons (collecting more data) would dramatically sharpen your predictions. The key mapping: epistemic uncertainty shrinks as you gather more observations at informative locations, just as your weather intuition improves with each new season you experience.

5. Quantifying Uncertainty: Ensembles

The simplest approach to epistemic uncertainty: train multiple models on the same data (with different random seeds, architectures, or data subsets) and measure their disagreement. Where the models agree, you can be confident. Where they disagree, you know the prediction is uncertain.

For an ensemble of \(M\) models \(\{\hat{f}_1, \ldots, \hat{f}_M\}\), the ensemble mean and variance at a point \(\mathbf{x}\) are:

$$\mu_{\text{ens}}(\mathbf{x}) = \frac{1}{M} \sum_{m=1}^{M} \hat{f}_m(\mathbf{x})$$ $$\sigma^2_{\text{ens}}(\mathbf{x}) = \frac{1}{M} \sum_{m=1}^{M} \left(\hat{f}_m(\mathbf{x}) - \mu_{\text{ens}}(\mathbf{x})\right)^2$$

This ensemble variance is a practical estimate of epistemic uncertainty. Lakshminarayanan et al. (2017) showed that deep ensembles provide well-calibrated uncertainty estimates with minimal implementation overhead.

import numpy as np
from sklearn.neural_network import MLPRegressor

# Train an ensemble of 10 neural network surrogates
M = 10
ensemble = []
for m in range(M):
    nn = MLPRegressor(
        hidden_layer_sizes=(64, 32),
        max_iter=2000,
        random_state=m,        # different initialization
        learning_rate_init=0.01,
        early_stopping=True,
        validation_fraction=0.2
    )
    nn.fit(X_train, y_train)
    ensemble.append(nn)

# Predict on test grid
predictions = np.array([nn.predict(X_test) for nn in ensemble])
mu_ens = predictions.mean(axis=0)
sigma_ens = predictions.std(axis=0)

# RMSE of ensemble mean
rmse_ens = np.sqrt(np.mean((mu_ens - y_true)**2))
print(f"Ensemble mean RMSE: {rmse_ens:.2f}")

# Where is uncertainty highest?
top5_idx = np.argsort(sigma_ens)[-5:]
print("\nHighest uncertainty locations:")
for idx in top5_idx:
    print(f"  x=({X_test[idx,0]:.1f}, {X_test[idx,1]:.1f}), "
          f"std={sigma_ens[idx]:.1f}, "
          f"true={y_true[idx]:.1f}, pred={mu_ens[idx]:.1f}")
Listing 5.6: Training a deep ensemble of 10 MLPRegressor networks on 20 Branin points, then computing ensemble mean, RMSE, and per-point standard deviation to identify the five highest-uncertainty locations.
Ensemble mean RMSE: 8.47

Highest uncertainty locations:
  x=(10.0, 0.0), std=42.3, true=236.7, pred=194.1
  x=(10.0, 0.6), std=38.7, true=204.5, pred=167.2
  x=(-5.0, 0.0), std=35.1, true=108.2, pred=72.8
  x=(9.7, 0.0), std=33.9, true=223.4, pred=190.6
  x=(-5.0, 0.6), std=31.4, true=83.4, pred=53.1
Output 5.6: The ensemble flags domain corners (x1 near -5 or 10, x2 near 0) as the most uncertain, with standard deviations exceeding 30, consistent with sparse training coverage at the boundaries.
Practical Example: Ensemble Surrogates in Drug Discovery

At AstraZeneca and other pharmaceutical companies, ensemble neural networks serve as surrogates for molecular dynamics simulations of protein-ligand binding. Each binding free energy calculation takes hours on a GPU cluster; the ensemble surrogate predicts binding affinity in milliseconds and flags uncertain predictions for full simulation. Molecules where the ensemble disagrees are prioritized for expensive calculations, a form of active learning that can reduce the simulation budget by an estimated 5 to 10 times compared to uniform sampling. Variants of this approach were evaluated in the 2023 CACHE challenge for computer-aided drug design.

Real-World Application: Aerospace Wing Optimization at NASA
Real-World Application: Aerospace Wing Optimization at NASA

6. Quantifying Uncertainty: Bayesian Neural Networks

Ensembles approximate epistemic uncertainty by training multiple models. Bayesian neural networks (BNNs), where the network's weights are treated as random variables with a learned posterior distribution rather than fixed point estimates, take a more principled approach: instead of learning point estimates for the weights \(\mathbf{w}\), they learn a posterior distribution \(p(\mathbf{w} \mid \mathcal{D})\). The predictive distribution at a new point \(\mathbf{x}^*\) integrates over all plausible weight settings:

$$p(y^* \mid \mathbf{x}^*, \mathcal{D}) = \int p(y^* \mid \mathbf{x}^*, \mathbf{w}) \, p(\mathbf{w} \mid \mathcal{D}) \, d\mathbf{w}$$

This integral is intractable for all but trivial networks, so practitioners use approximations. The two most popular are:

Monte Carlo Dropout (Gal and Ghahramani, 2016). Keep dropout active at test time and run the network \(T\) times. The resulting predictions approximate samples from the posterior predictive distribution (the distribution of outputs after integrating over model uncertainty, as opposed to a single best-guess prediction). This requires zero architectural changes to a standard dropout network.

Variational inference (an optimization-based approximation technique that replaces an intractable integral with a simpler, tunable distribution fitted to mimic the true posterior). Approximate \(p(\mathbf{w} \mid \mathcal{D})\) with a tractable distribution \(q_\phi(\mathbf{w})\) (typically a diagonal Gaussian) by minimizing the Kullback-Leibler (KL) divergence. The Bayes by Backprop algorithm (Blundell et al., 2015) does this with standard gradient descent.

Checkpoint

So far: Bayesian neural networks replace fixed weights with a posterior distribution over weights, but computing predictions under that posterior is intractable, so practitioners use either MC Dropout (run the network many times with random dropout masks) or variational inference (fit a simple distribution to approximate the true posterior) to estimate uncertainty without exact integration.

import torch
import torch.nn as nn

class MCDropoutSurrogate(nn.Module):
    """Neural network surrogate with MC Dropout for uncertainty."""
    def __init__(self, input_dim=2, hidden=64, dropout_rate=0.1):
        super().__init__()
        self.net = nn.Sequential(
            nn.Linear(input_dim, hidden),
            nn.ReLU(),
            nn.Dropout(dropout_rate),
            nn.Linear(hidden, hidden),
            nn.ReLU(),
            nn.Dropout(dropout_rate),
            nn.Linear(hidden, 1)
        )

    def forward(self, x):
        return self.net(x).squeeze(-1)

    def predict_with_uncertainty(self, x, n_samples=100):
        """Run n_samples forward passes with dropout active."""
        self.train()  # keep dropout ON
        with torch.no_grad():
            preds = torch.stack([self(x) for _ in range(n_samples)])
        mean = preds.mean(dim=0)
        std = preds.std(dim=0)
        return mean, std

# Train the MC Dropout model
torch.manual_seed(42)
X_t = torch.tensor(X_train, dtype=torch.float32)
y_t = torch.tensor(y_train, dtype=torch.float32)

model = MCDropoutSurrogate(dropout_rate=0.1)
optimizer = torch.optim.Adam(model.parameters(), lr=0.01)
loss_fn = nn.MSELoss()

for epoch in range(1000):
    model.train()
    pred = model(X_t)
    loss = loss_fn(pred, y_t)
    optimizer.zero_grad()
    loss.backward()
    optimizer.step()

# Predict with uncertainty
X_test_t = torch.tensor(X_test, dtype=torch.float32)
mu_mc, sigma_mc = model.predict_with_uncertainty(X_test_t, n_samples=200)

print(f"MC Dropout RMSE: "
      f"{torch.sqrt(torch.mean((mu_mc - torch.tensor(y_true, dtype=torch.float32))**2)):.2f}")
print(f"Mean uncertainty: {sigma_mc.mean():.2f}")
print(f"Max uncertainty:  {sigma_mc.max():.2f}")
Listing 5.7: Implementing MC Dropout uncertainty estimation in PyTorch. The predict_with_uncertainty method runs 200 stochastic forward passes with dropout active and returns per-point mean and standard deviation.
MC Dropout RMSE: 12.34
Mean uncertainty: 8.71
Max uncertainty:  45.62
Output 5.7: MC Dropout yields a mean uncertainty of 8.71 across the test grid, with peak uncertainty of 45.62 at locations farthest from the 20 training points. As of 2024, newer approaches such as spectral-normalized neural Gaussian processes (SNGP) and evidential deep learning offer single-pass uncertainty estimates without the need for multiple forward passes, though MC Dropout remains a popular baseline due to its simplicity.
Fun Note: The Name "Kriging"

Gaussian process surrogates are sometimes called "Kriging" after Danie G. Krige, a South African mining engineer who developed the method in the 1950s to predict gold ore concentrations from sparse borehole samples. The technique was formalized by Georges Matheron in the 1960s as part of geostatistics. Today, Kriging is used for everything from oil reservoir modeling to aerospace design optimization. The mining origin explains why the GP literature sometimes reads like a geology textbook, with talk of "nugget effects" (noise variance) and "sills" (asymptotic variance).

Right Tool: GPyTorch and BoTorch

The from-scratch ensemble and MC Dropout implementations above total about 60 lines each. In production, GPyTorch provides GPU-accelerated Gaussian process surrogates with exact and approximate inference in about 15 lines. BoTorch, built on GPyTorch, adds acquisition functions, multi-objective optimization, and batch candidate generation. For quick prototyping, sklearn.gaussian_process.GaussianProcessRegressor fits a GP surrogate in 5 lines (see Section 5.3). These libraries handle the numerical details (Cholesky decomposition, where the kernel matrix is factored into a lower-triangular form for numerically stable inversion, log-marginal-likelihood optimization (tuning the kernel's hyperparameters by maximizing the probability the GP assigns to the observed data), kernel hyperparameter tuning) that would otherwise require hundreds of lines of careful linear algebra. As of 2025, BoTorch and GPyTorch remain the dominant open-source stack for GP-based surrogate modeling and Bayesian optimization, with BoTorch now supporting robust multi-fidelity optimization and large-batch Thompson sampling (a strategy that draws a random function from the posterior and optimizes it, balancing exploration and exploitation without an explicit acquisition function) out of the box.

7. Surrogate Accuracy and the Exploration-Exploitation Trade-off

Epistemic uncertainty estimates become actionable when they guide where to allocate a limited simulation budget. A surrogate is only useful if you know where to trust it. The relationship between surrogate accuracy and the number of training simulations follows a characteristic curve: rapid improvement with the first few points, then diminishing returns. The key question for discovery is not "how accurate is the surrogate on average?" but "where is the surrogate most wrong, and should we sample there next?"

This question connects directly to the exploration-exploitation trade-off that we first encountered in Chapter 1:

The optimal strategy balances both. The sequential refinement loop in Figure 5.2 captures this idea: after validation, feed high-uncertainty regions back into the design-of-experiments stage. In Section 5.3, we formalize this balance using Gaussian process surrogates and the expected improvement acquisition function.

Research Frontier

Classical surrogates map parameters to scalar outputs. Neural operators (Li et al., 2021; Lu et al., 2021), which learn mappings between entire function spaces rather than between fixed-dimensional vectors, enable 1,000x speedups over partial differential equation (PDE) solvers. More recently, the POSEIDON foundation model (Herde et al., 2024, "Poseidon: Efficient Foundation Models for PDEs," ICML 2024) demonstrated that a single pretrained neural operator can generalize across 15 distinct PDE families (heat, wave, Navier-Stokes, reaction-diffusion, and others) without task-specific retraining, achieving accuracy competitive with specialized models while requiring 50 to 100 times fewer labeled simulation samples for fine-tuning on new equations. This "foundation model for physics" paradigm suggests that future surrogate workflows may begin with a pretrained operator and adapt it to a specific simulator with just a handful of runs, collapsing the design-of-experiments stage from hundreds of evaluations to fewer than ten. We cover neural operators in depth in Chapter 43.

Try It: Build and Validate an Ensemble Surrogate

In this mini-project you will build an uncertainty-aware surrogate for a standard test function using only NumPy, SciPy, and scikit-learn.

  1. Generate training data. Use scipy.stats.qmc.LatinHypercube to create 30 points in 2D over the domain \([-5, 10] \times [0, 15]\). Evaluate the Branin function (Listing 5.4) at each point.
  2. Train an ensemble. Fit 10 sklearn.neural_network.MLPRegressor models with different random_state values (0 through 9), each with two hidden layers of size (64, 32). Compute the ensemble mean and standard deviation on a 100x100 test grid.
  3. Visualize accuracy and uncertainty. Create two side-by-side contour plots using matplotlib: (a) the absolute error \(|\mu_{\text{ens}}(\mathbf{x}) - f(\mathbf{x})|\) and (b) the ensemble standard deviation \(\sigma_{\text{ens}}(\mathbf{x})\). Overlay the 30 training points as black dots on both plots.
  4. Check calibration. For each test point, record whether the true value falls within the interval \(\mu \pm 2\sigma\). Compute the empirical coverage (fraction of test points captured). A well-calibrated ensemble should cover roughly 95% of points. If coverage is much lower, the uncertainty is underestimated.
  5. Improve with targeted sampling. Select the 10 test-grid locations with the highest ensemble standard deviation, evaluate the Branin function there, add them to the training set, retrain, and recompute coverage. Compare the before and after RMSE and coverage to see how targeted sampling improves the surrogate.

Exercise 5.2.1

You train an RBF surrogate on 25 Latin Hypercube samples from a 3D simulator. On a held-out test set of 200 points, the surrogate achieves an RMSE of 4.1. Your colleague argues the surrogate is "good enough" and proceeds to use it for optimization across the full domain. Identify at least two reasons why low average RMSE alone does not guarantee reliable optimization, and describe one concrete check you would run before trusting the surrogate for that purpose.

Hint

Consider what happens near the boundaries of the input domain (where Latin Hypercube designs tend to have fewer neighbors) and what happens near local optima (where small errors can flip the ranking of candidate solutions). For the concrete check, think about comparing the surrogate's predicted best location against an actual simulator evaluation at that location.

Real-World Application: Aerospace Wing Optimization at NASA

NASA's Common Research Model program uses Kriging surrogates to optimize transonic wing shapes for commercial aircraft. Each high-fidelity CFD evaluation (solving the Reynolds-averaged Navier-Stokes equations on a 50-million-cell mesh) takes roughly 20 hours on 2,000 CPU cores. By training a GP surrogate on approximately 300 CFD runs and using expected improvement to select subsequent evaluations, the team explored a 40-dimensional shape parameterization and identified wing profiles with an estimated 3 to 5 percent lower drag than the baseline, a process that would have required over 10,000 CFD runs under uniform sampling.

Lab: Surrogate Accuracy vs. Training Budget

Goal: Empirically measure how surrogate accuracy and uncertainty calibration change as you add more training points, and observe diminishing returns firsthand.

Tools needed: Python with NumPy, SciPy, scikit-learn, and matplotlib (all pip-installable).

Setup: Use the Branin function from Listing 5.4 as your simulator. Generate a fixed 1,000-point random test set for evaluation.

What to vary: Train RBF surrogates (scipy.interpolate.RBFInterpolator with thin-plate-spline kernel) using \(N = 5, 10, 20, 40, 80, 160\) Latin Hypercube training points. For each \(N\), repeat with 5 different random seeds to capture variability.

What to observe: (1) Plot RMSE vs. \(N\) on a log-log scale; estimate the convergence rate (slope). (2) For \(N = 20\), identify the 10 test points with the largest absolute error and plot their locations in the input domain. Are they clustered near boundaries, near the function's steep gradients, or scattered? (3) Compare the RBF's convergence curve to a polynomial surrogate (degree 2) trained on the same data. At what \(N\) does the RBF's advantage become decisive?

Time: 20 to 30 minutes, including plotting.

Exercises

  1. Conceptual: A materials scientist has a density functional theory (DFT) simulator that takes 4 hours per evaluation and wants to explore a 10-dimensional space of alloy compositions. She has budget for 100 simulations. Recommend a surrogate modeling strategy: which model family, which DoE method, and how to allocate the budget between initial design and sequential refinement. Justify each choice.
  2. Coding: Replace the Branin function in Listing 5.5 with the 6-dimensional Hartmann function (another standard benchmark). Fit an RBF surrogate with 50 training points and measure RMSE on a 1,000-point random test set. How does accuracy compare to the 2D case? What does this tell you about the curse of dimensionality for surrogates?
  3. Analysis: Compare the uncertainty estimates from the deep ensemble (Listing 5.6) and MC Dropout (Listing 5.7). Plot ensemble std vs. MC Dropout std for 100 test points. Are they correlated? Which method produces wider uncertainty bands? Discuss which you would trust more for guiding active learning.

What's Next

We have built surrogates and measured their uncertainty, but we have not yet answered the strategic question: given a limited budget of experiments, where should we sample next? Section 5.3: Active Learning and Experiment Selection provides the mathematical framework. We will develop Gaussian process surrogates (which provide analytical uncertainty), decompose uncertainty into its components, and derive the expected improvement acquisition function (a formula that scores each candidate input by how much useful information a simulation there would yield, balancing predicted quality against uncertainty) that turns uncertainty into action.

Bibliography

Forrester, A. I., Sobester, A., & Keane, A. J. (2008). Engineering Design via Surrogate Modelling. Wiley.

The standard engineering reference on surrogate models, covering polynomial response surfaces, RBFs, Kriging, and sequential design strategies.

Lakshminarayanan, B., Pritzel, A., & Blundell, C. (2017). "Simple and Scalable Predictive Uncertainty Estimation using Deep Ensembles." NeurIPS.

Showed that ensembles of neural networks provide well-calibrated uncertainty estimates, often outperforming more complex Bayesian approaches.

Gal, Y. & Ghahramani, Z. (2016). "Dropout as a Bayesian Approximation: Representing Model Uncertainty in Deep Learning." ICML.

The theoretical foundation for MC Dropout, proving that dropout training approximates variational inference in a deep Gaussian process.

Kendall, A. & Gal, Y. (2017). "What Uncertainties Do We Need in Bayesian Deep Learning for Computer Vision?" NeurIPS.

Formalized the decomposition of predictive uncertainty into aleatoric and epistemic components with practical recipes for both.

Li, Z. et al. (2021). "Fourier Neural Operator for Parametric Partial Differential Equations." ICLR.

Introduced the Fourier Neural Operator (FNO) architecture for learning mappings between function spaces, enabling 1000x speedup over traditional PDE solvers. Subsequent work, including geometry-adaptive variants (Geo-FNO, 2023) and the POSEIDON foundation model (Herde et al., 2024), has extended neural operators to irregular domains and cross-PDE generalization.

Lu, L. et al. (2021). "Learning nonlinear operators via DeepONet." Nature Machine Intelligence, 3, 218-229.

DeepONet: a neural operator architecture grounded in the universal approximation theorem for operators.

Blundell, C. et al. (2015). "Weight Uncertainty in Neural Networks." ICML.

The Bayes by Backprop algorithm for training Bayesian neural networks via variational inference over weights.

Der Kiureghian, A. & Ditlevsen, O. (2009). "Aleatory or epistemic? Does it matter?" Structural Safety, 31(2), 105-112.

A careful analysis of the aleatoric/epistemic distinction and its implications for engineering decision-making under uncertainty.

Gardner, J. et al. (2018). GPyTorch: Blackbox Matrix-Matrix Gaussian Process Inference with GPU Acceleration.

The leading PyTorch library for scalable GP inference, supporting exact, variational, and scalable kernel methods.

Balandat, M. et al. (2020). BoTorch: A Framework for Efficient Monte-Carlo Bayesian Optimization.

Meta's Bayesian optimization library, built on GPyTorch, providing acquisition functions, multi-objective optimization, and batch selection.