Windows下编译TensorFlow1.3 C++ library及创建一个简单的TensorFlow C++程序

       由于最近比较忙,一直到假期才有空,因此将自己学到的知识进行分享。如果有不对的地方,请指出,谢谢!目前深度学习越来越火,学习、使用tensorflow的相关工作者也越来越多。最近在研究tensorflow线下采用 python 脚本训练出模型, 利用freeze_graph工具输出.pb图文件,之后再线上生产环境windows平台上用C++代码直接调用预先训练好的模型完成预测的工作。因为目前tensorflow提供的C++的API比较少,所以参考了以上几篇已有的日志,做个总结。这里编译出TensorFlow C++ library,遇到的坑进行填埋。之后的调用C++library相对比较简单,可以参考链接部分。

Step1:Windows 10必备环境准备

1.1安装VS2015

1.2安装Swigwin-3.0.12,其可执行文件地址为 D:/lib/swigwin-3.0.12/swig.exe

1.4安装python3.5,安装时注意选择将路径添加到环境变量。

1.5安装CMake-3.8.0 ,安装时注意选择将路径添加到环境变量。

1.6安装Git,用于在编译过程中从GitHub上下载依赖项。

1.7 将GitHub上TensorFlow的master分支 下载并解压到文件夹D:\tf中,编辑文件tensorflow/tensorflow/contrib/cmake/CMakeLists.txt,将第87行至93行修改如下:

if (tensorflow_OPTIMIZE_FOR_NATIVE_ARCH)include(CheckCXXCompilerFlag)CHECK_CXX_COMPILER_FLAG("-march=native" COMPILER_OPT_ARCH_NATIVE_SUPPORTED)if (COMPILER_OPT_ARCH_NATIVE_SUPPORTED)set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -march=native")else()CHECK_CXX_COMPILER_FLAG("/arch:AVX" COMPILER_OPT_ARCH_AVX_SUPPORTED)if(COMPILER_OPT_ARCH_AVX_SUPPORTED)set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /arch:AVX")endif()endif()
endif()

总结下这一部分的三个重要地址:

Python可执行文件地址为:D:/lib/Python35/python.exe;
Python库文件地址为:D:/lib/Python35/libs/python35.lib(release版本), D:/lib/Python35/libs/python35_d.lib(Debug版本);
Swigwin可执行文件地址:D:/lib/swigwin-3.0.12/swig.exe。

 

Step2:编译 TensorFlow shared lib

2.1 打开文件夹 D:\tf\tensorflow-master\tensorflow\contrib\cmake, 新建文件夹\build。以管理员身份运行 开始 \ 所有程序 \ Visual Studio 2015\Visual Studio Tools\ Developer Command Prompt for VS 2015,输入powershell,使用命令切换到新建的build文件夹下。使用指令1用于build编译项目。可以看到,使用的就是上一部分保存的三个路径。当命令行中出现Generating done,说明build成功。

# 指令1(release)
cmake .. -A x64 -DCMAKE_BUILD_TYPE=Release -DSWIG_EXECUTABLE=D:/lib/swigwin-3.0.12/swig.exe-DPYTHON_EXECUTABLE=D:/lib/Python35/python.exe -DPYTHON_LIBRARIES=D:/lib/Python35/libs/python35.lib -Dtensorflow_BUILD_SHARED_LIB=ON# 指令1(debug)
cmake .. -A x64 -DCMAKE_BUILD_TYPE=Debug -DSWIG_EXECUTABLE=D:/lib/swigwin-3.0.12/swig.exe-DPYTHON_EXECUTABLE=D:/lib/Python35/python.exe -DPYTHON_LIBRARIES=D:/lib/Python35/libs/python35_d.lib-Dtensorflow_BUILD_SHARED_LIB=ON

或者,这里我用cmake-gui界面进行cmake编译出release和debug版本,如下图所示:

 

2.2 命令行中输入指令2开始编译,在编译过程中保持网络畅通,有15个依赖库需要下载。编译过程中可能出现一些警告,不用担心,只要没有错误编译就可以通过。

# 指令2(release)
MSBuild /p:Configuration=Release ALL_BUILD.vcxproj
# 指令2(debug)
MSBuild /p:Configuration=Debug ALL_BUILD.vcxproj

 

2.3 但是,我在自己的电脑上编译失败,并出现了90个错误,这些错误都指向了两文件:

D:\tf\tensorflow-master\tensorflow\contrib\cmake\build\re2\src\re2\re2\testing\re2_test.cc
D:\tf\tensorflow-master\tensorflow\contrib\cmake\build\re2\src\re2\re2\testing\search_test.cc

 

re2包提供了正则表达式的功能,文件夹testing中是测试文件,在TensorFlow运行过程中其实不需要这些测试功能,所以可以通过禁止编译re2的测试部分来移除这些错误。

Step3:排除错误

3.1对出错的工程文件夹下,修改文件D:\tf\tensorflow-master\tensorflow\contrib\cmake\build\re2\src\re2\CMakeLists.txt(一定要FQ下载到),将第16行修改为:

option(RE2_BUILD_TESTING “enable testing for RE2” OFF)

,并保存。

3.2 重新进行编译(步骤2.2)。在编译过程中,会出现错误:

C:\Program Files (x86)\MSBuild\Microsoft.Cpp\v4.0\V140\Microsoft.CppCommon.targets(171,5): error MSB6006: “cmd.exe”已退
出,代码为 1。 [D:\tensorflow-master\tensorflow\contrib\cmake\build\grpc.vcxproj]

这个应该是没有成功下载grpc,这个应该是个bug,给的链接不对(多次编译都编不过去),百度了下grpc对我现在的应用暂时用不多(不了解可以百度gprc)因此,暂时不需要grpc,也就不下载,编辑文件tensorflow/tensorflow/contrib/cmake/CMakeLists.txt,将第23行修改如下:

option(tensorflow_ENABLE_GRPC_SUPPORT "Enable gRPC support" OFF)

3.3重新cmake 和Build编译项目,并重新进行编译,重复步骤2.1,2.2和3.1。可能会出现错误:

fatal error C1060: compiler is out of heap space

这应该是跟自己的硬件相关,我自己的电脑配置不太好。出现这个错误,首先等待编译过程的完成,然后重复运行指令2。大概重复运行两三次这个问题就没有了。每次重复运行前,需等待整个编译过程完成。

也可能会出现这样的错误(Debug编译出现这样的错误):

这可能在实际中编译采用的是x86,并没有真正采用x64的环境进行编译,因此打开命令窗口Developer Command Prompt for VS 2015,输入powershell,使用命令切换到新建的build文件夹下,输入指令3,然后在输入指令2。

# 指令3
set PreferredToolArchitecture=x64

3.4 编译到最后会出现错误(debug版本比较严格)符号重载的错误,如下图所示:

error C2678: binary '<': no operator found which takes a left-hand operand of type IndicesRowIterator

 修改对应的文件夹下的文件,我这里是D:\tf\tensorflow-master-ngrpc\tensorflow\contrib\boosted_trees\lib\utils\sparse_column_iterable.cc,增加到文件中,增加的内容如下所示:

bool operator<( const IndicesRowIterator& other ) const {
QCHECK_LT( iter_, other.iter_ );
return ( row_idx_ < other.row_idx_ );
}

最终编译成功。出现需要的相应的release和debug版本的lib和动态链接库

Step4:在Windows上编译和运行一个简单的TensorFlow C++ 程序

4.1在vs2015中创建一个新的工程solution,并在对应的文件中输入如下:

#include <vector>
#include <eigen/Dense>#include "matmul.h"
#include "tensorflow/core/public/session.h"
#include "tensorflow/cc/ops/standard_ops.h"using namespace tensorflow;// Build a computation graph that takes a tensor of shape [?, 2] and
// multiplies it by a hard-coded matrix.
GraphDef CreateGraphDef()
{Scope root = Scope::NewRootScope();auto X = ops::Placeholder(root.WithOpName("x"), DT_FLOAT, ops::Placeholder::Shape({ -1, 2 }));auto A = ops::Const(root, { { 3.f, 2.f },{ -1.f, 0.f } });auto Y = ops::MatMul(root.WithOpName("y"), A, X, ops::MatMul::TransposeB(true));GraphDef def;TF_CHECK_OK(root.ToGraphDef(&def));return def;
}int main()
{GraphDef graph_def = CreateGraphDef();// Start up the session
  SessionOptions options;std::unique_ptr<Session> session(NewSession(options));TF_CHECK_OK(session->Create(graph_def));// Define some data.  This needs to be converted to an Eigen Tensor to be// fed into the placeholder.  Note that this will be broken up into two// separate vectors of length 2: [1, 2] and [3, 4], which will separately// be multiplied by the matrix.std::vector<float> data = { 1, 2, 3, 4 };auto mapped_X_ = Eigen::TensorMap<Eigen::Tensor<float, 2, Eigen::RowMajor>>(&data[0], 2, 2);auto eigen_X_ = Eigen::Tensor<float, 2, Eigen::RowMajor>(mapped_X_);Tensor X_(DT_FLOAT, TensorShape({ 2, 2 }));X_.tensor<float, 2>() = eigen_X_;std::vector<Tensor> outputs;TF_CHECK_OK(session->Run({ { "x", X_ } }, { "y" }, {}, &outputs));// Get the result and print it outTensor Y_ = outputs[0];std::cout << Y_.tensor<float, 2>() << std::endl;session->Close();getchar();
}

 

4.2在对应的头文件中输入如下:

#pragma once#define COMPILER_MSVC
#define NOMINMAX

 

4.3在vs2015中,属性配置界面中,include Directories:

D:\tf\tensorflow-master-ngrpc\tensorflow\contrib\cmake\build\Debug
D:\tf\tensorflow-master-ngrpc\tensorflow\contrib\cmake\build\external\nsync\public
D:\tf\tensorflow-master-ngrpc\tensorflow\contrib\cmake\build\protobuf\src\protobuf\src
D:\tf\tensorflow-master-ngrpc\tensorflow\contrib\cmake\build\external\eigen_archive
D:\tf\tensorflow-master-ngrpc\tensorflow\contrib\cmake\build
D:\tf\tensorflow-master-ngrpc
D:\tf\tensorflow-master-ngrpc\third_party\eigen3

4.4在vs2015中,属性配置界面中,Additional Library Directories(release版本):

D:\tf\tensorflow-master-ngrpc\tensorflow\contrib\cmake\build\Release

4.5在vs2015中,属性配置界面中,Linker Settings(release版本):

tensorflow.lib

4.6编译和运行程序,运行结果如下所示:

 7 17
-1 -3

参考:

https://joe-antognini.github.io/machine-learning/build-windows-tf

http://quqixun.com/?p=785

http://blog.csdn.net/longji/article/details/72760409

http://blog.csdn.net/rockingdingo/article/details/75452711

https://github.com/tensorflow/tensorflow/issues

https://github.com/tensorflow/tensorflow/tree/master/tensorflow/contrib/cmake

https://stackoverflow.com/questions/42603407/how-to-compile-tensor-flow-with-sse-and-and-avx-instructions-on-windows

 

转载于:https://www.cnblogs.com/jliangqiu2016/p/7642471.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/428699.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

粉红小猪中有一个叫“快乐小鸡”的游戏

最近在学习svg,书看了一本 然后再找了个框架 snap.svg 摸索着写了个游戏给女儿玩。哈哈。即涨知识又娱乐。 转载于:https://www.cnblogs.com/goldli/p/7649898.html

idea .defaultMessage

idea .defaultMessage 等同于eclipse里的getDefaultMessage idea只能能获取到bean设置NotBlank等message响应到jsp的key&#xff0c;不能在jsp里获取validationMessage properties文件里的value 那么我们就不要value只要key 转载于:https://www.cnblogs.com/duneF/p/7654780.h…

【vue系列之二】详解vue-cli 2.0配置文件

上次给大家分享的是用vue-cli快速搭建vue项目&#xff0c;虽然很省时间和精力&#xff0c;但想要真正搞明白&#xff0c;我们还需要对其原理一探究竟。 大家拿到一个项目&#xff0c;要快速上手&#xff0c;正确的思路是这样的&#xff1a; 首先&#xff0c;如果在项目有readme…

4. Spring 如何通过 XML 文件配置Bean,以及如何获取Bean

在 Spring 容器内拼凑 bean 叫做装配。装配 bean 的时候&#xff0c;你是在告诉容器&#xff0c;需要哪些 bean &#xff0c;以及容器如何使用依赖注入将它们配合在一起。 理论上&#xff0c;bean 装配的信息可以从任何资源获得&#xff0c;包括属性文件&#xff0c;关系数据库…

基于用户击键特征的身份鉴别系统

简单来说&#xff0c;我们要做的就是一种通过用户敲击键盘的习惯进行身份鉴别的系统。国内外之前有一些相关研究&#xff0c;但是通常是数千条数据训练&#xff0c;而且不能随意改变敲击的字符串&#xff0c;或者是有的要求采用带有压力传感器的键盘&#xff0c;难以实用和推广…

常见三种字符编码的区别:ASCII、Unicode、UTF-8

什么是字符编码&#xff1f; 计算机只能处理数字&#xff0c;如果要处理文本&#xff0c;就必须先把文本转换为数字才能处理。最早的计算机在设计时采用8个比特&#xff08;bit&#xff09;作为一个字节&#xff08;byte&#xff09;&#xff0c;所以&#xff0c;一个字节能表…

导航,头部,CSS基础

制作自己的导航条。HTML头部元素&#xff1a;<base> 定义了页面链接标签的默认链接地址<style> 定义了HTML文档的样式文件<link> 定义了一个文档和外部资源之间的关系练习样式表&#xff1a;行内样式表内嵌样式表外部样式表分别练习定义三类选择器&#x…

十五、导航,头部,CSS基础

制作自己的导航条。HTML头部元素&#xff1a;<base> 定义了页面链接标签的默认链接地址<style> 定义了HTML文档的样式文件<link> 定义了一个文档和外部资源之间的关系 练习样式表&#xff1a;行内样式表内嵌样式表外部样式表分别练习定义三类选择器&#…

【网络爬虫入门04】彻底掌握BeautifulSoup的CSS选择器

【网络爬虫入门04】彻底掌握BeautifulSoup的CSS选择器 广东职业技术学院 欧浩源 2017-10-21 1、引言 目前&#xff0c;除了官方文档之外&#xff0c;市面上及网络详细介绍BeautifulSoup使用的技术书籍和博客软文并不多&#xff0c;而在这仅有的资料中介绍CSS选择器的少之又少。…

Mybatis基于XML配置SQL映射器(一)

Durid和Mybatis开发环境搭建 SpringBoot搭建基于SpringSpringMvcMybatis的REST服务&#xff08;http://www.cnblogs.com/nbfujx/p/7694768.html&#xff09; Mybatis之代码生成器 Maven Plugin管理 1 <build>2 <plugins>3 <plugin>4 …

linux运维、架构之路-Zabbix监控

一、监控常用命令 1、物理服务器监控命令 ①添加yum源 wget -O /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-6.repo wget -O /etc/yum.repos.d/epel.repo http://mirrors.aliyun.com/repo/epel-6.repo ②安装 yum -y install OpenIPMI ipmitoo…

vi命令

vi命令是UNIX操作系统和类UNIX操作系统中最通用的全屏幕纯文本编辑器。 Linux中的vi编辑器叫vim&#xff0c;它是vi的增强版&#xff08;vi Improved&#xff09;&#xff0c;与vi编辑器完全兼容&#xff0c;而且实现了很多增强功能。 vi编辑器支持编辑模式和命令模式&#xff…

SQL基本语法

SQL 基本语法 表库操作 创建表create table 表名(字段名 类型(长度) 约束,字段名 类型(长度) 约束); 创建主键约束id int primary key, primary key(id) // 在创建表最后创建主键约束 删除主键alter table 表名 drop primary key; 主键自动增长主键字段后加auto_increment(只适…

KindEditor富文本编辑器上传功能PHP语言报错问题

问题产生过程&#xff1a;项目原本使用的是Ueditor编辑器&#xff0c;由于其中js代码有使用parentNode获取HTML节点&#xff0c;IE浏览器内核不支持parentNode &#xff0c;会有二次加载富文本编辑器不渲染的问题&#xff0c;所以更换编辑器为kindeditor&#xff0c;其中上传文…

二、PyCharm 创建Django 第一个项目

PyCharm 下创建Django项目 File->New Project->Django 目录说明&#xff1a; dj: 项目的容器。manage.py: 一个实用的命令行工具&#xff0c;可让你以各种方式与该 Django 项目进行交互。dj/__init__.py: 一个空文件&#xff0c;告诉 Python 该目录是一个 Python 包。dj/…

linux last failed login表示什么意思_Linux用户

Linux的用户在登录(login)之后&#xff0c;就带有一个用户身份(user ID, UID)和一个组身份(group ID, GID)。在Linux文件管理背景知识中&#xff0c;我们又看到&#xff0c;每个文件又有九位的权限说明&#xff0c;用来指明该文件允许哪些用户执行哪些操作(读、写或者执行)。(参…

CSS3详解:transform、transition

CSS3 transform是什么&#xff1f; transform的含义是&#xff1a;改变&#xff0c;使…变形&#xff1b;转换 CSS3 transform都有哪些常用属性&#xff1f; transform的属性包括&#xff1a;rotate() / skew() / scale() / translate(,) &#xff0c;分别还有x、y之分&#xf…

c++ 线程什么时候run_多线程并发支撑基础之JAVA内存模型

Java内存模型可以说是Java并发的底层支持&#xff0c;了解Java内存模型才能正在了解Java并发。内存模型在内存中设置一个变量"value 1&#xff1b;"那么其他线程能在什么时候读取到这个结果呢&#xff1f;有可能不能立即甚至永远都读不到。比如指令顺序与源代码中的…

润乾报表 数据集ds1中,数据源xmglxt_x3无数据库连接,且未设定数据连接工厂,请检查数据源设定:...

一、润乾报表错误内容 产生数据工厂: com.runqian.report4.dataset.SQLDataSetFactory 失败 错误来源&#xff1a;: 数据集ds1中&#xff0c;数据源xmglxt_x3无数据库连接&#xff0c;且未设定数据连接工厂&#xff0c;请检查数据源设定&#xff1a; 二、解决方法 同事做的润乾…

WPF中的数据绑定Data Binding使用小结

完整的数据绑定的语法说明可以在这里查看&#xff1a; http://www.nbdtech.com/Free/WpfBinding.pdf MSDN资料&#xff1a; Data Binding: Part 1 http://msdn.microsoft.com/en-us/library/aa480224.aspx Data Binding: Part 2 http://msdn.microsoft.com/en-us/library/aa480…