TensorFlow实战学习笔记(一)

1.1 TensorFlow概要

TensorFlow是Google第二代分布式机器学习系统,于2015年11月在GitHub上开源,且在2016年4月补充了分布式版本,并与2017年1月发布了1.0版本的预览,API接口趋于稳定。目前TensorFlow仍处于快速开发迭代中。
    TensorFlow的官网地址:www.tensorflow.org
    GitHub网址:github.com/tensorflow/tensorflow
    模型仓库地址:github.com/tensorflow/models
    TensorFlow即是一个实现机器学习算法的接口,也是执行机器学习算法的框架。它前端支持Python、C++、Go、Java等多种开发语言,后端使用C++、CUDA等写成。TensorFlow实现的算法可以在众多异构的系统上方便地移植,比如Android手机、iPhone、普通的CPU服务器,乃至大规模GPU集群。除了执行深度学习算法,TensorFlow还可以用来实现很多其他算法,包括线性回归、逻辑回归、随机森林等。

1.2 TensorFlow编程模型简介

1.2.1 核心概念

    TensorFlow中的计算可以表示为一个有向图(directed graph),或称为计算图(computation graph),其中每一个运算操作(operation)将作为一个节点(node),节点之间的连接称为边(edge)。这个计算图描述了数据的计算流程,它也负责维护和更新状态,用户可以对计算图的分支进行条件控制或循环操作。计算图中的每一个节点可以有任意多个输入和输出,每个节点可以描述了一种运算操作,节点可以算是运算操作的实例化(instance)。在计算图的边中流动(flow)的数据被称为张量(tensor),故得名TensorFlow。而tensor的数据类型可以是事先定义的,也可以根据计算图的结构推断得到。下面是用Python设计并执行计算图的示例。

import tensorflow as tf
b = tf.Variable(tf.zeros([100])) #生成100维的向量,初始化为0
w = tf.Variable(tf.random_uniform([784,100],-1,1)) #生成784*100的随机矩阵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中,可以通过注册机制加入新的运算操作或者运算核。表1-2所示为部分TensorFlow内建的运算操作。
Session是用户使用Tensorflow时的交互式接口。用户可以通过Session的Extend方法添加新的节点和边,用以创建计算图,然后就可以通过Session的run方法执行计算图:用户给出需要计算的节点,同时提供输入数据,Tf就会自动寻找所有需要计算的节点并按依赖顺序执行它们。对绝大多数的用户来说,他们只会创建一次计算图,然后反复地执行整个计算图或其中的一部分图。在大多数运算中,计算图会被反复执行多次,而数据也就是tensor并不会被持续保留,只是在计算图中过一遍。

1.2.2 实现原理

(1)工作组件

Client:客户端通过Session的接口与master及多个worker相连。

Worker:worker可以与多个硬件设备相连,比如CPU或GPU,并负责管理这些硬件。

Master: master则负责指导所有worker按流程执行计算图。

TensorFlow中每一个worker可以管理多个设备,每一个设备的name包含硬件类别、编号、任务号(单机版本没有)。

单机模式:/job:localhost/device:cpu:0
分布式模式: /job:worker/task:17/device:gpu:3

(2)运行模式

单机模式:计算图会按依赖关系被顺序执行。当一个节点的所有上游依赖都被执行完时(依赖数为0),这个节点就会被加入ready queue以等待执行;同时,它下游所有节点的依赖数减1,实际上这就是标准的计算拓扑序的方式。

分布式模式:设计了一套为节点分配设备的策略。这个策略首先需要计算一个代价模型,这个代价模型估算每一个节点的输入、输出tensor的大小,以及所需的计算时间。代价模型一部分由人工经验制定的启发式规则得到,另一部分则是由对一小部分数据进行实际运算而测量得到的。当给节点分配设备的方案被确定,整个计算图就会被划分成许多子图,使用同一个设备且相邻的节点会被划分到同一个子图。
同时,从单机单设备的版本改造为单机多设备的版本也非常容易,下面的代码只添加加粗的这一行,就实现了从一块GPU训练到多块GPU训练的改造。

(3)分布式TensorFlow的容错性

容错性也是分布式TensorFlow的一个特点。故障会在两种情况下被检测出来。

①信息从发送节点传输到接受节点失败时。

②周期性的worker心跳检测失败。

当一个故障被检测到时,整个计算图会被终止并重启。

1.2.3拓展功能

(1)TensorFlow原生支持自动求导。

(2)TensorFlow还支持单独执行子图,用户可以选择计算图的任意子图,并沿某些边输入数据,同时从另一些边获取输出结果。

(3)TensorFlow支持计算图的控制流,比如:if-condition和while-loop,因为大部分机器学习算法需要反复迭代,所以这个功能非常重要。

(4)TensorFlow的数据输入除了通过feed node,也有特殊的input node可以让用户直接输入文件系统的路径,例如一个Google Cloud Platfrom的文件路径。

(5)队列(queue)也是TensorFlow任务调度的一个重要特性,这个特性可以让计算图的不同节点异步地执行。

(6)容器(Container)是TensorFlow中一种特殊的管理长期变量的机制,例如Variable对象就存储在容器中。

1.2.4性能优化

(1)TensorFlow同时支持几种高度优化的第三方计算库。

线性代数计算库:Eigen

矩阵乘法计算库:BLAS、cuBLAS(CUDA BLAS)

深度学习计算库:cuda-convnet、cuDNN

(2)TensorFlow提供了三种不同的加速神经网络训练的并行计算模式。

数据并行:通过将一个mini-batch的数据放在不同的设备上计算,实现梯度计算的并行化。计算还可以分同步、异步和混合三种方式。同步的优点是没有梯度干扰,缺点是容错性差,一台机器出现问题后要重跑。异步的优点是有一定的容错性,但是受梯度干扰问题,导致每一组梯度的利用效率都下降了。一般来说,同步训练的模型精度较好。

模型并行:将计算图的不同部分放在不同的设备上运算,可以实现简单模型的并行,其目标在于减少每一轮训练迭代的时间,不同于数据并行同时进行多份数据的训练。

流水线并行:和异步的数据并行很像,只不过是在同一个硬件设备上实现并行。大致思路是将计算做成流水线,在一个设备上连续地并行执行,提高设备的利用率。

参考文献:
《TensorFlow实战》
https://blog.csdn.net/program_developer/article/details/78861954

猜你喜欢

转载自blog.csdn.net/xavier_muse/article/details/90613033