Skip to content

sciml

Neural networks of hybrid problems.

A hybrid problem combines a mechanistic model in SBML with neural networks, which is what PEtab SciML describes. This package is the native half of the support: Network is the architecture and the arrays of one network and Network.forward evaluates it with numpy; nominal_parameters sets the arrays a problem describes; input_id, output_id, element_id and unit_id build the ids of the inputs, the outputs, the elements of the arrays and the units of a network in a model. A Hybridization says where a network sits in a problem: before the simulation, where a fit evaluates it, or in the right hand side or an observable of the model, where compile_network writes it into the model; ALL_CONDITIONS is the condition of an input which holds for every condition. Hybridization.fit_parameters gives the parameters of a fit defined in python and freezes the other elements; network_fit_parameters is the primitive it and the reader share. The package knows nothing of PEtab, the translation of a PEtab SciML problem is sbmlsim.fit.petab_v2.sciml.

The layers are implemented against the backends of sbmlsim.sciml.backend, which are the extension point of the layers and not needed to use a network.

The architecture is read and written with petab_sciml, which is not a dependency of sbmlsim but the sciml extra:

pip install sbmlsim[sciml]

NetworkCompilationError

Bases: NetworkError, ValueError

A network cannot be compiled into a model.

The message names the network and, where it applies, the node or the target, and the reason.

NetworkError

Bases: Exception

The base of the errors of a network.

A caller catches every error of the import and the evaluation of a network with it.

NetworkHybridizationError

Bases: NetworkError, ValueError

A hybridization does not fit its network, its model or its fit.

The message names the network and, where it applies, the input, the output or the target.

NetworkImportError

Bases: NetworkError, ValueError

A network or its arrays cannot be read.

The message names the network and, where it applies, the layer and the array.

UnsupportedLayerError

UnsupportedLayerError(network, node, target, reason)

Bases: NetworkError, NotImplementedError

A node of the forward pass has no implementation.

Attributes:

Name Type Description
network

id of the network.

node

name of the node of the forward pass.

target

the layer type, function or method of the node.

reason

why the node is not evaluated.

Initialize the error.

Parameters:

Name Type Description Default
network str

id of the network.

required
node str

name of the node of the forward pass.

required
target str

the layer type, function or method of the node.

required
reason str

why the node is not evaluated.

required

Hybridization dataclass

Hybridization(
    network,
    pattern,
    model,
    inputs,
    outputs,
    frozen=frozenset(),
    constants=dict(),
)

A network with its inputs, its outputs and its place in a problem.

The hybridization is validated when it is created, as far as it can be without the model: validate checks it against the model. Two hybridizations are equal when their attributes are; a hybridization is not hashable, its attributes are dictionaries.

Attributes:

Name Type Description
network Network

the network.

pattern NetworkPattern

where the network sits.

model str

id of the model in the experiment.

inputs Mapping[str, NetworkInput]

id of the input -> the input. The id is <net>__input<k> for an input which is given as an array and <net>__input<k>__<index> for an element of an input which is given element by element, see sbmlsim.sciml.network.input_id.

outputs Mapping[str, str]

id of the element of an output -> target, see sbmlsim.sciml.network.output_id. The target is an entity of the model for RHS, an entity or the selection of its concentration ([prey]) for PRE_INITIALIZATION, and the symbol an observable uses for OBSERVABLE, which the compiler adds to the model. An output without a target is not used.

frozen Collection[str]

ids of the elements of the arrays which are not estimated.

constants Mapping[str, float]

id -> value of the symbols of the formulas which are neither entities of the model nor parameters of the fit.

error

error(message)

Get an error which names the network.

Parameters:

Name Type Description Default
message str

what is wrong.

required

Returns:

Type Description
NetworkHybridizationError

The error, to be raised.

input_shapes

input_shapes()

Get the shapes of the inputs of the forward pass, see input_shapes.

output_shapes

output_shapes()

Get the shapes of the outputs of the network for its inputs.

fit_parameters

fit_parameters(estimate, bounds=None)

Get the parameters of a fit of the network and freeze the rest.

The pattern decides whether the elements are entities of the model, see sbmlsim.sciml.parameters.network_fit_parameters, and every element which is not estimated is frozen.

Parameters:

Name Type Description Default
estimate Mapping[str, bool]

key of the entry -> whether the elements are estimated, for the network, a layer or an array.

required
bounds Mapping[str, tuple[float, float]] | None

key of the entry -> lower and upper bound, none by default.

None

Returns:

Type Description
list[FitParameter]

The parameters of the fit and the hybridization with the other

Hybridization

elements frozen.

Raises:

Type Description
NetworkImportError

if a key does not name the network, a layer or an array, or if an estimated element has no value.

summary

summary()

Describe the network for the console and the report.

Returns:

Type Description
HookSummary

The id of the network, its pattern, its layers with their types

HookSummary

in the order of the forward pass, the targets of its outputs and

HookSummary

one group per array of the layers the forward pass calls, with

HookSummary

the ids of all elements of the array.

conditions

conditions()

Get the conditions for which an input has formulas or arrays.

Returns:

Type Description
dict[str, list[str]]

id of an input -> the conditions its formulas or arrays name,

dict[str, list[str]]

without ALL_CONDITIONS; an input of one formula is not listed.

symbols

symbols()

Get the ids whose values derived_changes reads.

Returns:

Type Description
frozenset[str]

The symbols of the formulas of the inputs and the ids of the

frozenset[str]

elements which are not frozen, for a network before the

frozenset[str]

simulation. For a network which is compiled, which the model

frozenset[str]

evaluates, the ids of the frozen elements and of the outputs:

frozenset[str]

the model must have them, and derived_changes checks that the

frozenset[str]

model carries the values of the frozen elements.

targets

targets()

Get the entities of the model derived_changes sets.

The targets are the keys of derived_changes as they are written: the id of an entity or the selection of the concentration of a species ([prey]), which sbmlsim.fit.derived compares by their entity (entity_of).

Returns:

Type Description
frozenset[str]

The targets of the outputs for a network before the simulation,

frozenset[str]

and the ids of the elements of the inputs which are arrays of

frozenset[str]

conditions for a network which is compiled.

check_parameters

check_parameters(targets)

Check the targets of the parameters of a fit against the network.

Parameters:

Name Type Description Default
targets Collection[str]

the entities the parameters of the fit write, without the prefix of a target which is not an entity of the model.

required

Raises:

Type Description
NetworkHybridizationError

if a parameter writes an element which is frozen, an output or its target, or an element of an input.

input_values

input_values(values, condition)

Get the inputs of the network for the values of a simulation.

Parameters:

Name Type Description Default
values Mapping[str, float]

id -> value of the parameters of the fit, of the changes of the simulation and of the entities of the model, in the units of the model. The constants of the hybridization are the values of the symbols which are not part of it.

required
condition str

id of the condition of the simulation.

required

Returns:

Type Description
list[ndarray]

The inputs, one array per input of the forward pass.

Raises:

Type Description
NetworkHybridizationError

if an input has no formula or array for the condition, if a symbol of a formula has no value, or if the value of a formula is not defined or not a finite number.

derived_changes

derived_changes(values, condition)

Get the changes of a simulation which follow from its values.

A network before the simulation is evaluated: its inputs are resolved with input_values, its arrays are the nominal values with the values of the elements which are not frozen, which the fit estimates, and its outputs are the changes of their targets. For a network which is compiled the changes are the elements of the inputs which are arrays of conditions, and the values of its frozen elements are compared with the network, which is how a model which was compiled from another network is found.

Parameters:

Name Type Description Default
values Mapping[str, float]

id -> value, see input_values. The values of the elements of the network which are not frozen are read from it by their id, the values of the frozen ones are ignored.

required
condition str

id of the condition of the simulation.

required

Returns:

Type Description
dict[str, float]

target -> value, in the unit of the target in the model.

Raises:

Type Description
NetworkHybridizationError

if an input cannot be resolved, see input_values, if an element which is not frozen has no value, if an output is not a finite number, or if the values of the frozen elements of a network which is compiled are missing or differ from the network.

validate

validate(sbml_path)

Check the hybridization against the model.

Parameters:

Name Type Description Default
sbml_path Path

the SBML model the network is a part of, without the network.

required

Raises:

Type Description
NetworkHybridizationError

if the model cannot be read, if a target cannot be set by the network, see _check_target, if a constant is an entity of the model, if a formula uses a symbol which is an output of the network, or if an input of PRE_INITIALIZATION is not a constant of the simulation, i.e. depends on the time, a species, a reaction, a species reference, an entity which a rule sets or an event changes.

NetworkInput dataclass

NetworkInput(formula=None, formulas=None, arrays=None)

An input of a network or an element of one.

Exactly one of the attributes is given.

Attributes:

Name Type Description
formula str | None

an L3 formula of SBML which holds for every condition, e.g. prey, alpha * prey or 0.5.

formulas Mapping[str, str] | None

id of the condition -> formula, for an input which differs between the conditions. ALL_CONDITIONS is the formula of the conditions which are not listed.

arrays Mapping[str, ArrayLike] | None

id of the condition -> values, ALL_CONDITIONS for the values of the conditions which are not listed. The arrays of an input have one shape.

is_conditional property

is_conditional

Check whether the input differs between the conditions.

shape property

shape

Get the shape of the arrays, None for an input of formulas.

all_formulas

all_formulas()

Get the formulas of the input, empty for an input of arrays.

formula_of

formula_of(condition)

Get the formula of a condition.

Parameters:

Name Type Description Default
condition str

id of the condition.

required

Returns:

Type Description
str | None

The formula, None for an input of arrays and for a condition

str | None

without a formula.

array_of

array_of(condition)

Get the array of a condition.

Parameters:

Name Type Description Default
condition str

id of the condition.

required

Returns:

Type Description
ndarray | None

The array, None for an input of formulas and for a condition

ndarray | None

without an array.

NetworkPattern

Bases: StrEnum

The place of a network in a hybrid problem.

is_compiled property

is_compiled

Check whether a network of the pattern is compiled into the model.

Network dataclass

Network(sid, model, parameters=dict())

The architecture and the arrays of one network.

A network is validated when it is created: the id, the forward pass and the nominal values are checked against the architecture, and every layer needs an implementation. A network does not change afterwards: its attributes cannot be assigned, the mappings of parameters cannot be changed and its arrays cannot be written, so the structures derived from them (array_specs, used_layers, parameter_ids) are computed once and stay true. The arrays are copies of the ones the network was built from. The model is shared and not copied, it must not be changed after the network was created, the derived structures would not follow. A network with other nominal values is a new network, e.g. dataclasses.replace(network, parameters=...). A copy of a network (copy.deepcopy, pickle of any protocol) is created again from its id, architecture and arrays, so it is validated and frozen like the original.

Two networks are equal when they have the same id, the same architecture and the same arrays, which is what the round trip of a problem and the pickling of a fit compare. The hash is the one of the id only, networks of one id are equal or differ in the architecture or the arrays.

Attributes:

Name Type Description
sid str

id of the network, an SBML SId which is the nn_model_id of the model.

model NNModel

the architecture, i.e. the content of the NN YAML.

parameters FrozenParameters

the nominal values of the arrays in the PyTorch layout, layer id -> array name -> values.

from_files classmethod

from_files(yaml_path, array_path=None, sid=None)

Read a network from its NN YAML and its array file.

The arrays of a file with metadata/pytorch_format false are stored in the column major layout, i.e. with the axes in the reverse order, and are permuted into the PyTorch layout.

Parameters:

Name Type Description Default
yaml_path Path

the NN YAML.

required
array_path Path | None

the HDF5 file with the arrays of the network. Without it the network has no values, which a problem sets.

None
sid str | None

id of the network, the nn_model_id of the YAML when None. The arrays are read from the group of this id.

None

Returns:

Type Description
Network

The network.

Raises:

Type Description
NetworkImportError

if a file does not exist or cannot be read, if the network is not valid (see Network), if the array file has no arrays for the network, or if an array does not belong to a layer or does not have the shape of the layer.

UnsupportedLayerError

if the network has a layer without an implementation.

read_arrays

read_arrays(array_path)

Read the arrays of the network from an array file.

An empty array is an array the file does not provide, which is how a file leaves out the arrays a problem sets.

Parameters:

Name Type Description Default
array_path Path

the HDF5 file.

required

Returns:

Type Description
NetworkParameters

The arrays in the PyTorch layout, not checked against the

NetworkParameters

architecture; a network created with them checks them.

Raises:

Type Description
NetworkImportError

if the file does not exist, cannot be read or has no arrays for the network.

check_forward

check_forward()

Check the forward pass against the layers.

Raises:

Type Description
NetworkImportError

if a call_module node calls a layer the network does not have, or if an output node does not have one argument, the output or the list of the outputs.

array_specs

array_specs()

Get the arrays of every layer of the network.

Returns:

Type Description
dict[str, dict[str, ArraySpec]]

The arrays of the layers, layer id -> array name -> shape and

dict[str, dict[str, ArraySpec]]

kind, in the order of the layers. The layers were checked when the

dict[str, dict[str, ArraySpec]]

network was created.

used_layers

used_layers()

Get the ids of the layers the forward pass calls, in its order.

backends

backends()

Get the backends which evaluate every node of the forward pass.

This is about the evaluation of the nodes: the layers and functions of the forward pass, not the layers the network defines and does not call.

Returns:

Type Description
frozenset[BackendKind]

The backends all layers and functions of the forward pass support.

Raises:

Type Description
UnsupportedLayerError

if a node has no implementation.

check_arrays

check_arrays(parameters, complete=True)

Check arrays against the architecture.

Parameters:

Name Type Description Default
parameters Mapping[str, Mapping[str, ndarray]]

the arrays, layer id -> array name -> values.

required
complete bool

whether every required array of a layer of the forward pass must be there.

True

Raises:

Type Description
NetworkImportError

if an array does not belong to a layer of the network, does not have the shape of the layer, holds a value which is not finite or, with complete, is missing.

forward

forward(*inputs, parameters=None)

Evaluate the network with numpy, in evaluation mode.

Parameters:

Name Type Description Default
*inputs ndarray

the inputs in the PyTorch layout, one per input of the forward pass.

()
parameters NetworkParameters | None

the arrays the network is evaluated with, the nominal values when None.

None

Returns:

Type Description
ndarray

The outputs of the network, arrays which share no memory with the

...

inputs.

Raises:

Type Description
NetworkImportError

if an array of a layer is missing or has the wrong shape.

UnsupportedLayerError

if a layer or function has no implementation.

ValueError

if the inputs do not fit the network.

parameter_ids

parameter_ids()

Get the ids of the elements of the arrays which are parameters.

The ids follow from the architecture, so they exist for an array without values as well. The running statistics of a normalization layer are not parameters.

Returns:

Type Description
ParameterIds

id of the element -> layer id, array name and PyTorch index, in

ParameterIds

the order of the layers, the arrays and the row major order of the

ParameterIds

elements.

Raises:

Type Description
NetworkImportError

if two elements have the same id, which the ids of two layers such as block.0 and block_0 cause.

with_values

with_values(values)

Get the arrays with the values of some elements replaced.

Parameters:

Name Type Description Default
values Mapping[str, float]

id of the element -> value.

required

Returns:

Type Description
NetworkParameters

A copy of the nominal values with the elements replaced. The

NetworkParameters

network is not changed.

Raises:

Type Description
NetworkImportError

if an id is not the id of an element of the network, if a value is not finite, or if an element of an array without nominal values is set.

compile_network

compile_network(sbml_path, hybridizations, output_path)

Write a model with the networks of its right hand side and observables.

All networks of the patterns RHS and OBSERVABLE are added in one pass and one model is written. The hybridizations of the pattern PRE_INITIALIZATION are not a part of the model and are left out.

Parameters:

Name Type Description Default
sbml_path Path

the SBML model without the networks.

required
hybridizations Sequence[Hybridization]

the hybridizations of the model.

required
output_path Path

the path the model with the networks is written to, see compiled_path.

required

Returns:

Type Description
Path

The path of the model which was written.

Raises:

Type Description
NetworkCompilationError

if no hybridization is compiled, if the hybridizations name different models, if two hybridizations of a network differ, if two networks give a constant different values, if two networks set one target, if an id of a network is an id of the model or of another part of a network, if a formula of an input uses a symbol which is neither a constant of the hybridization nor a value in the math of the model at its level and version (see _Model.is_value), if an initial assignment sets a target, if an expression has no MathML of SBML, or if the model with the networks is not valid SBML. The message names the network.

NetworkHybridizationError

if the model does not exist or a hybridization does not fit it, e.g. a target of RHS which is not a parameter or which a rule or an event sets, see Hybridization.validate. Hybridization also refuses a network with a layer or function which is not evaluated on expressions for the patterns which are compiled.

compiled_path

compiled_path(sbml_path, directory=None)

Get the path of the model which carries the networks of a model.

Parameters:

Name Type Description Default
sbml_path Path

the model without the networks.

required
directory Path | None

the directory the model is written to, the directory of the model by default.

None

Returns:

Type Description
Path

<stem>_sciml.xml in the directory.

element_id

element_id(network, layer, array, index)

Get the id of an element of an array.

Parameters:

Name Type Description Default
network str

id of the network.

required
layer str

id of the layer.

required
array str

name of the array, e.g. weight.

required
index tuple[int, ...]

the PyTorch index of the element.

required

Returns:

Type Description
str

The id, e.g. net1__layer1__weight__0_1. A character which is not

str

part of an SBML SId is replaced by _, e.g. the dot in the id of a

str

layer of a nested module.

input_id

input_id(network, k, index=None)

Get the id of an input of a network or of an element of it.

Parameters:

Name Type Description Default
network str

id of the network.

required
k int

the position of the input in the inputs of the forward pass.

required
index tuple[int, ...] | None

the index of the element, None for the input as an array.

None

Returns:

Type Description
str

The id, e.g. net1__input0__1 for an element and net1__input0 for

str

the array.

Raises:

Type Description
ValueError

if the position or an axis of the index is negative.

output_id

output_id(network, k, index)

Get the id of an element of an output of a network.

Parameters:

Name Type Description Default
network str

id of the network.

required
k int

the position of the output in the outputs of the forward pass.

required
index tuple[int, ...]

the index of the element.

required

Returns:

Type Description
str

The id, e.g. net1__output0__0.

Raises:

Type Description
ValueError

if the position or an axis of the index is negative.

parse_io_id

parse_io_id(network, kind, sid)

Read the position and the index from the id of an input or an output.

Parameters:

Name Type Description Default
network str

id of the network.

required
kind str

input or output.

required
sid str

the id, e.g. net1__input0__1 or net1__input0.

required

Returns:

Type Description
int

The position and the index of the element, None as index for an

tuple[int, ...] | None

id without one, i.e. for an input as an array.

Raises:

Type Description
ValueError

if the id is not the id of an input or output of the network.

unit_id

unit_id(network, node, index)

Get the id of a unit of a node of the forward pass.

Parameters:

Name Type Description Default
network str

id of the network.

required
node str

name of the node.

required
index tuple[int, ...]

the index of the unit in the value of the node.

required

Returns:

Type Description
str

The id, e.g. net1__tanh_1__3. A character which is not part of an

str

SBML SId is replaced by _.

network_fit_parameters

network_fit_parameters(
    network, estimate, bounds, external=False
)

Create the fit parameters of the estimated elements of a network.

estimate and bounds are given for the network, for a layer or for an array, and the more specific entry wins, see covered_arrays.

The nominal values of the elements are the values the network carries, which are the start values of the estimated elements and the values of the frozen ones. They are set on the network, not here, so that the network a hybridization runs is the network the fit parameters describe: dataclasses.replace(network, parameters=nominal_parameters(network, values)).

The elements of a layer which the forward pass does not call are left out: the outputs of the network do not depend on them, so a fit cannot estimate them.

Parameters:

Name Type Description Default
network Network

the network with the nominal values of its elements.

required
estimate Mapping[str, bool]

key of the entry -> whether the elements are estimated. An element no entry covers is not estimated.

required
bounds Mapping[str, tuple[float, float]]

key of the entry -> lower and upper bound of the elements. An estimated element no entry covers is not bounded.

required
external bool

whether the elements are not entities of a model, which is the case for a network which runs before the simulation. The target of such a parameter is sciml:<id>. The elements of a network which is compiled into a model are entities of it.

False

Returns:

Type Description
list[FitParameter]

One parameter per estimated element, named by the id of the element,

list[FitParameter]

with the nominal value as start value, the linear scale and the unit

list[FitParameter]

dimensionless, in the order of Network.parameter_ids.

Raises:

Type Description
NetworkImportError

if a key does not name the network, a layer or an array, or if an estimated element has no nominal value.

ValueError

if a nominal value is outside of its bounds.

nominal_parameters

nominal_parameters(network, values=None)

Get the nominal values of the arrays of a network.

Parameters:

Name Type Description Default
network Network

the network with the values of its array file.

required
values Mapping[str, float] | None

key of the entry -> value of every element the entry covers, see covered_arrays. An array no entry covers keeps the values of the array file.

None

Returns:

Type Description
NetworkParameters

The arrays in the PyTorch layout. The network is not changed.

Raises:

Type Description
NetworkImportError

if a key does not name the network, a layer or an array, if a value is not finite, or if an array of a layer of the forward pass has values neither in the array file nor in values.