从包含新操作的python中创建的pb图在c ++中创建图
Posted
技术标签:
【中文标题】从包含新操作的python中创建的pb图在c ++中创建图【英文标题】:create graph in c++ from pb graph created in python containing new op 【发布时间】:2018-07-18 02:52:31 【问题描述】:如何将我的 libtensorflow_cc.so 库与我的自定义操作链接,以便我可以在 c++ 中进行培训?我的自定义操作是用 c++ 编写的,使用它的图形是在 python 中计算的。我可以加载 pb 图表,但我无法创建图表。
我在 python 中创建了一个图形并使用 write_graph 保存为一个 protobuf 文件。我的图表使用了一个自定义操作,其内核用 C++ 编写并注册为https://www.tensorflow.org/versions/master/extend/adding_an_op#compile_the_op_using_your_system_compiler_tensorflow_binary_installation。我想在 C++ 中加载我的图表进行训练,图表在没有警告的情况下加载,但是对于“session->Create(graph_def)”我得到一个错误:
Non-OK-status: session->Create(graph_def) status: Not found:
Op type not registered 'MyOp' in binary running on user-linux.
Make sure the Op and Kernel are registered in the binary running in this process.
Note that if you are loading a saved graph which used ops from tf.contrib,
accessing (e.g.) `tf.contrib.resampler` should be done before importing the graph,
as contrib ops are lazily registered when the module is first accessed.
我没有使用来自 tf.contrib 的任何东西。这是我的 c++ 代码的一个更简单的版本:
std::string graph_definition = "Mygraph.pb";
Session* session;
GraphDef graph_def;
SessionOptions opts;
//load graph
TF_CHECK_OK(ReadBinaryProto(Env::Default(), graph_definition, &graph_def));
// create a new session
TF_CHECK_OK(NewSession(opts, &session));
// Load graph into session
TF_CHECK_OK(session->Create(graph_def));
【问题讨论】:
【参考方案1】:您似乎需要使用在c/c_api.h
中定义的TF_LoadLibrary
加载您的库。在c/c_api_test.cc
中,您有一个如何工作的示例:
// Load the library.
TF_Status* status = TF_NewStatus();
TF_Library* lib =
TF_LoadLibrary("tensorflow/c/test_op.so", status);
TF_Code code = TF_GetCode(status);
string status_msg(TF_Message(status));
TF_DeleteStatus(status);
ASSERT_EQ(TF_OK, code) << status_msg;
该函数加载库并注册它在 TensorFlow 运行时中定义的操作和内核。
编辑:
好吧,从技术上讲,加载库的重要函数是tensorflow::LoadLibrary
,在core/framework/load_library.cc
中定义。然而,这个函数 1) 似乎没有在任何头文件中公开声明(实际上,c/c_api.cc
包含这个函数的声明供内部使用) 2) 具有相当模糊的参数。据我所知,C API 似乎是目前在 C++ 程序中加载库的更简单方法,即使您必须注意适当地销毁对象(即调用 TF_DeleteLibraryHandle
)。顺便说一句,似乎也没有办法卸载库;您可以销毁库句柄对象,但这不会卸载库。
【讨论】:
我通过在 c+ 代码中包含 my_op.cc 头文件解决了我的问题。警告正在寻找 REGISTER_OP(my_op) 标签。我认为@jdehesa 提出的方法是在 C++ 中构建图形所必需的,但如果我只想运行以前在 python 中计算的图形,不是吗? @Ceveloper 这很有趣,我认为库加载函数执行的注册在任何情况下都是必要的,但如果只是在声明中包含标头,那肯定要简单得多。以上是关于从包含新操作的python中创建的pb图在c ++中创建图的主要内容,如果未能解决你的问题,请参考以下文章