1. 如何學習TensorFlow源碼
如果從源碼構建TensorFlow會需要執行如下命令:
bazel build -c opt //tensorflow/tools/pip_package:build_pip_package
對應的BUILD文件的rule為:
sh_binary(
name = "build_pip_package",
srcs = ["build_pip_package.sh"],
data = [
"MANIFEST.in",
"README",
"setup.py",
"//tensorflow/core:framework_headers",
":other_headers",
":simple_console",
"//tensorflow:tensorflow_py",
"//tensorflow/examples/tutorials/mnist:package",
"//tensorflow/models/embedding:package",
"//tensorflow/models/image/cifar10:all_files",
"//tensorflow/models/image/mnist:convolutional",
"//tensorflow/models/rnn:package",
"//tensorflow/models/rnn/ptb:package",
"//tensorflow/models/rnn/translate:package",
"//tensorflow/tensorboard",
],
)
sh_binary在這里的主要作用是生成data的這些依賴。一個一個來看,一開始的三個文件MANIFEST.in、README、setup.py是直接存在的,因此不會有什麼操作。
「//tensorflow/core:framework_headers」:其對應的rule為:
filegroup(
name = "framework_headers",
srcs = [
"framework/allocator.h",
......
"util/device_name_utils.h",
2. 如何高效的學習 TensorFlow 代碼
如果從源碼構建TensorFlow會需要執行如下命令: bazel build -c opt //tensorflow/tools/pip_package:build_pip_package 對應的BUILD文件的rule為: sh_binary( name = "build_pip_package", srcs = ["build_pip_package.sh"], data
3. tensorflow seq2seq 跑默認腳本的測試結果很差,什麼原因
但Sublime Text提示和跳轉不夠強大,改一下代碼然後編譯運行測試,對於大型C++項目我也是聽從大牛,一般看源碼用順手的工具即可、C++代碼我一般都先打開Sublime Text、java無論看python,使用Qt Creator,不要有工具之爭,暫時使用體驗非常不錯。
BTW,或者需要安裝各種插件、bazel這些命令上,大部分時間可能還是耗在vim
4. 如何使用bazel build
安裝
安裝過程請參考: http://bazel.io/docs/install.html
使用工作區(workspace)
所有的Bazel構建都是基於一個 工作區(workspace) 概念,它是文件系統中一個保存了全部源代碼的目錄,同時還將包含一些構建後的輸出目錄的符號鏈接(例如:bazel-bin和 bazel-out 等輸出目錄)。工作區目錄可以隨意放在哪裡,但是工作區的根目錄必須包含一個名為 WORKSPACE 的工作區配置文件。工作區配置文件可以是一個空文件,也可以包含引用外部構建輸出所需的 依賴關系。
在一個工作區內,可以根據需要共享多個項目。為了簡單,我們先從只有一個項目的工作區開始介紹。
先假設你已經有了一個項目,對應 ~/gitroot/my-project/ 目錄。我們先創建一個空的 ~/gitroot/my-project/WORKSPACE 工作區配置文件,用於表示這是Bazel項目對應的根目錄。
創建自己的Build構建文件
使用下面的命令創建一個簡單的Java項目:
$ # If you're not already there, move to your workspace directory.
$ cd ~/gitroot/my-project
$ mkdir -p src/main/java/com/example
$ cat > src/main/java/com/example/ProjectRunner.java <<EOF
package com.example;
public class ProjectRunner {
public static void main(String args[]) {
Greeting.sayHi();
}
}
EOF
$ cat > src/main/java/com/example/Greeting.java <<EOF
package com.example;
public class Greeting {
public static void sayHi() {
System.out.println("Hi!");
}
}
EOF
Bazel通過工作區中所有名為 BUILD 的文件來解析需要構建的項目信息,因此,我們需要先在 ~/gitroot/my-project 目錄創建一個 BUILD 構建文件。下面是BUILD構建文件的內容:
# ~/gitroot/my-project/BUILD
java_binary(
name = "my-runner",
srcs = glob(["**/*.java"]),
main_class = "com.example.ProjectRunner",
)
BUILD文件採用類似Python的語法。雖然不能包含任意的Python語法,但是BUILD文件中的每個構建規則看起來都象是一個Python函數調用,而且你也可以用 "#" 開頭來添加單行注釋。
java_binary 是一個構建規則。其中 name 對應一個構建目標的標識符,可用用它來向Bazel指定構建哪個項目。srcs 對應一個源文件列表,Bazel需要將這些源文件編譯為二進制文件。其中 glob(["**/*.java"]) 表示遞歸包含每個子目錄中以每個 .java 為後綴名的文件。com.example.ProjectRunner 指定包含main方法的類。
現在可以用下面的命令構建這個Java程序了:
$ cd ~/gitroot/my-project
$ bazel build //:my-runner
INFO: Found 1 target...
Target //:my-runner up-to-date:
bazel-bin/my-runner.jar
bazel-bin/my-runner
INFO: Elapsed time: 1.021s, Critical Path: 0.83s
$ bazel-bin/my-runner
Hi!
恭喜,你已經成功構建了第一個Bazel項目了!
添加依賴關系
對於小項目創建一個規則是可以的,但是隨著項目的變大,則需要分別構建項目的不同的部件,最終再組裝成產品。這種構建方式可以避免因為局部細小的修改兒導致重現構建整個應用,同時不同的構建步驟可以很好地並發執行以提高構建效率。
我們現在將一個項目拆分為兩個部分獨立構建,同時設置它們之間的依賴關系。基於上面的例子,我們重寫了BUILD構建文件:
java_binary(
name = "my-other-runner",
srcs = ["src/main/java/com/example/ProjectRunner.java"],
main_class = "com.example.ProjectRunner",
deps = [":greeter"],
)
java_library(
name = "greeter",
srcs = ["src/main/java/com/example/Greeting.java"],
)
雖然源文件是一樣的,但是現在Bazel將採用不同的方式來構建:首先是構建 greeter庫,然後是構建 my-other-runner。可以在構建成功後立刻運行 //:my-other-runner:
$ bazel run //:my-other-runner
INFO: Found 1 target...
Target //:my-other-runner up-to-date:
bazel-bin/my-other-runner.jar
bazel-bin/my-other-runner
INFO: Elapsed time: 2.454s, Critical Path: 1.58s
INFO: Running command line: bazel-bin/my-other-runner
Hi!
現在如果你改動ProjectRunner.java代碼並重新構建my-other-runner目標,Greeting.java文件因為沒有變化而不會重現編譯。
使用多個包(Packages)
對於更大的項目,我們通常需要將它們拆分到多個目錄中。你可以用類似//path/to/directory:target-name的名字引用在其他BUILD文件定義的目標。假設src/main/java/com/example/有一個cmdline/子目錄,包含下面的文件:
$ mkdir -p src/main/java/com/example/cmdline
$ cat > src/main/java/com/example/cmdline/Runner.java <<EOF
package com.example.cmdline;
import com.example.Greeting;
public class Runner {
public static void main(String args[]) {
Greeting.sayHi();
}
}
EOF
Runner.java依賴com.example.Greeting,因此我們需要在src/main/java/com/example/cmdline/BUILD構建文件中添加相應的依賴規則:
# ~/gitroot/my-project/src/main/java/com/example/cmdline/BUILD
java_binary(
name = "runner",
srcs = ["Runner.java"],
main_class = "com.example.cmdline.Runner",
deps = ["//:greeter"]
)
然而,默認情況下構建目標都是 私有 的。也就是說,我們只能在同一個BUILD文件中被引用。這可以避免將很多實現的細節暴漏給公共的介面,但是也意味著我們需要手工允許runner所依賴的//:greeter目標。就是類似下面這個在構建runner目標時遇到的錯誤:
$ bazel build //src/main/java/com/example/cmdline:runner
ERROR: /home/user/gitroot/my-project/src/main/java/com/example/cmdline/BUILD:2:1:
Target '//:greeter' is not visible from target '//src/main/java/com/example/cmdline:runner'.
Check the visibility declaration of the former target if you think the dependency is legitimate.
ERROR: Analysis of target '//src/main/java/com/example/cmdline:runner' failed; build aborted.
INFO: Elapsed time: 0.091s
可用通過在BUILD文件增加visibility = level屬性來改變目標的可間范圍。下面是通過在~/gitroot/my-project/BUILD文件增加可見規則,來改變greeter目標的可見范圍:
java_library(
name = "greeter",
srcs = ["src/main/java/com/example/Greeting.java"],
visibility = ["//src/main/java/com/example/cmdline:__pkg__"],
)
這個規則表示//:greeter目標對於//src/main/java/com/example/cmdline包是可見的。現在我們可以重新構建runner目標程序:
$ bazel run //src/main/java/com/example/cmdline:runner
INFO: Found 1 target...
Target //src/main/java/com/example/cmdline:runner up-to-date:
bazel-bin/src/main/java/com/example/cmdline/runner.jar
bazel-bin/src/main/java/com/example/cmdline/runner
INFO: Elapsed time: 1.576s, Critical Path: 0.81s
INFO: Running command line: bazel-bin/src/main/java/com/example/cmdline/runner
Hi!
參考文檔 中有可見性配置說明。
部署
如果你查看 bazel-bin/src/main/java/com/example/cmdline/runner.jar 的內容,可以看到裡面只包含了Runner.class,並沒有保護所依賴的Greeting.class:
$ jar tf bazel-bin/src/main/java/com/example/cmdline/runner.jar
META-INF/
META-INF/MANIFEST.MF
com/
com/example/
com/example/cmdline/
com/example/cmdline/Runner.class
這只能在本機正常工作(因為Bazel的runner腳本已經將greeter jar添加到了classpath),但是如果將runner.jar單獨復制到另一台機器上講不能正常運行。如果想要構建可用於部署發布的自包含所有依賴的目標,可以構建runner_deploy.jar目標(類似<target-name>_deploy.jar以_deploy為後綴的名字對應可部署目標)。
$ bazel build //src/main/java/com/example/cmdline:runner_deploy.jar
INFO: Found 1 target...
Target //src/main/java/com/example/cmdline:runner_deploy.jar up-to-date:
bazel-bin/src/main/java/com/example/cmdline/runner_deploy.jar
INFO: Elapsed time: 1.700s, Critical Path: 0.23s
runner_deploy.jar中將包含全部的依賴。
下一步
現在,您可以創建自己的目標並組裝最終產品了。接下來,可查看 相關教程 分別學習如何用Bazel構建一個伺服器、Android和iOS應用。也可以參考 用戶手冊獲得更多的信息。如果有問題的話,可以到 bazel-discuss 論壇提問。
5. 如何學習TensorFlow源碼
如果從源碼構建TensorFlow會需要執行如下命令:
bazel build -c opt //tensorflow/tools/pip_package:build_pip_package
對應的BUILD文件的rule為:
sh_binary(
name = "build_pip_package",
srcs = ["build_pip_package.sh"],
data = [
"MANIFEST.in",
"README",
"setup.py",
"//tensorflow/core:framework_headers",
":other_headers",
":simple_console",
"//tensorflow:tensorflow_py",
"//tensorflow/examples/tutorials/mnist:package",
"//tensorflow/models/embedding:package",
"//tensorflow/models/image/cifar10:all_files",
"//tensorflow/models/image/mnist:convolutional",
"//tensorflow/models/rnn:package",
"//tensorflow/models/rnn/ptb:package",
"//tensorflow/models/rnn/translate:package",
"//tensorflow/tensorboard",
],
)
sh_binary在這里的主要作用是生成data的這些依賴。一個一個來看,一開始的三個文件MANIFEST.in、README、setup.py是直接存在的,因此不會有什麼操作。
「//tensorflow/core:framework_headers」:其對應的rule為:
filegroup(
name = "framework_headers",
srcs = [
"framework/allocator.h",
......
"util/device_name_utils.h",
],
)
這里filegroup的作用是給這一堆頭文件一個別名,方便其他rule引用。
「:other_headers」:rule為:
transitive_hdrs(
name = "other_headers",
deps = [
"//third_party/eigen3",
"//tensorflow/core:protos_all_cc",
],
)
transitive_hdrs的定義在:
load("//tensorflow:tensorflow.bzl", "transitive_hdrs")
實現為:
# Bazel rule for collecting the header files that a target depends on.
def _transitive_hdrs_impl(ctx):
outputs = set()
for dep in ctx.attr.deps:
outputs += dep.cc.transitive_headers
return struct(files=outputs)
_transitive_hdrs = rule(attrs={
"deps": attr.label_list(allow_files=True,
providers=["cc"]),
},
implementation=_transitive_hdrs_impl,)
def transitive_hdrs(name, deps=[], **kwargs):
_transitive_hdrs(name=name + "_gather",
deps=deps)
native.filegroup(name=name,
srcs=[":" + name + "_gather"])
其作用依舊是收集依賴需要的頭文件。
「:simple_console」:其rule為:
py_binary(
name = "simple_console",
srcs = ["simple_console.py"],
srcs_version = "PY2AND3",
deps = ["//tensorflow:tensorflow_py"],
)
py_library(
name = "tensorflow_py",
srcs = ["__init__.py"],
srcs_version = "PY2AND3",
visibility = ["//visibility:public"],
deps = ["//tensorflow/python"],
)
simple_console.py的代碼的主要部分是:
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
import code
import sys
def main(_):
"""Run an interactive console."""
code.interact()
return 0
if __name__ == '__main__':
sys.exit(main(sys.argv))
可以看到起通過deps = [「//tensorflow/python」]構建了依賴包,然後生成了對應的執行文件。看下依賴的rule規則。//tensorflow/python對應的rule為:
py_library(
name = "python",
srcs = [
"__init__.py",
],
srcs_version = "PY2AND3",
visibility = ["//tensorflow:__pkg__"],
deps = [
":client",
":client_testlib",
":framework",
":framework_test_lib",
":kernel_tests/gradient_checker",
":platform",
":platform_test",
":summary",
":training",
"//tensorflow/contrib:contrib_py",
],
)
這里如果仔細看的話會發現其主要是生成一堆python的模塊。從這里貌似可以看出每個python的mole都對應了一個rule,且mole依賴的mole都寫在了deps里。特別的,作為一個C++的切入,我們關注下training這個依賴:
py_library(
name = "training",
srcs = glob(
["training/**/*.py"],
exclude = ["**/*test*"],
),
srcs_version = "PY2AND3",
deps = [
":client",
":framework",
":lib",
":ops",
":protos_all_py",
":pywrap_tensorflow",
":training_ops",
],
)
這里其依賴的pywrap_tensorflow的rule為:
tf_py_wrap_cc(
name = "pywrap_tensorflow",
srcs = ["tensorflow.i"],
swig_includes = [
"client/device_lib.i",
"client/events_writer.i",
"client/server_lib.i",
"client/tf_session.i",
"framework/python_op_gen.i",
"lib/core/py_func.i",
"lib/core/status.i",
"lib/core/status_helper.i",
"lib/core/strings.i",
"lib/io/py_record_reader.i",
"lib/io/py_record_writer.i",
"platform/base.i",
"platform/numpy.i",
"util/port.i",
"util/py_checkpoint_reader.i",
],
deps = [
":py_func_lib",
":py_record_reader_lib",
":py_record_writer_lib",
":python_op_gen",
":tf_session_helper",
"//tensorflow/core/distributed_runtime:server_lib",
"//tensorflow/core/distributed_runtime/rpc:grpc_server_lib",
"//tensorflow/core/distributed_runtime/rpc:grpc_session",
"//util/python:python_headers",
],
)
tf_py_wrap_cc為其自己實現的一個rule,這里的.i就是SWIG的interface文件。來看下其實現:
def tf_py_wrap_cc(name, srcs, swig_includes=[], deps=[], copts=[], **kwargs):
mole_name = name.split("/")[-1]
# Convert a rule name such as foo/bar/baz to foo/bar/_baz.so
# and use that as the name for the rule procing the .so file.
cc_library_name = "/".join(name.split("/")[:-1] + ["_" + mole_name + ".so"])
extra_deps = []
_py_wrap_cc(name=name + "_py_wrap",
srcs=srcs,
swig_includes=swig_includes,
deps=deps + extra_deps,
mole_name=mole_name,
py_mole_name=name)
native.cc_binary(
name=cc_library_name,
srcs=[mole_name + ".cc"],
copts=(copts + ["-Wno-self-assign", "-Wno-write-strings"]
+ tf_extension_copts()),
linkopts=tf_extension_linkopts(),
linkstatic=1,
linkshared=1,
deps=deps + extra_deps)
native.py_library(name=name,
srcs=[":" + name + ".py"],
srcs_version="PY2AND3",
data=[":" + cc_library_name])
按照SWIG的正常流程,先要通過swig命令生成我們的wrap的c文件,然後和依賴生成我們的so文件,最後生成一個同名的python文件用於import。這里native.cc_binary和native.py_library做了我們後面的兩件事情,而swig命令的執行則交給了_py_wrap_cc。其實現為:
_py_wrap_cc = rule(attrs={
"srcs": attr.label_list(mandatory=True,
allow_files=True,),
"swig_includes": attr.label_list(cfg=DATA_CFG,
allow_files=True,),
"deps": attr.label_list(allow_files=True,
providers=["cc"],),
"swig_deps": attr.label(default=Label(
"//tensorflow:swig")), # swig_templates
"mole_name": attr.string(mandatory=True),
"py_mole_name": attr.string(mandatory=True),
"swig_binary": attr.label(default=Label("//tensorflow:swig"),
cfg=HOST_CFG,
executable=True,
allow_files=True,),
},
outputs={
"cc_out": "%{mole_name}.cc",
"py_out": "%{py_mole_name}.py",
},
implementation=_py_wrap_cc_impl,)
_py_wrap_cc_impl的實現為:
# Bazel rules for building swig files.
def _py_wrap_cc_impl(ctx):
srcs = ctx.files.srcs
if len(srcs) != 1:
fail("Exactly one SWIG source file label must be specified.", "srcs")
mole_name = ctx.attr.mole_name
cc_out = ctx.outputs.cc_out
py_out = ctx.outputs.py_out
src = ctx.files.srcs[0]
args = ["-c++", "-python"]
args += ["-mole", mole_name]
args += ["-l" + f.path for f in ctx.files.swig_includes]
cc_include_dirs = set()
cc_includes = set()
for dep in ctx.attr.deps:
cc_include_dirs += [h.dirname for h in dep.cc.transitive_headers]
cc_includes += dep.cc.transitive_headers
args += ["-I" + x for x in cc_include_dirs]
args += ["-I" + ctx.label.workspace_root]
args += ["-o", cc_out.path]
args += ["-outdir", py_out.dirname]
args += [src.path]
outputs = [cc_out, py_out]
ctx.action(executable=ctx.executable.swig_binary,
arguments=args,
mnemonic="PythonSwig",
inputs=sorted(set([src]) + cc_includes + ctx.files.swig_includes +
ctx.attr.swig_deps.files),
outputs=outputs,
progress_message="SWIGing {input}".format(input=src.path))
return struct(files=set(outputs))
這里的ctx.executable.swig_binary是一個shell腳本,內容為:
# If possible, read swig path out of "swig_path" generated by configure
SWIG=swig
SWIG_PATH=tensorflow/tools/swig/swig_path
if [ -e $SWIG_PATH ]; then
SWIG=`cat $SWIG_PATH`
fi
# If this line fails, rerun configure to set the path to swig correctly
"$SWIG" "$@"
可以看到起就是調用了swig命令。
「//tensorflow:tensorflow_py」:其rule為:
py_library(
name = "tensorflow_py",
srcs = ["__init__.py"],
srcs_version = "PY2AND3",
visibility = ["//visibility:public"],
deps = ["//tensorflow/python"],
)
6. 看caffe和tensorflow源碼用什麼IDE
無論看Python、Java、C++代碼我一般都先打開Sublime Text,改一下代碼然後編譯運行測試。
但Sublime Text提示和跳轉不夠強大,或者需要安裝各種插件,對於大型C++項目我也是聽從大牛推薦,使用Qt Creator,暫時使用體驗非常不錯。
BTW,一般看源碼用順手的工具即可,不要有工具之爭,大部分時間可能還是耗在vim、bazel這些命令上。
7. ubuntu16.04 tensoflow使用伺服器需要支持gpu嗎
1. 下載
1.1 系統鏡像
由於我嘗試了ubuntu14.04,安裝Nvidia驅動之後,會出現循環登錄的問題,並始終無法找到有效的解決途徑,所以只能選擇ubuntu16.04了。
1.2 CUDA 8.0
說明:
(1)在NVIDIA的CUDA下載頁面下,選擇要使用的CUDA版本進行下載。
(2)我們這里使用CUDA8.0(頁面有提示GTX1070、GTX1080支持8.0版本),學員如果沒有使用以上兩個版本的GPU,可以下載CUDA7.5。DOWNLOAD(下載)。
(3)下載需要注冊。
(4)圖解選擇
1.3 cuDNN v5
說明:
(1)下載需要填寫一個調查問卷,就三個選項,建議認真填寫,畢竟人家免費給咱使用。
(2)填寫完畢點擊 I Agree To 前面的小方框,出現如下:
1.4 Tensorflow 0.11
tensorflow github上面提到 4 種安裝方式,本教程使用 第四種 源碼安裝
Virtualenv installation
Anaconda installation
Docker installation
Installing from sources
說明:
(1)打開下載頁面,往下翻,直到下圖這個位置:
(2) 點擊Python 2開始下載。
最後,將1.2-1.4中下載文件全部存放至自己的移動硬碟/U盤內,等待安裝時候使用。
2. 安裝ubuntu16.04 LTS 系統
安裝Ubuntu16.04:
說明:
(1)我們直接安裝的英文原版系統,語言也是選擇英文的。
(2)上述鏈接在–第三步:安裝類型上選擇的是–自定義。我們選擇的是–清除整個磁碟並且安裝,如果你有Windows系統,還會提示安裝Ubuntu16.04與Windows並存模式。這個自行選擇,切記!這個地方謹慎選擇。
(3)感謝網路經驗上傳者!
3. 安裝NVIDIA驅動
打開terminal輸入以下指令:
sudo apt-get update1
然後在系統設置->軟體更新->附加驅動->選擇nvidia最新驅動(361)->應用更改
3. cuda 8.0
3.1 安裝cuda
在cuda所在目錄打開terminal依次輸入以下指令:
cd /home/***(自己的用戶名)/Desktop/###(這個命令意思是找到剛剛我們用U盤傳過來的文件)
sudo dpkg -i cuda-repo-ubuntu1604-8-0-rc_8.0.27-1_amd64.deb
sudo apt-get update
sudo apt-get install cuda1234
3.2 gcc降版本
ubuntu的gcc編譯器是5.4.0,然而cuda8.0不支持5.0以上的編譯器,因此需要降級,把編譯器版本降到4.9:
在terminal中執行:
sudo apt-get install g++-4.9
sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-4.9 20
sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-5 10
sudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-4.9 20
sudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-5 10
sudo update-alternatives --install /usr/bin/cc cc /usr/bin/gcc 30
sudo update-alternatives --set cc /usr/bin/gcc
sudo update-alternatives --install /usr/bin/c++ c++ /usr/bin/g++ 30
sudo update-alternatives --set c++ /usr/bin/g++123456789
3. 安裝cuDNN
打開terminal依次輸入以下指令:
cd /home/***(自己的用戶名)/Desktop/###(這個命令意思是找到剛剛我們用U盤傳過來的文件)
tar xvzf cudnn-8.0-linux-x64-v5.1-ga.tgz###(解壓這個文件)
sudo cp cuda/include/cudnn.h /usr/local/cuda/include###(復制)
sudo cp cuda/lib64/libcudnn* /usr/local/cuda/lib64###(復制)
sudo chmod a+r /usr/local/cuda/include/cudnn.h /usr/local/cuda/lib64/libcudnn*12345
4. 安裝其他依賴
4.1 配置環境變數
按照上圖的教程,在terminal中輸入以下命令:
sudo gedit ~/.bash_profile #打開.bash_profile1
然後在打開的文本末尾加入:
export LD_LIBRARY_PATH="$LD_LIBRARY_PATH:/usr/local/cuda/lib64:/usr/local/cuda/extras/CUPTI/lib64"
export CUDA_HOME=/usr/local/cuda12
繼續在terminal中輸入:
source ~/.bash_profile #使更改的環境變數生效1
當然,也有其他教程在文件~/.bashrc文件中寫入的,方法與上面的類似。如果在後面配置./config文件出現問題時,可以實現這個方法。
4.2 安裝其他庫
/tensorflow/tensorflow/blob/master/tensorflow/g3doc/get_started/os_setup.md
我們是在github的Tensorflow官方網頁上,根據提示安裝,地址如上。
按步驟截圖如下
在terminal中輸入以下命令:
sudo apt-get install python-pip python-dev 1
4. 安裝Bazel
4.1 安裝Bazel依賴
由於本教程使用tensorflow源碼編譯/安裝,所以需要使用 bazel build。
在terminal中依次輸入以下1-7的命令
4.2 安裝Bazel
之後回到之前的Tensorflow安裝教程頁面: /tensorflow/tensorflow/blob/master/tensorflow/g3doc/get_started/os_setup.md
點擊鏈接: installer for your system,跳轉到Bazel的下載頁面:
下載bazel-0.3.2-installer-linux-x86_64.sh到桌面,然後在terminal中輸入以下命令
cd /home/***(自己的用戶名)/Desktop/###(這個命令意思是找到剛剛我們用U盤傳過來的文件)
chmod +x PATH_TO_INSTALL.SH #對.sh文件授權
./PATH_TO_INSTALL.SH --user #運行.sh文件123
4.3 安裝第三方庫
在terminal中輸入以下命令
sudo apt-get install python-numpy swig python-dev python-wheel #安裝第三方庫
sudo apt-get install git
git clone git://github.com/numpy/numpy.git numpy 123
5. 安裝tensorflow
5.1 下載tensorflow
在terminal中輸入以下命令
git clone /tensorflow/tensorflow1
特別注意,我使用的是tensorflow 0.11版本,該版本要求cuda 7.5 以上,cuDNN v5。
默認下載目錄是在/home下
5.2 配置tensorflow
還是剛剛的網址
/tensorflow/tensorflow/blob/master/tensorflow/g3doc/get_started/os_setup.md
在terminal中輸入以下命令:
cd ~/tensorflow #切換到tensorflow文件夾
./configure #執行configure文件12
然後按照下圖選項進行操作:
5.3 創建pip
在terminal中輸入以下命令:
bazel build -c opt //tensorflow/tools/pip_package:build_pip_package
bazel build -c opt --config=cuda //tensorflow/tools/pip_package:build_pip_package
bazel-bin/tensorflow/tools/pip_package/build_pip_package /tmp/tensorflow_pkg
sudo pip install /home/***(你自己的用戶名)/Desktop/tensorflow-0.10.0-cp2-none-any.whl1234
5.4 設置tensorflow環境
bazel build -c opt //tensorflow/tools/pip_package:build_pip_package
# To build with GPU support:
bazel build -c opt --config=cuda //tensorflow/tools/pip_package:build_pip_package
mkdir _python_build
cd _python_build
ln -s ../bazel-bin/tensorflow/tools/pip_package/build_pip_package.runfiles/org_tensorflow/* .
ln -s ../tensorflow/tools/pip_package/* .
python setup.py develop12345678
這樣就大功告成啦~!!!
6. 測試tensorflow
這里進行測試,如果你能跟我看到同樣的畫面,那恭喜你成功配置GPU版的tensorflow啦!
8. 在win10里 為什麼 Bazel 編譯 tensorflow.dll 提示 /arch:SSE4.2 無效命令要編譯SSE4.2的參數怎麼配置
河南新華正在火熱報名,歡迎參觀!!!
9. 誰有Crystal FLOW C++ 的破解版
如果從源碼構建TensorFlow會需要執行如下命令:
bazel build -c opt //tensorflow/tools/pip_package:build_pip_package
對應的BUILD文件的rule為:
sh_binary(
name = "build_pip_package",
srcs = ["build_pip_package.sh"],
data = [
"MANIFEST.in",
"README",
"setup.py",
"//tensorflow/core:framework_headers",
":other_headers",
":simple_console",
"//tensorflow:tensorflow_py",
"//tensorflow/examples/tutorials/mnist:package",
"//tensorflow/models/embedding:package",
"//tensorflow/models/image/cifar10:all_files",
"//tensorflow/models/image/mnist:convolutional",
"//tensorflow/models/rnn:package",
"//tensorflow/models/rnn/ptb:package",
"//tensorflow/models/rnn/translate:package",
"//tensorflow/tensorboard",
],
)
sh_binary在這里的主要作用是生成data的這些依賴。一個一個來看,一開始的三個文件MANIFEST.in、README、setup.py是直接存在的,因此不會有什麼操作。
「//tensorflow/core:framework_headers」:其對應的rule為:
filegroup(
name = "framework_headers",
srcs = [
"framework/allocator.h",
......
"util/device_name_utils.h",
],
)
這里filegroup的作用是給這一堆頭文件一個別名,方便其他rule引用。
「:other_headers」:rule為:
transitive_hdrs(
name = "other_headers",
deps = [
"//third_party/eigen3",
"//tensorflow/core:protos_all_cc",
],
)
transitive_hdrs的定義在:
load("//tensorflow:tensorflow.bzl", "transitive_hdrs")
實現為:
# Bazel rule for collecting the header files that a target depends on.
def _transitive_hdrs_impl(ctx):
outputs = set()
for dep in ctx.attr.deps:
outputs += dep.cc.transitive_headers
return struct(files=outputs)
_transitive_hdrs = rule(attrs={
"deps": attr.label_list(allow_files=True,
providers=["cc"]),
},
implementation=_transitive_hdrs_impl,)
def transitive_hdrs(name, deps=[], **kwargs):
_transitive_hdrs(name=name + "_gather",
deps=deps)
native.filegroup(name=name,
srcs=[":" + name + "_gather"])
其作用依舊是收集依賴需要的頭文件。
「:simple_console」:其rule為:
py_binary(
name = "simple_console",
srcs = ["simple_console.py"],
srcs_version = "PY2AND3",
deps = ["//tensorflow:tensorflow_py"],
)
py_library(
name = "tensorflow_py",
srcs = ["__init__.py"],
srcs_version = "PY2AND3",
visibility = ["//visibility:public"],
deps = ["//tensorflow/python"],
)
simple_console.py的代碼的主要部分是:
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
import code
import sys
def main(_):
"""Run an interactive console."""
code.interact()
return 0
if __name__ == '__main__':
sys.exit(main(sys.argv))
可以看到起通過deps = [「//tensorflow/python」]構建了依賴包,然後生成了對應的執行文件。看下依賴的rule規則。//tensorflow/python對應的rule為:
py_library(
name = "python",
srcs = [
"__init__.py",
],
srcs_version = "PY2AND3",
visibility = ["//tensorflow:__pkg__"],
deps = [
":client",
":client_testlib",
":framework",
":framework_test_lib",
":kernel_tests/gradient_checker",
":platform",
":platform_test",
":summary",
":training",
"//tensorflow/contrib:contrib_py",
],
)
這里如果仔細看的話會發現其主要是生成一堆python的模塊。從這里貌似可以看出每個python的mole都對應了一個rule,且mole依賴的mole都寫在了deps里。特別的,作為一個C++的切入,我們關注下training這個依賴:
py_library(
name = "training",
srcs = glob(
["training/**/*.py"],
exclude = ["**/*test*"],
),
srcs_version = "PY2AND3",
deps = [
":client",
":framework",
":lib",
":ops",
":protos_all_py",
":pywrap_tensorflow",
":training_ops",
],
)
這里其依賴的pywrap_tensorflow的rule為:
tf_py_wrap_cc(
name = "pywrap_tensorflow",
srcs = ["tensorflow.i"],
swig_includes = [
"client/device_lib.i",
"client/events_writer.i",
"client/server_lib.i",
"client/tf_session.i",
"framework/python_op_gen.i",
"lib/core/py_func.i",
"lib/core/status.i",
"lib/core/status_helper.i",
"lib/core/strings.i",
"lib/io/py_record_reader.i",
"lib/io/py_record_writer.i",
"platform/base.i",
"platform/numpy.i",
"util/port.i",
"util/py_checkpoint_reader.i",
],
deps = [
":py_func_lib",
":py_record_reader_lib",
":py_record_writer_lib",
":python_op_gen",
":tf_session_helper",
"//tensorflow/core/distributed_runtime:server_lib",
"//tensorflow/core/distributed_runtime/rpc:grpc_server_lib",
"//tensorflow/core/distributed_runtime/rpc:grpc_session",
"//util/python:python_headers",
],
)
tf_py_wrap_cc為其自己實現的一個rule,這里的.i就是SWIG的interface文件。來看下其實現:
def tf_py_wrap_cc(name, srcs, swig_includes=[], deps=[], copts=[], **kwargs):
mole_name = name.split("/")[-1]
# Convert a rule name such as foo/bar/baz to foo/bar/_baz.so
# and use that as the name for the rule procing the .so file.
cc_library_name = "/".join(name.split("/")[:-1] + ["_" + mole_name + ".so"])
extra_deps = []
_py_wrap_cc(name=name + "_py_wrap",
srcs=srcs,
swig_includes=swig_includes,
deps=deps + extra_deps,
mole_name=mole_name,
py_mole_name=name)
native.cc_binary(
name=cc_library_name,
srcs=[mole_name + ".cc"],
copts=(copts + ["-Wno-self-assign", "-Wno-write-strings"]
+ tf_extension_copts()),
linkopts=tf_extension_linkopts(),
linkstatic=1,
linkshared=1,
deps=deps + extra_deps)
native.py_library(name=name,
srcs=[":" + name + ".py"],
srcs_version="PY2AND3",
data=[":" + cc_library_name])
按照SWIG的正常流程,先要通過swig命令生成我們的wrap的c文件,然後和依賴生成我們的so文件,最後生成一個同名的python文件用於import。這里native.cc_binary和native.py_library做了我們後面的兩件事情,而swig命令的執行則交給了_py_wrap_cc。其實現為:
_py_wrap_cc = rule(attrs={
"srcs": attr.label_list(mandatory=True,
allow_files=True,),
"swig_includes": attr.label_list(cfg=DATA_CFG,
allow_files=True,),
"deps": attr.label_list(allow_files=True,
providers=["cc"],),
"swig_deps": attr.label(default=Label(
"//tensorflow:swig")), # swig_templates
"mole_name": attr.string(mandatory=True),
"py_mole_name": attr.string(mandatory=True),
"swig_binary": attr.label(default=Label("//tensorflow:swig"),
cfg=HOST_CFG,
executable=True,
allow_files=True,),
},
outputs={
"cc_out": "%{mole_name}.cc",
"py_out": "%{py_mole_name}.py",
},
implementation=_py_wrap_cc_impl,)
_py_wrap_cc_impl的實現為:
# Bazel rules for building swig files.
def _py_wrap_cc_impl(ctx):
srcs = ctx.files.srcs
if len(srcs) != 1:
fail("Exactly one SWIG source file label must be specified.", "srcs")
mole_name = ctx.attr.mole_name
cc_out = ctx.outputs.cc_out
py_out = ctx.outputs.py_out
src = ctx.files.srcs[0]
args = ["-c++", "-python"]
args += ["-mole", mole_name]
args += ["-l" + f.path for f in ctx.files.swig_includes]
cc_include_dirs = set()
cc_includes = set()
for dep in ctx.attr.deps:
cc_include_dirs += [h.dirname for h in dep.cc.transitive_headers]
cc_includes += dep.cc.transitive_headers
args += ["-I" + x for x in cc_include_dirs]
args += ["-I" + ctx.label.workspace_root]
args += ["-o", cc_out.path]
args += ["-outdir", py_out.dirname]
args += [src.path]
outputs = [cc_out, py_out]
ctx.action(executable=ctx.executable.swig_binary,
arguments=args,
mnemonic="PythonSwig",
inputs=sorted(set([src]) + cc_includes + ctx.files.swig_includes +
ctx.attr.swig_deps.files),
outputs=outputs,
progress_message="SWIGing {input}".format(input=src.path))
return struct(files=set(outputs))
這里的ctx.executable.swig_binary是一個shell腳本,內容為:
# If possible, read swig path out of "swig_path" generated by configure
SWIG=swig
SWIG_PATH=tensorflow/tools/swig/swig_path
if [ -e $SWIG_PATH ]; then
SWIG=`cat $SWIG_PATH`
fi
# If this line fails, rerun configure to set the path to swig correctly
"$SWIG" "$@"
可以看到起就是調用了swig命令。
「//tensorflow:tensorflow_py」:其rule為:
py_library(
name = "tensorflow_py",
srcs = ["__init__.py"],
srcs_version = "PY2AND3",
visibility = ["//visibility:public"],
deps = ["//tensorflow/python"],
)
10. 關於C代碼報不安全的時候怎麼辦
方法一:在程序最前面加#define _CRT_SECURE_NO_DEPRECATE;
方法二:在程序最前面加#define _CRT_SECURE_NO_WARNINGS;
方法三:在程序最前面加#pragma warning(disable:4996);
方法四:把scanf改為scanf_s;
方法五:無需在程序最前面加那行代碼,只需在新建項目時取消勾選「SDL檢查」即可;
方法六:若項目已建立好,在項目屬性里關閉SDL也行;
方法七:在工程項目設置一下就行;將報錯那個宏定義放到 項目屬性 -- C/C++-- 預處理器 -- 預處理器定義;
方法八:在 項目屬性 -- c/c++ -- 命令行 添加:/D _CRT_SECURE_NO_WARNINGS 就行了。