Normalising Inputs

The NormaliseY decorator will scale the y-inputs to a unit normal distribution.

class vanguard.normalise.NormaliseY(**kwargs)[source]

Bases: Decorator

Normalise the y-inputs and the variance.

Let \({\bf y}\) and \({\bf\psi}\) denote train_y and y_std respectively. If the values in \({\bf y}\) have empirical mean \(\overline{Y}\) and variance \(s^2\), then this decorator will compute the following transformations before initialisation:

\[{\bf y} \mapsto \frac{{\bf y} - \overline{Y}}{s}, \quad {\bf\psi} \mapsto \ \frac{{\bf\psi}}{s}.\]

The inverse transformation is then applied to the return values of posterior methods.

Note

The empirical variance is the _sample_ empirical variance, not the population empirical variance (that is, it is \(\frac{1}{n-1}\sum_{y \in \bf y} (y - \overline{Y})^2\), where \(n\) is the number of data points in train_y).

Example:
>>> import numpy as np
>>> from vanguard.kernels import ScaledRBFKernel
>>> from vanguard.vanilla import GaussianGPController
>>>
>>> @NormaliseY(ignore_methods=("__init__",))
... class NormalisedController(GaussianGPController):
...     pass
>>>
>>> controller = NormalisedController(
...                     train_x=np.array([0.0, 1.0, 2.0, 3.0]),
...                     train_x_std=1.0,
...                     train_y=np.array([0.0, 1.0, 4.0, 9.0]),
...                     y_std=0.5,
...                     kernel_class=ScaledRBFKernel
...                     )
>>> controller.train_y.T.cpu()
tensor([[-0.8660, -0.6186,  0.1237,  1.3609]])
>>> controller.train_y.mean().item()
0.0
>>> controller.train_y.std().item()
1.0
Parameters:

kwargs (Any)

__init__(**kwargs)[source]

Initialise self.

Parameters:

kwargs (Any) – Keyword arguments passed to Decorator.

property safe_updates: dict[type, set[str]]

Get a dictionary (class -> set[names]) of overrides/new methods that we consider “safe”.