How to use an ONNX neural network as a surrogate model

Objective:

This article explains how to import a pre-trained neural network (.onnx) into nTop as a surrogate model. A surrogate is a fast stand-in for an expensive simulation or a complex design relationship. nTop evaluates it natively in the notebook, and it behaves like any other scalar parameter, so you can use it as an objective or constraint in a Parameter Optimization.

Applies to:

  • Parameter Optimization
  • Import Neural Network
  • Dependent Parameter

Overview

The workflow chains four blocks, with an optional fifth for testing:

Independent Parameter (one per model input) → Parameter Group → Import Neural Network → Dependent Parameter → objective / constraint

# Block Role
1 Independent Parameter One per model input. Defines the label, default value, lower bound, and upper bound.
2 Parameter Group Collects the inputs in the order the model expects.
3 Import Neural Network Loads the .onnx file and produces a Surrogate Model.
4 Dependent Parameter (Surrogate overload) Evaluates the surrogate and exposes the result as a scalar parameter.
5 Evaluate Parameter (optional) Test-evaluates the dependent parameter against the input group.

Before you begin

Your ONNX model must meet these requirements:

  • It takes float32 inputs and returns float32 outputs.
  • You know the order of its inputs, the range of values it was trained on, and the unit system of its inputs and output.

Procedure

Step 1: Create one Independent Parameter per model input

Add an Independent Parameter block for each input of the model. Set the Label, Default Value, Lower Bound, and Upper Bound.

  • The bounds define the range the optimizer is allowed to explore. Make them match the range the network was trained on.
  • Give the bounds the units of the physical quantity (for example, mm), or leave them unitless for ratios.
  • Use meaningful labels. They appear in the optimizer setup and results.

Step 2: Combine the inputs in a Parameter Group

Add a Parameter Group block and connect the Independent Parameters to inputs 0, 1, 2, and so on. The index is the position in the model's input vector, so connect them in the same order the model was trained with.

If you'll use the group in more than one place (for example, by both the surrogate and Evaluate Parameter), wrap it in a variable so both connections hold.

Step 3: Import the neural network

Add an Import Neural Network block and set its inputs:

Input Description
Model Path to the .onnx file.
Inputs The Parameter Group from Step 2.
Reference Unit Gives the output its units, for example 1 MPa, 1 mm, or 1 for unitless. The network itself is unitless, so this is the only thing that gives the result dimensions.
Output Index Which model output to use. Defaults to 0, which is correct for a single-output model.

The block outputs a Surrogate Model.

Step 4: Create the Dependent Parameter

Add a Dependent Parameter block, choose the Surrogate overload, connect the Surrogate Model, and give it a descriptive Label such as Stiffness.

Note: nTop has two Dependent Parameter overloads. One takes a function and the other takes a surrogate. Use the surrogate overload here. For the function version, see How to set up the Dependent Parameter.

Step 5 [OPTIONAL]: Test the evaluation

Add an Evaluate Parameter block. Connect the Dependent Parameter and the Parameter Group (as Input Parameters). It returns a real number at the default input values, which confirms the surrogate evaluates before you wire up the optimizer.

Step 6: Use it in your optimization

Use the Dependent Parameter as an objective or constraint in your Parameter Optimization, the same as any other scalar parameter.

Example

Consider a small fully connected regression network with 3 inputs and 1 output:

input [1,3] → Gemm (8x3) → ReLU → Gemm (4x8) → ReLU → Gemm (1x4) → output [1,1]

The notebook is set up as follows:

Block Settings
Independent Parameter (index 0) label wall_thickness, default 2 mm, lower 0.5 mm, upper 5 mm
Independent Parameter (index 1) label infill_density, default 0.5, lower 0.1, upper 1 (unitless)
Independent Parameter (index 2) label strut_radius, default 1 mm, lower 0.2 mm, upper 2 mm
Parameter Group inputs 0, 1, 2 connected to the three parameters, in that order
Import Neural Network Model = path to the .onnx, Inputs = the group, Reference Unit = 1 MPa, Output Index = default
Dependent Parameter (surrogate overload) Surrogate = the imported model, Label = Stiffness
Evaluate Parameter Dependent Parameter = Stiffness, Input Parameters = the group

Because the output has shape [1,1], there is a single output and Output Index = 0 is correct. This is a demo network, so don't read its output as a physical result.

Models with multiple outputs

Add one Import Neural Network block and one Dependent Parameter block per output, each with a different Output Index (0, 1, 2, and so on).

Requirements and common pitfalls

  • Input order is positional. nTop doesn't match inputs by name. If the order in the Parameter Group differs from the order used in training, you'll get plausible-looking but wrong numbers and no error. Document the meaning and order of each index next to the group.
  • Input ranges. The network only knows the range it was trained on. If the model was trained on normalized inputs, scale your parameters to match. Keep the optimizer bounds inside the training range, because surrogates extrapolate badly.
  • Units. Independent Parameters carry units into the group, but the model sees only the numbers. Check which unit system the model was trained in. Reference Unit is the only thing that gives the output a unit.
  • Data types. The model must use float32 inputs and outputs.
  • Supported operators. This workflow was tested with a plain fully connected network (Gemm and ReLU operators). Other operator sets haven't been tested. If an import fails, check the model's operators first.
  • File path. If the block errors, confirm the Model path points to the correct .onnx file.

Example Files

Was this article helpful?