我有一个关于gpflow 2中的多输出内核的问题。对于我正在处理的应用程序,我想创建一个独立的多输出内核,它在一些输出维度(但不是全部)之间共享内核。GPflow中的两个相关类是SharedIndependent
和SeparateIndependent
多输出内核类。然而,它们要么对所有P输出维度使用一个共享内核,要么对P输出维度使用P个单独的内核
下面附带的代码是多输出内核笔记本(https://gpflow.readthedocs.io/en/master/notebooks/advanced/multioutput.html)的一个小改编。4个输出维度可分为2组(每组2个输出维度):一组具有高灵活性,另一组具有低灵活性。我想在这个任务中使用2个内核,以便为平方指数内核检测2个不同的长度尺度参数。为了完整起见,我在示例笔记本中为SharedIndependent
类和SeparateIndependent
类添加了实现
目前,我已尝试将这些组合如下:SeparateIndependent([SharedIndependent(SquaredExponential()+Linear(), output_dim=2) for _ in range(2)])
。这会导致以下错误:(15是诱导点的数量)
ValueError: Dimensions must be equal, but are 2 and 15 for '{{node add_8}} = AddV2[T=DT_DOUBLE](stack, mul_13)' with input shapes: [2,15,2,15,2], [1,15,15].
我还尝试为此创建一个新的多输出内核类,它在很大程度上模仿了SeparateIndependent
类,并对K(X, X2)
和K_diag(X)
函数中的循环列表理解进行了一些修改。由于不知道如何为多输出内核类注册正确的Kuu()
、Kuf()
和conditional()
函数,因此这没有成功。尝试使用不同名称创建与SeparateIndependent
类相同的类也失败
我很高兴知道是否有可能将SharedIndependent
和SeparateIndependent
类结合起来,或者构建一个新的MOK类是否是解决这个问题的更好方法。如果是这样,解决注册条件表达式(Kuu()
、Kuf()
和conditional()
)问题的最佳方法是什么
import numpy as np
import matplotlib.pyplot as plt
import tensorflow as tf
import gpflow
from gpflow.kernels import SquaredExponential, Linear, SharedIndependent, SeparateIndependent
from gpflow.inducing_variables import SharedIndependentInducingVariables, InducingPoints
from gpflow.utilities import print_summary
from gpflow.ci_utils import ci_niter
gpflow.config.set_default_float(np.float64)
np.random.seed(0)
MAXITER = ci_niter(2000)
N = 100 # number of points
D = 1 # number of input dimensions
M = 15 # number of inducing points
L = P = 4 # number of latent GPs, number of observations = output dimension
def generate_data(N=100):
X = np.random.rand(N)[:, None] * 10 - 5 # Inputs = N x D
G = np.hstack((0.5 * np.sin(X/2) + X, 3.0 * np.cos(X/2) - X,0.5 * np.sin(4 * X) + X, 3.0 * np.cos(4*X) - X)) # G = N x L
W = np.array([[0.5, -0.3, 0, 0], [0.5, -0.3, 0, 0], [0, 0, -0.4, 0.6],[0.0, 0.0, 0.6, -0.4]]) # L x P
F = np.matmul(G, W) # N x P
Y = F + np.random.randn(*F.shape) * [0.2, 0.2, 0.2, 0.2]
return X, Y
X, Y = data = generate_data(N)
print(X.shape, Y.shape)
Zinit = np.linspace(-5, 5, M)[:, None]
def plot_model(m, name, lower=-7.0, upper=7.0):
pX = np.linspace(lower, upper, 100)[:, None]
pY, pYv = m.predict_y(pX)
if pY.ndim == 3:
pY = pY[:, 0, :]
plt.plot(X, Y, "x")
plt.gca().set_prop_cycle(None)
plt.plot(pX, pY)
for i in range(pY.shape[1]):
top = pY[:, i] + 2.0 * pYv[:, i] ** 0.5
bot = pY[:, i] - 2.0 * pYv[:, i] ** 0.5
plt.fill_between(pX[:, 0], top, bot, alpha=0.3)
plt.xlabel("X")
plt.ylabel("f")
plt.title(f"{name} kernel.")
plt.show()
# initialization of inducing input locations (M random points from the training inputs)
Z = Zinit.copy()
# create multi-output inducing variables from Z
iv = SharedIndependentInducingVariables(InducingPoints(Z))
def optimize_model_with_scipy(model):
optimizer = gpflow.optimizers.Scipy()
optimizer.minimize(
model.training_loss_closure(data),
variables=model.trainable_variables,
method="l-bfgs-b",
options={"disp": True, "maxiter": MAXITER},
)
# create multi-output kernel
kernels = [
(SeparateIndependent([SquaredExponential() + Linear() for _ in range(P)]),'Seperate Independent'),
(SharedIndependent(SquaredExponential()+Linear(), output_dim=P), 'Shared Independent'),
(SeparateIndependent([SharedIndependent(SquaredExponential()+Linear(), output_dim=2) for _ in range(2)]), 'Partially shared independent')
]
for (kernel, name) in kernels:
m = gpflow.models.SVGP(kernel, gpflow.likelihoods.Gaussian(), inducing_variable=iv, num_latent_gps=P)
print_summary(m)
optimize_model_with_scipy(m)
print_summary(m)
plot_model(m, name)
目前没有回答
相关问题 更多 >
编程相关推荐