如何修复 gpflow 中内核长度尺度的某些尺寸?

How to fix some dimensions of a kernel lengthscale in gpflow?

我有一个二维内核,

k = gpflow.kernels.RBF(lengthscales=[24*5,1e-5])
m = gpflow.models.GPR(data=(X,Y), kernel=k, mean_function=None)

我想固定二维的长度尺度,只优化另一个。

我可以禁用所有长度优化,

gpflow.set_trainable(m.kernel.lengthscales, False) 

但我不能只将一个维度传递给此方法。

在 GPy 中我们会调用 m.kern.lengthscale[1:].fixed() 或其他东西。

也许我可以使用转换来大致实现这一点(例如 ),但这相当复杂。

GPflow 对每个参数使用单个 tf.Variable - 例如内核的 lengthscales - 而 TensorFlow 只允许您更改整个变量的 trainable 状态。对于任意维度,每个维度都有一个单独的参数并不容易实现,但您可以轻松地 class 您想要的内核并用 属性 覆盖 lengthscales ,如下所示:

import gpflow
import tensorflow as tf

class MyKernel(gpflow.kernels.SquaredExponential):  # or whichever kernel you want
    @property
    def lengthscales(self) -> tf.Tensor:
        return tf.stack([self.lengthscale_0, self.lengthscale_1])

    @lengthscales.setter
    def lengthscales(self, value):
        self.lengthscale_0 = gpflow.Parameter(value[0], transform=gpflow.utilities.positive())
        self.lengthscale_1 = value[1]  # fixed

那么你可以简单地使用k = MyKernel(lengthscales=[24*5, 1e-5])。 (虽然 1e-5 的长度尺度看起来不对!但这超出了这个问题的范围。)

这是有效的,因为 superclass 的 __init__(在 gpflow.kernels.Stationary 中)分配了 self.lengthscales = Parameter(lengthscales, transform=positive()),所以在这个custom class 这会调用 属性 setter,后者又会创建两个单独的属性。 属性 getter 然后将它们拼接在一起,用于实际需要 two-dimensional 向量的方法。