从包含新操作的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 ++中创建图的主要内容,如果未能解决你的问题,请参考以下文章

在当前目录中创建的新文件夹

如何收听我在 Python 中创建的音频?

我可以从 Python 触发在 KV 文件中创建的屏幕吗?

CSS3 过渡以突出显示在 JQuery 中创建的新元素

使用 Maven 从 Bamboo 发布时在 SVN 标记中创建的多余主干子文件夹

从 vuejs 组件中创建的钩子调用方法