【问题标题】:GPflow - GP classification with 1-dim Linear kernel fits poorly for 2 dimension dataGPflow - 具有 1 维线性内核的 GP 分类不适合二维数据
【发布时间】:2022-02-28 16:54:55
【问题描述】:

在#1435 问题之后,我还有一个关于如何使用 GPflow 的问题。

我在另一个内核中复制了这个问题:https://github.com/avalonhse/BayesNotebook/blob/master/Issue_2_GPFlow_Linear_Classification.ipynb

我的目的是将加性内核拟合到二维数据(维度 1 中的平方指数和维度 2 中的线性内核)。按照#1435的指导,我已经成功地用内核gpflow.kernels.Linear(variance= 0.1)拟合了模型。

Linear kernel

但是,当我按照我最初的计划使用内核 gpflow.kernels.Linear(active_dims=1,variance= 0.01) 时,模型不适合。我使用具有相同内核的 GPy 作为参考,结果看起来很合理。

1-dim GPFlow kernel

import numpy as np
X = np.array([[ 9.96578428, 60.],[ 9.96578428, 40.],[ 9.96578428, 20.],
       [10.96578428, 30.],[11.96578428, 40.],[12.96578428, 50.],
       [12.96578428, 70.],[8.96578428, 30. ],[ 7.96578428, 40.],
       [ 6.96578428, 50.],[ 6.96578428, 30.],[ 6.96578428, 10.],
       [11.4655664 , 71.],[ 8.56605404, 63.],[12.41574177, 69.],
       [10.61562964, 48.],[ 7.61470984, 51.],[ 9.31514956, 45.]])
Y = np.array([[1., 1., 0., 0., 0., 0., 0., 0., 0., 1., 1., 0., 1., 1., 0., 0., 1., 0.]]).T

# plotting
import matplotlib.pyplot as plt
import matplotlib
%matplotlib inline
def plot(X,Y):
    mask = Y[:, 0] == 1

    plt.figure(figsize=(6, 6))
    plt.plot(X[mask, 0], X[mask, 1], "oC0", mew=0, alpha=0.5)

    plt.ylim(-10, 100)
    plt.xlim(5, 15)

    _ = plt.plot(X[np.logical_not(mask), 0], X[np.logical_not(mask), 1], "oC1", mew=0, alpha=0.5)

plot(X,Y)

# Evaluate real function and the predicted probability
res = 500
xx, yy = np.meshgrid(np.linspace(5, 15, res),
                     np.linspace(- 10, 120, res))
Xplot =  np.vstack((xx.flatten(), yy.flatten())).T

# Code followed the Notebook : https://gpflow.readthedocs.io/en/develop/notebooks/basics/classification.html

import tensorflow as tf
import tensorflow_probability as tfp
import gpflow
from gpflow.utilities import print_summary, set_trainable, to_default_float
gpflow.config.set_default_summary_fmt("notebook")

def testGPFlow(k):
    m = gpflow.models.VGP(
        (X, Y), 
        kernel= k,
        likelihood=gpflow.likelihoods.Bernoulli()
    )
    print("\n ########### Model before optimzation ########### \n")
    print_summary(m)

    print("\n ########### Model after optimzation ########### \n")
    opt = gpflow.optimizers.Scipy()
    res = opt.minimize(
        m.training_loss, variables=m.trainable_variables, options=dict(maxiter=2500), method="L-BFGS-B"
    )        

    print(' Message: ' + str(res.message) + '\n Status = ' + str(res.status) + '\n Number of iterations = ' + str(res.nit))
    print_summary(m)

    means, _ = m.predict_y(Xplot)  # here we only care about the mean
    y_prob = means.numpy().reshape(*xx.shape)

    print("Fitting model using GPFlow")
    plot(X,Y)

    _ = plt.contour(
        xx,
        yy,
        y_prob,
        [0.5],  # plot the p=0.5 contour line only
        colors="k",
        linewidths=1.8,
        zorder=100,
    )
k = gpflow.kernels.Linear(active_dims=[1],variance= 0.01)
testGPFlow(k)

k = gpflow.kernels.Linear(variance= 1)
testGPFlow(k)

GPy 代码仅供参考,用于建议拟合模型应该如何。我知道 GPy 和 GPflow 使用不同的方法。我的问题是为什么当我在一维中指定线性内核时 GPflow 模型不适合。

【问题讨论】:

    标签: gpflow gpy


    【解决方案1】:

    感谢 Hoang 发布这个问题并使用 GPflow。

    当您在 Gpy 中指定 input_dim 时,您是在告诉算法对二维进行操作。 GPflow 中的Active_dims 表现不同。它指定您希望内核作用于哪些维度。 'active_dims = 1' 告诉 GPflow 仅将线性内核应用于 y 维度。

    由于您希望您的内核同时作用于x 和y 维度,您应该指定active_dims = [0,1] 而不仅仅是'active_dims = 1'。当我使用此修复程序运行您的代码时,我得到的结果与 GPy 的结果相同:

    【讨论】:

    • 如果这解决了您的问题,@Hoang Le,请将其标记为已接受的答案。谢谢。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-08-31
    • 2019-06-09
    • 1970-01-01
    • 1970-01-01
    • 2016-04-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多