-1

当我尝试构建分层 GL-LVM 模型时,我遇到了一个奇怪的“ValueError:mean must be 1 dimensional”。基本上我正在尝试复制这篇论文:Hierarchical Gaussian Process Latent Variable Models using GPflow。

因此我实现了我自己的新模型如下:

class myGPLVM(gpflow.models.BayesianModel):
    def __init__(self, data, latent_data, x_data_mean, kernel):
        super().__init__()
        print("GPLVM")
        self.kernel0 = kernel[0]
        self.kernel1 = kernel[1]
        self.mean_function = Zero()
        self.likelihood0 = gpflow.likelihoods.Gaussian(1.0)
        self.likelihood1 = gpflow.likelihoods.Gaussian(1.0)
        # make some parameters
        self.data = (gpflow.Parameter(x_data_mean), gpflow.Parameter(latent_data), data)

    def hierarchy_ll(self):
        x, h, y = self.data
        K = self.kernel0(x)
        num_data = x.shape[0]
        k_diag = tf.linalg.diag_part(K)
        s_diag = tf.fill([num_data], self.likelihood0.variance)
        ks = tf.linalg.set_diag(K, k_diag + s_diag)
        L = tf.linalg.cholesky(ks)
        m = self.mean_function(x)

        return multivariate_normal(h, m, L)

    def log_likelihood(self):
        """
        Computes the log likelihood.

        .. math::
            \log p(Y | \theta).

        """
        x, h, y = self.data
        K = self.kernel1(h)
        num_data = h.shape[0]
        k_diag = tf.linalg.diag_part(K)
        s_diag = tf.fill([num_data], self.likelihood1.variance)
        ks = tf.linalg.set_diag(K, k_diag + s_diag)
        L = tf.linalg.cholesky(ks)
        m = self.mean_function(h)

        # [R,] log-likelihoods for each independent dimension of Y
        log_prob = multivariate_normal(y, m, L).  # <- trows the error!
        log_prob_h = self.hierarchy_ll()
        log_likelihood = tf.reduce_sum(log_prob) + tf.reduce_sum(log_prob_h)
        return log_likelihood

该模型似乎适用于玩具示例:

    from sklearn.datasets.samples_generator import make_blobs
    X, y = make_blobs(n_samples=40, centers=3, n_features=12, random_state=2)
    Y = tf.convert_to_tensor(X, dtype=default_float())

但是当我尝试使用 bvh 文件(实际上是论文中的文件)时,失败并让我犯了错误。我还使用 Lawrence 的代码从mocap中读取了我的 bvh,我对其进行了修改以适应 python3

无论如何,已经几天了,我没有想法。我尝试了多种方法来强制我的平均数组“m”是一维的,但没有任何效果。我还尝试了第一篇 GPLVM 论文中的“three_phase_oil_flow”数据集,它也同样有效。

因此,我会假设我的模型是正确的,或者至少我进行了一些优化,并且认为可能是 bvh 读者可能是原因。但是数据对我来说似乎一切都很好......特别是我不明白为什么在强制使用多元函数时:

m = np.zeros((np.shape(m)[0], 1))
log_prob = multivariate_normal(y, m, L)

甚至使用 gpflow Zero 功能

m = Zero(h)
log_prob = multivariate_normal(y, m, L)

它仍然给我带来了错误。任何帮助将不胜感激。

编辑感谢:Artem Artemev 如果有人想尝试重现其余代码: https ://github.com/michaelStettler/h-GPLVM

错误流:

(venv) MacBookMichael2:stackOverflow michaelstettler$ python3 HGPLVM.py 
(199, 96)
shape Y (199, 3, 38)
2020-01-26 17:00:48.104029: I tensorflow/core/platform/cpu_feature_guard.cc:142] Your CPU supports instructions that this TensorFlow binary was not compiled to use: AVX2 FMA
2020-01-26 17:00:48.113609: I tensorflow/compiler/xla/service/service.cc:168] XLA service 0x7f8dd5ff5410 executing computations on platform Host. Devices:
2020-01-26 17:00:48.113627: I tensorflow/compiler/xla/service/service.cc:175]   StreamExecutor device (0): Host, Default Version
shape Y (199, 38)
Number of points: 199 and Number of dimensions: 38
shape x_mean_latent (199, 8)
shape x_mean_init (199, 2)
HGPLVM
gpr_data (199, 2) (199, 8) (199, 38)
2020-01-26 17:00:48.139003: W tensorflow/python/util/util.cc:299] Sets are not currently considered sequences, but this may change in the future, so consider avoiding using them.
shape m (199, 1)
Traceback (most recent call last):
  File "HGPLVM.py", line 131, in <module>
    _ = opt.minimize(closure, method="bfgs", variables=model.trainable_variables, options=dict(maxiter=maxiter))
  File "/Users/michaelstettler/PycharmProjects/GPflow/venv/lib/python3.6/site-packages/gpflow/optimizers/scipy.py", line 60, in minimize
    **scipy_kwargs)
  File "/Users/michaelstettler/PycharmProjects/GPflow/venv/lib/python3.6/site-packages/scipy/optimize/_minimize.py", line 594, in minimize
    return _minimize_bfgs(fun, x0, args, jac, callback, **options)
  File "/Users/michaelstettler/PycharmProjects/GPflow/venv/lib/python3.6/site-packages/scipy/optimize/optimize.py", line 998, in _minimize_bfgs
    gfk = myfprime(x0)
  File "/Users/michaelstettler/PycharmProjects/GPflow/venv/lib/python3.6/site-packages/scipy/optimize/optimize.py", line 327, in function_wrapper
    return function(*(wrapper_args + args))
  File "/Users/michaelstettler/PycharmProjects/GPflow/venv/lib/python3.6/site-packages/scipy/optimize/optimize.py", line 73, in derivative
    self(x, *args)
  File "/Users/michaelstettler/PycharmProjects/GPflow/venv/lib/python3.6/site-packages/scipy/optimize/optimize.py", line 65, in __call__
    fg = self.fun(x, *args)
  File "/Users/michaelstettler/PycharmProjects/GPflow/venv/lib/python3.6/site-packages/gpflow/optimizers/scipy.py", line 72, in _eval
    loss, grads = _compute_loss_and_gradients(closure, variables)
  File "/Users/michaelstettler/PycharmProjects/GPflow/venv/lib/python3.6/site-packages/gpflow/optimizers/scipy.py", line 116, in _compute_loss_and_gradients
    loss = loss_cb()
  File "HGPLVM.py", line 127, in closure
    return - model.log_marginal_likelihood()
  File "/Users/michaelstettler/PycharmProjects/GPflow/venv/lib/python3.6/site-packages/gpflow/models/model.py", line 45, in log_marginal_likelihood
    return self.log_likelihood(*args, **kwargs) + self.log_prior()
  File "HGPLVM.py", line 62, in log_likelihood
    log_prob = multivariate_normal(y, m, L)
  File "mtrand.pyx", line 3729, in numpy.random.mtrand.RandomState.multivariate_normal
ValueError: mean must be 1 dimensional
4

1 回答 1

1

我建议发布一个有效的 MWE 代码。我曾尝试使用您的代码片段,但它给了我错误。

我没有multivariate_normal功能问题。如果您已正确本地化问题,您可以更彻底地调试 TF2.0 并找到导致该异常的位置。这是我正在运行的代码:

In [2]: from sklearn.datasets.samples_generator import make_blobs
   ...: X, y = make_blobs(n_samples=40, centers=3, n_features=12, random_state=2)
In [10]: m = np.zeros((np.shape(y)[0], 1))
In [11]: m.shape
Out[11]: (40, 1)
In [12]: y.shape
Out[12]: (40,)
In [13]: L = np.eye(m.shape[0])
In [15]: gpflow.logdensities.multivariate_normal(y, m, L)
Out[15]:
<tf.Tensor: shape=(40,), dtype=float64, numpy=
array([ -56.75754133,  ...])>
于 2020-01-20T14:47:27.517 回答