{ "cells": [ { "cell_type": "markdown", "id": "c5130161", "metadata": {}, "source": [ "# Regression Example\n", "\n", "This notebook provides two examples for performing basic regression on nonlinear data. The first example builds a traditional neural network and the second uses an affine observable PMM." ] }, { "cell_type": "markdown", "id": "8defe0c7", "metadata": {}, "source": [ "## Imports" ] }, { "cell_type": "code", "execution_count": 1, "id": "c9583d5a", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Requirement already satisfied: scikit-learn in /home/pcook/Research/FRIB/pmmenv/lib/python3.12/site-packages (1.8.0)\n", "Requirement already satisfied: numpy>=1.24.1 in /home/pcook/Research/FRIB/pmmenv/lib/python3.12/site-packages (from scikit-learn) (2.4.0)\n", "Requirement already satisfied: scipy>=1.10.0 in /home/pcook/Research/FRIB/pmmenv/lib/python3.12/site-packages (from scikit-learn) (1.16.3)\n", "Requirement already satisfied: joblib>=1.3.0 in /home/pcook/Research/FRIB/pmmenv/lib/python3.12/site-packages (from scikit-learn) (1.5.3)\n", "Requirement already satisfied: threadpoolctl>=3.2.0 in /home/pcook/Research/FRIB/pmmenv/lib/python3.12/site-packages (from scikit-learn) (3.6.0)\n", "Note: you may need to restart the kernel to use updated packages.\n" ] } ], "source": [ "%pip install scikit-learn" ] }, { "cell_type": "code", "execution_count": 2, "id": "e78966bd", "metadata": {}, "outputs": [], "source": [ "import jax\n", "import jax.numpy as np\n", "import jax.random as jr\n", "import parametricmatrixmodels as pmm\n", "import matplotlib.pyplot as plt\n", "from sklearn.preprocessing import StandardScaler, MinMaxScaler\n", "# enable x64 for JAX\n", "jax.config.update(\"jax_enable_x64\", True)" ] }, { "cell_type": "markdown", "id": "4b23be7d", "metadata": {}, "source": [ "## Data Creation" ] }, { "cell_type": "code", "execution_count": 3, "id": "d7a41f8e", "metadata": { "scrolled": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "(100, 1)\n", "(100, 1)\n" ] }, { "data": { "text/plain": [ "[]" ] }, "execution_count": 3, "metadata": {}, "output_type": "execute_result" }, { "data": { "image/png": "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fOc7g58fO3ZM1157rTZv3qy5c+c6uURXWX1/pIGdkKuvvnpwN62sLJwbkmeddZZmzZqlF198cbD9PZlM6sUXX9SqVavcXZwHpFIpff3rX9eWLVv00ksvqb6+3u0lecZf/MVf6I033hj22PLly3XJJZdozZo1oQ5CJGn+/PkjWr1///vfe/4aFfpAxKrq6mrdcccdampqUl1dnS688EJ9//vflyTdfPPNLq/OfRdccMGwz8855xxJ0tSpU7mb00AQsnDhQl144YX653/+Z7333nuDfxbGXYDVq1frtttu0+zZszVnzhw9/PDD6u7u1vLly91emutWrlypjRs3auvWraqqqhqsm4lGoxo9erTLq3NXVVXViFqZMWPGaNy4cdTQSLr77rt11VVX6f7779cXv/hF7dmzRz/60Y88v/tKIGLD97//fX3iE5/QV77yFZ0+fVpz587Vzp07vd+jDdft2LFD+/fv1/79+0cEZqkQHoD9pS99Se+9957uvfdedXZ2asaMGdq+ffuIAtYwWr9+vSRp4cKFwx5/8sknc6YBEW5XXnmltmzZorVr1+qf/umfVF9fr4cffli33nqr20vLKpIK429BAADgCeFMUgMAAE8gEAEAAK4hEAEAAK4hEAEAAK4hEAEAAK4hEAEAAK4hEAEAAK4hEAEAAK4hEAEAAK4hEAEAAK4hEAEAAK4hEAEAAK75/xGv8gsNYbroAAAAAElFTkSuQmCC", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "# random seed for reproducibility\n", "SEED = 0\n", "key = jr.key(SEED)\n", "\n", "n_pnts = 100\n", "X = np.linspace(-2 * np.pi, 2 * np.pi, n_pnts)\n", "Y = np.sin(X) + 0.1 * X**2\n", "\n", "# add noise\n", "key, noise_key = jr.split(key)\n", "\n", "Y = Y + 0.2 * jr.normal(noise_key, Y.shape)\n", "\n", "# data must be in the shape [n_pnts, n_features] for the pmm library\n", "X = X[:, None]\n", "Y = Y[:, None]\n", "print(X.shape)\n", "print(Y.shape)\n", "\n", "plt.plot(X, Y, 'o')" ] }, { "cell_type": "markdown", "id": "54ec5169", "metadata": {}, "source": [ "## Data Partitioning" ] }, { "cell_type": "code", "execution_count": 4, "id": "73771245", "metadata": {}, "outputs": [], "source": [ "# train on 70% of the data, validate on 15%, test on the rest\n", "train_perc = 0.7\n", "val_perc = 0.15\n", "\n", "n_train = int(n_pnts * train_perc)\n", "n_val = int(n_pnts * val_perc)\n", "n_test = n_pnts - n_train - n_val\n", "\n", "key, shuffle_key = jr.split(key)\n", "\n", "# shuffle the data and then split\n", "X_sh = jr.permutation(shuffle_key, X)\n", "Y_sh = jr.permutation(shuffle_key, Y)\n", "\n", "X_train = X_sh[:n_train]\n", "Y_train = Y_sh[:n_train]\n", "X_val = X_sh[n_train:n_train + n_val]\n", "Y_val = Y_sh[n_train:n_train + n_val]\n", "X_test = X_sh[n_train + n_val:]\n", "Y_test = Y_sh[n_train + n_val:]" ] }, { "cell_type": "markdown", "id": "ec05f0c8", "metadata": {}, "source": [ "## Traditional Neural Network" ] }, { "cell_type": "markdown", "id": "ae389dc7", "metadata": {}, "source": [ "### Data Preparation (Scaling)\n", "\n", "Regression neural networks typically function best when the data are scaled to have unit variance and zero mean (`StandardScaler`)" ] }, { "cell_type": "code", "execution_count": 5, "id": "cbfb0405", "metadata": {}, "outputs": [], "source": [ "xscaler = StandardScaler()\n", "yscaler = StandardScaler()\n", "\n", "X_train_sc = xscaler.fit_transform(X_train)\n", "X_val_sc = xscaler.transform(X_val)\n", "Y_train_sc = yscaler.fit_transform(Y_train)\n", "Y_val_sc = yscaler.transform(Y_val)\n", "\n", "# we need to convert the arrays back from numpy arrays to jax.numpy arrays, since sklearn uses pure numpy\n", "X_train_sc = np.array(X_train_sc)\n", "X_val_sc = np.array(X_val_sc)\n", "Y_train_sc = np.array(Y_train_sc)\n", "Y_val_sc = np.array(Y_val_sc)" ] }, { "cell_type": "markdown", "id": "9468335e", "metadata": {}, "source": [ "### Model Creation\n", "\n", "The model is built from an ordered sequence of `Module`s. For a traditional neural network, these are just `LinearNN` modules. Since we want linear sequential execution, we use a `SequentialModel`." ] }, { "cell_type": "code", "execution_count": 6, "id": "74afec31", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "SequentialModel(\n", " [\n", " LinearNN(\n", " []\n", " ),\n", " LinearNN(\n", " []\n", " ),\n", " LinearNN(\n", " []\n", " ),\n", " ]\n", ")\n" ] } ], "source": [ "# two hidden layers with 64 neurons each and the ReLU activation function\n", "# one output neuron\n", "modules = [\n", " pmm.modules.LinearNN(\n", " out_features=64, bias=True, activation=pmm.modules.ReLU()\n", " ),\n", " pmm.modules.LinearNN(\n", " out_features=64, bias=True, activation=pmm.modules.ReLU()\n", " ),\n", " pmm.modules.LinearNN(out_features=1, bias=True),\n", " ]\n", "\n", "model = pmm.SequentialModel(modules)\n", "\n", "# print model summary before compilation\n", "print(model)" ] }, { "cell_type": "markdown", "id": "e80b2a8a", "metadata": {}, "source": [ "We can see that the model summary is very sparse at the moment. This is because the model doesn't know what data to expect yet and doesn't have any initial values for trainable parameters." ] }, { "cell_type": "markdown", "id": "d795ea73", "metadata": {}, "source": [ "### Model Compilation\n", "\n", "It's more accurate to call this preparation or initialization, since all compilation happens JIT. This step doesn't _need_ to be done manually, as the model will automatically compile itself for the provided training data when the `Model.train` method is called.\n", "\n", "Models are compiled by providing them with a random key or seed as well as the shape of the input data (excluding the batch dimension). This allows the model to prepare all its modules by, for instance, setting initial values for trainable parameters. Forward passes (inferences/predictions) cannot be done with Models (or Modules) until after compilation with the corresponding input shape." ] }, { "cell_type": "code", "execution_count": 7, "id": "2c490289", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "SequentialModel(\n", " [\n", " LinearNN(\n", " [\n", " Flatten,\n", " MatMul(trainable) (trainable floats: 64),\n", " Bias(real=True) (trainable floats: 64),\n", " ReLU,\n", " ]\n", " ),\n", " LinearNN(\n", " [\n", " Flatten,\n", " MatMul(trainable) (trainable floats: 4,096),\n", " Bias(real=True) (trainable floats: 64),\n", " ReLU,\n", " ]\n", " ),\n", " LinearNN(\n", " [\n", " Flatten,\n", " MatMul(trainable) (trainable floats: 64),\n", " Bias(real=True) (trainable floats: 1),\n", " ]\n", " ),\n", " ]\n", ")\n", "Total trainable floats: 4353\n" ] } ], "source": [ "key, compile_key = jr.split(key)\n", "\n", "# the random key here can be replaced with an integer seed or None, in which case a random seed will be chosen\n", "# the model only needs to know the input shape without the batch dimension\n", "model.compile(key, X_train_sc.shape[1:])\n", "\n", "# print the model summary after compilation\n", "print(model)\n", "print(f\"Total trainable floats: {model.get_num_trainable_floats()}\")" ] }, { "cell_type": "markdown", "id": "0cd8ab73", "metadata": {}, "source": [ "Now we see some actual details about the model. We can see it is built from 3 `LinearNN` Modules (which themselves are actually also Models) which use three to four submodules each: `Flatten`, a trainable `MatMul`, a trainable and real-valued `Bias`, and for the hidden layers `ReLU`. This represents the classic $f(Wx+b)$ neural network layer operation.\n", "\n", "We can perform a forward pass (inference/prediction) with the randomly initialized model just to make sure everything is working:" ] }, { "cell_type": "code", "execution_count": 8, "id": "d3640a40", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "Array([[-0.00960011]], dtype=float64)" ] }, "execution_count": 8, "metadata": {}, "output_type": "execute_result" } ], "source": [ "model(np.array([[1.0]]))" ] }, { "cell_type": "markdown", "id": "4e136541", "metadata": {}, "source": [ "### 64-bit versus 32-bit\n", "\n", "By default, JAX disables 64-bit floating point support (double precision). This is re-enabled by calling `jax.config.update(\"jax_enable_x64\", True)` after JAX is imported but _before_ it is initialized (usually before the first array operation). On certain hardware (like consumer GPUs) 64-bit operations can be nearly an order of magnitude slower than 32-bit. Additionally, there is little benefit to storing the trainable parameters of a model in 64-bit precision or for training models with 64-bit precision. It is for this reason that the PMM library defaults to (and will raise warnings otherwise) 32-bit models, 32-bit training, and 64-bit inference.\n", "\n", "Here, we explicitly cast the model to 32-bit as well as the training/validation data." ] }, { "cell_type": "code", "execution_count": 9, "id": "59c43dd8", "metadata": {}, "outputs": [], "source": [ "model = model.astype(np.float32)\n", "\n", "X_train_sc_32 = X_train_sc.astype(np.float32)\n", "Y_train_sc_32 = Y_train_sc.astype(np.float32)\n", "X_val_sc_32 = X_val_sc.astype(np.float32)\n", "Y_val_sc_32 = Y_val_sc.astype(np.float32)" ] }, { "cell_type": "markdown", "id": "5bccce97", "metadata": {}, "source": [ "### Training\n", "\n", "To train the model, we simply call the `model.train()` method and supply it with the training and validation data and optionally things like the loss function and options for the optimization process such as the learning rate, total number of epochs, batch size, etc." ] }, { "cell_type": "code", "execution_count": 10, "id": "4618b7da", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "1/250 | 7.8607e-01/7.8607e-01 [####################] (0s)\n", "2/250 | 5.0318e-01/5.0318e-01 [####################] (0s)\n", "3/250 | 4.5940e-01/4.5940e-01 [####################] (0s)\n", "4/250 | 4.0544e-01/4.0544e-01 [####################] (0s)\n", "5/250 | 3.6005e-01/3.6005e-01 [####################] (0s)\n", "6/250 | 2.8516e-01/2.8516e-01 [####################] (0s)\n", "7/250 | 2.5043e-01/2.5043e-01 [####################] (0s)\n", "8/250 | 2.2804e-01/2.2804e-01 [####################] (0s)\n", "9/250 | 1.9864e-01/1.9864e-01 [####################] (0s)\n", "10/250 | 1.8128e-01/1.8128e-01 [####################] (0s)\n", "11/250 | 1.8519e-01/1.8128e-01 [####################] (0s)\n", "12/250 | 1.6765e-01/1.6765e-01 [####################] (0s)\n", "13/250 | 1.5993e-01/1.5993e-01 [####################] (0s)\n", "14/250 | 1.5118e-01/1.5118e-01 [####################] (0s)\n", "15/250 | 1.4756e-01/1.4756e-01 [####################] (0s)\n", "16/250 | 1.4488e-01/1.4488e-01 [####################] (0s)\n", "17/250 | 1.5423e-01/1.4488e-01 [####################] (0s)\n", "18/250 | 1.3836e-01/1.3836e-01 [####################] (0s)\n", "19/250 | 1.2858e-01/1.2858e-01 [####################] (0s)\n", "20/250 | 1.3492e-01/1.2858e-01 [####################] (0s)\n", "21/250 | 1.2824e-01/1.2824e-01 [####################] (0s)\n", "22/250 | 1.2356e-01/1.2356e-01 [####################] (0s)\n", "23/250 | 1.1941e-01/1.1941e-01 [####################] (0s)\n", "24/250 | 1.3161e-01/1.1941e-01 [####################] (0s)\n", "25/250 | 1.2221e-01/1.1941e-01 [####################] (0s)\n", "26/250 | 1.2183e-01/1.1941e-01 [####################] (0s)\n", "27/250 | 1.1759e-01/1.1759e-01 [####################] (0s)\n", "28/250 | 1.1619e-01/1.1619e-01 [####################] (0s)\n", "29/250 | 1.1807e-01/1.1619e-01 [####################] (0s)\n", "30/250 | 1.0958e-01/1.0958e-01 [####################] (0s)\n", "31/250 | 1.3600e-01/1.0958e-01 [####################] (0s)\n", "32/250 | 1.1083e-01/1.0958e-01 [####################] (0s)\n", "33/250 | 1.0806e-01/1.0806e-01 [####################] (0s)\n", "34/250 | 1.1257e-01/1.0806e-01 [####################] (0s)\n", "35/250 | 1.2772e-01/1.0806e-01 [####################] (0s)\n", "36/250 | 1.1246e-01/1.0806e-01 [####################] (0s)\n", "37/250 | 1.0966e-01/1.0806e-01 [####################] (0s)\n", "38/250 | 1.2023e-01/1.0806e-01 [####################] (0s)\n", "39/250 | 1.0668e-01/1.0668e-01 [####################] (0s)\n", "40/250 | 1.0356e-01/1.0356e-01 [####################] (0s)\n", "41/250 | 1.1708e-01/1.0356e-01 [####################] (0s)\n", "42/250 | 1.0925e-01/1.0356e-01 [####################] (0s)\n", "43/250 | 1.0966e-01/1.0356e-01 [####################] (0s)\n", "44/250 | 1.0242e-01/1.0242e-01 [####################] (0s)\n", "45/250 | 1.0997e-01/1.0242e-01 [####################] (0s)\n", "46/250 | 1.0356e-01/1.0242e-01 [####################] (0s)\n", "47/250 | 1.0313e-01/1.0242e-01 [####################] (0s)\n", "48/250 | 1.0253e-01/1.0242e-01 [####################] (0s)\n", "49/250 | 1.0032e-01/1.0032e-01 [####################] (0s)\n", "50/250 | 9.7897e-02/9.7897e-02 [####################] (0s)\n", "51/250 | 1.0216e-01/9.7897e-02 [####################] (0s)\n", "52/250 | 1.0057e-01/9.7897e-02 [####################] (0s)\n", "53/250 | 1.0118e-01/9.7897e-02 [####################] (0s)\n", "54/250 | 9.7351e-02/9.7351e-02 [####################] (0s)\n", "55/250 | 1.1234e-01/9.7351e-02 [####################] (0s)\n", "56/250 | 9.3110e-02/9.3110e-02 [####################] (0s)\n", "57/250 | 9.9734e-02/9.3110e-02 [####################] (0s)\n", "58/250 | 9.1770e-02/9.1770e-02 [####################] (0s)\n", "59/250 | 8.9069e-02/8.9069e-02 [####################] (0s)\n", "60/250 | 1.0289e-01/8.9069e-02 [####################] (0s)\n", "61/250 | 9.6913e-02/8.9069e-02 [####################] (0s)\n", "62/250 | 9.6241e-02/8.9069e-02 [####################] (0s)\n", "63/250 | 9.8420e-02/8.9069e-02 [####################] (0s)\n", "64/250 | 8.7649e-02/8.7649e-02 [####################] (0s)\n", "65/250 | 9.0070e-02/8.7649e-02 [####################] (0s)\n", "66/250 | 9.6413e-02/8.7649e-02 [####################] (0s)\n", "67/250 | 9.2351e-02/8.7649e-02 [####################] (0s)\n", "68/250 | 1.0716e-01/8.7649e-02 [####################] (0s)\n", "69/250 | 1.0409e-01/8.7649e-02 [####################] (0s)\n", "70/250 | 8.6707e-02/8.6707e-02 [####################] (0s)\n", "71/250 | 8.8159e-02/8.6707e-02 [####################] (0s)\n", "72/250 | 8.7628e-02/8.6707e-02 [####################] (0s)\n", "73/250 | 8.3547e-02/8.3547e-02 [####################] (0s)\n", "74/250 | 8.0006e-02/8.0006e-02 [####################] (0s)\n", "75/250 | 8.8055e-02/8.0006e-02 [####################] (0s)\n", "76/250 | 8.6013e-02/8.0006e-02 [####################] (0s)\n", "77/250 | 9.0464e-02/8.0006e-02 [####################] (0s)\n", "78/250 | 8.8312e-02/8.0006e-02 [####################] (0s)\n", "79/250 | 8.0211e-02/8.0006e-02 [####################] (0s)\n", "80/250 | 8.8458e-02/8.0006e-02 [####################] (0s)\n", "81/250 | 8.6534e-02/8.0006e-02 [####################] (0s)\n", "82/250 | 8.5332e-02/8.0006e-02 [####################] (0s)\n", "83/250 | 8.3566e-02/8.0006e-02 [####################] (0s)\n", "84/250 | 8.0716e-02/8.0006e-02 [####################] (0s)\n", "85/250 | 8.1569e-02/8.0006e-02 [####################] (0s)\n", "86/250 | 8.0372e-02/8.0006e-02 [####################] (0s)\n", "87/250 | 7.9148e-02/7.9148e-02 [####################] (0s)\n", "88/250 | 7.3478e-02/7.3478e-02 [####################] (0s)\n", "89/250 | 8.1903e-02/7.3478e-02 [####################] (0s)\n", "90/250 | 1.0176e-01/7.3478e-02 [####################] (0s)\n", "91/250 | 8.8403e-02/7.3478e-02 [####################] (0s)\n", "92/250 | 9.1995e-02/7.3478e-02 [####################] (0s)\n", "93/250 | 1.0767e-01/7.3478e-02 [####################] (0s)\n", "94/250 | 8.3559e-02/7.3478e-02 [####################] (0s)\n", "95/250 | 7.8728e-02/7.3478e-02 [####################] (0s)\n", "96/250 | 7.3051e-02/7.3051e-02 [####################] (0s)\n", "97/250 | 9.4739e-02/7.3051e-02 [####################] (0s)\n", "98/250 | 9.4280e-02/7.3051e-02 [####################] (0s)\n", "99/250 | 9.2930e-02/7.3051e-02 [####################] (0s)\n", "100/250 | 7.2277e-02/7.2277e-02 [####################] (0s)\n", "101/250 | 7.1439e-02/7.1439e-02 [####################] (0s)\n", "102/250 | 6.8890e-02/6.8890e-02 [####################] (0s)\n", "103/250 | 6.8998e-02/6.8890e-02 [####################] (0s)\n", "104/250 | 7.1708e-02/6.8890e-02 [####################] (0s)\n", "105/250 | 7.4463e-02/6.8890e-02 [####################] (0s)\n", "106/250 | 6.4985e-02/6.4985e-02 [####################] (0s)\n", "107/250 | 6.9123e-02/6.4985e-02 [####################] (0s)\n", "108/250 | 6.5660e-02/6.4985e-02 [####################] (0s)\n", "109/250 | 6.5931e-02/6.4985e-02 [####################] (0s)\n", "110/250 | 6.1449e-02/6.1449e-02 [####################] (0s)\n", "111/250 | 6.4720e-02/6.1449e-02 [####################] (0s)\n", "112/250 | 6.7240e-02/6.1449e-02 [####################] (0s)\n", "113/250 | 7.3970e-02/6.1449e-02 [####################] (0s)\n", "114/250 | 6.1726e-02/6.1449e-02 [####################] (0s)\n", "115/250 | 8.1460e-02/6.1449e-02 [####################] (0s)\n", "116/250 | 8.6221e-02/6.1449e-02 [####################] (0s)\n", "117/250 | 7.0352e-02/6.1449e-02 [####################] (0s)\n", "118/250 | 7.6675e-02/6.1449e-02 [####################] (0s)\n", "119/250 | 9.5870e-02/6.1449e-02 [####################] (0s)\n", "120/250 | 8.7505e-02/6.1449e-02 [####################] (0s)\n", "121/250 | 8.1257e-02/6.1449e-02 [####################] (0s)\n", "122/250 | 8.4181e-02/6.1449e-02 [####################] (0s)\n", "123/250 | 7.5042e-02/6.1449e-02 [####################] (0s)\n", "124/250 | 6.2688e-02/6.1449e-02 [####################] (0s)\n", "125/250 | 8.3008e-02/6.1449e-02 [####################] (0s)\n", "126/250 | 6.0585e-02/6.0585e-02 [####################] (0s)\n", "127/250 | 6.7834e-02/6.0585e-02 [####################] (0s)\n", "128/250 | 9.3002e-02/6.0585e-02 [####################] (0s)\n", "129/250 | 8.4863e-02/6.0585e-02 [####################] (0s)\n", "130/250 | 6.4601e-02/6.0585e-02 [####################] (0s)\n", "131/250 | 6.9106e-02/6.0585e-02 [####################] (0s)\n", "132/250 | 6.9529e-02/6.0585e-02 [####################] (0s)\n", "133/250 | 6.9735e-02/6.0585e-02 [####################] (0s)\n", "134/250 | 6.3158e-02/6.0585e-02 [####################] (0s)\n", "135/250 | 5.8077e-02/5.8077e-02 [####################] (0s)\n", "136/250 | 5.8051e-02/5.8051e-02 [####################] (0s)\n", "137/250 | 5.1926e-02/5.1926e-02 [####################] (0s)\n", "138/250 | 6.9325e-02/5.1926e-02 [####################] (0s)\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "139/250 | 6.6578e-02/5.1926e-02 [####################] (0s)\n", "140/250 | 5.4720e-02/5.1926e-02 [####################] (0s)\n", "141/250 | 6.1397e-02/5.1926e-02 [####################] (0s)\n", "142/250 | 4.6176e-02/4.6176e-02 [####################] (0s)\n", "143/250 | 5.6338e-02/4.6176e-02 [####################] (0s)\n", "144/250 | 5.9826e-02/4.6176e-02 [####################] (0s)\n", "145/250 | 5.2593e-02/4.6176e-02 [####################] (0s)\n", "146/250 | 4.7631e-02/4.6176e-02 [####################] (0s)\n", "147/250 | 6.0039e-02/4.6176e-02 [####################] (0s)\n", "148/250 | 5.1952e-02/4.6176e-02 [####################] (0s)\n", "149/250 | 6.4384e-02/4.6176e-02 [####################] (0s)\n", "150/250 | 4.7902e-02/4.6176e-02 [####################] (0s)\n", "151/250 | 5.4240e-02/4.6176e-02 [####################] (0s)\n", "152/250 | 8.7593e-02/4.6176e-02 [####################] (0s)\n", "153/250 | 5.5680e-02/4.6176e-02 [####################] (0s)\n", "154/250 | 5.9909e-02/4.6176e-02 [####################] (0s)\n", "155/250 | 4.5948e-02/4.5948e-02 [####################] (0s)\n", "156/250 | 4.5787e-02/4.5787e-02 [####################] (0s)\n", "157/250 | 5.4487e-02/4.5787e-02 [####################] (0s)\n", "158/250 | 4.5993e-02/4.5787e-02 [####################] (0s)\n", "159/250 | 5.2104e-02/4.5787e-02 [####################] (0s)\n", "160/250 | 6.5566e-02/4.5787e-02 [####################] (0s)\n", "161/250 | 4.5222e-02/4.5222e-02 [####################] (0s)\n", "162/250 | 5.6127e-02/4.5222e-02 [####################] (0s)\n", "163/250 | 5.9438e-02/4.5222e-02 [####################] (0s)\n", "164/250 | 4.9327e-02/4.5222e-02 [####################] (0s)\n", "165/250 | 3.8123e-02/3.8123e-02 [####################] (0s)\n", "166/250 | 5.3154e-02/3.8123e-02 [####################] (0s)\n", "167/250 | 4.5029e-02/3.8123e-02 [####################] (0s)\n", "168/250 | 4.1853e-02/3.8123e-02 [####################] (0s)\n", "169/250 | 4.6038e-02/3.8123e-02 [####################] (0s)\n", "170/250 | 5.9997e-02/3.8123e-02 [####################] (0s)\n", "171/250 | 4.2596e-02/3.8123e-02 [####################] (0s)\n", "172/250 | 4.8706e-02/3.8123e-02 [####################] (0s)\n", "173/250 | 4.2727e-02/3.8123e-02 [####################] (0s)\n", "174/250 | 5.2578e-02/3.8123e-02 [####################] (0s)\n", "175/250 | 4.3788e-02/3.8123e-02 [####################] (0s)\n", "176/250 | 7.0637e-02/3.8123e-02 [####################] (0s)\n", "177/250 | 4.1196e-02/3.8123e-02 [####################] (0s)\n", "178/250 | 3.1865e-02/3.1865e-02 [####################] (0s)\n", "179/250 | 3.7221e-02/3.1865e-02 [####################] (0s)\n", "180/250 | 3.3198e-02/3.1865e-02 [####################] (0s)\n", "181/250 | 3.1750e-02/3.1750e-02 [####################] (0s)\n", "182/250 | 3.2191e-02/3.1750e-02 [####################] (0s)\n", "183/250 | 3.5275e-02/3.1750e-02 [####################] (0s)\n", "184/250 | 5.1212e-02/3.1750e-02 [####################] (0s)\n", "185/250 | 4.9963e-02/3.1750e-02 [####################] (0s)\n", "186/250 | 4.9463e-02/3.1750e-02 [####################] (0s)\n", "187/250 | 5.6674e-02/3.1750e-02 [####################] (0s)\n", "188/250 | 2.8552e-02/2.8552e-02 [####################] (0s)\n", "189/250 | 2.9090e-02/2.8552e-02 [####################] (0s)\n", "190/250 | 2.9629e-02/2.8552e-02 [####################] (0s)\n", "191/250 | 3.5665e-02/2.8552e-02 [####################] (0s)\n", "192/250 | 3.7032e-02/2.8552e-02 [####################] (0s)\n", "193/250 | 2.9679e-02/2.8552e-02 [####################] (0s)\n", "194/250 | 3.8773e-02/2.8552e-02 [####################] (0s)\n", "195/250 | 3.4265e-02/2.8552e-02 [####################] (0s)\n", "196/250 | 4.1550e-02/2.8552e-02 [####################] (0s)\n", "197/250 | 3.5000e-02/2.8552e-02 [####################] (0s)\n", "198/250 | 3.6903e-02/2.8552e-02 [####################] (0s)\n", "199/250 | 2.7838e-02/2.7838e-02 [####################] (0s)\n", "200/250 | 2.5960e-02/2.5960e-02 [####################] (0s)\n", "201/250 | 2.7936e-02/2.5960e-02 [####################] (0s)\n", "202/250 | 3.4787e-02/2.5960e-02 [####################] (0s)\n", "203/250 | 3.4081e-02/2.5960e-02 [####################] (0s)\n", "204/250 | 4.0938e-02/2.5960e-02 [####################] (0s)\n", "205/250 | 3.7885e-02/2.5960e-02 [####################] (0s)\n", "206/250 | 3.4678e-02/2.5960e-02 [####################] (0s)\n", "207/250 | 6.0238e-02/2.5960e-02 [####################] (0s)\n", "208/250 | 3.5822e-02/2.5960e-02 [####################] (0s)\n", "209/250 | 2.8570e-02/2.5960e-02 [####################] (0s)\n", "210/250 | 2.7827e-02/2.5960e-02 [####################] (0s)\n", "211/250 | 3.3676e-02/2.5960e-02 [####################] (0s)\n", "212/250 | 3.0658e-02/2.5960e-02 [####################] (0s)\n", "213/250 | 3.1736e-02/2.5960e-02 [####################] (0s)\n", "214/250 | 3.2551e-02/2.5960e-02 [####################] (0s)\n", "215/250 | 2.3595e-02/2.3595e-02 [####################] (0s)\n", "216/250 | 3.0965e-02/2.3595e-02 [####################] (0s)\n", "217/250 | 4.1416e-02/2.3595e-02 [####################] (0s)\n", "218/250 | 7.1400e-02/2.3595e-02 [####################] (0s)\n", "219/250 | 6.0360e-02/2.3595e-02 [####################] (0s)\n", "220/250 | 4.7201e-02/2.3595e-02 [####################] (0s)\n", "221/250 | 4.6297e-02/2.3595e-02 [####################] (0s)\n", "222/250 | 4.8735e-02/2.3595e-02 [####################] (0s)\n", "223/250 | 3.6821e-02/2.3595e-02 [####################] (0s)\n", "224/250 | 3.1825e-02/2.3595e-02 [####################] (0s)\n", "225/250 | 3.2482e-02/2.3595e-02 [####################] (0s)\n", "226/250 | 3.4695e-02/2.3595e-02 [####################] (0s)\n", "227/250 | 3.2790e-02/2.3595e-02 [####################] (0s)\n", "228/250 | 3.5002e-02/2.3595e-02 [####################] (0s)\n", "229/250 | 4.2969e-02/2.3595e-02 [####################] (0s)\n", "230/250 | 4.6462e-02/2.3595e-02 [####################] (0s)\n", "231/250 | 4.0521e-02/2.3595e-02 [####################] (0s)\n", "232/250 | 3.8239e-02/2.3595e-02 [####################] (0s)\n", "233/250 | 3.0208e-02/2.3595e-02 [####################] (0s)\n", "234/250 | 2.4054e-02/2.3595e-02 [####################] (0s)\n", "235/250 | 4.7296e-02/2.3595e-02 [####################] (0s)\n", "236/250 | 3.9185e-02/2.3595e-02 [####################] (0s)\n", "237/250 | 3.4520e-02/2.3595e-02 [####################] (0s)\n", "238/250 | 3.4001e-02/2.3595e-02 [####################] (0s)\n", "239/250 | 4.1196e-02/2.3595e-02 [####################] (0s)\n", "240/250 | 2.8311e-02/2.3595e-02 [####################] (0s)\n", "241/250 | 5.0485e-02/2.3595e-02 [####################] (0s)\n", "242/250 | 3.6910e-02/2.3595e-02 [####################] (0s)\n", "243/250 | 4.3837e-02/2.3595e-02 [####################] (0s)\n", "244/250 | 3.7291e-02/2.3595e-02 [####################] (0s)\n", "245/250 | 3.3454e-02/2.3595e-02 [####################] (0s)\n", "246/250 | 2.1437e-02/2.1437e-02 [####################] (0s)\n", "247/250 | 3.5610e-02/2.1437e-02 [####################] (0s)\n", "248/250 | 2.7829e-02/2.1437e-02 [####################] (0s)\n", "249/250 | 4.2877e-02/2.1437e-02 [####################] (0s)\n", "250/250 | 3.8412e-02/2.1437e-02 [####################] (0s)\n", "\n", "========================================\n", "Total epochs: 250\n", "(best epoch: 245)\n", "(best validation loss: 2.1437E-02)\n", "========================================\n" ] } ], "source": [ "key, batch_key = jr.split(key)\n", "\n", "model.train(\n", " X_train_sc_32,\n", " Y=Y_train_sc_32,\n", " X_val=X_val_sc_32,\n", " Y_val=Y_val_sc_32,\n", " lr=1e-2,\n", " epochs=250,\n", " batch_size=5,\n", " batch_rng=batch_key,\n", " verbose=True)" ] }, { "cell_type": "markdown", "id": "7c004178", "metadata": {}, "source": [ "### Inference\n", "\n", "Now we're ready to make new predictions with the model. All Models and Modules are directly callable once compiled, so we need only to pass in the (scaled) inputs like `model(X)` and unscale the predictions." ] }, { "cell_type": "code", "execution_count": 11, "id": "9cb396f2", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "" ] }, "execution_count": 11, "metadata": {}, "output_type": "execute_result" }, { "data": { "image/png": "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", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "# pass in the scaled inputs (converted to JAX arrays again)\n", "X_sc = xscaler.transform(X)\n", "X_sc = np.array(X_sc)\n", "\n", "# get scaled predictions\n", "Y_pred_sc = model(X_sc)\n", "\n", "# unscale predictions\n", "Y_pred = yscaler.inverse_transform(Y_pred_sc)\n", "\n", "# plot results\n", "plt.plot(X, Y_pred, label=\"NN\", lw=2, zorder=10)\n", "plt.plot(X_train, Y_train, 'o', label=\"Train\")\n", "plt.plot(X_val, Y_val, 's', label=\"Val\")\n", "plt.plot(X_test, Y_test, 'x', label=\"Test\")\n", "plt.legend()" ] }, { "cell_type": "markdown", "id": "184c3307", "metadata": {}, "source": [ "## Parametric Matrix Model (`AffineObservablePMM`)\n", "\n", "Here we repeat the above process for the `AffineObservablePMM`, which is both a Module and a Model. For consistency, we wrap it with a `SequentialModel`, though this isn't necessary as it is itself a subclass of `SequentialModel`. The only other difference in usage here is that this kind of PMM performs best when the data are scaled uniformly, using `MinMaxScaler`." ] }, { "cell_type": "markdown", "id": "609b897b", "metadata": {}, "source": [ "### Data Preparation (Scaling)\n", "\n", "This kind of PMM typically functions best when the data are scaled uniformly (`MinMaxScaler`)" ] }, { "cell_type": "code", "execution_count": 12, "id": "640a64ac", "metadata": {}, "outputs": [], "source": [ "xscaler = MinMaxScaler()\n", "yscaler = MinMaxScaler()\n", "\n", "X_train_sc = xscaler.fit_transform(X_train)\n", "X_val_sc = xscaler.transform(X_val)\n", "Y_train_sc = yscaler.fit_transform(Y_train)\n", "Y_val_sc = yscaler.transform(Y_val)\n", "\n", "# we need to convert the arrays back from numpy arrays to jax.numpy arrays, since sklearn uses pure numpy\n", "X_train_sc = np.array(X_train_sc)\n", "X_val_sc = np.array(X_val_sc)\n", "Y_train_sc = np.array(Y_train_sc)\n", "Y_val_sc = np.array(Y_val_sc)" ] }, { "cell_type": "markdown", "id": "5b004f0d", "metadata": {}, "source": [ "### Model Creation\n", "\n", "This model is a single `AffineObservablePMM` module with a Hermitian matrices size of `5`, two eigenvectors, one secondary matrix, and using expectation values instead of transition amplitudes. Internally, this Module is just a `SequentialModel` of Modules that first form the primary matrix $H(c) = H_0 + \\sum_i c_i H_i$, then take the eigendecomposition, then compute the sum of transition amplitudes or expectation values with trainable secondary matrices, then finally add a trainable bias." ] }, { "cell_type": "code", "execution_count": 13, "id": "674e42ee", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "SequentialModel(\n", " [\n", " AffineObservablePMM(\n", " []\n", " ),\n", " ]\n", ")\n", "Total trainable floats: 0\n" ] } ], "source": [ "# just a single PMM module, which contains all the submodules\n", "modules = [\n", " pmm.modules.AffineObservablePMM(\n", " matrix_size=5,\n", " num_eig=2,\n", " num_secondaries=1,\n", " output_size=1,\n", " use_expectation_values=True\n", " )\n", " ]\n", "\n", "model = pmm.SequentialModel(modules)\n", "\n", "# print model summary before compilation\n", "print(model)\n", "print(f\"Total trainable floats: {model.get_num_trainable_floats()}\")" ] }, { "cell_type": "markdown", "id": "36bad79c", "metadata": {}, "source": [ "We can see that the model summary is very sparse at the moment. This is because the model doesn't know what data to expect yet and doesn't have any initial values for trainable parameters." ] }, { "cell_type": "markdown", "id": "1f679fe9", "metadata": {}, "source": [ "### Model Compilation\n", "\n", "It's more accurate to call this preparation or initialization, since all compilation happens JIT. This step doesn't _need_ to be done manually, as the model will automatically compile itself for the provided training data when the `Model.train` method is called.\n", "\n", "Models are compiled by providing them with a random key or seed as well as the shape of the input data (excluding the batch dimension). This allows the model to prepare all its modules by, for instance, setting initial values for trainable parameters. Forward passes (inferences/predictions) cannot be done with Models (or Modules) until after compilation with the corresponding input shape." ] }, { "cell_type": "code", "execution_count": 14, "id": "349df642", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "SequentialModel(\n", " [\n", " AffineObservablePMM(\n", " (\n", " AffineHermitianMatrix(5x5,) (trainable floats: 50),\n", " Eigenvectors(num_eig=2, which=LM),\n", " ExpectationValueSum(output_size=1, num_observables=1, centered=True) (trainable floats: 25),\n", " Bias(real=True) (trainable floats: 1),\n", " )\n", " ),\n", " ]\n", ")\n" ] } ], "source": [ "key, compile_key = jr.split(key)\n", "\n", "# the random key here can be replaced with an integer seed or None, in which case a random seed will be chosen\n", "# the model only needs to know the input shape without the batch dimension\n", "model.compile(key, X_train_sc.shape[1:])\n", "\n", "# print the model summary after compilation\n", "print(model)" ] }, { "cell_type": "markdown", "id": "28e0223f", "metadata": {}, "source": [ "Now we see some actual details about the model. We can see it is built from 1 `AffineObservablePMM` Module (which itself is a Model) which uses four submodules: `AffineHermitianMatrix`, `Eigenvectors`, `ExpectationValueSum`, and `Bias`.\n", "\n", "We can perform a forward pass (inference/prediction) with the randomly initialized model just to make sure everything is working:" ] }, { "cell_type": "code", "execution_count": 15, "id": "d86e12ac", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "Array([[0.01202144]], dtype=float64)" ] }, "execution_count": 15, "metadata": {}, "output_type": "execute_result" } ], "source": [ "model(np.array([[1.0]]))" ] }, { "cell_type": "markdown", "id": "2665a0b5", "metadata": {}, "source": [ "### 64-bit versus 32-bit\n", "\n", "By default, JAX disables 64-bit floating point support (double precision). This is re-enabled by calling `jax.config.update(\"jax_enable_x64\", True)` after JAX is imported but _before_ it is initialized (usually before the first array operation). On certain hardware (like consumer GPUs) 64-bit operations can be nearly an order of magnitude slower than 32-bit. Additionally, there is little benefit to storing the trainable parameters of a model in 64-bit precision or for training models with 64-bit precision. It is for this reason that the PMM library defaults to (and will raise warnings otherwise) 32-bit models, 32-bit training, and 64-bit inference.\n", "\n", "Here, we explicitly cast the model to 32-bit as well as the training/validation data." ] }, { "cell_type": "code", "execution_count": 16, "id": "27812ed7", "metadata": {}, "outputs": [], "source": [ "model = model.astype(np.float32)\n", "\n", "X_train_sc_32 = X_train_sc.astype(np.float32)\n", "Y_train_sc_32 = Y_train_sc.astype(np.float32)\n", "X_val_sc_32 = X_val_sc.astype(np.float32)\n", "Y_val_sc_32 = Y_val_sc.astype(np.float32)" ] }, { "cell_type": "markdown", "id": "cf6284bf", "metadata": {}, "source": [ "### Training\n", "\n", "To train the model, we simply call the `model.train()` method and supply it with the training and validation data and optionally things like the loss function and options for the optimization process such as the learning rate, total number of epochs, batch size, etc." ] }, { "cell_type": "code", "execution_count": 17, "id": "bd0c283a", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "1/250 | 5.4442e-02/5.4442e-02 [####################] (0s)\n", "2/250 | 1.1614e-01/5.4442e-02 [####################] (0s)\n", "3/250 | 5.6446e-02/5.4442e-02 [####################] (0s)\n", "4/250 | 5.8632e-02/5.4442e-02 [####################] (0s)\n", "5/250 | 9.0178e-02/5.4442e-02 [####################] (0s)\n", "6/250 | 5.4176e-02/5.4176e-02 [####################] (0s)\n", "7/250 | 6.2531e-02/5.4176e-02 [####################] (0s)\n", "8/250 | 5.2981e-02/5.2981e-02 [####################] (0s)\n", "9/250 | 3.3681e-02/3.3681e-02 [####################] (0s)\n", "10/250 | 2.9399e-02/2.9399e-02 [####################] (0s)\n", "11/250 | 3.0416e-02/2.9399e-02 [####################] (0s)\n", "12/250 | 2.5683e-02/2.5683e-02 [####################] (0s)\n", "13/250 | 2.2098e-02/2.2098e-02 [####################] (0s)\n", "14/250 | 1.8719e-02/1.8719e-02 [####################] (0s)\n", "15/250 | 1.2611e-02/1.2611e-02 [####################] (0s)\n", "16/250 | 1.0284e-02/1.0284e-02 [####################] (0s)\n", "17/250 | 1.0085e-02/1.0085e-02 [####################] (0s)\n", "18/250 | 1.2628e-02/1.0085e-02 [####################] (0s)\n", "19/250 | 8.1678e-03/8.1678e-03 [####################] (0s)\n", "20/250 | 6.8490e-03/6.8490e-03 [####################] (0s)\n", "21/250 | 7.4929e-03/6.8490e-03 [####################] (0s)\n", "22/250 | 6.5267e-03/6.5267e-03 [####################] (0s)\n", "23/250 | 5.5787e-03/5.5787e-03 [####################] (0s)\n", "24/250 | 7.4365e-03/5.5787e-03 [####################] (0s)\n", "25/250 | 6.4864e-03/5.5787e-03 [####################] (0s)\n", "26/250 | 6.3493e-03/5.5787e-03 [####################] (0s)\n", "27/250 | 5.9987e-03/5.5787e-03 [####################] (0s)\n", "28/250 | 7.7315e-03/5.5787e-03 [####################] (0s)\n", "29/250 | 5.9036e-03/5.5787e-03 [####################] (0s)\n", "30/250 | 6.0343e-03/5.5787e-03 [####################] (0s)\n", "31/250 | 6.7738e-03/5.5787e-03 [####################] (0s)\n", "32/250 | 6.3439e-03/5.5787e-03 [####################] (0s)\n", "33/250 | 9.1537e-03/5.5787e-03 [####################] (0s)\n", "34/250 | 7.5088e-03/5.5787e-03 [####################] (0s)\n", "35/250 | 6.0626e-03/5.5787e-03 [####################] (0s)\n", "36/250 | 6.4997e-03/5.5787e-03 [####################] (0s)\n", "37/250 | 6.7489e-03/5.5787e-03 [####################] (0s)\n", "38/250 | 7.2865e-03/5.5787e-03 [####################] (0s)\n", "39/250 | 7.4852e-03/5.5787e-03 [####################] (0s)\n", "40/250 | 6.1094e-03/5.5787e-03 [####################] (0s)\n", "41/250 | 5.7489e-03/5.5787e-03 [####################] (0s)\n", "42/250 | 6.0052e-03/5.5787e-03 [####################] (0s)\n", "43/250 | 7.0590e-03/5.5787e-03 [####################] (0s)\n", "44/250 | 7.0230e-03/5.5787e-03 [####################] (0s)\n", "45/250 | 6.9031e-03/5.5787e-03 [####################] (0s)\n", "46/250 | 6.2807e-03/5.5787e-03 [####################] (0s)\n", "47/250 | 7.0101e-03/5.5787e-03 [####################] (0s)\n", "48/250 | 7.6631e-03/5.5787e-03 [####################] (0s)\n", "49/250 | 6.0248e-03/5.5787e-03 [####################] (0s)\n", "50/250 | 6.5716e-03/5.5787e-03 [####################] (0s)\n", "51/250 | 6.7445e-03/5.5787e-03 [####################] (0s)\n", "52/250 | 5.2785e-03/5.2785e-03 [####################] (0s)\n", "53/250 | 3.1016e-03/3.1016e-03 [####################] (0s)\n", "54/250 | 8.9250e-03/3.1016e-03 [####################] (0s)\n", "55/250 | 6.9021e-03/3.1016e-03 [####################] (0s)\n", "56/250 | 3.8885e-03/3.1016e-03 [####################] (0s)\n", "57/250 | 7.6216e-03/3.1016e-03 [####################] (0s)\n", "58/250 | 7.3961e-03/3.1016e-03 [####################] (0s)\n", "59/250 | 7.0220e-03/3.1016e-03 [####################] (0s)\n", "60/250 | 6.1720e-03/3.1016e-03 [####################] (0s)\n", "61/250 | 5.7947e-03/3.1016e-03 [####################] (0s)\n", "62/250 | 5.0734e-03/3.1016e-03 [####################] (0s)\n", "63/250 | 4.9879e-03/3.1016e-03 [####################] (0s)\n", "64/250 | 5.5361e-03/3.1016e-03 [####################] (0s)\n", "65/250 | 4.5192e-03/3.1016e-03 [####################] (0s)\n", "66/250 | 6.7327e-03/3.1016e-03 [####################] (0s)\n", "67/250 | 7.7463e-03/3.1016e-03 [####################] (0s)\n", "68/250 | 5.5338e-03/3.1016e-03 [####################] (0s)\n", "69/250 | 3.7159e-03/3.1016e-03 [####################] (0s)\n", "70/250 | 3.1470e-03/3.1016e-03 [####################] (0s)\n", "71/250 | 5.3691e-03/3.1016e-03 [####################] (0s)\n", "72/250 | 9.9612e-03/3.1016e-03 [####################] (0s)\n", "73/250 | 5.4284e-03/3.1016e-03 [####################] (0s)\n", "74/250 | 6.3011e-03/3.1016e-03 [####################] (0s)\n", "75/250 | 4.0493e-03/3.1016e-03 [####################] (0s)\n", "76/250 | 4.3772e-03/3.1016e-03 [####################] (0s)\n", "77/250 | 4.2802e-03/3.1016e-03 [####################] (0s)\n", "78/250 | 6.9974e-03/3.1016e-03 [####################] (0s)\n", "79/250 | 3.5675e-03/3.1016e-03 [####################] (0s)\n", "80/250 | 5.5649e-03/3.1016e-03 [####################] (0s)\n", "81/250 | 7.4596e-03/3.1016e-03 [####################] (0s)\n", "82/250 | 4.3281e-03/3.1016e-03 [####################] (0s)\n", "83/250 | 2.9820e-03/2.9820e-03 [####################] (0s)\n", "84/250 | 6.6735e-03/2.9820e-03 [####################] (0s)\n", "85/250 | 3.7156e-03/2.9820e-03 [####################] (0s)\n", "86/250 | 2.8052e-03/2.8052e-03 [####################] (0s)\n", "87/250 | 1.6796e-02/2.8052e-03 [####################] (0s)\n", "88/250 | 1.0363e-02/2.8052e-03 [####################] (0s)\n", "89/250 | 5.0196e-03/2.8052e-03 [####################] (0s)\n", "90/250 | 3.4737e-03/2.8052e-03 [####################] (0s)\n", "91/250 | 1.9751e-03/1.9751e-03 [####################] (0s)\n", "92/250 | 2.8802e-03/1.9751e-03 [####################] (0s)\n", "93/250 | 5.8319e-03/1.9751e-03 [####################] (0s)\n", "94/250 | 3.4529e-03/1.9751e-03 [####################] (0s)\n", "95/250 | 2.6395e-03/1.9751e-03 [####################] (0s)\n", "96/250 | 2.8948e-03/1.9751e-03 [####################] (0s)\n", "97/250 | 3.9332e-03/1.9751e-03 [####################] (0s)\n", "98/250 | 5.2598e-03/1.9751e-03 [####################] (0s)\n", "99/250 | 4.5422e-03/1.9751e-03 [####################] (0s)\n", "100/250 | 3.1950e-03/1.9751e-03 [####################] (0s)\n", "101/250 | 7.2841e-03/1.9751e-03 [####################] (0s)\n", "102/250 | 7.1810e-03/1.9751e-03 [####################] (0s)\n", "103/250 | 5.0848e-03/1.9751e-03 [####################] (0s)\n", "104/250 | 3.0136e-03/1.9751e-03 [####################] (0s)\n", "105/250 | 2.4440e-03/1.9751e-03 [####################] (0s)\n", "106/250 | 3.4854e-03/1.9751e-03 [####################] (0s)\n", "107/250 | 3.3913e-03/1.9751e-03 [####################] (0s)\n", "108/250 | 1.9056e-03/1.9056e-03 [####################] (0s)\n", "109/250 | 2.3935e-03/1.9056e-03 [####################] (0s)\n", "110/250 | 2.2171e-03/1.9056e-03 [####################] (0s)\n", "111/250 | 2.8577e-03/1.9056e-03 [####################] (0s)\n", "112/250 | 2.0798e-03/1.9056e-03 [####################] (0s)\n", "113/250 | 2.2106e-03/1.9056e-03 [####################] (0s)\n", "114/250 | 2.2582e-03/1.9056e-03 [####################] (0s)\n", "115/250 | 1.9352e-03/1.9056e-03 [####################] (0s)\n", "116/250 | 3.8784e-03/1.9056e-03 [####################] (0s)\n", "117/250 | 2.3278e-03/1.9056e-03 [####################] (0s)\n", "118/250 | 6.5267e-03/1.9056e-03 [####################] (0s)\n", "119/250 | 7.0995e-03/1.9056e-03 [####################] (0s)\n", "120/250 | 2.6266e-03/1.9056e-03 [####################] (0s)\n", "121/250 | 4.7335e-03/1.9056e-03 [####################] (0s)\n", "122/250 | 7.1512e-03/1.9056e-03 [####################] (0s)\n", "123/250 | 4.2358e-03/1.9056e-03 [####################] (0s)\n", "124/250 | 3.5876e-03/1.9056e-03 [####################] (0s)\n", "125/250 | 3.0308e-03/1.9056e-03 [####################] (0s)\n", "126/250 | 4.3498e-03/1.9056e-03 [####################] (0s)\n", "127/250 | 3.6074e-03/1.9056e-03 [####################] (0s)\n", "128/250 | 3.4459e-03/1.9056e-03 [####################] (0s)\n", "129/250 | 2.9632e-03/1.9056e-03 [####################] (0s)\n", "130/250 | 3.1751e-03/1.9056e-03 [####################] (0s)\n", "131/250 | 3.5406e-03/1.9056e-03 [####################] (0s)\n", "132/250 | 2.7615e-03/1.9056e-03 [####################] (0s)\n", "133/250 | 2.3193e-03/1.9056e-03 [####################] (0s)\n", "134/250 | 2.5355e-03/1.9056e-03 [####################] (0s)\n", "135/250 | 2.2808e-03/1.9056e-03 [####################] (0s)\n", "136/250 | 2.4032e-03/1.9056e-03 [####################] (0s)\n", "137/250 | 3.0431e-03/1.9056e-03 [####################] (0s)\n", "138/250 | 2.8142e-03/1.9056e-03 [####################] (0s)\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "139/250 | 1.9903e-03/1.9056e-03 [####################] (0s)\n", "140/250 | 1.9782e-03/1.9056e-03 [####################] (0s)\n", "141/250 | 1.9603e-03/1.9056e-03 [####################] (0s)\n", "142/250 | 2.7303e-03/1.9056e-03 [####################] (0s)\n", "143/250 | 5.9771e-03/1.9056e-03 [####################] (0s)\n", "144/250 | 4.0507e-03/1.9056e-03 [####################] (0s)\n", "145/250 | 2.1805e-03/1.9056e-03 [####################] (0s)\n", "146/250 | 1.7523e-03/1.7523e-03 [####################] (0s)\n", "147/250 | 2.2935e-03/1.7523e-03 [####################] (0s)\n", "148/250 | 3.1664e-03/1.7523e-03 [####################] (0s)\n", "149/250 | 3.0230e-03/1.7523e-03 [####################] (0s)\n", "150/250 | 2.4747e-03/1.7523e-03 [####################] (0s)\n", "151/250 | 3.7523e-03/1.7523e-03 [####################] (0s)\n", "152/250 | 5.4125e-03/1.7523e-03 [####################] (0s)\n", "153/250 | 2.5811e-03/1.7523e-03 [####################] (0s)\n", "154/250 | 4.2159e-03/1.7523e-03 [####################] (0s)\n", "155/250 | 3.1262e-03/1.7523e-03 [####################] (0s)\n", "156/250 | 1.7317e-03/1.7317e-03 [####################] (0s)\n", "157/250 | 4.1367e-03/1.7317e-03 [####################] (0s)\n", "158/250 | 4.9401e-03/1.7317e-03 [####################] (0s)\n", "159/250 | 7.3494e-03/1.7317e-03 [####################] (0s)\n", "160/250 | 3.3021e-03/1.7317e-03 [####################] (0s)\n", "161/250 | 4.1837e-03/1.7317e-03 [####################] (0s)\n", "162/250 | 2.0441e-03/1.7317e-03 [####################] (0s)\n", "163/250 | 2.8287e-03/1.7317e-03 [####################] (0s)\n", "164/250 | 3.9031e-03/1.7317e-03 [####################] (0s)\n", "165/250 | 3.3648e-03/1.7317e-03 [####################] (0s)\n", "166/250 | 2.8648e-03/1.7317e-03 [####################] (0s)\n", "167/250 | 2.1758e-03/1.7317e-03 [####################] (0s)\n", "168/250 | 1.5925e-03/1.5925e-03 [####################] (0s)\n", "169/250 | 2.4283e-03/1.5925e-03 [####################] (0s)\n", "170/250 | 2.0659e-03/1.5925e-03 [####################] (0s)\n", "171/250 | 2.6633e-03/1.5925e-03 [####################] (0s)\n", "172/250 | 2.4290e-03/1.5925e-03 [####################] (0s)\n", "173/250 | 3.4595e-03/1.5925e-03 [####################] (0s)\n", "174/250 | 4.2879e-03/1.5925e-03 [####################] (0s)\n", "175/250 | 2.5606e-03/1.5925e-03 [####################] (0s)\n", "176/250 | 1.7552e-03/1.5925e-03 [####################] (0s)\n", "177/250 | 1.8150e-03/1.5925e-03 [####################] (0s)\n", "178/250 | 1.8843e-03/1.5925e-03 [####################] (0s)\n", "179/250 | 2.4673e-03/1.5925e-03 [####################] (0s)\n", "180/250 | 2.7264e-03/1.5925e-03 [####################] (0s)\n", "181/250 | 6.2605e-03/1.5925e-03 [####################] (0s)\n", "182/250 | 2.2474e-03/1.5925e-03 [####################] (0s)\n", "183/250 | 5.4456e-03/1.5925e-03 [####################] (0s)\n", "184/250 | 6.7805e-03/1.5925e-03 [####################] (0s)\n", "185/250 | 5.3535e-03/1.5925e-03 [####################] (0s)\n", "186/250 | 2.3965e-03/1.5925e-03 [####################] (0s)\n", "187/250 | 4.7688e-03/1.5925e-03 [####################] (0s)\n", "188/250 | 3.9332e-03/1.5925e-03 [####################] (0s)\n", "189/250 | 2.9458e-03/1.5925e-03 [####################] (0s)\n", "190/250 | 2.7969e-03/1.5925e-03 [####################] (0s)\n", "191/250 | 3.7599e-03/1.5925e-03 [####################] (0s)\n", "192/250 | 2.3289e-03/1.5925e-03 [####################] (0s)\n", "193/250 | 2.3922e-03/1.5925e-03 [####################] (0s)\n", "194/250 | 1.4419e-03/1.4419e-03 [####################] (0s)\n", "195/250 | 1.7286e-03/1.4419e-03 [####################] (0s)\n", "196/250 | 2.6265e-03/1.4419e-03 [####################] (0s)\n", "197/250 | 5.1592e-03/1.4419e-03 [####################] (0s)\n", "198/250 | 2.0504e-03/1.4419e-03 [####################] (0s)\n", "199/250 | 1.8579e-03/1.4419e-03 [####################] (0s)\n", "200/250 | 5.1812e-03/1.4419e-03 [####################] (0s)\n", "201/250 | 5.8354e-03/1.4419e-03 [####################] (0s)\n", "202/250 | 3.6949e-03/1.4419e-03 [####################] (0s)\n", "203/250 | 2.4144e-03/1.4419e-03 [####################] (0s)\n", "204/250 | 2.9960e-03/1.4419e-03 [####################] (0s)\n", "205/250 | 4.1210e-03/1.4419e-03 [####################] (0s)\n", "206/250 | 6.0538e-03/1.4419e-03 [####################] (0s)\n", "207/250 | 5.2219e-03/1.4419e-03 [####################] (0s)\n", "208/250 | 3.7427e-03/1.4419e-03 [####################] (0s)\n", "209/250 | 4.7810e-03/1.4419e-03 [####################] (0s)\n", "210/250 | 5.7836e-03/1.4419e-03 [####################] (0s)\n", "211/250 | 2.9323e-03/1.4419e-03 [####################] (0s)\n", "212/250 | 3.8641e-03/1.4419e-03 [####################] (0s)\n", "213/250 | 4.2803e-03/1.4419e-03 [####################] (0s)\n", "214/250 | 2.0412e-03/1.4419e-03 [####################] (0s)\n", "215/250 | 1.6764e-03/1.4419e-03 [####################] (0s)\n", "216/250 | 2.0434e-03/1.4419e-03 [####################] (0s)\n", "217/250 | 3.2198e-03/1.4419e-03 [####################] (0s)\n", "218/250 | 7.8106e-03/1.4419e-03 [####################] (0s)\n", "219/250 | 3.3164e-03/1.4419e-03 [####################] (0s)\n", "220/250 | 3.7824e-03/1.4419e-03 [####################] (0s)\n", "221/250 | 4.9126e-03/1.4419e-03 [####################] (0s)\n", "222/250 | 7.0033e-03/1.4419e-03 [####################] (0s)\n", "223/250 | 7.2956e-03/1.4419e-03 [####################] (0s)\n", "224/250 | 5.2377e-03/1.4419e-03 [####################] (0s)\n", "225/250 | 3.7460e-03/1.4419e-03 [####################] (0s)\n", "226/250 | 7.7423e-03/1.4419e-03 [####################] (0s)\n", "227/250 | 9.5499e-03/1.4419e-03 [####################] (0s)\n", "228/250 | 2.0417e-02/1.4419e-03 [####################] (0s)\n", "229/250 | 7.7284e-03/1.4419e-03 [####################] (0s)\n", "230/250 | 6.8024e-03/1.4419e-03 [####################] (0s)\n", "231/250 | 6.3797e-03/1.4419e-03 [####################] (0s)\n", "232/250 | 5.5671e-03/1.4419e-03 [####################] (0s)\n", "233/250 | 5.5593e-03/1.4419e-03 [####################] (0s)\n", "234/250 | 7.8933e-03/1.4419e-03 [####################] (0s)\n", "235/250 | 1.3514e-02/1.4419e-03 [####################] (0s)\n", "236/250 | 1.0794e-02/1.4419e-03 [####################] (0s)\n", "237/250 | 5.7856e-03/1.4419e-03 [####################] (0s)\n", "238/250 | 2.7149e-03/1.4419e-03 [####################] (0s)\n", "239/250 | 2.0554e-03/1.4419e-03 [####################] (0s)\n", "240/250 | 3.3540e-03/1.4419e-03 [####################] (0s)\n", "241/250 | 5.6794e-03/1.4419e-03 [####################] (0s)\n", "242/250 | 3.3093e-03/1.4419e-03 [####################] (0s)\n", "243/250 | 3.2271e-03/1.4419e-03 [####################] (0s)\n", "244/250 | 3.0530e-03/1.4419e-03 [####################] (0s)\n", "245/250 | 1.7806e-03/1.4419e-03 [####################] (0s)\n", "246/250 | 1.5051e-03/1.4419e-03 [####################] (0s)\n", "247/250 | 3.2142e-03/1.4419e-03 [####################] (0s)\n", "248/250 | 2.2576e-03/1.4419e-03 [####################] (0s)\n", "249/250 | 1.9008e-03/1.4419e-03 [####################] (0s)\n", "250/250 | 2.2744e-03/1.4419e-03 [####################] (0s)\n", "\n", "========================================\n", "Total epochs: 250\n", "(best epoch: 193)\n", "(best validation loss: 1.4419E-03)\n", "========================================\n" ] } ], "source": [ "# using the same batch key as with the neural network\n", "model.train(\n", " X_train_sc_32,\n", " Y=Y_train_sc_32,\n", " X_val=X_val_sc_32,\n", " Y_val=Y_val_sc_32,\n", " lr=1e-2,\n", " epochs=250,\n", " batch_size=5,\n", " batch_rng=batch_key,\n", " verbose=True)" ] }, { "cell_type": "markdown", "id": "d5e2e4d9", "metadata": {}, "source": [ "### Inference\n", "\n", "Now we're ready to make new predictions with the model. All Models and Modules are directly callable once compiled, so we need only to pass in the (scaled) inputs like `model(X)` and unscale the predictions." ] }, { "cell_type": "code", "execution_count": 18, "id": "2b1bc51e", "metadata": {}, "outputs": [ { "data": { "text/plain": [ "" ] }, "execution_count": 18, "metadata": {}, "output_type": "execute_result" }, { "data": { "image/png": "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", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "# pass in the scaled inputs (converted to JAX arrays again)\n", "X_sc = xscaler.transform(X)\n", "X_sc = np.array(X_sc)\n", "\n", "# get scaled predictions\n", "Y_pred_sc = model(X_sc)\n", "\n", "# unscale predictions\n", "Y_pred = yscaler.inverse_transform(Y_pred_sc)\n", "\n", "# plot results\n", "plt.plot(X, Y_pred, label=\"PMM\", lw=2, zorder=10)\n", "plt.plot(X_train, Y_train, 'o', label=\"Train\")\n", "plt.plot(X_val, Y_val, 's', label=\"Val\")\n", "plt.plot(X_test, Y_test, 'x', label=\"Test\")\n", "plt.legend()" ] } ], "metadata": { "kernelspec": { "display_name": "pmmenv", "language": "python", "name": "pmmenv" }, "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.12.7" } }, "nbformat": 4, "nbformat_minor": 5 }