我想用边际化超参数建立一个GP。
我已经看到,this notebook
的gpflow中提供的HMC采样器可以实现但是,当我尝试运行以下代码作为此步骤的第一步(注意这是在较旧版本的gpflow 0.5上)时,即使lengthscale和方差必须为正(负值将无意义)。
import numpy as np
from matplotlib import pyplot as plt
import gpflow
from gpflow import hmc
X = np.linspace(-3, 3, 20)
Y = np.random.exponential(np.sin(X) ** 2)
Y = (Y - np.mean(Y)) / np.std(Y)
k = gpflow.kernels.Matern32(1, lengthscales=.2, ARD=False)
m = gpflow.gpr.GPR(X[:, None], Y[:, None], k)
m.kern.lengthscales.prior = gpflow.priors.Gamma(1., 1.)
m.kern.variance.prior = gpflow.priors.Gamma(1., 1.)
# dont want likelihood be a hyperparam now so fixed
m.likelihood.variance = 1e-6
m.likelihood.variance.fixed = True
m.optimize(maxiter=1000)
samples = m.sample(500)
print(samples)
输出:
[[-0.43764571 -0.22753325]
[-0.50418501 -0.11070128]
[-0.5932655 0.00821438]
[-0.70217714 0.05077999]
[-0.77745654 0.09362291]
[-0.79404456 0.13649446]
[-0.83989415 0.27118385]
[-0.90355789 0.29589641]
...
我不太了解HMC采样,但我希望采样的后验超参数是正数,我已经检查了代码,尽管它未能弄清楚它似乎与Log1pe转换有关我自己。
有任何提示吗?
答案 0 :(得分:1)
如果您指定使用的 GPflow版本会很有帮助-特别是考虑到从您发布的输出中看,您似乎正在使用确实的旧版本GPflow(1.0之前的版本),此后实际上已得到改进。这里发生的事情(在旧的GPflow中)是sample()方法返回单个数组S x P,其中S是样本数,P是自由参数的数[例如,对于具有下三角变换的M x M矩阵参数(例如近似后验的协方差的Cholesky q_sqrt),实际上仅存储和优化了M *(M-1)/ 2个参数!]。这些是 unconstrained 空间中的值,即它们可以采用任何值。转换(请参见gpflow.transforms
模块)提供此值(在正负之间)和受约束值(例如gpflow.transforms.positive表示长度范围和方差)之间的映射。在旧的GPflow中,模型提供了一种get_samples_df()
方法,该方法采用sample()
返回的S x P数组,并返回一个pandas DataFrame,其中包含所有您想要的可训练参数的列。或者,理想情况下,您仅使用GPflow的最新版本,在该版本中HMC采样器直接返回DataFrame!