python - 如何获得完整的协方差矩阵并在 GPflow 中找到它的熵

标签 python tensorflow statistics gaussian gpflow

我想计算 GPFlow 中 GP 回归的协方差矩阵的行列式。我猜我可以用这个函数得到协方差矩阵:

GPModel.predict_f_full_cov

这里建议使用这个函数:

https://gpflow.readthedocs.io/en/develop/notebooks/regression.html

但是,我不知道如何使用这个函数或者它返回什么。我需要知道一个返回整个模型的协方差矩阵的函数,然后我需要知道如何计算它的行​​列式。

经过一些努力,我想出了如何给 predict_f_full_cov 一些我感兴趣的点,正如我们在这里看到的:

c = m.predict_f_full_cov(np.array([[.2],[.4],[.6],[.8]])))

这返回了两个数组,第一个是我要求的沿 x 轴的点的预测函数的平均值。第二个数组有点神秘。我猜这是协方差矩阵。我用这个把它拉出来:

covMatrix = m.predict_f_full_cov(np.array([[.2],[.4],[.6],[.8]]))[1][0]

然后我查找了如何计算行列式,如下所示:

x = np.linalg.det(covMatrix)

然后我计算了它的对数以获得协方差矩阵的熵:

print(-10*math.log(np.linalg.det(covMatrix)))

我使用两组不同的数据运行了两次。第一个噪音大,第二个噪音小。奇怪的是,较低噪声数据集的熵上升了。我很茫然。

我发现如果我只计算一个应该是线性的小区域的协方差矩阵,那么上下调噪声并不会达到我的预期。此外,如果我将 GP 回归到大量点,则行列式变为 0.0。

这是我使用的代码:

import gpflow
import numpy as np
N = 300
noiseSize = 0.01
X = np.random.rand(N,1)
Y = np.sin(12*X) + 0.66*np.cos(25*X)  + np.random.randn(N,1)*noiseSize + 3
k = gpflow.kernels.Matern52(1, lengthscales=0.3)
m = gpflow.models.GPR(X, Y, kern=k)
m.likelihood.variance = 0.01
aRange = np.linspace(0.1,0.9,200)
newRange = []
for point in aRange:
    newRange.append([point])
covMatrix = m.predict_f_full_cov(newRange)[1][0]
import math
print("Determinant: " + str(np.linalg.det(covMatrix)))
print(-10*math.log(np.linalg.det(covMatrix)))

最佳答案

所以,首先,多元正态分布的熵(和 GP,给定一组固定的点进行评估)only depends在其协方差矩阵上。

问题的答案:

  1. 是的 - 当您使集合 $X$ 越来越密集时,您会使协方差矩阵越来越大,对于许多简单的协方差核,这会使行列式越来越小。我的猜测是,这是由于大矩阵的行列式具有很多 乘积项(请参阅 Leibniz formula )和小于一个项的乘积比他们的总和更快归零。您可以轻松验证这一点:

Dimension and Covar

代码:

import numpy as np
import matplotlib.pyplot as plt
import sklearn.gaussian_process.kernels as k

plt.style.use("ggplot"); plt.ion()

n = np.linspace(2, 25, 23, dtype = int)
d = np.zeros(len(n))

for i in range(len(n)):
    X = np.linspace(-1, 1, n[i]).reshape(-1, 1)
    S = k.RBF()(X)
    d[i] = np.log(np.linalg.det(S))

plt.scatter(n, d)
plt.ylabel("Log Determinant of Covariance Matrix")
plt.xlabel("Dimension of Covariance Matrix")

在进入下一点之前,请注意多元正态的熵也有来自矩阵大小的贡献,所以即使行列式突然变为零,也有很小的贡献从维度上看。

  1. 正如预期的那样,随着噪声的降低,熵和行列式确实会降低,但不会完全趋于零;由于协方差中存在其他内核,它们将减少为行列式。对于下面的演示,协方差的维数保持不变 ($10*10$),噪声水平从 0 开始增加:

Error and Determinant

代码:

e = np.logspace(1, -10, 30)
d = np.zeros(len(e))
X = np.linspace(-1, 1, 10).reshape(-1, 1)

for i in range(len(e)):
    S = (k.RBF() + k.WhiteKernel(e[i])) (X)
    d[i] = np.log(np.linalg.det(S))

e = np.log(e)

plt.scatter(e, d)
plt.ylabel("Log Determinant")
plt.xlabel("Log Error")

关于python - 如何获得完整的协方差矩阵并在 GPflow 中找到它的熵,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53345624/

相关文章:

Python DataFrame 形状差异

tensorflow - 在 GPU 上训练的模型可以在 CPU 上用于推理,反之亦然吗?

python - 从 URL 列表(每个 URL 包含一个唯一的表)中抓取表数据,以便将其全部附加到单个列表/数据帧中?

matlab - 特定分布的pdf

r - 筛选回归模型中的(多重)共线性

python - Tensorflow 2.0 中的多输入 CNN 没有执行任何操作

python - 如何正确排序/排列类(class)成员

python - 运行时错误: There is no current event loop in thread 'MainThread'

python - 3D 张量输入到 keras 或 tensorflow 中的嵌入层?

python - 使用自定义损失函数创建 Keras 模型的函数只能运行一次