当与 Python 的 MATLAB 引擎一起使用时,GPflow/TensorFlow 优化中的 Protobuf 版本不匹配
Protobuf version mismatch in GPflow/TensorFlow optimization when used together with MATLAB engine for Python
我有一些用 MATLAB 编写的模拟代码,我必须 运行 使用 GPflowOpt 对其进行贝叶斯优化。我使用 GPflowOpt 文档中的 MATLAB Engine for Python to retrieve the results of the MATLAB objective function and pass them to my Python optimization code. I installed GPflowOpt (here) and the MATLAB Engine (here) according to the instructions and my stripped down version (see below) of 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 引擎进行一次调用(只需取消注释上面代码段中的两行),执行就会中断
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 中安装了所有东西,并在不同版本中来回多次重新安装 tensorflow 和 protobuf 包,但无济于事。这是当前安装的相关包的摘录:
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 的经验并且知道它的全部内容。
不幸的是,我忘记了我自己的问题,但显然我不是唯一一个提出这个问题的人,我将 post 我的个人解决方案在这里:
基本上,这一切都归结为在与 MATLAB 引擎交换数据之前,先执行一些任意代码,这些代码可以增强 Tensorflow,进而加载 protobuf 库(大概是为了进行一些内部数据交换)。
Python 世界和 MATLAB 之间的数据交换似乎是通过 protobuf 消息完成的。因此,如果您首先执行一些内部需要 protobuf 库的虚拟 Tensorflow 代码,它会愉快地加载您在本地环境中安装的代码,一切都很好。如果您先与 MATLAB 引擎交换一些数据(就像我在上面评论部分中所做的那样调用 engine.pwd()
),引擎将首先加载您的 MATLAB 安装中内置的 protobuf 库,然后那个将很可能是旧的并且与您的 Tensorflow 安装附带的不兼容。
所以我最后所做的就是对一些乏味的函数(例如 x^2
进行 3 次迭代)进行虚拟优化,以确保在初始化 MATLAB 引擎之前执行了 Tensorflow 的所有部分并与之互动。
也许有一种更简单的方法可以通过 Tensorflow 强制加载正确的 protobuf 版本,但我没有时间也不愿意深入研究。老实说,那时候我是第一次偶然发现 protobuf,并不知道它的用途和使用方法。现在,我可能只是查看 Python 的 protobuf 库,看看是否有某种 init
或 load
函数可以完成这项工作。
希望本文的描述对所有阅读本文并遇到相同问题的人有所帮助。
我有一些用 MATLAB 编写的模拟代码,我必须 运行 使用 GPflowOpt 对其进行贝叶斯优化。我使用 GPflowOpt 文档中的 MATLAB Engine for Python to retrieve the results of the MATLAB objective function and pass them to my Python optimization code. I installed GPflowOpt (here) and the MATLAB Engine (here) according to the instructions and my stripped down version (see below) of 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 引擎进行一次调用(只需取消注释上面代码段中的两行),执行就会中断
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 中安装了所有东西,并在不同版本中来回多次重新安装 tensorflow 和 protobuf 包,但无济于事。这是当前安装的相关包的摘录:
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 的经验并且知道它的全部内容。
不幸的是,我忘记了我自己的问题,但显然我不是唯一一个提出这个问题的人,我将 post 我的个人解决方案在这里:
基本上,这一切都归结为在与 MATLAB 引擎交换数据之前,先执行一些任意代码,这些代码可以增强 Tensorflow,进而加载 protobuf 库(大概是为了进行一些内部数据交换)。
Python 世界和 MATLAB 之间的数据交换似乎是通过 protobuf 消息完成的。因此,如果您首先执行一些内部需要 protobuf 库的虚拟 Tensorflow 代码,它会愉快地加载您在本地环境中安装的代码,一切都很好。如果您先与 MATLAB 引擎交换一些数据(就像我在上面评论部分中所做的那样调用 engine.pwd()
),引擎将首先加载您的 MATLAB 安装中内置的 protobuf 库,然后那个将很可能是旧的并且与您的 Tensorflow 安装附带的不兼容。
所以我最后所做的就是对一些乏味的函数(例如 x^2
进行 3 次迭代)进行虚拟优化,以确保在初始化 MATLAB 引擎之前执行了 Tensorflow 的所有部分并与之互动。
也许有一种更简单的方法可以通过 Tensorflow 强制加载正确的 protobuf 版本,但我没有时间也不愿意深入研究。老实说,那时候我是第一次偶然发现 protobuf,并不知道它的用途和使用方法。现在,我可能只是查看 Python 的 protobuf 库,看看是否有某种 init
或 load
函数可以完成这项工作。
希望本文的描述对所有阅读本文并遇到相同问题的人有所帮助。