1. 程式人生 > >win7下VS2015編譯tensorflow原始碼教程(線上和離線)及呼叫配置

win7下VS2015編譯tensorflow原始碼教程(線上和離線)及呼叫配置

這段時間一直用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工程,結果如下圖: