Tensorflow之旅(2)(戴德曼翻译)

作者: 戴德曼 | 来源:发表于2016-12-06 00:35 被阅读761次

    三, Tensorflow编程模型

    在这一章,我们将深度讨论Tensorflow的计算范式。开始,我们会研究Tensorflow的基本架构和计算原理,解释机器学习算法如何在Tensorflow里面使用数据流图语言表征。接下来,我们研究Tensorflow的运行模型,也就是Tensorflow如何把Tensorflow图转化为运行状态。然后,我们调查Tensorflow内在的,针对软硬件的不同算法优化。最后,我们列举一系列算法扩展,以支撑用户在Tensorflow对于计算模型,逻辑模型训练。

    A. 计算图架构

    在Tensorflow里面,机器学习算法被表证为计算图。计算图或者数据流图是一种有向图。有向图的顶点或者节点代表运算过程,有向图的边代表运算过程之间的数据流。如下图所示,先看左边,输出变量z是输入x和y的二值运算的结果,那么画两条分别从x和y向z的有向边,并且在z上标明运算加号。一个更加完整和复杂的数据流图在右边。下面,对于数据流图里面的元素(operation - 算子,tensor - 张量,variable - 变量和session - 过程)进行更为详尽的讨论。

    1)Operations(算子):使用图来表示一个算法的主要好处不仅仅是直观展示计算模型之间的依赖和关联,而且能够更普适的定义运算节点。在Tensorflow里,node(节点)代表着算子,也就是一种运算,更精确来说,代表了输入的数据在有向图上,如何流经这个节点【8】。一个算子可以是0到多个输入,也能产生0到多个输出。因此,一个算子代表一个数学等式,一个变量,一个常量,一个有向控制流,一个文件I/O操作或者甚至是一个网络通讯连接端口。在算子可以表达为一个常量或者变量不是像表达成一个函数那样直观,但是一个常量可以被当成一个没有输入,而且输出恒定的运算。相似的情况也适用于表征一个变量,也就是没有输入,输出当前状态或者当前变量的值。

            任何算子必须要严格的定义和实现。在论文【8】的研究,任何一种实现被当作一个算子的核函数。一种特定的核函数的具体编程都是针对某种硬件,比如CPU或者GPU的运算。

    2)Tensors(张量):在Tensorflow里面,代表数据流从一个算子流向另一个算子的边称之为张量。一个张量是一个具有固定类型同类数据的多维集合。张量维度也称为rank(阶)。张量的形状(shape)描述张量大小的元祖(tuple)。比如,对于每一个维度的元素个数。从数学的观点来看,张量是一个二维矩阵加一个表达张量阶的一维向量或者标量的生成物。

            从计算图的观点来看,张量是表征通向输出的算子的符号把手(symbolic handle)。在内存里,张量本身并不包含和存储数据,但是它提供了张量代表的数据访问的接口。在Tensorflow里面创建一个算子的时候,比如x+y,返回一个张量对象。然后,这个张量可能作为其他计算的输入,从而张量是连接源算子和目的算子的边。基于这样的认知,数据在Tensorflow的图中川流不息。

            除了通常意义的张量,Tensorflow还支持一种称之为稀疏张量(SparseTensor)的数据结构。这是一种空间有效字典类的数据表证,也就是大量零值的稀疏张量。

    3)Variables(变量):在通常情况,比如做随机梯度下降的单次运算的时候,机器学习模型的图会从开始到结束反复运算多次。在两次调用之间,图中主要的张量并不会被保存。但是整体上对于图的求值是需要保存状态的,比如神经网络的权重和参数。因此,变量正是为了满足这一需求而创建的算子,能够被添加到计算图中。

            变量可以看成是在内存中持久不变的张量副本。因此,变量的定义需要形状和固定数据类型两个特征。Tensorflow提供了一系列赋值函数完成图运算。

            在Tensorflow的图中创建一个变量节点的时候,需要定义相应的张量,这样在图运行时,变量可以随之初始化。变量的形状和数据类型也来自于这个初始器。有趣的是,变量自己并不存储这个初始的张量,相反构造一个变量会增加三种不同的节点:

            1)变量节点,保存持久状态。

            2)保存初始值的算子,通常是一个常量。

            3)初始器算子,在图求值的时候把初始值赋值给变量张量。

            一个例子如下图所示:三个节点代表变量定义。第一个变量v是一个变量的张量值在内存中的持久副本。第二个变量i是给变量提供初始值(可以是任意张量)的节点。最后一个赋值节点把初始值赋给变量,在赋值节点产生一个新的张量具有初始值的变量v‘。这样,v'可能作为另外算子的一个输入。

    4)Session(会话):在Tensorflow里面,算子的运算和张量的估值会在一定的上下文中进行,我们称之为Session(会话)。会话的责任之一就是将分配和管理资源的工作封装起来,比如缓存变量。更进一步来看,Tensorflow库里面的Session接口提供了一个run函数,作为整个图计算的执行入口。这个方法将输入节点带入整个图计算的过程,并且根据图定义返回相应的结果。另外,一个可选的映射,即从任意节点到相应替代值的映射,被称为feed nodes(反馈节点),可能也被run调用【8】。

            在调用run的时候,Tensorflow将会出输出节点开始反向分析计算图的节点依赖,计算所有节点的传递闭包。这些节点可能被分配到一个或者多个物理计算单元(CPU,GPU等),这些计算单元可以在一台或者多台机器上。分配的规则由Tensorflow的placement algorithm(分配算法)定义。这个算法会在本文后面部分谈到。此外,因为存在节点评估顺序的特定显式可能性,姑且称为控制依赖关系,执行算法将确保这些依赖关系不变。

    B. 执行模型

            如刚刚讨论的那样,对于执行各种计算图元素的组成,TensorFlow划分其任务在四个不同的组中实现:客户端,主控端,一组工作进程和一些设备。 当客户端通过会话的run调用请求评估一个TensorFlow图,这个请求被发送到主控端,主控端将任务委托给一个或多个工作进程处理和协调它们的执行。 每个工作进程随后负责一个或多个设备真实的运算和处理操作。

            在这个模型中,有两个扩展度。 第一扩展度是关于执行图运算机器的数量。 事实上,第二扩展度指的是在每台机器上,可能会有更多设备,例如,五个独立的GPU和/或三个CPU。 为此,存在两个“版本”的TensorFlow,一个用于在单个机器上本地执行(但可能有许多设备),一个支持分布式在许多机器和许多设备上实现。

            上图展示了执行模型和响应扩展度。而且Tensorflow在开始发布的时候,确实只公布了单机版本,而多机版本是在2016年的4月13日才姗姗来迟【16】。

          1)Devices(设备):设备是在TensorFlow执行模型中最小,最基本的实体。 上图中的所有节点,也就是每个算子的内核,最终都必须是映射到要执行的可用设备。 在实际执行过程中,设备通常是CPU或GPU。 然而,TensorFlow能够支持更多种类的物理执行单元。 例如,在2016年5月,谷歌宣布其定制的ASIC(专用集成电路)张量处理单元(TPU),是专门用于快速张量计算[17]。 因此,Tensorflow是可以容易地集成新出现的设备类新型硬件。

            为了整体评估在某个设备上的节点,主控端生成相应的工作进程。 作为工作进程可以在单个机器上管理一个或多个设备,设备是不仅通过名称标识,还标识其所在工作进程组的索引。 例如,特定组中的第一CPU可以由字符串“/ cpu:0”标识。

            2)placement algorithm(分配算法):为了决定哪一个节点分配给那一个设备,Tensorflow使用了一种特定分配算法。该算法模拟计算图的运算和遍历从输入张量到输出张量的全部节点。在遍历节点过程中,要决定哪一个可用设备D={d1,d2,...dn}运行给定节点v,算法使用一个成本模型Cv(d)。这个成本模型考虑四种信息来决定最优设备d = arg mind∈D Cν(d):

            1)在给定设备上是否存在该节点的实现(核函数)。比如,如果任何一个GPU上都不存在某种特定算子,那么选择任意GPU的成本都是无限的。

            2)估计一个节点的输入和输出丈量的大小(按字节计算)。

            3)给定设备对于核函数的期望计算时间。

            4)对于输入丈量到相应算子跨设备或者跨机器的传输成本进行启发式估算,万一该节点已经赋值的输入张量所在设备和当前设备并不一样。

        3)cross-device execution(跨设备运行):只要是用户拥有多个设备,Tensorflow通常都会把节点分配到这些设备上去。这个过程是通过把节点分类,然后一类分配到一个设备。这样分配的话,必须处理跨设备分配的节点依赖问题。让我们考虑A和B这样两个设备,其中节点v在设备A上。如果v的输出张量作为另外两个算子α, β的输入,同时α, β在设备B上。那么就存在从A到B的跨设备的边ν → α 和 ν → β。如下图所示:

            在实际运行中,需要使用一些传输手段完成v的输出张量从A设备,比如GPU,到设备B,比如CPU的过程。如下图所示,send和recv两类节点被生成完成这个传输过程。

            最后,Tensorflow使用“规范化”来优化(send,recv)对。在上图所示的例子中,我们看到两个recv节点,分别连接α, β。然而,一种等价的,但是更为有效的办法就是在设备B上只运行一个recv,如下图所示。

    相关文章

      网友评论

      • 智行知者:最近在华为研究知识工作自动化,也开始接触AI,ML,后面有应用问题还得请教哥哥您,:smile:
        戴德曼: @韦庆 不客气

      本文标题:Tensorflow之旅(2)(戴德曼翻译)

      本文链接:https://www.haomeiwen.com/subject/ykvkmttx.html