I have a 2d kernel,
k = gpflow.kernels.RBF(lengthscales=[24*5,1e-5])
m = gpflow.models.GPR(data=(X,Y), kernel=k, mean_function=None)
and I want to fix the lengthscale in the 2nd dimension, and just optimise the other.
I can disable all lengthscale optimisation using,
gpflow.set_trainable(m.kernel.lengthscales, False)
but I can't pass just one dimension to this method.
In GPy we would call m.kern.lengthscale[1:].fixed()
or something.
Maybe I could use a transform to roughly achieve this (e.g. here), but that's quite complicated.
GPflow uses a single
tf.Variable
for each parameter - such as a kernel'slengthscales
- and TensorFlow only allows you to change thetrainable
status of a Variable as a whole. Having a separate parameter per dimension would not be easy to implement for arbitrary dimensions, but you can easily subclass the kernel you want and overridelengthscales
with a property as follows:Then you can simply use
k = MyKernel(lengthscales=[24*5, 1e-5])
. (Though a lengthscale of 1e-5 doesn't look right! But that's outside the scope of this question.)This works because the superclass's
__init__
(in gpflow.kernels.Stationary) assignsself.lengthscales = Parameter(lengthscales, transform=positive())
, so in this custom class this instead calls the property setter which in turn creates the two separate attributes. The property getter then stitches them back together for the methods that actually expect the two-dimensional vector.