初步介绍
Google 于2011年推出人工深度学习系统——DistBelief。通过DistBelief,Google能够扫描数据中心数以千计的核心,并建立更大的神经网络。Google 的这个系统将Google 应用中的语音识别率提高了25%,以及在Google Photos中建立了图片搜索,并驱动了Google的图片字幕匹配实验。但它很难被设置,没有开源。
2015年11月,第二代分布式机器学习系统Tensorflow在github上开源!
2016年4月,发布了分布式版本!
2017年1月,发布了1.0预览版。API接口趋于稳定。同年3月发布了可用于工业级场景的1.0正式版!
Tensorflow优点:
1.既是一个实行机器学习算法的接口,同时也是执行机器学习算法的框架
2.Tensorflow 前端支持python,C++,GO,java等多种开发语言
3.Tensorflow 后端使用C++,CUDA等写成
4.Tensorflow可以在众多异构系统平台上移植:Android,iphone,TV,普通的CPU服务器以及大规模GPU集群等
5.Tensorflow 除了可以执行深度学习算法,还可以用来实现很多其他算法:线性回归,随机森林,支持向量机
6.Tensorflow可以建立大规模深度学习模型的应用场景:语音识别,自然语言处理,机器视觉,机器人控制,信息抽取,医药研发等等。
Tensorflow 基础架构
前端负责构造计算图,后端负责执行计算图。就像是前端是建筑专业,后端是土木专业。
Tensorflow 核心概念
1.计算图
2.操作
3.变量
4会话
一、计算图
计算图又被称为有向图,数据流图。数据流图用结点(nodes)和线(edges)的有向图来描述数学计算,结点一般用来表示施加的数学操作,但也可以表示数据输入的起点或者输出终点,线表示结点之间输入/输出的关系,这些数据“线”可以运输size可动态调整的多维数据数组,即张量(tensor)。
(注:有一类特殊边中没有数据流动,这种边被称为依赖控制,作用是控制结点的执行顺序,它可以让起始节点执行完毕再去执行目标节点,用户可以使用这样的边进行灵活控制,比如限制内存使用的最高峰值)
例:
二、操作
一个运算操作代表了一种类型的抽象运算,比如矩阵乘法或向量加法
一个运算操作可以有自己的属性,但是所有属性都必须被预先设置,或者能够在创建计算图时根据上下文推断出来
通过设置运算操作的属性可以用来支持不同的tensor元素类型,比如让向量加法支持浮点数或者整数
运算核(kernel)是一个运算操作在某个具体的硬件(cpu或gpu)的实现
在Tensorflow中可以通过注册机制加入新的运算操作或者为已有的运算操作添加新的计算核
三、变量
当训练模型时,用变量来存储和更新参数。变量包含张量(tensor)存放在内存的缓存区。建模时,他们需要明确的初始化,模型训练后他们必须要被存储到磁盘。这些变量的值可在之后模型训练和分析时被加载。
创建:当创建一个变量时,你将一个张量作为初始值传入构造函数variable()。Tensorflow提供了一系列操作符来初始化张量,初始值是常量或者随机值
注意,所有这些操作符都是需要你指定张量的shape。那个形状自动成为变量的shape。变量的shape通常是固定的,但Tensorflow提供了高级的机制来重新调整其行列数。
调用tf.Variable()添加一些操作(Op,operation)到graph:
1.一个variable 操作存放变量的值
2.一个初始化op将变量设置为初始值。这事实上是一个tf.assign操作
3.初始值的操作,例如示例中对biases变量的zeros操作也被加入了graph
tf.Variable的返回值是Python的tf.Variable类的一个实例
变量的初始化
一次性全部初始化
变量的初始化必须在模型的其他操作运行之前先明确地完成。最简单的方法是添加一个给所有变量初始化的操作,并在使用模型之前首先运行那个操作。
使用tf.initialize_all_variables()台南佳一个操作对变量做初始化。记得在完全构建好模型并加载之后再运行那个操作。
自定义初始化
tf.initialize_all_variables()函数便捷地添加一个op来初始化模型地所有变量。你也可以给它出入一组变量进行初始化。
由另一个变量初始化
你有时候会需要用另一个变量地初始化值给当前变量初始化。由于tf.initialize_all_variables()是并行地初始化所有变量,所以再有这种需求地情况下需要小心。
用其他变量地值初始化一个新的变量时,使用其他变量的initialized_value()属性。你可以直接把已初始化的值作为新变量的初始值,或者把它当作tensor计算得到一个值赋予新变量
四、会话
完成全部的构建准备、生成全部所需的操作之后,我们就可以建立一个tf.Session,用于运行图标
sess=tf.Session()
另外,也可以利用with代码生成Session,限制作用域:
with tf.Session() as sess:
Session函数没有传入参数,表明该代码将会依附于(如果还没有创建会话,则会创建新的会话)默认的本地会话。
生成会话之后,所有tf.Variable实例都会立即通过调用各自初始化操作中的sess.run()函数进行初始化
Tensorflow 实现原理
TensorFlow有一个重要组件client,也就是客户端,它通过Session的接口与master以及多个worker相连接。每一个worker可以与多个硬件设备连接,比如cpu和GPU,并负责管理这些硬件。Master则负责指导所有的worker按照流程执行计算图。
Tensorflow有单机模式和分布式模式。单机模式下,client,master,worker全部在同一台计算机上的同一个进程中。分布式模式允许client,master,worker在不同机器的不同进程中,同时由集群调度系统统一管理各项任务
TensorFlow中每一个worker可以管理多个设备,每一个设备的name包含硬件类别、编号、任务号(单机版本没有)。
TensorFlow为CPU和GPU提供管理设备的对象接口,每一个对象负责分配、释放设备内存,以及执行节点的运算核。TensorFlow中的Tensor是多维数组,数据类型支持8位至64位的int,以及IEEE标准的float.double.complex.string。
在只有一个硬件设备的情况下,计算图会按照依赖关系被顺序执行。当一个节点的所有上游依赖全部执行完毕(依赖数==0),这个节点就会被加入就绪队列(ready queen)以等待执行。同时这个节点的下游节点的依赖数自动减1。
当多个设备的时候,情况就变得复杂了。主要有两大难点:
(1)每一个节点该让什么设备执行?
TensorFlow设计了一套为节点分配设备的策略。这个策略首先需要计算一个代价模型。代价模型首先估算每一个节点的输入,输出Tensor的大小,以及所需要的计算时间。代价模型一部分由人工经验指定的启发式规则得到,另一部分则是对一小部分数据进行实际运算测量得到。
接下来,分配策略会模拟执行整个计算图,从起点开始,按照拓扑序执行。并在执行一个节点时,会把每一个能执行这个节点的设备都测试一遍,测试内容包括计算时间的估算以及数据传递所需要的通信时间。最后选择一个综合时间最短的设备计算相应的节点。这是一个简单的贪婪策略。
除了运算时间,内存的最高使用峰值也会被考虑进来。
Tensor flow的节点分配策略仍在不断优化改进。未来,可能会用一个强化学习的神经网络来辅助节点分配。同时,用户可以自定义某些分配限制条件。
(2)如何管理节点间的数据通信?
当给节点分配设备的方案被确定,整个计算图就会被划分为许多子图了,使用同一个设备并且相邻的节点会被划分到同一个子图。然后计算图中从x到y的边,会被取代为一个发送端的发送节点(send node),一个接收端的接受节点(receive node),以及从发送节点到接受节点的边。
把数据通信的问题转换为发送节点和接受节点的实现问题,用户不需要为不同的硬件环境实现通信方法。
两个子图之间可能会有多个接受节点,如果这些接受节点接受的都是同一个tensor,那么所有这些接受节点会被自动合并为一个,避免了数据的反复传递和设备内存占用。
发送节点和接受节点的设计简化了底层的通信模式,用户无需设计节点之间的通信流程,可以让同一套代码自动扩展到不同的硬件环境并处理复杂的通信流程。
从单机单设备的版本改造为单机多设备的版本也比较容易。下面的代码只添加了一行,就实现了从一块GPU到多块GPU训练的改造
参考文献:
http://www.studyai.com/article/a187469c758d4a2884c0fa733fdfe899