GPflow解讀-GPR

高斯過程回歸 (GPR)

首先定義一個(gè)輸入空間X,定義一個(gè)函數(shù)f,它將X上的點(diǎn)映射到空間F。

F上的每個(gè)點(diǎn)都是一個(gè)隨機(jī)變量,GPR假設(shè)F上的點(diǎn)服從高斯過程,即對(duì)于任意有限個(gè)點(diǎn)f_1, ..., f_n,他們的聯(lián)合分布都是一個(gè)高斯分布。其中均值由均值函數(shù)定義,協(xié)方差矩陣由協(xié)方差函數(shù)定義。

GPR還假設(shè)了一個(gè)一維的高斯噪音\epsilon,它也是服從高斯分布的一維隨機(jī)變量。f+\epsilon即表示觀測到的樣本點(diǎn)y,所有樣本點(diǎn)的集合稱為Y。由于f無法實(shí)際觀測到,因此我們把f稱為隱函數(shù),y稱為觀測函數(shù)。

以上就是GPR的數(shù)據(jù)生成過程。

那么對(duì)于給定一個(gè)新的輸入x_\ast,如何預(yù)測對(duì)應(yīng)的f_\asty_\ast呢?

首先明確我們要求的是f_\ast的后驗(yàn)分布

p(f_\ast | \bm{x}_\ast, \bm{X}, \bm{y}) = \mathcal{N} (\mu, \sigma^2) (1)

其中\mu=\bm{k_\ast}^T (K+\sigma_n^2 I)^{-1} \bm{y}, \sigma^2 = k_{\ast\ast} - \bm{k_\ast}^T (K + \sigma^2 I)^{-1}\bm{k_\ast}。推理過程可以參考GPML的17頁。

注意(1)中包含了GPR模型的超參數(shù),我們采用什么原則優(yōu)化超參數(shù)呢?

這里要說一下,GPML書中寫道,"The posterior in eq. (2.5) combines the likelihood and the prior, and captures everything we know about the parameters.",也就是說后驗(yàn)包含了我們知道的所有信息,包括先驗(yàn)和數(shù)據(jù)。
根據(jù)GPML的第五章model selection的109頁,有三個(gè)級(jí)別的參數(shù)優(yōu)化策略。第一層是最大化模型隱函數(shù)f的后驗(yàn)概率,第二層是最大化模型超參數(shù)\theta的后驗(yàn)概率,最后是將模型類型也當(dāng)做變量,最大化模型H的后驗(yàn)概率。

實(shí)際上我們采用的是第二層策略 (5.5),最大化超參數(shù)\theta的后驗(yàn)概率。但是由于分母無法計(jì)算且是關(guān)于\theta的常數(shù),因此最大化分子部分。分子部分是邊際似然函數(shù)\log p(\bm{y}|X)和超參數(shù)先驗(yàn)分布p(\theta)的乘積。

\log p(\bm{y}|X)=-\frac{1}{2}\bm{y}^T(K+\sigma_n^2I)^{-1}\bm{y} - \frac{1}{2}\log|K+\sigma^2I|-\frac{n}{2}\log2\pi (2)

這個(gè)策略又叫第二類型最大似然估計(jì)(ML-II)。

例子1

import gpflow
import numpy as np
import matplotlib
%matplotlib inline
matplotlib.rcParams['figure.figsize'] = (12, 6)
plt = matplotlib.pyplot

準(zhǔn)備數(shù)據(jù)

N = 12
X = np.random.rand(N,1)
Y = np.sin(12*X) + 0.66*np.cos(25*X) + np.random.randn(N,1)*0.1 + 3
plt.plot(X, Y, 'kx', mew=2)

構(gòu)建模型

k = gpflow.kernels.Matern52(1, lengthscales=0.3)
m = gpflow.models.GPR(X, Y, kern=k)
m.likelihood.variance = 0.01

k = gpflow.kernels.Matern52(1, lengthscales=0.3)
meanf = gpflow.mean_functions.Linear(1.0, 0.0)
m = gpflow.models.GPR(X, Y, k, meanf)
m.likelihood.variance = 0.01

優(yōu)化模型

gpflow.train.ScipyOptimizer().minimize(m)
plot(m)
m.as_pandas_table()

在新的點(diǎn)上預(yù)測函數(shù)值

xx = np.linspace(-0.1, 1.1, 100).reshape(100, 1)
mean, var = m.predict_y(xx)

源代碼解讀

在執(zhí)行gpflow.train.ScipyOptimizer().minimize(m)時(shí)發(fā)生了什么?

首先模型初始化、計(jì)算目標(biāo)函數(shù)。GPR._build_likelihood()計(jì)算的是gaussian log marginal likelihood,所以GPR的目標(biāo)函數(shù)實(shí)際上是對(duì)數(shù)邊際似然+對(duì)數(shù)參數(shù)先驗(yàn),見下面代碼:

  def build_objective(self):
        likelihood = self._build_likelihood()
        priors = []
        for param in self.parameters:
            unconstrained = param.unconstrained_tensor
            constrained = param._build_constrained(unconstrained)
            priors.append(param._build_prior(unconstrained, constrained))
        prior = self._build_prior(priors)
        return self._build_objective(likelihood, prior)

    def _build_objective(self, likelihood_tensor, prior_tensor):
        func = tf.add(likelihood_tensor, prior_tensor, name='nonneg_objective')
        return tf.negative(func, name='objective')  # 最小化的是負(fù)對(duì)數(shù)似然函數(shù)

其次構(gòu)建tensorflow計(jì)算圖,然后再利用L-BFGS-B優(yōu)化目標(biāo)函數(shù)。

在執(zhí)行m.predict_y(xx)時(shí)發(fā)生了什么?

調(diào)用GPR._build_predict(),根據(jù)GPML Regression一章的Algorithm2.1計(jì)算預(yù)測函數(shù)值。

例子2

例子1利用最大化\theta的似然函數(shù)(也就是f的邊際似然函數(shù))來求得\theta,然后通過解析解得到預(yù)測函數(shù)值。我們也可以用MCMC方法來預(yù)測函數(shù)值。這里我們要求的是p(\theta | \bm{X}, \bm{y}),也可以寫成p(f_\ast | \bm{x}_\ast, \bm{X}, \bm{y}) = \int p(f_\ast | \bm{x}_\ast, \bm{X}, \bm{y}, \theta) p(\theta) ~d\theta。我們用HMC從先驗(yàn)p(\theta)采樣N個(gè)點(diǎn),然后用\sum_i^N p(\bm{y} | \bm{X}, \theta) * p(\theta_i)來近似。

代碼

設(shè)置超參數(shù)的先驗(yàn)

m.clear()
m.kern.lengthscales.prior = gpflow.priors.Gamma(1., 1.)
m.kern.variance.prior = gpflow.priors.Gamma(1., 1.)
m.likelihood.variance.prior = gpflow.priors.Gamma(1., 1.)
m.mean_function.A.prior = gpflow.priors.Gaussian(0., 10.)
m.mean_function.b.prior = gpflow.priors.Gaussian(0., 10.)
m.compile()
m.as_pandas_table()

采樣

sampler = gpflow.train.HMC()
samples = sampler.sample(m, num_samples=500, epsilon=0.05, lmin=10, lmax=20, logprobs=False)

求平均

#plot the function posterior
xx = np.linspace(-0.1, 1.1, 100)[:,None]
plt.figure(figsize=(12, 6))
for i, s in samples.iloc[::20].iterrows():
    f = m.predict_f_samples(xx, 1, initialize=False, feed_dict=m.sample_feed_dict(s))
    plt.plot(xx, f[0,:,:], 'C0', lw=2, alpha=0.1)
    
plt.plot(X, Y, 'kx', mew=2)
_ = plt.xlim(xx.min(), xx.max())
_ = plt.ylim(0, 6)

至此,GPflow中的GPR就講完了。

參考文獻(xiàn)

[1] GPflow-master/doc/source/notebooks/regression.py
[2] Rasmussen, Carl Edward. "Gaussian processes in machine learning." Advanced lectures on machine learning. Springer, Berlin, Heidelberg, 2004. 63-71.

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容