使用GPFlow中的自定义内核进行分类时的Cholesky分解问题

时间:2019-09-03 03:32:56

标签: python gpflow

我在GPFlow中构造了一个自定义的Matern32内核,以对包含两个数据点之间的“距离”的一些昂贵的矩阵值进行运算:

import numpy as np
import tensorflow as tf
import gpflow

dat_mat = np.load('example_matrix.npy')

dat_diag = tf.constant(np.diag(dat_mat),dtype=tf.float64)
dat_mat = tf.constant(dat_mat,dtype=tf.float64)

def sub_mat(A,A2):
        global dat_mat
        A = tf.cast(A,tf.int32)
        A2 = tf.cast(A2,tf.int32)
        K_rows = tf.gather_nd(dat_mat, A)
        K_rows = tf.transpose(K_rows)
        K_mat = tf.gather_nd(K_rows, A2)
        K_mat = tf.transpose(K_mat)
        return tf.cast(K_mat, tf.float64)

class Matern32_RBF(gpflow.kernels.Kernel):
        global dat_mat, dat_diag
        def __init__(self):
                super().__init__(input_dim=1, active_dims=[0])
                self.var = gpflow.Param(1.0, transform=gpflow.transforms.Exp())
                self.mag = gpflow.Param(1.0, transform=gpflow.transforms.Exp())

        @gpflow.params_as_tensors
        def K(self, A, A2=None):
                if A2 is None:
                        A2=A
                K_mat = sub_mat(A,A2)
                z = np.sqrt(3)*K_mat*self.var
                return self.mag*(1+z)*tf.math.exp(-z)
        def Kdiag(self, A):
                A=tf.cast(A,tf.int32)
                K_diag = tf.cast(tf.gather_nd(dat_diag, A),tf.float64)
                z = np.sqrt(3)*K_diag*self.var
                return self.mag*(1+z)*tf.math.exp(-z)

此自定义内核是为执行二进制分类任务(附加示例数据文件)而实现的:

Y=np.loadtxt('example_data.csv', usecols=1)
len_dataset = len(Y)

#These x-values only refer to the rows of my computed distance matrix 
X=np.array(range(len_dataset))
X=X.astype(int)

X=X.reshape(-1,1)
Y=Y.reshape(-1,1)

k = Matern32_RBF()

#Data_set split
from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(X, Y, random_state=1)

custom_config = gpflow.settings.get_settings()
custom_config.numerics.jitter_level = 1e-3

opt = gpflow.train.ScipyOptimizer()
model = gpflow.models.VGP(X_train, y_train, likelihood=gpflow.likelihoods.Bernoulli(), kern=k)

with gpflow.settings.temp_settings(custom_config):
        opt.minimize(model)

运行以上命令会返回以下错误:

Traceback (most recent call last):
File "/home/wjm41/.conda/envs/gpenv/lib/python3.6/site-packages/tensorflow/python/client/session.py", line 1334, in _do_call
return fn(*args)
File "/home/wjm41/.conda/envs/gpenv/lib/python3.6/site-packages/tensorflow/python/client/session.py", line 1319, in _run_fn
options, feed_dict, fetch_list, target_list, run_metadata)
File "/home/wjm41/.conda/envs/gpenv/lib/python3.6/site-packages/tensorflow/python/client/session.py", line 1407, in _call_tf_sessionrun
run_metadata)
tensorflow.python.framework.errors_impl.InvalidArgumentError: Cholesky decomposition was not successful. The input might not be valid.
[[{{node VGP-cb46397c-6/Cholesky}}]]

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
File "trial.py", line 64, in
opt.minimize(model)
File "/home/wjm41/.conda/envs/gpenv/lib/python3.6/site-packages/gpflow/training/scipy_optimizer.py", line 89, in minimize
**kwargs)
File "/home/wjm41/.conda/envs/gpenv/lib/python3.6/site-packages/gpflow/training/external_optimizer.py", line 175, in minimize
optimizer_kwargs=self.optimizer_kwargs)
File "/home/wjm41/.conda/envs/gpenv/lib/python3.6/site-packages/gpflow/training/external_optimizer.py", line 436, in _minimize
result = scipy.optimize.minimize(*minimize_args, **minimize_kwargs)
File "/home/wjm41/.conda/envs/gpenv/lib/python3.6/site-packages/scipy/optimize/_minimize.py", line 601, in minimize
callback=callback, **options)
File "/home/wjm41/.conda/envs/gpenv/lib/python3.6/site-packages/scipy/optimize/lbfgsb.py", line 335, in _minimize_lbfgsb
f, g = func_and_grad(x)
File "/home/wjm41/.conda/envs/gpenv/lib/python3.6/site-packages/scipy/optimize/lbfgsb.py", line 285, in func_and_grad
f = fun(x, args)
File "/home/wjm41/.conda/envs/gpenv/lib/python3.6/site-packages/scipy/optimize/optimize.py", line 300, in function_wrapper
return function((wrapper_args + args))
File "/home/wjm41/.conda/envs/gpenv/lib/python3.6/site-packages/scipy/optimize/optimize.py", line 63, in call
fg = self.fun(x, *args)
File "/home/wjm41/.conda/envs/gpenv/lib/python3.6/site-packages/gpflow/training/external_optimizer.py", line 398, in loss_grad_func_wrapper
loss, gradient = loss_grad_func(x)
File "/home/wjm41/.conda/envs/gpenv/lib/python3.6/site-packages/gpflow/training/external_optimizer.py", line 309, in eval_func
augmented_fetches, feed_dict=augmented_feed_dict)
File "/home/wjm41/.conda/envs/gpenv/lib/python3.6/site-packages/tensorflow/python/client/session.py", line 929, in run
run_metadata_ptr)
File "/home/wjm41/.conda/envs/gpenv/lib/python3.6/site-packages/tensorflow/python/client/session.py", line 1152, in _run
feed_dict_tensor, options, run_metadata)
File "/home/wjm41/.conda/envs/gpenv/lib/python3.6/site-packages/tensorflow/python/client/session.py", line 1328, in _do_run
run_metadata)
File "/home/wjm41/.conda/envs/gpenv/lib/python3.6/site-packages/tensorflow/python/client/session.py", line 1348, in _do_call
raise type(e)(node_def, op, message)
tensorflow.python.framework.errors_impl.InvalidArgumentError: Cholesky decomposition was not successful. The input might not be valid.
[[node VGP-cb46397c-6/Cholesky (defined at /home/wjm41/.conda/envs/gpenv/lib/python3.6/site-packages/gpflow/models/vgp.py:108) ]]

Caused by op 'VGP-cb46397c-6/Cholesky', defined at:
File "trial.py", line 61, in
model = gpflow.models.VGP(X_train, y_train, likelihood=gpflow.likelihoods.Bernoulli(), kern=k)
File "/home/wjm41/.conda/envs/gpenv/lib/python3.6/site-packages/gpflow/core/compilable.py", line 90, in init
self.build()
File "/home/wjm41/.conda/envs/gpenv/lib/python3.6/site-packages/gpflow/core/node.py", line 156, in build
self._build()
File "/home/wjm41/.conda/envs/gpenv/lib/python3.6/site-packages/gpflow/models/model.py", line 79, in _build
likelihood = self._build_likelihood()
File "/home/wjm41/.conda/envs/gpenv/lib/python3.6/site-packages/gpflow/decors.py", line 67, in tensor_mode_wrapper
result = method(obj, *args, **kwargs)
File "/home/wjm41/.conda/envs/gpenv/lib/python3.6/site-packages/gpflow/models/vgp.py", line 108, in _build_likelihood
L = tf.cholesky(K)
File "/home/wjm41/.conda/envs/gpenv/lib/python3.6/site-packages/tensorflow/python/ops/gen_linalg_ops.py", line 767, in cholesky
"Cholesky", input=input, name=name)
File "/home/wjm41/.conda/envs/gpenv/lib/python3.6/site-packages/tensorflow/python/framework/op_def_library.py", line 788, in _apply_op_helper
op_def=op_def)
File "/home/wjm41/.conda/envs/gpenv/lib/python3.6/site-packages/tensorflow/python/util/deprecation.py", line 507, in new_func
return func(*args, **kwargs)
File "/home/wjm41/.conda/envs/gpenv/lib/python3.6/site-packages/tensorflow/python/framework/ops.py", line 3300, in create_op
op_def=op_def)
File "/home/wjm41/.conda/envs/gpenv/lib/python3.6/site-packages/tensorflow/python/framework/ops.py", line 1801, in init
self._traceback = tf_stack.extract_stack()

InvalidArgumentError (see above for traceback): Cholesky decomposition was not successful. The input might not be valid.
[[node VGP-cb46397c-6/Cholesky (defined at /home/wjm41/.conda/envs/gpenv/lib/python3.6/site-packages/gpflow/models/vgp.py:108) ]]

我尝试过改变GPFlow设置中的抖动级别以及内核参数的初始值,但这并没有解决此Cholesky分解问题。我的自定义内核可以很好地用于回归任务,所以我不确定问题出在哪里。我的数据真的条件恶劣吗? (示例数据是完整数据集的一小部分-有关脚本和数据,请参见here。)

我正在使用Python 3.6,GPFlow 1.3.0和TensorFlow 1.13.1。任何帮助将不胜感激!

1 个答案:

答案 0 :(得分:0)

我无法立即看到您的代码有问题。我的建议是调试代码,以查看在Cholesky故障之前获得的K矩阵。

在TensorFlow中进行调试很麻烦。我认为[1]中的建议相当不错,就是在TensorFlow图的一个操作内打开一个IPython终端。

[1] https://wookayin.github.io/tensorflow-talk-debugging/#55向前滑动46。