win10下c++调用tensorflow训练好的模型

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


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

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

1.编译Tensorflow源码

1.1 使用开源文件

开源地址:https://github.com/fo40225/tensorflow-windows-wheel ,tensorflow的很多编译好的版本都能直接下,这里面只有tensorflow1.7–1.10的版本有编译好的cpp库,其他的版本只有编译好的安装tf的python库的whl文件,所以强烈推荐大家用1.7~1.10的tensorflow。
例如我需要tensorflow1.10的、cpu支持AVX2指令集的版本,就下载tensorflow-windows-wheel/1.10.0/cpp/
例如我需要tensorflow1.10的、cpu支持SSE2指令集、且gpu支持CUDA9.2和CUDNN7.2的版本,就下载tensorflow-windows-wheel/1.10.0/cpp/

然后把其中的include路径包含进去,把lib文件添加到工程中,再在执行exe时把dll文件复制进去就好了

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等文件的目录下,不要放到解决方案的目录下。

参考文章

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值