0

我想用边缘化的超参数构建一个 GP。

我已经看到,这可以通过本笔记本gpflow 中提供的 HMC 采样器实现

但是,当我尝试运行以下代码作为第一步时(注意这是在 gpflow 0.5 上,旧版本),返回的样本是负数,即使长度尺度和方差需要是正数(负值将是无意义的)。

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 变换有关,尽管我自己没有弄清楚。
对此有任何提示吗?

4

1 回答 1

1

如果您指定了您正在使用的GPflow 版本,这将很有帮助- 特别是考虑到您发布的输出看起来您使用的是一个非常旧的 GPflow 版本(1.0 之前),而这实际上是从那以后得到改进的东西。这里发生的事情(在旧的 GPflow 中)是 sample() 方法返回单个数组 S x P,其中 S 是样本数,P 是自由参数的数量 [例如,对于 M x M 矩阵参数下三角变换(例如近似后验的协方差的Cholesky,q_sqrt),实际上只存储和优化了M * (M - 1)/2个参数!]。这些是无约束空间中的值,即它们可以取任何值。变换(见gpflow.transforms模块)提供该值(在正/负无穷之间)和受约束值(例如,长度尺度和方差的 gpflow.transforms.positive)之间的映射。在旧的 GPflow 中,该模型提供了一种get_samples_df()方法,该方法采用返回的 S x P 数组sample()并返回一个 pandas DataFrame,其中包含所有可训练参数的列,这将是您想要的。或者,理想情况下,您只需使用最新版本的 GPflow,其中 HMC 采样器直接返回 DataFrame!

于 2019-09-05T08:38:05.183 回答