Skip to content

RandomNeuralDGP

The signal is the output of a small MLP with random weights. The network is never trained — the random architecture is the data-generating process — so the whole dataset follows from random_state with no optimiser in the loop to make results depend on convergence.

This gives you a nonlinear target with no interpretable closed form, which is a fair test of flexible methods and a hard one for anything assuming additivity or low-order interactions.

Needs the neural extra

pip install "synthbench[neural]"
Importing synthbench does not pull PyTorch into sys.modules. The import happens the first time you touch RandomNeuralDGP, so the base install stays light.

Unlike the other DGPs, this one has no complexity parameter. Size the network directly with n_hidden_layers (default 2) and hidden_size (default 32); hidden layers are tanh-activated and the output unit is linear. Weights use kaiming_uniform_, biases start at zero.

from synthbench import BenchPipeline, RandomNeuralDGP

dgp = RandomNeuralDGP(
    n_hidden_layers=2,
    hidden_size=32,
    task_type="regression",
    random_state=0,
)
result = BenchPipeline(dgp).run(n_samples=500, n_features=10, random_state=42)

print(result.X.shape)  # (500, 10)
print(sum(result.metadata["signal_feature_importances"].values()))  # 1.0

Importances come from the first hidden layer's weight matrix: the squared L2 norm of each input column, normalised to sum to 1. A feature the first layer barely reads cannot influence the output much, so this is a reasonable proxy — but it is only the first layer, so it does not account for a feature being amplified or cancelled deeper in the network. Treat these as weaker ground truth than the coefficients LinearDGP reports.

The normalisation runs in Python floats rather than torch's float32, which is what lets the importances sum to exactly 1.0. The forward pass runs under torch.no_grad() and does not touch global RNG state.

For more than two classes, pass n_classes and the output layer widens to match — one unit per class, no ordering imposed. This is the DGP where multiclass costs nothing structurally, since the network was already free to emit any number of outputs.

Full parameter list: RandomNeuralDGP in the API reference.