GPflow: добавление множества ядер - PullRequest
0 голосов
/ 10 января 2020

Я пытаюсь построить аддитивную ковариационную функцию, просто складывая вместе много ядер RBF, каждое из которых действует только в одном измерении. Однако это, по-видимому, сильно замедляет процесс по сравнению с одним ядром RBF, действующим во всех измерениях - до такой степени, что это просто нереальный вариант. Есть ли что-то, что я делаю неправильно?

Ниже приведен код, который должен показать, что у меня есть (GPflow 1.5.1, я считаю).

import numpy as np
import matplotlib.pyplot as plt
from datetime import datetime
import gpflow
import tensorflow as tf

# make simulator with continuous input and regular output
# Here's our toy model
def Simulator(x, x2, x3, x4, x5):
    y = np.sin(2*x) + np.exp(0.5*x) - 2*x2 + np.sin(4*x3) + 0.5*x4  - 0.1*x5
    return y

N = 20000*91  # how many samples
dim = 100  # how many continuous dims?
X = np.random.rand(N, dim)
y = Simulator(X[:,0], X[:,4], X[:,2], X[:,8], X[:,9]).reshape(-1, 1)
active_vars = list(range(dim))

startTime = datetime.now()

# Kernel:
with gpflow.defer_build():
    # build the additive covariance function
    # the covariance for the first variable
    k = gpflow.kernels.RBF(input_dim = 1, variance=1.0, active_dims = [active_vars[0]], ARD = False)
    k.variance.trainable = False
    # then add all further covariances
    for i in active_vars[1:]:
        k_add = gpflow.kernels.RBF(input_dim = 1, variance=1.0, active_dims = [i], ARD = False)
        k_add.variance.trainable = False
        k += k_add

        # and then add the variance
        k_var = gpflow.kernels.Constant(input_dim = 1)
        k = k_var*k
k.compile()

# Now build the GP model
M = min(300, len(X))  # Number of inducing locations
Z = X[np.random.choice(range(0, len(X)), M, replace=False)].copy()  # Initialise inducing locations to a random M inputs in the dataset
m = gpflow.models.SVGP(X = X, Y = y, Z = Z, kern=k, mean_function = None, likelihood = gpflow.likelihoods.Gaussian(), minibatch_size=100)
m.likelihood.variance.trainable = True  # do we want intrinsic noise?
m.feature.trainable = True  # do we want to optimise inducing point locations?


# now let's optimise
class Logger(gpflow.actions.Action):
    def __init__(self, model):
        self.model = model
        self.logf = []

    def run(self, ctx):
        if (ctx.iteration % 10) == 0:
            # Extract likelihood tensor from TensorFlow session
            likelihood = - ctx.session.run(self.model.likelihood_tensor)
            # Append likelihood value to list
            self.logf.append(likelihood)

# optimise ELBO
#minibatch_size = 100
#m.X.set_batch_size(minibatch_size)
#m.Y.set_batch_size(minibatch_size)

# We turn off training for inducing point locations
m.feature.trainable = True



# optimize

def run_adam(model, iterations):
    """
    Utility function running the Adam Optimiser interleaved with a `Logger` action.

    :param model: GPflow model
    :param interations: number of iterations
    """
    # Create an Adam Optimiser action
    adam = gpflow.train.AdamOptimizer().make_optimize_action(model)
    # Create a Logger action
    logger = Logger(model)
    actions = [adam, logger]
    # Create optimisation loop that interleaves Adam with Logger
    loop = gpflow.actions.Loop(actions, stop=iterations)()
    # Bind current TF session to model
    model.anchor(model.enquire_session())
    return logger

startTime = datetime.now()

logger = run_adam(m, gpflow.test_util.notebook_niter(10))

fig = plt.figure()
ax1 = fig.add_subplot()
ax1.plot(-np.array(logger.logf))
plt.xlabel('iteration')
plt.ylabel('ELBO');


print(datetime.now() - startTime)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...