win10下CMake编译tensorflow源码并用c++接口调用tensorflow模型超详细教程

10 篇文章 1 订阅
4 篇文章 0 订阅


最近在研究如何用C++ 调用基于python库训练的tensorflow模型,完成模型预测。具体步骤如下:

  • 在python中,用tensorflow的python库,训练模型,并生成pb文件;
  • 准备好tensorflow的c++库(重点);
  • 在c++中用tensorflow的API来调用这个pb文件。

1.编译Tensorflow源码

关于编译tensorflow源码的方法有两种:CMake和Bazel,不管哪一种编译的方法都会遇到一些坑,当然如果不想自己踩坑,也可以选择第三种方法,使用tensorflow的编译好版本文件,具体查看方法三。

根据官网给出的编译器对应关系:https://tensorflow.google.cn/install/source,tensorflow 1.12版以后需要用bazel去编译,cmake只能去编译1.12版以前的旧版,大家看自己的需求自行选择吧!

1.1 使用cmake编译

操作系统:windows
安装git,
安装visual studio 2015(即vs14)
安装python3.5或3.6(或直接安装anaconda,下载地址)并加入环境变量
下载swig,
安装cmake,版本号需要>=3.6.3,
科学上网(最好有,否则一些依赖的文件可能下载不下来导致编译失败,错误信息为:error downloading xxx failed)

遇到的问题

2.C++调用tensorflow model

训练就不多说了,不过要留意整个计算图中的输入输出的tensor的名称,例如我的网络有两个输入,叫’input1’和’input2’,有两个输出,叫’output1’和’output2’,这些名字后面要用到。

生成pb文件可以添加如下代码:

constant_graph = tf.graph_util.convert_variables_to_constants(sess, sess.graph_def,['output1','output2'])
with tf.gfile.FastGFile('weight.pb', mode='wb') as f:
    f.write(constant_graph.SerializeToString())

请注意上述代码第一行中需要写上输出tensor的名称列表(输入tensor不用写)。

1.编译成功后我们可以用这些头文件以及tensorflow.lib/dll来编写自己的测试工程了。

#pragma once  //这一句防止重复include头文件
 
#define COMPILER_MSVC
#define NOMINMAX  //这一句防止max/min函数命名冲突

2.源文件为TestTensorFlow.cpp

#include "TestTensorFlow.h"
 
#include "tensorflow/cc/client/client_session.h"
#include "tensorflow/cc/ops/standard_ops.h"
#include "tensorflow/core/framework/tensor.h"
 
int main() {
	using namespace tensorflow;
	using namespace tensorflow::ops;
	Scope root = Scope::NewRootScope();
	// Matrix A = [3 2; -1 0]
	auto A = Const(root, { { 3.f, 2.f },{ -1.f, 0.f } });
	// Vector b = [3 5]
	auto b = Const(root, { { 3.f, 5.f } });
	// v = Ab^T
	auto v = MatMul(root.WithOpName("v"), A, b, MatMul::TransposeB(true));
	std::vector<Tensor> outputs;
	ClientSession session(root);
	// Run and fetch v
	TF_CHECK_OK(session.Run({ v }, &outputs));
	// Expect outputs[0] == [19; -3]
	LOG(INFO) << outputs[0].matrix<float>();
	return 0;
}

遇到的问题

C2589 “(”:“::”右边的非法标记

第一种办法:设置项目属性,在预定义处理器中添加定义NOMINMAX来禁止使用Visual C++的min/max宏定义。 项目属性 ——> C/C++ ——> 预处理器 ——> 预处理器定义 (此处添加预定义编译开关 NOMINMAX)
但是visual C++中定义能自动匹配double和int,如果进行了上述设置,代码中手动将int型的数据乘以1.0来达到double的目的。
第二种办法: 加上括号,与Vsual C++的min/max宏定义区分开

你得到一个LNK1181错误在Visual Studio LIB或.obj文件指定在连接在当前目录没有发现,任何指定的目录LIBPATH链接器选项,或任何的LIB环境变量中指定的目录。
您可以添加包含libclamav的目录。lib库文件到LIBPATH解决这个问题(这个说明可能会有所不同,取决于你的Visual Studio版本):

在“解决方案资源管理器”中,右键单击项目,然后单击“属性”。
在“属性页”对话框中展开“链接器”,然后单击“常规”。
在附加库目录字段中,指定libclamav所在的路径,libclamav.lib
当LIBPATH包含空格时也可能发生错误。如果是这种情况,请将库移动到没有空格的路径上,或者在路径周围加上引号。

我希望我能给你1000个赞!我试图更新一个遗留项目,LIBPATH中有空格!我已经找了好几个小时了,没人告诉我。我不知道它在原来的开发环境中是如何工作的!也许他们碰巧也有它在LIB环境……无论如何,我不知道更现代的VS版本是如何处理这个问题的,但是vc++ 6(别问了!)并没有优雅表示。- 5月19日14时9分12秒
为了防止别人无意中发现我的错误,我犯了一个更基本、更愚蠢的错误。我试图在“仅在项目中”构建。确保先构建您的依赖项!右键点击你的项目文件,然后点击build。

问题:找不到tensorflow.dll文件,无法继续执行代码

解决:把dll文件放到.cpp,.h等文件的目录下,不要放到解决方案的目录下。

参考文章

  • 3
    点赞
  • 21
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
C与C++混编动态库,使用CMake进行编译和构建非常方便。CMake是一个开源的跨平台构建工具,可以根据不同平台的需求生成对应的makefile或者Visual Studio等项目文件。下面是使用CMake编译和构建C与C++混编动态库的简要步骤: 1. 创建一个工程文件夹,例如"mylibrary",并在该文件夹下创建源码文件: - C源码文件:例如"library.c" ```c int add(int a, int b) { return a + b; } ``` - C++源码文件:例如"library.cpp" ```cpp #include <iostream> extern "C" { int multiply(int a, int b) { return a * b; } } int main() { std::cout << "Hello, C++!" << std::endl; return 0; } ``` 2. 在源码文件夹下创建一个CMakeLists.txt文件,并指定库类型、源码文件和输出路径: ```cmake cmake_minimum_required(VERSION 3.0) project(mylibrary) # 指定混编动态库 set(CMAKE_C_FLAGS "-fPIC") set(CMAKE_CXX_FLAGS "-fPIC") # 添加源码文件 set(SOURCE_FILES library.c library.cpp) # 编译为动态库 add_library(mylibrary SHARED ${SOURCE_FILES}) # 指定输出路径 set(LIBRARY_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/lib) ``` 3. 在工程文件夹下创建一个build文件夹,用来存放编译生成的中间文件和最终生成的动态库: ``` mkdir build cd build ``` 4. 在终端中进入build文件夹,使用cmake命令生成makefile或者Visual Studio项目文件: ``` cmake .. ``` 5. 使用生成的makefile进行编译和构建: ``` make ``` 6. 编译成功后,会在lib文件夹下生成对应平台的动态库文件,例如Linux下的libmylibrary.so或者Windows下的mylibrary.dll。可以将该动态库文件与其他C或者C++项目进行链接,以便调用其中的函数。 通过这样的方法,我们可以很方便地将C与C++源码混编生成动态库,并且使用CMake可以提供跨平台的构建能力,极大地简化了编译和构建的工作。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值