首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >诱导变量的重塑- GPflow

诱导变量的重塑- GPflow
EN

Stack Overflow用户
提问于 2020-09-30 21:07:43
回答 1查看 317关注 0票数 0

我有一个SGPR模型:

代码语言:javascript
复制
import numpy as np
import gpflow

X, Y = np.random.randn(50, 2), np.random.randn(50, 1)
Z1 = np.random.randn(13, 2)

k = gpflow.kernels.SquaredExponential()
m = gpflow.models.SGPR(data=(X, Y), kernel=k, inducing_variable=Z1)

我想给归纳变量赋值,但形状不同,比如:

代码语言:javascript
复制
Z2 = np.random.randn(29, 2)
m.inducing_variable.Z.assign(Z2)

但如果我这么做,我会:

代码语言:javascript
复制
ValueError: Shapes (13, 2) and (29, 2) are incompatible

有没有办法在不重新定义模型的情况下重新分配诱导变量?

上下文:我不想用诱导变量对模型进行优化,而是在不优化诱导变量的情况下对模型进行优化,在优化的每一步手动重新分配诱导变量。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-09-30 22:09:11

更新:这个问题由https://github.com/GPflow/GPflow/pull/1594解决,它将成为下一个GPflow修补程序发行版(2.1.4)的一部分。

有了这个修复,您就不需要定制类了。您所需要做的就是在第一个维度上使用None显式地设置静态形状:

代码语言:javascript
复制
inducing_variable = gpflow.inducing_variables.InducingPoints(
    tf.Variable(
        Z1,  # initial value
        trainable=False,  # True does not work - see Note below
        shape=(None, Z1.shape[1]),  # or even tf.TensorShape(None)
        dtype=gpflow.default_float(),  # required due to tf's 32bit default
    )
)
m = gpflow.models.SGPR(data=(X, Y), kernel=k, inducing_variable=inducing_variable)

那么m.inducing_variable.Z.assign(Z2)应该工作得很好。

注意到,在这种情况下,Z不能训练,因为TensorFlow优化器需要在构造时知道形状,并且不支持动态形状。

现在(截至GPflow 2.1.2)还没有一个内置的方式来改变SGPR的诱导变量的形状,尽管原则上是可能的。不过,您可以通过自己的诱导变量类获得您想要的:

代码语言:javascript
复制
class VariableInducingPoints(gpflow.inducing_variables.InducingPoints):
     def __init__(self, Z, name=None):
         super().__init__(Z, name=name)
         # overwrite with Variable with None as first element in shape so
         # we can assign arrays with arbitrary length along this dimension:
         self.Z = tf.Variable(Z, dtype=gpflow.default_float(),
             shape=(None, Z.shape[1])
         )

     def __len__(self):
         return tf.shape(self.Z)[0]  # dynamic shape
         # instead of the static shape returned by the InducingPoints parent class

然后再做

代码语言:javascript
复制
m = gpflow.models.SGPR(
    data=(X, Y), kernel=k, inducing_variable=VariableInducingPoints(Z1)
)

而不是。那么,您的m.inducing_variable.Z.assign()应该按照您的喜好工作。

(对于SVGP,诱导变量的大小和由q_muq_sqrt定义的分布必须匹配,并且在构造时已知,因此在这种情况下,更改诱导变量的数量就不那么简单了。)

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/64145766

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档