我正在尝试在 GPFlow 中实现变分异方差高斯过程回归。
我的想法是使用带有自定义构建似然的变分稀疏高斯过程模型 (gpflow.models.SVGP),它表示给定两个独立 GP f、g的y的密度:
p( y | f , g ) = N(y | f , t( g ) ) 其中 t(·) 是使g为正的某种变换(当前使用tf.nn.softplus
)。
为了完成这项工作,我将其设置为 2,但将以,方法仅输出形状为 (N, 1) 的张量的model.num_latent
方式实现似然性。以下是我当前的实现:logp
conditional_mean
conditional_variance
from gpflow.likelihoods import Likelihood
from gpflow.decors import params_as_tensors
import tensorflow as tf
import tensorflow_probability as tfp
tfd = tfp.distributions
class HeteroscedasticGaussian(Likelihood):
r"""
When using this class, num_latent must be 2.
It does not support multi-output (num_output will be 1)
"""
def __init__(self, transform=tf.nn.softplus, **kwargs):
super().__init__(**kwargs)
self.transform = transform
@params_as_tensors
def Y_given_F(self, F):
mu = tf.squeeze(F[:, 0])
sigma = self.transform(tf.squeeze(F[:, 1]))
Y_given_F = tfd.Normal(mu, sigma)
return Y_given_F
@params_as_tensors
def logp(self, F, Y):
return self.Y_given_F(F).log_prob(Y)
@params_as_tensors
def conditional_mean(self, F):
return self.Y_given_F(F).mean()
@params_as_tensors
def conditional_variance(self, F):
return self.Y_given_F(F).variance()
我的疑问是如何使该方法variational_expectations
与 d f d g上的双积分一起工作。我打算使用 Gauss-Hermite 求积,但我不明白如何用ndiagquad
.
是不是像打电话一样简单
ndiagquad(self.logp, self.num_gauss_hermite_points, Fmu, Fvar, Y=Y)
??
编辑:
一些 MWE,使用variational_expectations
来自基类的实现Likelihood
。
import gpflow as gpf
import tensorflow as tf
import numpy as np
N = 1001
M = 100
X = np.linspace(0, 4*np.pi, N)[:, None]
F = np.sin(X)
G = np.cos(X)
E = np.logaddexp(0, G) * np.random.normal(size=(N,1))
Y = F + E
Z_idx = np.random.choice(N, M, replace=False)
kernel = gpf.kernels.SquaredExponential(input_dim=1)
likelihood = HeteroscedasticGaussian()
likelihood.num_gauss_hermite_points = 11
model = gpf.models.SVGP(
X=X, Z=X[Z_idx], Y=Y,
kern=kernel,
likelihood=likelihood,
num_latent=2
)
# This method will call
# model.likelihood.variational_expectations(...)
# internally
model.compute_log_likelihood()
我收到以下错误消息:
InvalidArgumentError: Incompatible shapes: [1001,11] vs. [2002]
[[{{node SVGP-bdd79b25-24/Normal/log_prob/standardize/sub}}]]
我认为这与f有关,g相互堆叠(形状 [2002] = 2*N,N = 1001),并且每个维度仅生成 Gauss-Hermite 点 (11)观察(N = 1001),否则我们将有形状 [1001, 11, 11] 或 [1001, 121=11^2]。
所有帮助表示赞赏。