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工程,結果如下圖: