← Back to writing

Neural surrogates for physics-based inverse problems

When the forward model is slow, the prior is cheap, and the data is small.

Physics-based inverse problems live in a strange corner of ML. The forward model is expensive but exact; the dataset is small but informative; the prior is cheap because you already know how the system works. A neural surrogate lets you keep the physics and still run the inverse loop in real time.

I spent years on both ends of this problem — writing the light-transport simulators that serve as ground truth, and building the neural inverse solvers that have to run on a device in the clinic. What follows is the shape of the approach that survived contact with production.

The setup

The problem is inversion. You measure something — spectral reflectance, say — and you want the underlying parameters that produced it: absorption and scattering coefficients, the physiological quantities downstream of those. There is a forward model that maps parameters to measurements, and it is good. In our case it is Monte-Carlo photon transport: physically faithful, validated against bench-top phantoms, and far too slow to run inside an inverse loop on embedded hardware.

The classic move is iterative inversion. Guess parameters, run the forward model, compare to the measurement, update the guess, repeat. It works, and for offline analysis it is often the right answer. But every iteration is a forward evaluation, and if the forward model is a Monte-Carlo simulation, "real time on a CM4" is not a sentence you get to say.

So you have three facts to exploit. The forward model is expensive but you can run it as much as you want offline. The data is small but each sample is dense with physics. And the prior is unusually strong — you are not learning the world from scratch, you are learning a map you can already compute.

Learn the map, then invert through it

The surrogate approach splits the problem in two. First, train a fast neural approximation of the forward model — or, more usefully, of the inverse map directly — using the simulator as an inexhaustible, perfectly-labeled data generator. Then deploy the fast network where the physics can't go.

Because the forward model is exact, your training set is not something you scrape and clean. You sample it. You choose the region of parameter space that matters clinically, sample it densely, push each sample through the simulator, and get a labeled pair for free. The simulator is a data factory with no annotation cost and no label noise.

# Offline: the simulator manufactures the training set.
theta = sample_priors(n=200_000)          # optical params over the clinical range
refl  = montecarlo_forward(theta)         # exact, slow, run once, cached

# Train the amortized inverse map: measurement -> parameters.
model = InverseNet()
opt   = torch.optim.Adam(model.parameters())
for xb, yb in loader(refl, theta):        # x = reflectance, y = params
    pred = model(xb)
    loss = mse(pred, yb) + physics_consistency(pred, xb)
    loss.backward(); opt.step(); opt.zero_grad()

The physics_consistency term is the part that matters and the part people skip. A pure regression from measurement to parameters will happily learn a map that fits the training pairs and quietly violates the physics between them. If you have a differentiable (or cheaply approximable) forward model, you can push the predicted parameters back through it and penalize disagreement with the measurement. Now the network is not just memorizing input-output pairs; it is being held to the same conservation the simulator obeys.

A surrogate that fits the data but not the physics is not a surrogate. It is a lookup table with opinions about the gaps.

Amortized versus iterative

What you have built is an amortized inverse. Iterative inversion pays its cost at inference — every measurement triggers an optimization. Amortized inversion moves that cost to training time and pays almost nothing at inference: one forward pass of a small network.

That trade is what makes on-device inference possible. It is also what delivered the kind of speed-ups that changed what the product could do — turning an inversion that belonged in an offline analysis pass into something that runs in the capture loop. When people quote a large computational speed-up on this class of problem, this is usually the mechanism: not a faster optimizer, but the elimination of the optimization entirely.

The catch is that amortization is only valid where you trained it. An iterative method, run to convergence, is at least honest about a hard measurement — it struggles visibly. An amortized network answers every input with equal confidence, including the ones it has never seen. Which brings us to the part that keeps me up at night.

Failure modes, and the guardrails that catch them

The dominant failure mode is out-of-distribution optics. The clinical world produces measurements your sampled parameter range did not anticipate — an unusual tissue type, a geometry you didn't simulate, a hardware drift that shifts the measurement off the manifold you trained on. The network does not know it is off-manifold. It extrapolates, silently, and returns a confident wrong answer. In a medical context, confident and wrong is the worst possible combination.

The guardrails that earned their keep:

  • Physics-consistency at inference, not just training. Run the prediction back through a fast forward approximation and check the residual against the actual measurement. A large residual means the network is extrapolating — refuse or flag rather than report.
  • Explicit in-distribution checks. Know the boundary of your training manifold and test each measurement against it. Cheap density or reconstruction-error checks catch most excursions before they reach a clinician.
  • Calibrated uncertainty, treated as load-bearing. A surrogate should say how sure it is, and that number has to mean something. The point of the uncertainty is to gate action, not to decorate a dashboard.
  • The slow path as a backstop. Keep the iterative solver available offline. When the fast path flags low confidence, you have somewhere to fall back to. Speed is the default, not the only option.

None of these are exotic. They are the difference between a demo that inverts beautifully on held-out simulation data and a system you are willing to run on a person.

When to reach for this

A neural surrogate is the right tool when the forward model is trustworthy and slow, the parameter space of interest is bounded and samplable, and you need inference fast enough that iterative methods are out. That describes a lot of physics-adjacent ML: optics, materials, some of geophysics, anywhere a good simulator exists but cannot run in the loop.

It is the wrong tool when the forward model is itself uncertain — then you are amortizing your own errors — or when the clinical distribution is so open that you cannot bound what you will see. In those cases the honesty of an iterative method, or a hybrid that uses the surrogate to warm-start a few refinement steps, is worth the latency.

The reason this approach is satisfying is that it refuses the usual trade. You do not give up the physics to get speed, and you do not give up speed to keep the physics. You compute the physics exhaustively where it is cheap — offline, in the simulator — and carry only its shadow, the trained map, to where it needs to be fast. The whole craft is in making sure the shadow never forgets what cast it.