MyNixOS website logo
Description

Application of NODEs in 'Monolix', 'NONMEM', and 'nlmixr2'.

An easy-to-use tool for implementing Neural Ordinary Differential Equations (NODEs) in pharmacometric software such as 'Monolix', 'NONMEM', and 'nlmixr2', see Bräm et al. (2024) <doi:10.1007/s10928-023-09886-4> and Bräm et al. (2025) <doi:10.1002/psp4.13265>. The main functionality is to automatically generate structural model code describing computations within a neural network. Additionally, parameters and software settings can be initialized automatically. For using these additional functionalities with 'Monolix', 'pmxNODE' interfaces with 'MonolixSuite' via the 'lixoftConnectors' package. The 'lixoftConnectors' package is distributed with 'MonolixSuite' (<https://monolixsuite.slp-software.com/r-functions/2024R1/package-lixoftconnectors>) and is not available from public repositories.

pmxNODE

The goal of pmxNODE is to facilitate the implementation of neural ordinary differential equations (NODEs) in pharmacometric software, i.e., Monolix, NONMEM, and nlmixr2.

Installation

You can install the development version of pmxNODE like so:

devtools::install_github("braemd/pmxNODE")

How to use

General workflow

The general workflow of pmxNODE consists of few steps:

  • Write a structural model, as you would do normaly for Monolix, NONMEM, or nlmixr2. However, you can utilize NN functions in your model code, e.g., for complex or unknown model parts.

  • Convert the written model file with the nn_converter_XXX function from the pmxNODE package, e.g. nn_converter_mlx for Monolix. This function can also directly generate a .mlxtran file with automatically initialized model parameters.

  • We suggest to fit the model to the data first without inter-individual variability on neural networks parameters (argument pop = True in the nn_converter_mlx function) and add the random effects in a second run, where parameters were initialized with last estimates.

NN functions

The NN functions in your structural model do need to be of following form:

  • They must be named in order to uniquely identify them in the model (e.g., if the same NN is used to outflow of an absorption compartment and as inflow into the central compartment) and to generate uniquly identifiable parameters.

  • The following arguments are mandatory:

    • state: Defines the state that goes into the NN
    • min_init: The minimal expected input into the NN
    • max_init: The maximal expected input into the NN The minimal and maximal expected inputs are needed to properly initialize the weights of the NN. They don’t need to be exact but should roughly give the range of expected inputs.
  • The following arguments are optional:

    • n_hidden: Number of units in the hidden layer. Default is 5.
    • act: Activation function to be used in the hidden layer. Currently, only “ReLU” and “Softplus” are available. Default is “ReLU”.
    • time_nn: Whether the NN should be a “Time-dependent NN” according to https://doi.org/10.1007/s10928-023-09886-4, i.e., whether the weights from input to hidden layer should be negative. Default is FALSE.

Package loading and initialization

We first need to load the pmxNODE package and to initialize the lixoftConnectors package (can be done with the software_initializer function from pmxNODE).

If the lixoftConnectors package is not yet installed, an installation path to the package .tar.gz file from Monolix must be provided.

library(pmxNODE)
library(ggplot2)
#> Warning: Paket 'ggplot2' wurde unter R Version 4.2.3 erstellt
software_initializer(software = "Monolix",
                     mlx_path = "C:/ProgramData/Lixoft/MonolixSuite2021R2")
#> Lade nötiges Paket: RJSONIO
#> [INFO] The lixoftConnectors package has been successfully initialized:
#> lixoftConnectors package version -> 2021.2
#> Lixoft softwares suite version   -> 2021R2

Examples

Some examples are available in the pmxNODE package. To see all example files, you can use the get_example_list function. To copy an example to a folder of your choice, you can use the copy_example function. After calling the copy_examples function, two files should be in the target folder, a data file and a Monolix model file.

get_example_list()

copy_examples(
  target_folder = "~/pmxNODE",
  example_nr = 1,
  example_software = "Monolix"
)

Converting and population fit

Before fitting the model, it needs to be converted with the nn_converter_mlx function. In addition to the path/file name of the unconverted Monolix model and the argument on including inter-individual variability for the neural network parameters, a Monolix .mlxtran file can be automatically generated with the gen_mlx_file = TRUE argument. In order to do so, a data file and the header types must be provided. If no file name for the new Monolix file is given through the mlx_name argument, the Monolix file name is automatically generated based on the Monolix model file. Note that a suffix is added to the file name, either _pop if pop = TRUE or _ind if ind = TRUE.

The model can be automatically run from R with the function run_mlx from the pmxNODE package.

nn_converter_mlx(mlx_path = "~/pmxNODE/mlx_example1_model.txt",
                 pop = TRUE,
                 gen_mlx_file = TRUE,
                 mlx_name = "~/pmxNODE/mlx_example1",
                 data_file = "~/pmxNODE/data_example1_mlx.csv",
                 header_types = c("id","time","amount","observation"))

run_mlx("~/pmxNODE/mlx_example1_pop.mlxtran")

Converting and individual fit

In order to get the parameter estimations from the population fit (without inter-individual variability), the pre_fixef_extractor_mlx function can be utilized.

These parameter estimates can be given as additional argument pre_fixef to the nn_converter_mlx function. To include inter-individual variability, the population argument is set to false (pop = FALSE) in the nn_converter_mlx function.

The final model with inter-individual variability can then be fitted again with the run_mlx function.

est_parms <- pre_fixef_extractor_mlx("~/pmxNODE/mlx_example1_pop.mlxtran")

nn_converter_mlx(mlx_path = "~/pmxNODE/mlx_example1_model.txt",
                 pop = FALSE,
                 pre_fixef = est_parms,
                 gen_mlx_file = TRUE,
                 mlx_name = "~/pmxNODE/mlx_example1",
                 data_file = "~/pmxNODE/data_example1_mlx.csv",
                 header_types = c("id","time","amount","observation"))

run_mlx("~/pmxNODE/mlx_example1_ind.mlxtran")
Metadata

Version

0.1.0

License

Unknown

Platforms (78)

    Darwin
    FreeBSD
    Genode
    GHCJS
    Linux
    MMIXware
    NetBSD
    none
    OpenBSD
    Redox
    Solaris
    uefi
    WASI
    Windows
Show all
  • aarch64-darwin
  • aarch64-freebsd
  • aarch64-genode
  • aarch64-linux
  • aarch64-netbsd
  • aarch64-none
  • aarch64-uefi
  • aarch64-windows
  • aarch64_be-none
  • arm-none
  • armv5tel-linux
  • armv6l-linux
  • armv6l-netbsd
  • armv6l-none
  • armv7a-linux
  • armv7a-netbsd
  • armv7l-linux
  • armv7l-netbsd
  • avr-none
  • i686-cygwin
  • i686-freebsd
  • i686-genode
  • i686-linux
  • i686-netbsd
  • i686-none
  • i686-openbsd
  • i686-windows
  • javascript-ghcjs
  • loongarch64-linux
  • m68k-linux
  • m68k-netbsd
  • m68k-none
  • microblaze-linux
  • microblaze-none
  • microblazeel-linux
  • microblazeel-none
  • mips-linux
  • mips-none
  • mips64-linux
  • mips64-none
  • mips64el-linux
  • mipsel-linux
  • mipsel-netbsd
  • mmix-mmixware
  • msp430-none
  • or1k-none
  • powerpc-linux
  • powerpc-netbsd
  • powerpc-none
  • powerpc64-linux
  • powerpc64le-linux
  • powerpcle-none
  • riscv32-linux
  • riscv32-netbsd
  • riscv32-none
  • riscv64-linux
  • riscv64-netbsd
  • riscv64-none
  • rx-none
  • s390-linux
  • s390-none
  • s390x-linux
  • s390x-none
  • vc4-none
  • wasm32-wasi
  • wasm64-wasi
  • x86_64-cygwin
  • x86_64-darwin
  • x86_64-freebsd
  • x86_64-genode
  • x86_64-linux
  • x86_64-netbsd
  • x86_64-none
  • x86_64-openbsd
  • x86_64-redox
  • x86_64-solaris
  • x86_64-uefi
  • x86_64-windows