3

我正在尝试使用 GPflow 来安装 GP。我想对长度尺度使用自动相关性确定和先验。

我知道如何分别做:

kernel = gpflow.kernels.SquaredExponential(lengthscales=([10] * X_train.shape[1]))

kernel.lengthscales.prior = tfp.distributions.Gamma(
    to_default_float(3), to_default_float(0.25)
)

...但我想两者都做(所以基本上每个特征的先验都是不同的 Gamma 分布)。

我尝试只使用两行代码并且没有错误,但先前似乎没有添加或更改任何内容。

我怎样才能将这两者结合起来?

编辑:我又玩了一些,我想也许没那么重要,因为在训练期间调整了长度尺度。然而,长度尺度的起点对我的模型的准确性有重大影响,并且它们从起点开始不会发生显着变化。

例如,使用 lengthscales = 10 进行初始化会得到 7 - 13 之间的优化长度,15 会得到 12-18 等。使用较小的长度刻度(例如 0.1 或 1)进行初始化会导致长度刻度更接近 10。

尽管如此,我认为如果可以为使用 ARD 的每个功能设置先验,那将是非常有价值的。如果(仅?)可能使用 MCMC 方法,我可能会进行下一步调查。

4

1 回答 1

1

对于每个输入维度,您也可以有不同的先验分布:您只需要相应地定义先验。例如,

alpha_ard = np.array([3.0, 4.0, 3.0, 3.0, 7.0])
beta_ard = np.array([0.25, 0.4, 0.4, 0.25, 0.25])
kernel.lengthscales.prior = tfp.distributions.Gamma(alpha_ard, beta_ard)

请注意,先验现在有batch_shape[5] 而不是之前的 []。

这确实改变了一些事情,您可以通过以下简单示例进行验证:

import gpflow
import numpy as np
import tensorflow_probability as tfp
import tensorflow as tf

num_data = 1
input_dim = 5
output_dim = 1

X_train = np.ones((num_data, input_dim))
Y_train = np.ones((num_data, output_dim))

single_prior = tfp.distributions.Gamma(np.float64(3.0), np.float64(0.25))
ard_equal_priors = tfp.distributions.Gamma(np.array([3.0]*5), np.array([0.25]*5))
ard_different_priors = tfp.distributions.Gamma(np.array([1.0, 2.0, 3.0, 4.0, 5.0]), np.array([0.25, 0.1, 0.5, 0.2, 0.3]))

def build_model(prior):
    kernel = gpflow.kernels.SquaredExponential(lengthscales=([1.0] * input_dim))
    kernel.lengthscales.prior = prior
    model = gpflow.models.GPR((X_train, Y_train), kernel, noise_variance=0.01)
    opt = gpflow.optimizers.Scipy()
    opt.minimize(model.training_loss, model.trainable_variables)

m1 = build_model(single_prior)
m2 = build_model(ard_equal_priors)
m3 = build_model(ard_different_priors)

m1最终m2得到完全相同的长度尺度,而m3不同。

在不使用 MCMC 的情况下,超参数只是点估计(最大似然 [MLE] 没有设置先验,或者最大后验 [MAP] 像你一样设置先验)。通常有几个局部最优值,所以你最终会选择哪一个取决于初始化。有关更多说明,请参阅这篇蒸馏文章

于 2020-07-09T09:11:45.577 回答