PyTorch教程-18.3。高斯过程推理

电子说

1.2w人已加入

描述

在本节中,我们将展示如何使用我们在上一节中介绍的 GP 先验执行后验推理和进行预测。我们将从回归开始,我们可以在其中以封闭形式执行推理。这是一个“简而言之 GP”部分,可在实践中快速启动和运行高斯过程。我们将从头开始编写所有基本操作的代码,然后介绍 GPyTorch,这将使使用最先进的高斯过程以及与深度神经网络的集成更加方便。我们将在下一节中深入探讨这些更高级的主题。在该部分中,我们还将考虑需要近似推理的设置——分类、点过程或任何非高斯似然。

18.3.1。回归的后验推理

观察模型与我们想要学习的功能相关联, f(x), 根据我们的观察y(x), 都由一些输入索引x. 在分类上,x可以是图像的像素,并且y可能是关联的类标签。在回归中, y通常表示连续输出,例如地表温度、海平面、CO2浓度等

在回归中,我们通常假设输出是由潜在的无噪声函数给出的f(x)加上 iid 高斯噪声 ϵ(x):

(18.3.1)y(x)=f(x)+ϵ(x),

和ϵ(x)∼N(0,σ2). 让 y=y(X)=(y(x1),…,y(xn))⊤是我们训练观察的向量,并且 f=(f(x1),…,f(xn))⊤是潜在无噪声函数值的向量,在训练输入中查询 X=x1,…,xn.

我们假设f(x)∼GP(m,k),这意味着任何函数值的集合f具有联合多元高斯分布,均值向量 μi=m(xi)和协方差矩阵 Kij=k(xi,xj). RBF核 k(xi,xj)=a2exp⁡(−12ℓ2||xi−xj||2) 将是协方差函数的标准选择。为了符号简单起见,我们将假设均值函数m(x)=0; 我们的推导可以在以后很容易地推广。

假设我们想对一组输入进行预测

(18.3.2)X∗=x∗1,x∗2,…,x∗m.

那么我们想要找到x2和 p(f∗|y,X). 在回归设置中,我们可以在找到联合分布后,使用高斯恒等式方便地找到这个分布f∗=f(X∗) 和y.

如果我们在训练输入处评估等式(18.3.1)X, 我们有 y=f+ϵ. 根据高斯过程的定义(见上一节), f∼N(0,K(X,X))在哪里K(X,X)是一个 n×n通过在所有可能的输入对上评估我们的协方差函数(又名kernel )形成的矩阵xi,xj∈X. ϵ只是一个由 iid 样本组成的向量N(0,σ2)从而有分布 N(0,σ2I).y因此是两个独立的多元高斯变量的总和,因此具有分布N(0,K(X,X)+σ2I). 也可以证明 cov(f∗,y)=cov(y,f∗)⊤=K(X∗,X) 在哪里K(X∗,X)是一个m×n通过评估所有对测试和训练输入的内核形成的矩阵。

(18.3.3)[yf∗]∼N(0,A=[K(X,X)+σ2IK(X,X∗)K(X∗,X)K(X∗,X∗)])

然后我们可以使用标准高斯恒等式从联合分布中找到条件分布(例如,参见 Bishop 第 2 章), f∗|y,X,X∗∼N(m∗,S∗), 在哪里m∗=K(X∗,X)[K(X,X)+σ2I]−1y, 和 S=K(X∗,X∗)−K(X∗,X)[K(X,X)+σ2I]−1K(X,X∗).

通常,我们不需要使用完整的预测协方差矩阵S, 而不是使用对角线S对于每个预测的不确定性。通常出于这个原因,我们为单个测试点编写预测分布x∗,而不是测试点的集合。

核矩阵有参数θ我们也希望估计,例如振幅a和长度尺度ℓ上面的 RBF 内核。为了这些目的,我们使用边际似然,p(y|θ,X),我们已经在计算边际分布以找到联合分布时得出y,f∗. 正如我们将看到的,边际似然划分为模型拟合和模型复杂性项,并自动编码用于学习超参数的奥卡姆剃刀概念。有关完整讨论,请参阅 MacKay Ch。28 (MacKay 和 Mac Kay,2003 年),以及 Rasmussen 和 Williams Ch。5 (拉斯穆森和威廉姆斯,2006 年)。

 

import math
import os
import gpytorch
import matplotlib.pyplot as plt
import numpy as np
import torch
from scipy import optimize
from scipy.spatial import distance_matrix
from d2l import torch as d2l

d2l.set_figsize()

 

18.3.2。在 GP 回归中进行预测和学习内核超参数的方程式

我们在这里列出了您将用于学习超参数和在高斯过程回归中进行预测的方程式。同样,我们假设一个回归目标向量y, 由输入索引 X={x1,…,xn},我们希望在测试输入中做出预测x∗. 我们假设具有方差的 iid 加性零均值高斯噪声σ2. 我们先使用高斯过程 f(x)∼GP(m,k)对于潜在的无噪声函数,具有均值函数m和核函数k. 内核本身有参数θ我们想学习。例如,如果我们使用 RBF 内核, k(xi,xj)=a2exp⁡(−12ℓ2||x−x′||2), 我们想学习θ={a2,ℓ2}. 让K(X,X) 代表一个n×n对应于为所有可能的对评估内核的矩阵n培训投入。让 K(x∗,X)代表一个1×n通过评估形成的向量k(x∗,xi),i=1,…,n. 让μ是通过计算均值函数形成的均值向量m(x)在每个训练点x.

通常在处理高斯过程时,我们遵循一个两步过程。1.学习内核超参数θ^通过最大化这些超参数的边际似然。2.使用预测均值作为点预测器,2倍预测标准差形成95%可信集,以这些学习到的超参数为条件θ^.

对数边际似然只是一个对数高斯密度,其形式为:

(18.3.4)log⁡p(y|θ,X)=−12y⊤[Kθ(X,X)+σ2I]−1y−12log⁡|Kθ(X,X)|+c

预测分布具有以下形式:

(18.3.5)p(y∗|x∗,y,θ)=N(a∗,v∗)

(18.3.6)a∗=kθ(x∗,X)[Kθ(X,X)+σ2I]−1(y−μ)+μ

(18.3.7)v∗=kθ(x∗,x∗)−Kθ(x∗,X)[Kθ(X,X)+σ2I]−1kθ(X,x∗)

18.3.3。解释学习和预测方程

关于高斯过程的预测分布,有一些关键点需要注意:

尽管模型类具有灵活性,但可以 对封闭形式的 GP 回归进行精确的贝叶斯推理。除了学习内核超参数外,没有任何训练。我们可以准确地写下我们想要用来进行预测的方程式。高斯过程在这方面相对特殊,这极大地促进了它们的便利性、多功能性和持续流行。

预测均值a∗是训练目标的线性组合y, 由内核加权 kθ(x∗,X)[Kθ(X,X)+σ2I]−1. 正如我们将看到的,内核(及其超参数)因此在模型的泛化特性中起着至关重要的作用。

预测均值明确取决于目标值 y但预测方差没有。预测不确定性反而随着测试输入而增长x∗ 远离目标位置X,由内核函数控制。然而,不确定性将隐含地取决于目标的价值y通过内核超参数θ,这是从数据中学到的。

边际似然划分为模型拟合和模型复杂性(对数行列式)项。边际似然倾向于选择提供与数据仍然一致的最简单拟合的超参数。

关键的计算瓶颈来自解决线性系统和计算对数行列式n×n对称正定矩阵K(X,X)为了n训练点。天真地,这些操作每个都会招致O(n3) 计算,以及O(n2)核(协方差)矩阵的每个条目的存储,通常从 Cholesky 分解开始。从历史上看,这些瓶颈将 GP 限制在训练点少于 10,000 的问题上,并给 GP 带来了近十年来不准确的“速度慢”的名声。在高级主题中,我们将讨论如何将 GP 扩展到具有数百万个点的问题。

对于核函数的流行选择,K(X,X)通常接近奇异,这可能会在执行 Cholesky 分解或其他旨在求解线性系统的操作时导致数值问题。幸运的是,在回归中我们经常使用 Kθ(X,X)+σ2I,使得噪声方差 σ2被添加到对角线K(X,X), 显着改善其条件。如果噪声方差很小,或者我们正在进行无噪声回归,通常的做法是在对角线上添加少量“抖动”,数量级为 10−6, 改善调理。

18.3.4。从零开始的工作示例

让我们创建一些回归数据,然后用 GP 拟合数据,从头开始实施每一步。我们将从中抽样数据

(18.3.8)y(x)=sin⁡(x)+12sin⁡(4x)+ϵ,

和ϵ∼N(0,σ2). 我们希望找到的无噪声函数是 f(x)=sin⁡(x)+12sin⁡(4x). 我们将从使用噪声标准偏差开始σ=0.25.

 

def data_maker1(x, sig):
  return np.sin(x) + 0.5 * np.sin(4 * x) + np.random.randn(x.shape[0]) * sig

sig = 0.25
train_x, test_x = np.linspace(0, 5, 50), np.linspace(0, 5, 500)
train_y, test_y = data_maker1(train_x, sig=sig), data_maker1(test_x, sig=0.)

d2l.plt.scatter(train_x, train_y)
d2l.plt.plot(test_x, test_y)
d2l.plt.xlabel("x", fontsize=20)
d2l.plt.ylabel("Observations y", fontsize=20)
d2l.plt.show()

 

GP

在这里,我们将嘈杂的观察结果视为圆圈,将我们希望找到的蓝色无噪声函数视为圆圈。

现在,让我们在潜在无噪声函数之前指定一个 GP, f(x)∼GP(m,k). 我们将使用均值函数 m(x)=0和 RBF 协方差函数(核)

(18.3.9)k(xi,xj)=a2exp⁡(−12ℓ2||x−x′||2).

 

mean = np.zeros(test_x.shape[0])
cov = d2l.rbfkernel(test_x, test_x, ls=0.2)

 

我们从 0.2 的长度尺度开始。在我们拟合数据之前,重要的是要考虑我们是否指定了合理的先验。让我们想象一下这个先验的一些样本函数,以及 95% 的可信集(我们相信真正的函数有 95% 的可能性在这个区域内)。

 

prior_samples = np.random.multivariate_normal(mean=mean, cov=cov, size=5)
d2l.plt.plot(test_x, prior_samples.T, color='black', alpha=0.5)
d2l.plt.plot(test_x, mean, linewidth=2.)
d2l.plt.fill_between(test_x, mean - 2 * np.diag(cov), mean + 2 * np.diag(cov),
         alpha=0.25)
d2l.plt.show()

 

GP

这些样本看起来合理吗?函数的高级属性是否与我们尝试建模的数据类型一致?

现在让我们在任意测试点形成后验预测分布的均值和方差x∗.

(18.3.10)f¯∗=K(x,x∗)T(K(x,x)+σ2I)−1y

(18.3.11)V(f∗)=K(x∗,x∗)−K(x,x∗)T(K(x,x)+σ2I)−1K(x,x∗)

在我们做出预测之前,我们应该学习我们的内核超参数 θ和噪声方差σ2. 让我们将长度尺度初始化为 0.75,因为与我们正在拟合的数据相比,我们之前的函数看起来变化太快了。我们还将猜测噪声标准偏差σ0.75。

为了学习这些参数,我们将最大化这些参数的边际似然。

(18.3.12)log⁡p(y|X)=log⁡∫p(y|f,X)p(f|X)df

(18.3.13)log⁡p(y|X)=−12yT(K(x,x)+σ2I)−1y−12log⁡|K(x,x)+σ2I|−n2log⁡2π

也许我们之前的功能变化太快了。我们假设长度尺度为 0.4。我们还将猜测噪声标准偏差为 0.75。这些只是超参数初始化——我们将从边际似然中学习这些参数。

 

ell_est = 0.4
post_sig_est = 0.5

def neg_MLL(pars):
  K = d2l.rbfkernel(train_x, train_x, ls=pars[0])
  kernel_term = -0.5 * train_y @ 
    np.linalg.inv(K + pars[1] ** 2 * np.eye(train_x.shape[0])) @ train_y
  logdet = -0.5 * np.log(np.linalg.det(K + pars[1] ** 2 * 
                     np.eye(train_x.shape[0])))
  const = -train_x.shape[0] / 2. * np.log(2 * np.pi)

  return -(kernel_term + logdet + const)


learned_hypers = optimize.minimize(neg_MLL, x0=np.array([ell_est,post_sig_est]),
                  bounds=((0.01, 10.), (0.01, 10.)))
ell = learned_hypers.x[0]
post_sig_est = learned_hypers.x[1]

 

在本例中,我们学习了 0.299 的长度尺度和 0.24 的噪声标准差。请注意,学习到的噪声非常接近真实噪声,这有助于表明我们的 GP 非常明确地解决了这个问题。

一般来说,仔细考虑选择内核和初始化超参数是至关重要的。虽然边际似然优化对初始化来说相对稳健,但它也不能避免糟糕的初始化。尝试使用各种初始化运行上面的脚本,看看你发现了什么结果。

现在,让我们用这些学习到的超级计算机进行预测。

 

K_x_xstar = d2l.rbfkernel(train_x, test_x, ls=ell)
K_x_x = d2l.rbfkernel(train_x, train_x, ls=ell)
K_xstar_xstar = d2l.rbfkernel(test_x, test_x, ls=ell)

post_mean = K_x_xstar.T @ np.linalg.inv((K_x_x + 
        post_sig_est ** 2 * np.eye(train_x.shape[0]))) @ train_y
post_cov = K_xstar_xstar - K_x_xstar.T @ np.linalg.inv((K_x_x + 
        post_sig_est ** 2 * np.eye(train_x.shape[0]))) @ K_x_xstar

lw_bd = post_mean - 2 * np.sqrt(np.diag(post_cov))
up_bd = post_mean + 2 * np.sqrt(np.diag(post_cov))

d2l.plt.scatter(train_x, train_y)
d2l.plt.plot(test_x, test_y, linewidth=2.)
d2l.plt.plot(test_x, post_mean, linewidth=2.)
d2l.plt.fill_between(test_x, lw_bd, up_bd, alpha=0.25)
d2l.plt.legend(['Observed Data', 'True Function', 'Predictive Mean', '95% Set on True Func'])
d2l.plt.show()

 

GP

我们看到橙色的后验均值几乎完全匹配真正的无噪声函数!请注意,我们显示的 95% 可信集是针对无潜在噪声(真实)函数的,而不是数据点。我们看到这个可信集完全包含了真实的功能,并且看起来并不过分宽泛或狭窄。我们不希望也不期望它包含数据点。如果我们希望有一个可靠的观察集,我们应该计算

 

lw_bd_observed = post_mean - 2 * np.sqrt(np.diag(post_cov) + post_sig_est ** 2)
up_bd_observed = post_mean + 2 * np.sqrt(np.diag(post_cov) + post_sig_est ** 2)

 

不确定性有两个来源,认知不确定性,代表可减少的不确定性,以及任意或不可减少的 不确定性。这里的认知不确定性表示无噪声函数真实值的不确定性。随着我们远离数据点,这种不确定性应该会增加,因为远离数据有更多种类的函数值与我们的数据一致。随着我们观察到越来越多的数据,我们对真实函数的信念变得更加自信,认知不确定性消失。这种情况下的任意 不确定性是观察噪声,因为数据是通过这种噪声提供给我们的,并且无法减少。

数据中的认知不确定性由潜在无噪声函数 np.diag(post_cov) 的方差捕获。任意不 确定性由噪声方差 post_sig_est**2 捕获。

不幸的是,人们常常不关心他们如何表示不确定性,许多论文显示的误差条完全未定义,不清楚我们是在可视化认知不确定性还是任意不确定性或两者兼而有之,并且将噪声方差与噪声标准差混淆,标准差与标准误差、可信集的置信区间等。如果不明确不确定性代表什么,它本质上是没有意义的。

本着密切关注我们的不确定性代表什么的精神,重要的是要注意我们对无噪声函数的方差估计取平方根的 两倍。由于我们的预测分布是高斯分布,这个数量使我们能够形成一个 95% 的可信集,代表我们对 95% 可能包含基本事实函数的区间的信念。噪声 方差存在于完全不同的尺度上,并且更难解释。

最后,让我们来看看20个后验样本。这些样本告诉我们我们认为哪些类型的函数可能适合我们的数据,这是后验的。

 

post_samples = np.random.multivariate_normal(post_mean, post_cov, size=20)
d2l.plt.scatter(train_x, train_y)
d2l.plt.plot(test_x, test_y, linewidth=2.)
d2l.plt.plot(test_x, post_mean, linewidth=2.)
d2l.plt.plot(test_x, post_samples.T, color='gray', alpha=0.25)
d2l.plt.fill_between(test_x, lw_bd, up_bd, alpha=0.25)
plt.legend(['Observed Data', 'True Function', 'Predictive Mean', 'Posterior Samples'])
d2l.plt.show()

 

GP

在基本回归应用中,最常见的做法是分别使用后验预测均值和标准差作为不确定性的点预测器和度量。在更高级的应用程序中,例如使用蒙特卡洛采集函数的贝叶斯优化或基于模型的 RL 的高斯过程,通常需要采用后验样本。然而,即使在基本应用程序中没有严格要求,这些样本也能让我们更直观地了解我们对数据的拟合程度,并且通常有助于将其包含在可视化中。

18.3.5。使用 GPyTorch 让生活更轻松

正如我们所见,完全从头开始实现基本的高斯过程回归实际上非常容易。然而,一旦我们想要探索各种内核选择,考虑近似推理(这甚至是分类所必需的),将 GP 与神经网络相结合,甚至拥有大于约 10,000 个点的数据集,那么从头开始的实现就变成了笨重和麻烦。一些最有效的可扩展 GP 推理方法,例如 SKI(也称为 KISS-GP),可能需要数百行代码来实现高级数值线性代数例程。

在这些情况下,GPyTorch库将使我们的生活变得更加轻松。我们将在未来关于高斯过程数值和高级方法的笔记本中更多地讨论 GPyTorch。GPyTorch 库包含 许多示例。为了感受这个包,我们将通过简单的回归示例,展示如何使用 GPyTorch 对其进行调整以重现我们的上述结果。这看起来像是简单地重现上面的基本回归的大量代码,从某种意义上说,它确实如此。但是我们可以立即使用各种内核、可扩展推理技术和近似推理,只需从下面更改几行代码,而不是编写可能有数千行的新代码。

 

# First let's convert our data into tensors for use with PyTorch
train_x = torch.tensor(train_x)
train_y = torch.tensor(train_y)
test_y = torch.tensor(test_y)

# We are using exact GP inference with a zero mean and RBF kernel
class ExactGPModel(gpytorch.models.ExactGP):
  def __init__(self, train_x, train_y, likelihood):
    super(ExactGPModel, self).__init__(train_x, train_y, likelihood)
    self.mean_module = gpytorch.means.ZeroMean()
    self.covar_module = gpytorch.kernels.ScaleKernel(
      gpytorch.kernels.RBFKernel())

  def forward(self, x):
    mean_x = self.mean_module(x)
    covar_x = self.covar_module(x)
    return gpytorch.distributions.MultivariateNormal(mean_x, covar_x)

 

此代码块将数据置于 GPyTorch 的正确格式中,并指定我们正在使用精确推理,以及我们要使用的均值函数(零)和核函数(RBF)。我们可以很容易地使用任何其他内核,例如,通过调用 gpytorch.kernels.matern_kernel() 或 gpyotrch.kernels.spectral_mixture_kernel()。到目前为止,我们只讨论了精确推理,其中可以在不进行任何近似的情况下推断出预测分布。对于高斯过程,我们只有在具有高斯似然时才能进行精确推理;更具体地说,当我们假设我们的观察结果是由高斯过程和高斯噪声表示的无噪声函数生成的。在未来的笔记本中,我们将考虑其他设置,例如分类,我们无法做出这些假设。

 

# Initialize Gaussian likelihood
likelihood = gpytorch.likelihoods.GaussianLikelihood()
model = ExactGPModel(train_x, train_y, likelihood)
training_iter = 50
# Find optimal model hyperparameters
model.train()
likelihood.train()
# Use the adam optimizer, includes GaussianLikelihood parameters
optimizer = torch.optim.Adam(model.parameters(), lr=0.1)
# Set our loss as the negative log GP marginal likelihood
mll = gpytorch.mlls.ExactMarginalLogLikelihood(likelihood, model)

 

在这里,我们明确指定我们想要使用的可能性(高斯),我们将用于训练内核超参数的目标(这里是边际可能性),以及我们想要用于优化该目标的过程(在本例中,Adam ). 我们注意到,虽然我们使用的是“随机”优化器 Adam,但在本例中,它是全批次 Adam。因为边际似然不会分解数据实例,所以我们不能对“小批量”数据使用优化器并保证收敛。GPyTorch 也支持其他优化器,例如 L-BFGS。与标准深度学习不同,做好边际似然优化工作与良好的泛化密切相关,这通常使我们倾向于使用像 L-BFGS 这样强大的优化器,前提是它们的成本并不高得令人望而却步。

 

for i in range(training_iter):
  # Zero gradients from previous iteration
  optimizer.zero_grad()
  # Output from model
  output = model(train_x)
  # Calc loss and backprop gradients
  loss = -mll(output, train_y)
  loss.backward()
  if i % 10 == 0:
    print(f'Iter {i+1:d}/{training_iter:d} - Loss: {loss.item():.3f} '
       f'squared lengthscale: '
       f'{model.covar_module.base_kernel.lengthscale.item():.3f} '
       f'noise variance: {model.likelihood.noise.item():.3f}')
  optimizer.step()

 

 

Iter 1/50 - Loss: 0.973 squared lengthscale: 0.693 noise variance: 0.693
Iter 11/50 - Loss: 0.684 squared lengthscale: 0.511 noise variance: 0.313
Iter 21/50 - Loss: 0.422 squared lengthscale: 0.533 noise variance: 0.128
Iter 31/50 - Loss: 0.304 squared lengthscale: 0.535 noise variance: 0.056
Iter 41/50 - Loss: 0.320 squared lengthscale: 0.522 noise variance: 0.040

 

在这里,我们实际运行优化程序,每 10 次迭代输出一次损失值。

 

# Get into evaluation (predictive posterior) mode
test_x = torch.tensor(test_x)
model.eval()
likelihood.eval()
observed_pred = likelihood(model(test_x))

 

上面的代码块使我们能够对我们的测试输入进行预测。

 

with torch.no_grad():
  # Initialize plot
  f, ax = d2l.plt.subplots(1, 1, figsize=(4, 3))
  # Get upper and lower bounds for 95% credible set (in this case, in
  # observation space)
  lower, upper = observed_pred.confidence_region()
  ax.scatter(train_x.numpy(), train_y.numpy())
  ax.plot(test_x.numpy(), test_y.numpy(), linewidth=2.)
  ax.plot(test_x.numpy(), observed_pred.mean.numpy(), linewidth=2.)
  ax.fill_between(test_x.numpy(), lower.numpy(), upper.numpy(), alpha=0.25)
  ax.set_ylim([-1.5, 1.5])
  ax.legend(['True Function', 'Predictive Mean', 'Observed Data',
        '95% Credible Set'])

 

GP

最后,我们绘制拟合图。

我们看到拟合几乎相同。需要注意的几件事:GPyTorch 正在处理平方长度尺度和观察噪声。例如,我们在 for scratch 代码中学习到的噪声标准差约为 0.283。GPyTorch 找到的噪声方差是 0.81≈0.2832. 在 GPyTorch 图中,我们还展示了观察空间中的可信集而不是潜在函数空间,以证明它们确实覆盖了观察到的数据点。

18.3.6。概括

我们可以将高斯过程先验与数据结合起来形成后验,我们用它来进行预测。我们还可以形成边际似然,这对于核超参数的自动学习很有用,核超参数控制高斯过程的变化率等属性。为回归形成后验和学习内核超参数的机制很简单,涉及大约十几行代码。对于任何想要快速“启动并运行”高斯过程的读者来说,这个笔记本都是一个很好的参考。我们还介绍了 GPyTorch 库。尽管用于基本回归的 GPyTorch 代码相对较长,但可以针对其他内核函数或我们将在以后的笔记本中讨论的更高级功能(例如可扩展推理或用于分类的非高斯似然)进行简单修改。

18.3.7。练习

我们强调了学习内核超参数的重要性,以及超参数和内核对高斯过程泛化特性的影响。尝试跳过我们学习 hypers 的步骤,而是猜测各种长度尺度和噪声方差,并检查它们对预测的影响。当你使用大长度尺度时会发生什么?一个小的长度尺度?噪声方差大?噪声方差小?

我们已经说过边际似然不是凸目标,但是可以在 GP 回归中可靠地估计长度尺度和噪声方差等超参数。这通常是正确的——事实上,边际似然在学习长度尺度超参数方面比空间统计中的传统方法要好得多,后者涉及拟合经验自相关函数(“协方差图”)。可以说,至少在最近关于可扩展推理的工作之前,机器学习对高斯过程研究的最大贡献是为超参数学习引入了边际似然。

然而,即使这些参数的不同配对也为许多数据集提供了可解释的不同合理解释,从而导致我们目标中的局部最优。如果我们使用大长度尺度,那么我们假设真正的基础函数正在缓慢变化。如果观察到的数据变化很大,那么我们唯一可以合理地拥有大长度尺度的就是大的噪声方差。另一方面,如果我们使用较小的长度尺度,我们的拟合将对数据的变化非常敏感,几乎没有空间来解释噪声变化(任意不确定性)。

尝试看看您是否可以找到这些局部最优值:使用具有大噪声的非常大的长度尺度和具有小噪声的小长度尺度进行初始化。你会收敛到不同的解决方案吗?

我们已经说过,贝叶斯方法的一个基本优势是自然地表示认知不确定性。在上面的例子中,我们无法完全看到认知不确定性的影响。尝试使用 进行预测。当您的预测超出数据范围时,95% 的可信集会发生什么变化?它是否涵盖了该区间内的真实函数?如果你只想象那个区域的任意不确定性,会发生什么?test_x = np.linspace(0, 10, 1000)

尝试运行上述示例,但使用 10,000、20,000 和 40,000 个训练点,并测量运行时间。培训时间如何安排?或者,运行时间如何随测试点的数量变化?预测均值和预测方差是否不同?通过从理论上计算出训练和测试的时间复杂度,以及使用不同数量的点运行上面的代码来回答这个问题。

尝试使用不同的协方差函数运行 GPyTorch 示例,例如 Matern 内核。结果如何变化?在 GPyTorch 库中找到的光谱混合内核怎么样?有些比其他更容易训练边际可能性吗?一些对于长期预测和短期预测更有价值吗?

在我们的 GPyTorch 示例中,我们绘制了包括观察噪声在内的预测分布,而在我们的“从头开始”示例中,我们仅包括认知不确定性。重做 GPyTorch 示例,但这次只绘制认知不确定性,并与从头开始的结果进行比较。预测分布现在看起来一样吗?(他们应该。)

Discussions

打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分