{ "cells": [ { "cell_type": "markdown", "id": "b16dfc76-0c78-416c-9565-c0825087a06a", "metadata": {}, "source": [ "# Neural ODE" ] }, { "cell_type": "markdown", "id": "a8768437-4934-45d8-9d34-d0783e81cf94", "metadata": {}, "source": [ "This example trains a [Neural ODE](https://arxiv.org/abs/1806.07366) to reproduce a toy dataset of nonlinear oscillators.\n", "\n", "This example is available as a Jupyter notebook [here](https://github.com/patrick-kidger/diffrax/blob/main/examples/neural_ode.ipynb)." ] }, { "cell_type": "code", "execution_count": 1, "id": "276cbbe5-dac1-4814-807c-e50cc633b11a", "metadata": {}, "outputs": [], "source": [ "import time\n", "\n", "import diffrax\n", "import equinox as eqx # https://github.com/patrick-kidger/equinox\n", "import jax\n", "import jax.nn as jnn\n", "import jax.numpy as jnp\n", "import jax.random as jr\n", "import matplotlib.pyplot as plt\n", "import optax # https://github.com/deepmind/optax" ] }, { "cell_type": "markdown", "id": "d0f36a4f-3813-4f84-8d61-96500ea1f237", "metadata": {}, "source": [ "We use [Equinox](https://github.com/patrick-kidger/equinox) to build neural networks. We use [Optax](https://github.com/deepmind/optax) for optimisers (Adam etc.)" ] }, { "cell_type": "markdown", "id": "5016bd6c-4981-4783-a3cf-087b89b680c4", "metadata": {}, "source": [ "Recalling that a neural ODE is defined as\n", "\n", "$y(t) = y(0) + \\int_0^t f_\\theta(s, y(s)) ds$,\n", "\n", "then here we're now about to define the $f_\\theta$ that appears on that right hand side." ] }, { "cell_type": "code", "execution_count": 2, "id": "243412cd-9f19-489f-a10e-bf0eb8bf3788", "metadata": {}, "outputs": [], "source": [ "class Func(eqx.Module):\n", " mlp: eqx.nn.MLP\n", "\n", " def __init__(self, data_size, width_size, depth, *, key, **kwargs):\n", " super().__init__(**kwargs)\n", " self.mlp = eqx.nn.MLP(\n", " in_size=data_size,\n", " out_size=data_size,\n", " width_size=width_size,\n", " depth=depth,\n", " activation=jnn.softplus,\n", " key=key,\n", " )\n", "\n", " def __call__(self, t, y, args):\n", " return self.mlp(y)" ] }, { "cell_type": "markdown", "id": "1aa17137-a851-4214-9187-53711d0e07da", "metadata": {}, "source": [ "Here we wrap up the entire ODE solve into a model." ] }, { "cell_type": "code", "execution_count": 3, "id": "fdb14ae0-1aa5-4e10-ba3b-d977d5d6ac3d", "metadata": {}, "outputs": [], "source": [ "class NeuralODE(eqx.Module):\n", " func: Func\n", "\n", " def __init__(self, data_size, width_size, depth, *, key, **kwargs):\n", " super().__init__(**kwargs)\n", " self.func = Func(data_size, width_size, depth, key=key)\n", "\n", " def __call__(self, ts, y0):\n", " solution = diffrax.diffeqsolve(\n", " diffrax.ODETerm(self.func),\n", " diffrax.Tsit5(),\n", " t0=ts[0],\n", " t1=ts[-1],\n", " dt0=ts[1] - ts[0],\n", " y0=y0,\n", " stepsize_controller=diffrax.PIDController(rtol=1e-3, atol=1e-6),\n", " saveat=diffrax.SaveAt(ts=ts),\n", " )\n", " return solution.ys" ] }, { "cell_type": "markdown", "id": "97d3264c-2edc-465e-b61f-05125645e1df", "metadata": {}, "source": [ "Toy dataset of nonlinear oscillators. Sample paths look like deformed sines and cosines." ] }, { "cell_type": "code", "execution_count": 4, "id": "29225b09-3a50-4a7f-bbcf-5824d44f3e62", "metadata": {}, "outputs": [], "source": [ "def _get_data(ts, *, key):\n", " y0 = jr.uniform(key, (2,), minval=-0.6, maxval=1)\n", "\n", " def f(t, y, args):\n", " x = y / (1 + y)\n", " return jnp.stack([x[1], -x[0]], axis=-1)\n", "\n", " solver = diffrax.Tsit5()\n", " dt0 = 0.1\n", " saveat = diffrax.SaveAt(ts=ts)\n", " sol = diffrax.diffeqsolve(\n", " diffrax.ODETerm(f), solver, ts[0], ts[-1], dt0, y0, saveat=saveat\n", " )\n", " ys = sol.ys\n", " return ys\n", "\n", "\n", "def get_data(dataset_size, *, key):\n", " ts = jnp.linspace(0, 10, 100)\n", " key = jr.split(key, dataset_size)\n", " ys = jax.vmap(lambda key: _get_data(ts, key=key))(key)\n", " return ts, ys" ] }, { "cell_type": "code", "execution_count": 5, "id": "6505387d-6900-401d-9ceb-b741f349f1e6", "metadata": {}, "outputs": [], "source": [ "def dataloader(arrays, batch_size, *, key):\n", " dataset_size = arrays[0].shape[0]\n", " assert all(array.shape[0] == dataset_size for array in arrays)\n", " indices = jnp.arange(dataset_size)\n", " while True:\n", " perm = jr.permutation(key, indices)\n", " (key,) = jr.split(key, 1)\n", " start = 0\n", " end = batch_size\n", " while end < dataset_size:\n", " batch_perm = perm[start:end]\n", " yield tuple(array[batch_perm] for array in arrays)\n", " start = end\n", " end = start + batch_size" ] }, { "cell_type": "markdown", "id": "acd937f6-4642-4b8a-b309-aae63a9269dc", "metadata": {}, "source": [ "Main entry point. Try runnning `main()`." ] }, { "cell_type": "code", "execution_count": 6, "id": "135540f6-d5ea-4c79-b083-0b86fd3edbe3", "metadata": {}, "outputs": [], "source": [ "def main(\n", " dataset_size=256,\n", " batch_size=32,\n", " lr_strategy=(3e-3, 3e-3),\n", " steps_strategy=(500, 500),\n", " length_strategy=(0.1, 1),\n", " width_size=64,\n", " depth=2,\n", " seed=5678,\n", " plot=True,\n", " print_every=100,\n", "):\n", " key = jr.PRNGKey(seed)\n", " data_key, model_key, loader_key = jr.split(key, 3)\n", "\n", " ts, ys = get_data(dataset_size, key=data_key)\n", " _, length_size, data_size = ys.shape\n", "\n", " model = NeuralODE(data_size, width_size, depth, key=model_key)\n", "\n", " # Training loop like normal.\n", " #\n", " # Only thing to notice is that up until step 500 we train on only the first 10% of\n", " # each time series. This is a standard trick to avoid getting caught in a local\n", " # minimum.\n", "\n", " @eqx.filter_value_and_grad\n", " def grad_loss(model, ti, yi):\n", " y_pred = jax.vmap(model, in_axes=(None, 0))(ti, yi[:, 0])\n", " return jnp.mean((yi - y_pred) ** 2)\n", "\n", " @eqx.filter_jit\n", " def make_step(ti, yi, model, opt_state):\n", " loss, grads = grad_loss(model, ti, yi)\n", " updates, opt_state = optim.update(grads, opt_state)\n", " model = eqx.apply_updates(model, updates)\n", " return loss, model, opt_state\n", "\n", " for lr, steps, length in zip(lr_strategy, steps_strategy, length_strategy):\n", " optim = optax.adabelief(lr)\n", " opt_state = optim.init(eqx.filter(model, eqx.is_inexact_array))\n", " _ts = ts[: int(length_size * length)]\n", " _ys = ys[:, : int(length_size * length)]\n", " for step, (yi,) in zip(\n", " range(steps), dataloader((_ys,), batch_size, key=loader_key)\n", " ):\n", " start = time.time()\n", " loss, model, opt_state = make_step(_ts, yi, model, opt_state)\n", " end = time.time()\n", " if (step % print_every) == 0 or step == steps - 1:\n", " print(f\"Step: {step}, Loss: {loss}, Computation time: {end - start}\")\n", "\n", " if plot:\n", " plt.plot(ts, ys[0, :, 0], c=\"dodgerblue\", label=\"Real\")\n", " plt.plot(ts, ys[0, :, 1], c=\"dodgerblue\")\n", " model_y = model(ts, ys[0, 0])\n", " plt.plot(ts, model_y[:, 0], c=\"crimson\", label=\"Model\")\n", " plt.plot(ts, model_y[:, 1], c=\"crimson\")\n", " plt.legend()\n", " plt.tight_layout()\n", " plt.savefig(\"neural_ode.png\")\n", " plt.show()\n", "\n", " return ts, ys, model" ] }, { "cell_type": "code", "execution_count": 7, "id": "fba5156d-22d4-40c9-991b-e6b29a53abed", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Step: 0, Loss: 0.1665748506784439, Computation time: 24.193979501724243\n", "Step: 100, Loss: 0.011155527085065842, Computation time: 0.08653044700622559\n", "Step: 200, Loss: 0.006481727119535208, Computation time: 0.08708548545837402\n", "Step: 300, Loss: 0.001382559770718217, Computation time: 0.09218716621398926\n", "Step: 400, Loss: 0.001073717838153243, Computation time: 0.09549355506896973\n", "Step: 499, Loss: 0.0007992316968739033, Computation time: 0.09554696083068848\n", "Step: 0, Loss: 0.02832634374499321, Computation time: 24.159853219985962\n", "Step: 100, Loss: 0.005440382286906242, Computation time: 0.4165775775909424\n", "Step: 200, Loss: 0.004360489547252655, Computation time: 0.43640780448913574\n", "Step: 300, Loss: 0.001799552352167666, Computation time: 0.44630861282348633\n", "Step: 400, Loss: 0.0017023109830915928, Computation time: 0.4568369388580322\n", "Step: 499, Loss: 0.0011540694395080209, Computation time: 0.4471282958984375\n" ] }, { "data": { "image/png": "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\n", "text/plain": [ "
" ] }, "metadata": { "needs_background": "light" }, "output_type": "display_data" } ], "source": [ "ts, ys, model = main()" ] }, { "cell_type": "markdown", "id": "ea7c0626-7e83-4a2b-84c9-44bcfc147f35", "metadata": {}, "source": [ "Some notes on speed:\n", "The hyperparameters for the above example haven't really been optimised. Try experimenting with them to see how much faster you can make this example run. There's lots of things you can try tweaking:\n", "\n", "- The size of the neural network.\n", "- The numerical solver.\n", "- The step size controller, including both its step size and its tolerances.\n", "- The length of the dataset. (Do you really need to use all of a time series every time?)\n", "- Batch size, learning rate, choice of optimiser.\n", "- ... etc.!\n", "\n", "Some notes on being Markov:\n", "\n", "- This example has assumed that the problem is Markov. Essentially, that the data `ys` is a complete observation of the system, and that we're not missing any channels. Note how the result of our model is evolving in data space. This is unlike e.g. an RNN, which has hidden state, and a linear map from hidden state to data.\n", "- If we wanted we could generalise this to the non-Markov case: inside `NeuralODE`, project the initial condition into some high-dimensional latent space, do the ODE solve there, then take a linear map to get the output. See the [Latent ODE example](../latent_ode) for an example doing this as part of a generative model; also see [Augmented Neural ODEs](https://arxiv.org/abs/1904.01681) for a short paper on it." ] } ], "metadata": { "kernelspec": { "display_name": "jax0227", "language": "python", "name": "jax0227" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.9.7" } }, "nbformat": 4, "nbformat_minor": 5 }