1.自动求导java
2.子图的执行node
3.计算图控制流python
4.队列/容器算法
当计算tensor C关于tensor W的梯度时,会先寻找从W到C的正向路径,而后从C回溯到W,对这条回溯路径上的每个节点增长一个对应的求解梯度的节点,根据链式法则计算总的梯度。这就是反向传播算法。这些新增的节点会计算梯度函数,好比[db,dW,dx]=tf.gradients(C,[b,w,x])性能优化
自动求导虽然对用户很方便,但伴随而来的是Tensorflow对计算的优化(好比节点分配设备的策略)变得很麻烦,尤为是内存使用问题。如上图在反向传播过程当中,咱们仍须要用到计算图开头的tensor如W,x这些数据,所以它们仍需占用内存。服务器
Tensorflow支持单独执行子图,用户能够选择计算图的任意子图,并沿着某些边输入数据,同时从另外一些边获取输出结果。session
Tensorflow用节点名加port的形式指定数据。例如,bar:0表示名为bar的节点的第一个输出。在调用Session的run方法执行子图时,用户能够选择一组输入数据的映射,好比name:port->tensor;同时,用户必须指定一组输出数据,好比name[:port],来选择执行哪些节点,若是port也被选择,那么这些port输出的数据将会做为Run函数调用的结果返回。机器学习
当你指定好一个输入输出的子图时,震哥哥计算图就会根据新指定的输入输出进行调整,输入数据的节点会链接一个feed_node,输出数据的节点会链接一个fetch_node。Tensorflow会根据输出数据自动推导出哪些节点须要被执行。异步
大部分的机器学习算法须要大量的逻辑判断和反复迭代,因此计算图的执行控制方式显得很是重要。分布式
Tensorflow提供Switch Merge两种operator,能够根据某个布尔值跳过某段子图,而后把两段子图的结果合并,实现if-else的功能。
Tensorflow还提供了Enter,Leave以及NextIteration来实现循环和迭代。在使用高阶语言如python,java的if-else,while.for循环设计计算图的执行流程时,这些控制流会被自动编译为上述那些operator。Loop的每一次循环,会有惟一的tag。它的执行结果会输出成frame,这样用户能够方便的查询结果日志。
Tensorflow的控制流支持分布式,每一轮循环中的节点可能不一样机器的不一样设备上。分布式控制流的实现方式也是经过对计算图进行重构改写,循环内的节点会被划分到不一样的小的子图上。每一个子图链接控制节点,实现本身的循环。循环完成后,循环终止信号会被发送到其余子图。
队列是Tensorflow任务调度的一个重要特性。这个特性可让计算图的不一样节点异步的执行。使用队列的目的是当一个batch的数据运算时,提早从磁盘读取下一个数据,减小磁盘I/O的阻塞时间。同时还能够异步的计算许多梯度,在组合成一个更复杂的总体梯度。
除了传统的先进先出(FIFO)队列。Tensorflow还实现了洗牌队列(shuffling quene),用来知足某些机器学习算法对随机性的要求,对损失函数优化以及模型收敛会有帮助。
容器是TensorFlow中一种特殊的管理长期变量的机制,例如Variable变量对象就存放在容器中。每个进程会有一个默认的容器一直存在,直到进程结束。使用容器还可以在不一样的计算图的不一样session之间共享一些状态变量。
1.运算操做调度
2.异步计算支持
3.第三方计算库
4三种并行计算模式
Tensorflow中有不少高度抽象的运算操做,这些运算操做可能由不少复杂的计算组合而成。当有多个高阶运算操做同时存在时,他们的前几层多是彻底一致的重复计算(输入与运算内容一致)。TensorFlow会自动识别这些重复计算,同时改写计算图,只执行一次重复的计算,而后把这些高阶运算的后续计算所有链接到这些共有的计算上,避免冗余计算。
同时,巧妙地安排运算地顺序也能够极大地改善数据传输与内存占用地问题。好比,适当调整顺序以错开某些大块数据同时在内存中地时间,对于显存容量比较小的GPU来讲,相当重要。
TensorFlow也会精细的安排接受节点的执行时间,若是接受节点过早的接受数据,那么数据会过早的堆积在设备内存中,因此,Tensorflow设计了接受策略,在恰好须要数据时词汇接收数据
TensorFlow提供异步计算支持。这样线程执行时就无需一直等待某个计算节点完成。有一些节点,好比receive,enqueue,dequeue就是异步的实现。这些节点没必要因等待I/O而阻塞一个线程继续执行其余任务
(1)数据并行模式
(2)模型并行模式
(3)流水线并行模式
经过把一个mini-batch的数据放在不一样设备上计算,实现梯度计算的并行化。例如把1000个样本的mini-batch拆分红10份,每份100个样本,进行并行计算。完成后,把这10份梯度数据合并获得最终梯度并更新到共享的参数服务器。这样的操做会产生许多彻底同样的子图的副本,在client上能够用一个线程同步控制这些副本运算的循环。
数据并行模式能够用异步方式来实现,使用多个线程控制梯度计算,每个线程计算完成后,异步地更新模型参数。同步的方式至关于用一个较大的mini-batch,优势是没有梯度干扰,缺点是容错性差。一台机器出问题,就须要重头再来。异步的方式优势是容错性好,可是由于梯度干扰的问题,每组的梯度利用率降低
模型并行就是将计算图的不一样部分放在不一样的设备上运算,能够实现简单的模型并行,其目标在于减小每一轮训练迭代的时间,不一样于数据并行同时进行多份数据的训练。模型并行须要模型自身有大量的互不依赖或者依赖程度不高的子图。在不一样硬件环境上性能损耗不一样。
和异步数据并行很像。只不过是在同一个硬件设备上实行并行。大体思路是将计算作成流水线,在一个设备上连续的并行执行,提升设备利用率。
参考文献:http://www.studyai.com/article/2caa27c6bcbe4add99faa4fdf4d02106