【问题标题】:Protobuf version mismatch in GPflow/TensorFlow optimization when used together with MATLAB engine for Python与适用于 Python 的 MATLAB 引擎一起使用时,GPflow/TensorFlow 优化中的 Protobuf 版本不匹配
【发布时间】:2020-06-07 21:27:20
【问题描述】:

我有一些用 MATLAB 编写的仿真代码,我必须使用 GPflowOpt 对其进行贝叶斯优化。我使用MATLAB Engine for Python 来检索 MATLAB 目标函数的结果并将它们传递给我的 Python 优化代码。我根据说明安装了 GPflowOpt (here) 和 MATLAB 引擎 (here),并且来自 GPflowOpt 文档的this example code 的精简版(见下文)按预期工作。

import gpflow
import gpflowopt
import matlab.engine
import numpy as np

def vlmop2(x):
    transl = 1 / np.sqrt(2)
    part1 = (x[:, [0]] - transl) ** 2 + (x[:, [1]] - transl) ** 2
    part2 = (x[:, [0]] + transl) ** 2 + (x[:, [1]] + transl) ** 2
    y1 = 1 - np.exp(-1 * part1)
    y2 = 1 - np.exp(-1 * part2)
    return np.hstack((y1, y2))

if __name__ == '__main__':
#    engine = matlab.engine.start_matlab()
#    print('Working dir: ', engine.pwd())

    domain = gpflowopt.domain.ContinuousParameter('x1', -2, 2) + \
             gpflowopt.domain.ContinuousParameter('x2', -2, 2)

    design = gpflowopt.design.LatinHyperCube(11, domain)
    X = design.generate()
    Y = vlmop2(X)

    # One model for each objective
    objective_models = [gpflow.gpr.GPR(X.copy(), Y[:,[i]].copy(), gpflow.kernels.Matern52(2, ARD=True)) for i in range(Y.shape[1])]
    for model in objective_models:
        model.likelihood.variance = 0.01

    hvpoi = gpflowopt.acquisition.HVProbabilityOfImprovement(objective_models)

    # First setup the optimization strategy for the acquisition function
    # Combining MC step followed by L-BFGS-B
    acquisition_opt = gpflowopt.optim.StagedOptimizer([gpflowopt.optim.MCOptimizer(domain, 1000),
                                                       gpflowopt.optim.SciPyOptimizer(domain)])

    # Then run the BayesianOptimizer for 20 iterations
    optimizer = gpflowopt.BayesianOptimizer(domain, hvpoi, optimizer=acquisition_opt, verbose=True)
    result = optimizer.optimize([vlmop2], n_iter=5)

    print(result)
    print(optimizer.acquisition.pareto.front.value)

但只要我在代码中的某处仅对 MATLAB 引擎进行一次调用(只需取消注释我上面的 sn-p 中的两行),就会立即执行中断

result = optimizer.optimize([vlmop2], n_iter=5)

我遇到了一些奇怪的错误,抱怨一些 Protobuf 版本号不匹配:

[libprotobuf FATAL /tmp/B3p3/glnxa64/protobuf3/src/google/protobuf/stubs/common.cc:68] This program requires version 3.8.0 of the Protocol Buffer runtime library, but the installed version is 3.6.1.  Please update your library.  If you compiled the program yourself, make sure that your headers are from the same version of Protocol Buffers as your link-time library.  (Version verification failed in "external/com_google_protobuf/src/google/protobuf/any.pb.cc".)
terminate called after throwing an instance of 'google::protobuf::FatalException'

我阅读了一些关于 Protobuf 是什么、它的作用以及它显然是 TensorFlow 的一部分的信息,但我不知道为什么我可能会在这里遇到一些版本不匹配的问题。我在 virtualenv 中安装了所有东西,并在不同版本中来回重新安装了 tensorflowprotobuf 包,但无济于事。这是当前安装的相关包的摘录:

Package               Version
--------------------- ----------
gpflow                0.5
gpflowopt             0.1.1
matlabengineforpython R2019b
numpy                 1.18.5
protobuf              3.12.2
tensorflow            1.15.3
tensorflow-estimator  1.15.1

很奇怪,我什至不知道为什么错误消息指出我安装了 Protobuf 版本 3.6.1,尽管 protobuf 包显然是更高版本,我不知道这个 3.6.1 版本可以隐藏在我的哪里系统。更有趣的是,只要不涉及 MATLAB 引擎,代码就可以像魅力一样工作。但是只要我对engine.eval(…) 打了一个电话,它就结束了,代码就向南了。有趣的是,只要我只是初始化引擎并且不与它交换任何数据,代码仍然可以工作

我之前已经在另一个使用 scikit-opt 的优化任务中使用了 MATLAB 引擎,我基本上做了同样的事情(从 MATLAB 脚本中获取函数结果并在 Python 中处理它)并且它完美地工作。但不知何故,它拒绝与 TensorFlow 共存,我不知道去哪里找。

如果需要,我很乐意提供更多信息,也许有人在 TensorFlow+Protobuf+MATLAB 方面有经验并且知道它的全部内容。

【问题讨论】:

  • 您能找到任何解决方案吗?在尝试在模拟软件中使用 Tensorflow 时,我也面临同样的 protobuf 版本问题。
  • 确实,当时我找到了一些解决该特定问题的方法。它基本上归结为在首先通过 GPflowOpt 执行一些虚拟优化之前不初始化 MATLAB 引擎。由于 MATLAB 带有它自己的 protobuf 库的预编译版本,因此首先初始化引擎总是会导致加载 MATLAB 附带的 protobuf 库,在我的情况下,它比 Tensorflow 所需的还要旧。切换顺序(首先运行一些任意优化,然后初始化 Tensorflow 并在之后初始化引擎)对我有用。
  • 诚然,这是一个便宜的解决方案,但由于我的论文需要这个并且时间紧迫,我没有时间调查 Tensorflow 库的哪个部分负责加载 protobuf图书馆。我敢打赌,如果您深入研究代码,您会找到执行此操作的特定代码部分。如果你幸运的话,你甚至可以调用那个特定的函数,然后你就完成了 - 不会因为一些虚拟优化而争吵。

标签: python matlab tensorflow protocol-buffers


【解决方案1】:

不幸的是,我忘记了自己的问题,但显然我不是唯一一个有此问题的人,我将在此处发布 我的个人解决方案:

基本上,这一切都归结为首先执行一些任意代码来增强 Tensorflow,进而在与 MATLAB 引擎交换数据之前加载 protobuf 库(可能用于一些内部数据交换)。

Python 世界和 MATLAB 之间的数据交换似乎是通过 protobuf 消息完成的。因此,如果您首先执行一些内部需要 protobuf 库的虚拟 Tensorflow 代码,它会愉快地加载您在本地环境中安装的代码,一切都很好。如果您首先与 MATLAB 引擎交换一些数据(就像我在上面评论部分中所做的那样调用 engine.pwd()),引擎将首先加载您的 MATLAB 安装中内置的 protobuf 库,并且很可能较旧且与您的 Tensorflow 安装附带的不兼容。

所以我最后所做的只是对一些枯燥的函数(如 x^2)执行虚拟优化,例如 3 次迭代,以确保在初始化 MATLAB 引擎并与之交互之前执行 Tensorflow 的所有部分.

也许有一种更简单的方法可以通过 Tensorflow 强制加载正确的 protobuf 版本,但我没有时间也没有意愿深入挖掘。老实说,当时我第一次偶然发现了 protobuf,并不完全知道它的用途和使用方法。现在,我可能只是查看 Python 的 protobuf 库,看看是否有某种 initload 函数可以完成这项工作。

我希望这个描述对阅读它并遇到相同问题的每个人都有帮助。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-08-09
    • 2022-10-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-06-17
    相关资源
    最近更新 更多