TensorFlow实战:TensorFlow简介


人工智能、机器学习与深度学习

从计算机发明之初,人们就希望它能代替人们完成重复性劳动,而计算机要想像人类一样智能的完成许多工作,需要掌握这个世界海量的知识。

为了使计算机更多的掌握开放环境(open domain)下的知识,研究人员做了许多工作,其中一个影响力非常大的领域是知识图库1(Ontology) .虽然使用知识图库可以让计算机很好地掌握人工定义的知识,但是建立知识图库需要的成本太大,另一方面通过知识图库方式明确定义的知识有限。我们常说的经验,就是一个很难描述的知识,如何让计算机和人类一样从历史的经验中获取新的知识?这就是机器学习需要解决的事情

机器学习

现学术界2对机器学习的定义为:”如果一个程序可以在任务T上,随着经验E的增加,效果P也可以随之增加,则称为这个程序可以从经验中学习“.例如在对垃圾邮件分类的任务中,”一个程序”指的就是需要用到的机器学习算法,”任务T”指区分垃圾邮件的任务,”经验E”为已经区分过是否为垃圾邮件的历史邮件,在监督式学习问题上,这也被称为训练数据;”效果P”为机器学习算法在区分垃圾邮件任务上的正确率.

在大部分情况下,在训练数据达到一定数量之前,越多的训练数据可以使算法对未知邮件的判断越精准。之所以说这是在大部分情况下,是因为算法的效果除了依赖训练数据,也依赖于从数据中提取的特征。(假设邮件分类中提取的数据都是邮件时间,那数据量大小和判别垃圾邮件之间的关联不大),无法从数据中学习更好的特征表达,这是传统的机器学习算法一个共同的问题.

深度学习

类似从邮件中提取特征,如何数字化的表达现实世界中的实体,这个在科学计算中一个重要的问题。深度学习解决的核心问题之一就是自动地将简单的特征组合成更加复杂的特征,并使用这些组合特征解决问题。深度学习是机器学习的一个分支,它除了可以学习特征和任务之间的关联之外,还能自动从简单特征中提取更加复杂的特征

图示展现了深度学习和传统机器学习在流程上的差异.
这里写图片描述

深度学习算法可以从数据中学习更加复杂的特征表达。

人工智能

总的来说,人工智能、机器学习和深度学习是非常相关的几个领域。人工智能是一类非常宽泛的问题,机器学习是解决这类问题的一个重要手段,深度学习则是机器学习的一个分支。
这里写图片描述



深度学习工具介绍和对比

深度学习研究的热潮持续高涨,各种开源深度学习框架也层出不穷,下面列出目前一些主流的深度学习开源工具。

主流的深度学习开源工具总结表

工具名称 维护团体 支持语言 支持系统
TensorFlow Google C++、Python Linux、Mac-OS、Windows、Android、iOS
Caffe 伯克利视觉学习中心 C++、Python、MATLAB Linux、Mac-OS、Windows
Theano 蒙特利尔大学 Python Linux、Mac-OS、Windows
Torch Facebook等 Lua、LuaJIT、C Linux、Mac-OS、Windows、Android、iOS
MXNet DMLC C++、Python、Go、R Linux、Mac、Windows、Android、iOS
CNTK MSR Python、C++ Linux、Windows
Deeplearn4j Skymind Java、Scala Linux、Windows、Mac

主流的深度学习框架介绍

TensorFlow

TensorFlow是相对高阶的机器学习库,用户可以方便地用它设计神经网络结构,而不必为了追求效率实现C++或CUDA代码。TensorFlow通过SWIG(Simplified Wrapper and Interface Generator)实现对多种语言的支持,包括有Python、R、C++等

因为TensorFlow有着对多平台、多语言支持特性。并且TensorFlow拥有产品级的高质量代码,背后又有Google强大的开发、维护能力的加持,相比于基于Python的其他框架,TensorFlow更加成熟、更加完善。

Caffe

Caffe是一个被广泛使用的开源深度学习框架,由伯克利视觉学中心进行维护。Caffe的核心概念是Layer,每一个神经网络的模块都是一个Layer。设计网络时,只需要把各个Layer拼接在一起构成完整的网络。

Caffe最初设计目标针对于图像,对于CNN的支持非常好,而对后续的其他网络结构支持不是特别充分。而且Caffe在实现新的Layer时,需要将正向和反向两种计算过程的函数都实现,这对普通用户来说还是很难上手的。

Theano

Theano的核心是一个数学表达式编译器,专门为处理大规模神经网络训练的计算而设计。它可以将用户定义的各种计算编译为高效的底层代码,并链接各种可以加速的库。
Theano是一个完全基于Python的符号计算库,未提供面向底层的C++接口,故移植性差,一般作为研究工具,不作为产品来使用

Torch

Torch给自己的定位是LuaJIT上的一个高效的科学计算库,支持大量的机器学习算法,同时以GPU上的计算优先。Torch的底层语言使用的是Lua,Lua的性能优秀,拥有一个非常直接的调用C程序的接口,可移植强。不过,Lua相对Python还不是那么主流,对大多数用户有学习成本。


TensorFlow简介

编程模型简介

核心概念

TensorFlow中的计算可以表示为一个计算图(computation graph),又称有向图(directed graph)。在计算图中每一个运算操作(operation)将作为一个节点(node),节点与节点之间的连接称为边(edge)。计算图的每一个节点可以有任意多个输入和输出,节点可以算是运算操作的实例化(instance).在计算图的edge中流动(flow)的数据称为张量(tensor),故得名tensorflow.

下面是用Python设计并执行计算图的示例:

# -*- coding:utf-8 -*-
import tensorflow as tf

b = tf.Variable(tf.zeros[100]) #生成100维的向量,初始化为0
W = tf.Variable(tf.random_uniform([784,100],-1,1)) #生成784x100的随机矩阵w
x = tf.placeholder(name="X") #输入的Placeholder

relu = tf.nn.relu(tf.matmul(W,x)+b) #ReLU(Wx+b)
C=[...] #根据ReLU函数的结果计算Cost

s = tf.Session()
for step in range(0,10):
    input=...construct 100-D input array... #为输入创建一个100维的向量
    result = s.run(C,feed_dict={x:input}) #获取Cost,供给输入x
    print(step,result)

计算图代码示例
这里写图片描述

一个运算操作代表一种类型的抽象运算,运算操作可以有自己的属性,所有属性需要预设或者可推断。运算核(kernel)是一个运算操作在某个具体硬件(CPU/GPU等)的实现。在TensorFlow中,可以通过注册机制加入新的运算操作或运算核。

Session是用户使用TensorFlow时的交互式接口,用户可以通过Session的Extend方法创建node和edge,通过run方法执行计算图。在大多数运算,计算图某部分会被重复执行多次,使用Variable可以保存运算过程中tensor至内存或显存中,可用于迭代等操作

实现原理

TensorFlow有一个重要组件client,即客户端,client通过Session的接口与master和多个worker相连。其中每个worker可以与多个硬件设备(device)相连并管理这些硬件

TensorFlow有单机模式和分布式模式两种实现,单机即client、master、worker全部在一台机器上的同一进程;分布式允许client、master、worker在不同的机器的不同进程中,同时由集群调度系统统一管理。

TensorFlow单机版本和分布式版本示例图
这里写图片描述

1.在只有一个硬件的情况下 计算图会按依赖关系被顺序执行。

2.在有多个硬件的情况下
情况就复杂了。主要有二点:

a.每一个节点该让什么硬件设备执行

TensorFlow设计了一套为节点分配设备的策略。

该策略首先计算一个代价模型,估算每一个节点的输入、输出tensor的大小,以及所需要的计算时间。代价模型一部分由人工经验制定的启发式规则得到,另一部分则是对一小部分数据进行实际运算测量得到的

接下来,分配策略会模拟执行整个计算图,在模拟每个节点时,会把能执行该节点的设备都测试一遍,再考虑到代价模型对该节点的计算时间估计,加上数据传输通信时间。最后选择一个综合时间最短的设备作为节点的运算设备

可以看出分配策略是一个简单的贪婪策略虽然不能确保找到全局最优,但可以较快的找到一个不错的节点运算方案。TensorFlow也允许用户对节点的分配设置限制条件。例如这个节点分配GPU类型的设备等。

b.如何管理节点间的通信

当给节点分配设备的方案确定,整个计算图就会被划分为许多子图,使用同一设备并且相邻的节点会划分到同一子图。计算图从x到y的边,就会被取代为发送端的发送节点(send node)、一个接收端的接收节点(receive node),以及从发送节点到接收节点的边。如图
这里写图片描述

这样把数据通信问题转换为send node 和recv node的实现问题,同时可以解决数据重复传输的问题。发送节点和接收节点的设计简化了底层的通信模式。


TensorFlow主要依赖包

本节讲述TensorFlow依赖的两个最主要的工具包—Protocol Buffer和Bazel.

Protocol Buffer

Protocol Buffer是Google开发的处理结构化数据的工具。此处的结构化数据指的是拥有多种属性的数据。Protocol Buffer解决的主要问题就是处理结构化数据,即将数据序列化传输,再将序列化后的数据反序列化.

类似的结构化数据处理工具有XML和JSON格式,例如一段数据

name:zhangsan
id:111111
email:[email protected]

XML格式表达:

<user>
    <name>zhangsan</name>
    <id>111111</id>
    <email>[email protected]</email>
</user>

JSON格式表达:

{
    "name":"zhangsan",
    "id":"1111111",
    "email":"[email protected]",
}

Protocol Buffer格式的数据和XML或JSON格式有比较大的区别,首先,Protocol Buffer序列化数据是二进制流,而且使用Protocol Buffer时需要先定义数据的格式(schema)。还原一个序列化后的数据流,需要使用定义好的schema.这样做的好处是Protocol Buffer序列化后的数据要比XML格式的数据小3到10倍,解析时间快20到100倍。

Protocol Buffer的schema格式

message user{
    optional string name = 1;
    required int32 id = 2;
    repeated string email = 3;
}

Protocol Buffer定义数据格式文件一般保存在.proto文件中,每一个message代表了一类结构化数据。Protocol Buffer里属性可以为基本数据类型,也可以为另一个message.(类似于C语言的struct结构体).

还可以指定数据的属性是optional(可选)还是required(必须的)或者是repeated(可重复的).

Bazel

Bazel3是Google开源的自动化构建工具,相比于传统的Makefile、Ant或者Maven,Bazel在速度、可伸展性、灵活性以及对不同程序语言和平台的支持上都要出色。

Bazel的一个基本概念的项目空间(workspace),一个workspace可以简单的理解为一个文件夹(类似ecplise的工程目录)。在这个文件夹中包含了编译这个软件所需要的源代码以及输出编译结果的软连接地址

一个workspace可以包含一个或多个应用。一个workspace对应的文件夹是这个项目的根目录,在这个根目录中需要一个WORKSPACE文件,该文件定义了对外部资源的依赖关系

在一个workspace内,Bazel通过BUILD文件来找到需要编译的目标,BUILD文件指定了每一个编译目标的输入、输出以及编译方式
以Python为例,B**azel对Python支持的编译方式有三种:py_binary(可执行程序)、py_library(链接库)和py_test(测试程序)**。例如在一个workspace中有4个文件:WORKSPACE、BUILD、hello_main.py和hello_lib.py

BUILD  #指定需要编译的目标
hello_lib.py  #库文件
hello_main.py  #编译目标
WORKSPACE  #给出此项目的外部依赖关系(可为空)

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(
    name = "hello_lib",
    srcs=[
        "hello_lib.py",
    ]
)
py_binary(
    name = "hello_main",
    srcs=[
        "hello_main.py",
    ],
    deps=[
    ":hello_lib",
    ],
)

BUILD文件是由一系列的编译目标组成,每一个编译目标第一行指定编译方式,例如示例中的py_library和py_binary。每一条编译目标的主体是编译的具体信息,具体信息是通过name、srcs,deps等属性完成。其中name是一个编译目标的名称,srcs给出了编译所需要的源代码(可以为列表),deps给出了编译需要的依赖关系.



TensorFlow测试样例

再安装好TensorFlow后,安装参考https://blog.csdn.net/u011974639/article/details/72851153。

这里采用Python语言。编写一个简单的TensorFlow样例程序实现两个向量求和:

import tensorflow as tf

a = tf.constant([1.0,2.0],name='a') #定义两个常量
b = tf.constant([2.0,3.0],name='b') 

result = a + b #向量的加法

sess = tf.Session()  #生成一个会话,通过会话计算结果
print(sess.run(result))

输出结果:[3. 5.]


参考资料

《TensorFlow实战Google深度学习框架》 - 才云科技 郑泽宇等
《TensorFlow实战》 -黄文坚等





猜你喜欢

转载自blog.csdn.net/qq_33144323/article/details/80791957