Я пытаюсь построить аддитивную ковариационную функцию, просто складывая вместе много ядер 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)