class TestBohamiann(unittest.TestCase):

    def setUp(self):
        self.X = np.random.rand(10, 3)
        self.y = np.sinc(self.X * 10 - 5).sum(axis=1)
        self.model = Bohamiann(normalize_input=True, normalize_output=True, use_double_precision=True)
        self.model.train(self.X, self.y, num_burn_in_steps=20, num_steps=100, keep_every=10)

    def test_predict(self):
        X_test = np.random.rand(10, self.X.shape[1])

        m, v = self.model.predict(X_test)

        assert len(m.shape) == 1
        assert m.shape[0] == X_test.shape[0]
        assert len(v.shape) == 1
        assert v.shape[0] == X_test.shape[0]

    def test_gradient_mean(self):
        X_test = np.random.rand(10, self.X.shape[1])

        def wrapper(x):
            return self.model.predict([x])[0]

        def wrapper_grad(x):
            return self.model.predictive_mean_gradient(x)

        grad = self.model.predictive_mean_gradient(X_test[0])
        assert grad.shape[0] == X_test.shape[1]

        for xi in X_test:
            err = check_grad(wrapper, wrapper_grad, xi, epsilon=1e-6)
            assert err < 1e-5

    def test_gradient_variance(self):
        X_test = np.random.rand(10, self.X.shape[1])

        def wrapper(x):
            v = self.model.predict([x])[1]
            return v

        def wrapper_grad(x):
            return self.model.predictive_variance_gradient(x)

        grad = self.model.predictive_variance_gradient(X_test[0])
        assert grad.shape[0] == X_test.shape[1]

        for xi in X_test:
            err = check_grad(wrapper, wrapper_grad, xi, epsilon=1e-6)
            assert err < 1e-5
Exemple #2
0
class WrapperBohamiann(BaseModel):

    def __init__(self, get_net=get_default_network, lr=1e-5, use_double_precision=False, verbose=False):
        """
        Wrapper around pybnn Bohamiann implementation. It automatically adjusts the length by the MCMC chain,
        by performing 100 times more burnin steps than we have data points and sampling ~100 networks weights.

        Parameters
        ----------
        get_net: func
            Architecture specification

        lr: float
           The MCMC step length

        use_double_precision: Boolean
           Use float32 or float64 precision. Note: Using float64 makes the training slower.

        verbose: Boolean
           Determines whether to print pybnn output.
        """

        self.lr = lr
        self.verbose = verbose
        self.bnn = Bohamiann(get_network=get_net, use_double_precision=use_double_precision)

    def train(self, X, y, **kwargs):
        self.X = X
        self.y = y
        self.bnn.train(X, y, lr=self.lr,
                       num_burn_in_steps=X.shape[0] * 100,
                       num_steps=X.shape[0] * 100 + 10000, verbose=self.verbose)

    def predict(self, X_test):
        return self.bnn.predict(X_test)
Exemple #3
0
class BayesianNN(object):
    def __init__(self):
        self.model = Bohamiann(print_every_n_steps=1000,
                               sampling_method="adaptive_sghmc")
        self.trained = False

    def fit(self, x, y):
        self.model.train(x,
                         y.flatten(),
                         num_steps=10000 + 100 * len(x),
                         num_burn_in_steps=100 * len(x),
                         keep_every=200,
                         lr=1e-2,
                         verbose=True,
                         continue_training=self.trained)

    def predict(self, x):
        mean, var = self.model.predict(x)

        return mean, 1.96 * np.sqrt(var)
Exemple #4
0
class OrionBohamiannWrapper(BaseModel):
    """
    Wrapper for PyBNN's BOHAMIANN model

    Parameters
    ----------
    normalize_input: bool
        Normalize the input based on the provided bounds (zero mean and unit standard deviation).
        Defaults to ``True``.
    normalize_output: bool
        Normalize the output based on data (zero mean and unit standard deviation).
        Defaults to ``False``.
    burnin_steps: int or None.
        The number of burnin steps before the sampling procedure starts.
        If ``None``, ``burnin_steps = n_dims * 100`` where ``n_dims`` is the dimensionality
        of the search space. Defaults to ``None``.
    sampling_method: str
        Can be one of ``['adaptive_sghmc', 'sgld', 'preconditioned_sgld', 'sghmc']``.
        Defaults to ``"adaptive_sghmc"``. See PyBNN samplers'
        `code <https://github.com/automl/pybnn/tree/master/pybnn/sampler>`_ for more information.
    use_double_precision: bool
        Use double precision if using ``bohamiann``. Note that it can run faster on GPU
        if using single precision. Defaults to ``True``.
    num_steps: int or None
        Number of sampling steps to perform after burn-in is finished.
        In total, ``num_steps // keep_every`` network weights will be sampled.
        If ``None``, ``num_steps = n_dims * 100 + 10000`` where ``n_dims`` is the
        dimensionality of the search space.
    keep_every: int
        Number of sampling steps (after burn-in) to perform before keeping a sample.
        In total, ``num_steps // keep_every`` network weights will be sampled.
    learning_rate: float
        Learning rate. Defaults to 1e-2.
    batch_size: int
        Batch size for training the neural network. Defaults to 20.
    epsilon: float
        epsilon for numerical stability. Defaults to 1e-10.
    mdecay: float
        momemtum decay. Defaults to 0.05.
    verbose: bool
        Write progress logs in stdout. Defaults to ``False``.

    """
    def __init__(self,
                 lower,
                 upper,
                 sampling_method="adaptive_sghmc",
                 use_double_precision=True,
                 num_steps=None,
                 keep_every=100,
                 burnin_steps=None,
                 learning_rate=1e-2,
                 batch_size=20,
                 epsilon=1e-10,
                 mdecay=0.05,
                 verbose=False,
                 **kwargs):

        self.num_steps = num_steps
        self.keep_every = keep_every
        self.burnin_steps = burnin_steps
        self.learning_rate = learning_rate
        self.batch_size = batch_size
        self.epsilon = epsilon
        self.mdecay = mdecay
        self.verbose = verbose

        self.bnn = Bohamiann(get_network=get_default_network,
                             sampling_method=sampling_method,
                             use_double_precision=use_double_precision,
                             **kwargs)
        self.burnin_steps = burnin_steps

        self.lower = lower
        self.upper = upper

    # pylint:disable=no-self-use
    def set_state(self, state_dict):
        """Restore the state of the optimizer"""
        torch.random.set_rng_state(state_dict["torch"])

    # pylint:disable=no-self-use
    def state_dict(self):
        """Return the current state of the optimizer so that it can be restored"""
        return {"torch": torch.random.get_rng_state()}

    def seed(self, seed):
        """Seed all internal RNGs"""
        if torch.cuda.is_available():
            torch.backends.cudnn.benchmark = False
            torch.cuda.manual_seed_all(seed)
            torch.backends.cudnn.deterministic = True

        torch.manual_seed(seed)

    def train(self, X, y, **kwargs):
        """
        Sets num_steps and burnin_steps before training with parent's train()
        """
        self.X = X
        self.y = y

        if self.num_steps:
            num_steps = self.num_steps
        else:
            num_steps = X.shape[0] * 100 + 10000

        if self.burnin_steps is None:
            burnin_steps = X.shape[0] * 100
        else:
            burnin_steps = self.burnin_steps

        self.bnn.train(X,
                       y,
                       num_steps=num_steps,
                       keep_every=self.keep_every,
                       num_burn_in_steps=burnin_steps,
                       lr=self.learning_rate,
                       batch_size=self.batch_size,
                       epsilon=self.epsilon,
                       mdecay=self.mdecay,
                       continue_training=False,
                       verbose=self.verbose,
                       **kwargs)

    def predict(self, X_test):
        """Predict using bnn.predict()"""
        return self.bnn.predict(X_test)
Exemple #5
0
class BOHAMIANNWarp(BaseModel):
    """
    A Wrapper for MC Dropout for a fully connected
    feed forward neural network..
    """
    def __init__(self,
                 num_samples=6000,
                 keep_every=50,
                 lr=1e-2,
                 normalize_input: bool = True,
                 normalize_output: bool = True,
                 verbose=True,
                 seed=42):

        self.verbose = verbose
        self.num_samples = num_samples
        self.keep_every = keep_every
        self.lr = lr
        self.model = Bohamiann(normalize_input=normalize_input,
                               normalize_output=normalize_output,
                               seed=seed)

    def _create_model(self, X, Y):
        Y = Y.flatten()
        num_burn_in_steps = X.shape[0] * 100
        num_steps = X.shape[0] * 100 + self.num_samples

        self.model.train(X,
                         Y,
                         num_steps=num_steps,
                         num_burn_in_steps=num_burn_in_steps,
                         keep_every=self.keep_every,
                         lr=self.lr,
                         verbose=self.verbose)

    def _update_model(self, X_all, Y_all):
        """
        Updates the model with new observations.
        """
        Y_all = Y_all.flatten()
        num_burn_in_steps = X_all.shape[0] * 100
        num_steps = X_all.shape[0] * 100 + self.num_samples

        if self.model is None:
            self._create_model(X_all, Y_all)
        else:
            self.model.train(X_all,
                             Y_all,
                             num_steps=num_steps,
                             num_burn_in_steps=num_burn_in_steps,
                             keep_every=self.keep_every,
                             lr=self.lr,
                             verbose=self.verbose)

    def predict(self, X):
        """
        Predictions with the model. Returns predictive means and standard deviations at X.
        """
        X = np.atleast_2d(X)
        m, v = self.model.predict(X)
        # m and v have shape (N,)
        s = np.sqrt(v)
        return m[:, None], s[:, None]

    def predict_withGradients(self, X):
        """
        Returns the mean, standard deviation, mean gradient and standard deviation gradient at X.
        """
        return print('Not Implemented')
Exemple #6
0
plt.xlim(0, 1)

plt.show()

# -- Train Model ---
model = Bohamiann(print_every_n_steps=1000)
model.train(x[:, None],
            y,
            num_steps=20000,
            num_burn_in_steps=2000,
            keep_every=50,
            lr=1e-2,
            verbose=True)

# -- Predict with Model ---
m, v = model.predict(grid[:, None])
plt.plot(x, y, "ro")
plt.grid()
plt.plot(grid, fvals, "k--")
plt.plot(grid, m, "blue")
plt.fill_between(grid,
                 m + np.sqrt(v),
                 m - np.sqrt(v),
                 color="orange",
                 alpha=0.8)
plt.fill_between(grid,
                 m + 2 * np.sqrt(v),
                 m - 2 * np.sqrt(v),
                 color="orange",
                 alpha=0.6)
plt.fill_between(grid,