我有一个 2d 内核,
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()或其他方法。
m.kern.lengthscale[1:].fixed()
tf.VariableGPflow对每个参数(例如内核的参数)使用一个参数lengthscales,而 TensorFlow 只允许您更改trainable整个变量的状态。对于任意维度,每个维度都有一个单独的参数并不容易实现,但您可以轻松地将所需的内核子类化并lengthscales使用属性覆盖,如下所示:
tf.Variable
lengthscales
trainable
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 的长度尺度看起来不正确!但这超出了本问题的范围。)
k = MyKernel(lengthscales=[24*5, 1e-5])
这是可行的,因为超类__init__(在gpflow.kernels.Stationary中)分配了self.lengthscales = Parameter(lengthscales, transform=positive()),因此在这个自定义类中,它反而调用属性设置器,进而创建两个单独的属性。然后,属性获取器将它们重新拼接在一起,用于实际需要二维向量的方法。
__init__
self.lengthscales = Parameter(lengthscales, transform=positive())