【问题标题】:Cholesky decomposition issue with subtractive kernel in gpflowgpflow中减法内核的Cholesky分解问题
【发布时间】:2020-01-26 15:30:55
【问题描述】:

我正在尝试以下内核:

class AperiodicMatern12(gpflow.kernels.Kernel):
  def __init__(self, input_dim = None, period = 1.0, variance = 1.0, 
      lengthscales = 1.0, active_dims = None, name = None):
    super().init(input_dim, active_dims = active_dims)
    k0 = gpflow.kernels.Matern12(input_dim, active_dims = active_dims)
    k1 = gpflow.kernels.Matern12(input_dim, active_dims = active_dims)
    k = gpflow.kernels.Periodic(base = k1, period = period)
    self.base = k0
    self.per = k

  @gpflow.params_as_tensors
  def K(self, X, X2 = None):
    res = self.base.K(X, X2) - self.per.K(X, X2)
    return res

  def Kdiag(self, X):
    return np.diag(self.K(X))

当我运行它时:

lik = gpflow.likelihoods.Gaussian()
k = AperiodicMatern12(1, active_dims = [0])
m = gpflow.models.GPR(X, Y, kern = k)
gpflow.train.ScipyOptimizer().minimize(m)

我明白了:

InvalidArgumentError(参见上文的回溯):Cholesky 分解不成功。输入可能无效。 [[node GPR-0b2840db-15/likelihood_1/Cholesky(定义在/Users/mjg/anaconda3/lib/python3.6/site-packages/gpflow/models/gpr.py:72)]]

当我尝试将内核定义为添加剂时:

@gpflow.params_as_tensors
def K(self, X, X2 = None):
  res = self.base.K(X, X2) + self.per.K(X, X2)
  return res

一切正常。 X 和 Y 在这两种情况下都是标准化的。那么减法内核有什么问题呢?

【问题讨论】:

  • 谢谢 - 现在一切正常

标签: gpflow


【解决方案1】:

Cholesky 分解仅适用于正定矩阵。因此,如果输入参数不是正定的,或者 - 等效地,换句话说 - 当输入矩阵具有任何负特征值时,Cholesky 分解操作将失败。发生这种情况时,实际计算内核矩阵的特征值通常会有所帮助(例如np.linalg.eigvals(tf.Session().run(k.K(X))))。

内核矩阵的特征值可能为负有两种不同的情况:最常见的原因是由于有限的数值精度问题,“几乎为正”的负特征值 - 这就是为什么我们通常添加一个抖动矩阵(对角矩阵与10^(-6) 在对角线上)在 GPflow 中计算 Cholesky 分解之前。第二个原因是核矩阵的计算存在错误。这里就是这种情况:

X = np.linspace(0, 10, 11)[:,None]  # dummy 1D data matrix
session = gpflow.get_default_session()
K = session.run(k.K(X))
np.linalg.eigvals(K)

输出

array([-9.00767547,  1.78835489,  1.51465032,  1.18585391,  0.97478308,
        0.79231475,  0.67625953,  0.5866432 ,  0.52938737,  0.4691057 ,
        0.49032271])

虽然两个核(正定矩阵)的总和总是给出一个有效核(另一个正定矩阵),但此属性对于差异一般不成立。

更新:在非常特殊的情况下,两个内核的差异可能是另一个有效的正定内核。 Durrande et al.'s construction of periodic and aperiodic Matern-class kernels 就是这种情况。它们的构造特定于来自 Matern 家族的内核,并且不同于基于在gpflow.kernels.Periodic 中实现的任何固定内核的周期性内核的一般实现。

GPflow 不提供 Durrande 等人。开箱即用的 a/periodic Matern 内核,尽管在 GPflow 上实现它们很容易,GPflow 项目很乐意考虑将这些内核添加到 GPflow 代码库的拉取请求。

【讨论】:

  • 我在看 Durrande 等人的作品。 (2016 年;peerj.com/articles/cs-50.pdf),特别是补充材料 (peerj.com/articles/cs-50/#supplemental-information) 中图 3 的 Jupyter 笔记本,其中包含在 GPy 中演示此类内核的代码。
  • 啊,我相信 Durrande 等人的构造之所以有效,是因为他们构造的 PeriodicMatern52 内核与 Matern52 基本内核之间存在特殊联系。 GPflow 的通用Periodic() 类使用不同的周期性结构。我会看看我是否可以更深入地研究这一点,但您可能必须手动重新实现他们的PeriodicMatern52 内核(幸运的是,使用 TensorFlow,您不必处理渐变!)。
  • @MatthewGraham 如果您想为 GPflow 贡献 Durrande 等人的 Matern 类周期性内核的实现,我很乐意查看您的 PR!
  • 当我可以解决 Cholesky 分解问题时,我可能会这样做
  • @MatthewGraham 澄清一下,您的 Cholesky 分解问题是因为您的设置实际上并未构建有效的内核。 gpflow.kernels.Periodic(base=gpflow.kernels.Matern12())(通用周期性构造)与GPy.kern.PeriodicMatern12()(Durrande 等人的 RKHS 构造)是一个非常不同的内核。因此,为了能够在 gpflow 中构建您的 AperiodicMatern12,您首先需要为 Durrande 等人的内核实现内核计算 - 然后您应该不会有任何 Cholesky 问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-02-12
  • 2015-06-20
  • 1970-01-01
  • 1970-01-01
  • 2020-05-29
  • 2021-01-24
  • 2013-11-01
相关资源
最近更新 更多