淘先锋技术网

首页 1 2 3 4 5 6 7

这段时间一直用python代码import tensorflow和keras的库,来搭建CNN框架进行图像的训练和预测,现在想用tensorflow的c++版来改写实现。故想自己编译一份tensroflow的lib和dll文件,创建工程调用其来实现相同的功能。本博客主要讲编译过程和一个简单的sample例子。

一.编译详细过程:

1.下载tensorflow源码,链接:点击打开链接,选择1.3.0版本。


2.准备工具:

 一台配置了英伟达显卡的x64位win7系统电脑

  (1)CMake 3.10.1点击打开链接

  (2)swigwin-3.0.12点击打开链接

  (3) VS2015

  (4) cuda8.0+cudnnv5.1(如何安装配置验证参考我的之前博文“win7下cuda8.0安装跑gpu版tensorflow”

   (5)  无网状态下需要下载部分文件。下面会介绍。

3.Cmake-gui编译tensorflow

  (1)打开cmake-gui, 在tensorflow所在本机位置的tensorflow-1.3.0\tensorflow-1.3.0\tensorflow\contrib\cmake

   路径下新建build文件夹2

  (2)Browse Source和Browse Build按照此下选择(cmake文件夹下如果没有build文件夹,自己新建一个)

  (3)点击cmake-gui左下角的Config按钮,会跳出来对话框,按照下图选择2015 Win64,然后点击Finish按钮


(4)会出现如下图的报错信息


(5)cmake-gui需要做如下配置,SWIG_EXECUTABLE路径设置到上面swigwin-3.0.12中swig.exe所在的位置


(6)再次点击configure按钮,出现下图,表示config成功


(7)展开tensorflow,按如下打勾的勾选上,然后点Generate

(8)出现Generating done表明生成成功

(9)然后点击Open Project按钮,打开工程


(10)点击菜单栏里的工具(T),选择选项按钮,在项目和解决方案下选择生成并运行项

     做如下配置:设置最大并行项目生成数为1


(11)生成ALL_BUILD项目。

(12)中间不会很顺利,会报一些错误,如下所示:

     

       

 

      分析无非这两大报错原因:a.由于网速慢或者资源原因,一些编译过程中需要下载的库download不下来。

                                            b. re2工程编译不过去

(13)re2工程编译失败处理("re2/re2.h": No such file or directory)

          转到到你的tensorflow文件里tensorflow-1.3.0\tensorflow\contrib\cmake\build\re2\src\re2目录下。

          删除该目录下的非文件夹的文件,除了CmakeList.txt保留。

          

       打开cmake-gui,如下图所示配置,单独重新配置re2工程。

        记得Ungrouped Entries下的RE2_BUILD_TESTING取消勾选

               BUILD下的BUILD_TESTING取消勾选

  

        

        之后点击Config、Generate按钮重新生成Re2工程。不需要点open project按钮

        重新仅生成Re2工程,成功。

(14)解决由于网速或者离线模式下相关文件不能下载而导致的失败问题

         比如报downloading "htpps://storage.gooleapis.com/libpng-public-archive/libpng-1.2.53.tar.gz' failed

         可以在有网的环境下事先下载好这份文件,拷贝到

        tensorflow-1.3.0\tensorflow\contrib\cmake\build\downloads文件夹下。

        然后转到tensorflow-1.3.0\tensorflow\contrib\cmake\build\png\src\png-stamp文件夹下,

       把download-png.cmake里的东西清空,如下图所示:

       

       

           对png工程重新仅生成该工程,编译成功。

           解决该问题的方法也可以给离线模式编译带来参考,可以事先先准备好这些编译过程中需要下载的文件,所有文件均在

            tensorflow-1.3.0\tensorflow\contrib\cmake\build\downloads文件夹里

            下图是我编译成功该版tensorflow需要依赖的库

            

(15)重新生成ALL Build一般就能成功了(我按照此逻辑装过三次),如果不行可以留言!

         生成成功后会在tensorflow-1.3.0\tensorflow\contrib\cmake\build\Release文件夹下看到tensorlow.lib和dll文件

        

到这边就编译结束啦!后面就可以写一些程序来调用这个dll。

该dll是x64 release版dll

下面是应用tensorflow.dll的一个简单会话例子。

 用VS2015新建一个控制台程序。


sample1.cpp中代码如下:

// sample1.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include <iostream>

#include <Eigen\\Dense>
#include "tensorflow/core/public/session.h"
#include "tensorflow/cc/ops/standard_ops.h"

using namespace tensorflow;

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()
{
	std::cout << "me" << std::endl;
	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 out
	Tensor Y_ = outputs[0];
	std::cout << Y_.tensor<float, 2>() << std::endl;

	session->Close();
	getchar();



    return 0;
}

同时在头文件stdafx.h文件中添加如下语句:

#include <tchar.h>
#define COMPILER_MSVC
#define NOMINMAX

完了之后对该工程进行路径及dll的配置:(我这边配的是绝对路径,最好用相对路径)


                      

                       

 

配置完后运行该sample工程,结果如下图: