如何修复 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 向量的方法。
我有一个二维内核,
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 向量的方法。