1

我正在尝试以下内核:

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 分解不成功。输入可能无效。[[节点 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 在这两种情况下都是标准化的。那么减法内核有什么问题呢?

4

1 回答 1

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 等人构建的周期性和非周期性 Matern 级内核就是这种情况。它们的构造特定于来自 Matern 家族的内核,并且不同于基于已实现的任何gpflow.kernels.Periodic固定内核的周期性内核的一般实现。

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

于 2020-01-26T22:55:46.910 回答