<< Tensorflow Wiin10 stage.1
Tensorflow Win10 stage.3 >>
一,Tensorflow 的主要依赖包
1.Protocol Buffer
Protocol Buffer是谷歌开发的处理结构化数据的工具,是Tensorflow系统中使用到的非常重要 的工具,Tensorflow中的数据基本都是通过Protocol Buffer 来组织的。
1.1 结构化数据 Structured Data
结构化数据也就是一种拥有多种属性的数据,例如一个用户信息:
name: n
id: 001
email: n@somemail.com
这个用户信息拥有了name, id, email这三个属性,这就是一个结构化数据。当我们想要把一个结构化数据持久化或者进行网络传输时,需要先将这个数据序列化(serialization)
1.1.1 序列化 Serialization
序列化,就是把结构化的数据变成数据流的格式,事实上就是将数据变成一个字符串。对结构化的数据进行序列化,并从序列化之后的数据流中还原出原来的结构化数据,称为处理结构化数据。Protocol Buffer 就是处理结构化数据的工具。
1.1.2 处理结构化数据的工具
XML
XML数据格式:
<user>
<name> n </name>
<id>001</id>
<email>n@somemail.com</email>
</user>
JSON
JSON数据格式:
{
"name" : n,
"id" : "001",
"email" : "n@somemail.com",
}
Protocol Buffer
Protocol Buffer格式的数据和XML和JSON格式的数据有比较大的区别:
- 首先,Protocol Buffer序列化之后的数据是不可读的字符串,而是二进制流。
- 其次,XML和JSON格式的数据信息都包含在了序列化之后的数据中,不需任何其他信息就能还原序列化之后的数据,而Protocol buffer 需要先定义数据的格式 (shema),根据这个定义好的格式还原一个序列之后的数据
因为这样的差别,Protocol Buffer序列化出来的数据要比XML格式的数据小3到10倍,解析时间要快20到100倍。下面是Protocol Buffer的数据格式定义文件:
message user{
optional string name = 1;
required int32 id = 2;
repeated string email = 3;
}
Protocol Buffer定义数据格式的文件一般保存在.proto文件中。每一个message代表了一类结构化的数据,例如上面的用户信息。
可以看到message里面定义了每个属性的类型和名字:
属性 | 数据类型 | 数据选项 |
---|---|---|
name | string | optional:可选的,实例的这个属性可以为空,用户可以不填写姓名 |
id | int32 | required:必须的,所有实例的这个属性不能为空,每个用户都有一个id |
string | repeated:可重复的,可以是一个列表,一个用户可以有多个邮件地址 |
之后我们将会看到Tensorflow是如何使用Protocol Buffer。分布式Tensorflow的通信协议gRPC也是以Protocol Buffer作为基础的。
2.Bazel
2.1 前提
-
64 bit Windows 7 or newer, or 64 bit Windows Server 2008 R2 or newer
-
MSYS2 shell
-
Microsoft Visual C++ Redistributable for Visual Studio 2015
这些是通常Bazel需要的一些DLL,你可能已经安装好了,后面我们会提到这个问题
2.2 安装
在Download Bazel for Windows上提供了几种安装Bazel的方法:
- Download Bazel from Github for Windows
- Installation using Chocolatey Pakage Manager
- Installation using Scoop Pakage Manager
在Github上下载只需要找到bazel-<version>-windows-x86_64.exe
,即对应版本的Windows安装包即可
我选择的是使用的是Chocolatey这个Windows上的一个不错的包管理程序进行安装的。
2.2.1 安装Chocolatey
在Chocolatey的下载官网上提供了几种安装方法,我使用的是Windows自带的PowerShell命令行程序进行安装的:
1,用管理员身份打开PowerShell。可以在菜单中W索引下找到Windows PowerShell然后右键点击以管理员身份运行
2,修改执行策略。Chocolatey要求执行策略不能是Restricted,首先使用命令Get-ExecutionPolicy
查看当前的执行策略,然后使用Set-ExecutionPolicy Bypass -Scope Process
修改执行策略,这时会弹出一个Warning的log,选择Y修改。查看当前的执行策略,此时已经修改为Bypass
3,输入下面的命令,从Chocolatey官网上下载并运行Chocolatey的PowerShell安装脚本install.ps1:
iex ((New-Object System.Net.WebClient).DownloadString('https://chocolatey.org/install.ps1'))
输入choco --version
,返回当前的Chocolatey版本,说明安装完成:
2.2.2 安装Bazel
输入choco install bazel
进行Bazel的安装,安装过程中会让你选择是否要安装Bazel的一些依赖项,也就是我们前面说到的,例如MSYS2,如果你不确定是否安装了这些依赖项的话,全部选择Y
2.2.3 在Windows上使用Bazel
环境变量配置
安装完Bazel之后,在你第一次进行build时,Bazel会自动配置好Python和Visual C++ 编译器的路径,当然你也可以自己指定路径:
1,输入bazel clean
2,然后在 计算机 -> 属性 -> 高级系统设置 -> 环境变量 中添加:
变量名 | 变量值 |
---|---|
Path | ① 添加MSYS2的usr\bin: 一般会在C:\tools下,或者是你已经安装的话可以指定你的MSYS2\usr\bin ② 添加bazel的路径: 你需要先把bazel的binary文件重命名为bazel.exe,然后放到你的Bazel路径下面,例如:C:\bazel,然后把这个路径添加到PATH中,用chocolatey进行安装一般是在C:\ProgramData\chocolatey\lib\bazel下 ③ 添加Python路径: Bazel支持Python2和Python3(if you build python) |
BAZEL_SH | C:\your\path\to\msys64\usr\bin\bash.exe |
BAZEL_PYTHON | C:\your\path\to\Python27\python.exe |
JAVA_HOME (if you build java) | C:\Program Files\Java\jdk1.8.0_151 |
BAZEL_VC / BAZEL_VS (if you build c++) | C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\VC / C:\Program Files (x86)\Microsoft Visual Studio\2017\BuildTools |
其中你可以选择配置BAZEL_VC或者是BAZEL_VS,如果要使用Visual Studio的BuildTools的话,需要先安装BuildTools,可以打开Visual Studio的下载页面进行下载。
配置完成后,在命令行界面或者是PowerShell界面输入bazel version
检查是否安装成功
P.S. 我在配置变量BAZEL_SH的时候出现了“配置失败,注册表损坏”的问题,结果查了一下,关掉杀毒软件如:电脑管家,金山毒霸之后,就可以配置了,具体原因暂时不明。。。。。。。。。。。。。。。。。。
2.3 Bazel基本概念
Bazel是谷歌开发的一个自动化构建工具,相比起传统的Makefile,ANT等,它具有更加优秀的速度,灵活性和对多语言以及多平台的支持。
2.3.1 项目空间 workspace
事实上workdspace就是一个文件夹,包含项目文件,可以是一个应用,也可以是多个应用,这个项目空间的文件夹就是项目的根目录。在一个项目空间中,包含了以下的文件:
文件 | 说明 |
---|---|
WORKSPACE | 这个文件定义了对外部资源的依赖,可以是一个空文件,表明项目没有任何的外部依赖 |
lib | 库文件和函数 |
src | 源文件 |
BUILD | Bazel通过这个文件来找到需要进行 编译的文件,采用一种类似于Python的语法,指定了每一个编译目标的输入,输出以及编译方式 |
编译方式有三种:py_library, py_binary, py_test
编译方式 | 说明 |
---|---|
py_binary | 将文件编译成一个可执行文件 |
py_library | 将文件编译成为一个库函数供其他py_binary和py_test文件调用 |
py_test | 编译测试程序 |
下面给出了一个Bazel的简单例子
2.4 Hello, world 例子
2.4.1 文件说明
如下图所示是一个简单的项目空间:
可以看到包含了四个文件: WORKSPACE, BUILD, hello_lib.py, hello_main.py
- WORKSPACE
为了简单起见,我们不需要任何的外部依赖,所以这里是一个空文件,可以看到文件的长度为0
- hello_lib.py
定义了一个简单的打印函数
def print_hello_world():
print('Hello, world')
- hello_main.py
调用hello_lib.py里面定义的打印函数
import hello_lib
hello_lib.print_hello_world()
- BUILD
定义了一系列的编译目标,这里的编译目标的先后顺序没有影响。在每个编译目标开始需要指明编译方式,可以看到就是下面的py_library和py_binary。
# 定义了一个编译方式为py_library的编译目标
py_library{
name = "hello_lib",
srcs = [
"hello_lib.py"
]
}
# 定义了一个编译方式为py_binary的编译目标
py_binary{
name = "hello_main",
srcs = [
"hello_main.py",
],
deps = [
":hello_lib.py"
]
}
我们通过定义name, srcs, deps等属性来定义编译信息的,这里我们只是简单用到了3个属性:
属性 | 说明 |
---|---|
name | 所要编译的文件名 |
srcs | 定义了所要编译的源文件 |
deps | 定义了这个文件的依赖文件,例如上面的hello_main.py调用了hello_lib.py中的函数,所以这个依赖就是":hello_lib.py" |
2.4.2 运行编译操作
在项目空间中输入bazel build:hello_main
得到输出结果: