四时宝库

程序员的知识宝库

tensorflow基础:数据流图的定义与运行——tf.Session对象

本文将脱离tensorflow的语境,介绍一些数据流图的基础知识,内容包括节点,边和节点以来关系。此外,为对一些关键原理进行解释,本文还提供了若干实例。

1.数据流图简介

借助Tensorflow api用代码描述的数据流图是每个tensorflow程序的核心。其本质是一组链接在一起的函数,每个函数都会将其输出传递给0个,1个或多个位于这个级联链上的其他函数。

这是一个最简单的数据流图。加法运算用圆圈表示,它接收两个输入1和2,并将它们的和通过3输出。计算公式可以简单写为 f(1,2)=1+2=3.

节点(node):在数据流图中,节点通常以圆圈,椭圆或方框表示,代表了对数据所做的运算或某种操作。

边(edge):则对应于向节点传入和传出的实际数值,通常用箭头表示。也可视为不同operation之间的连接。

再看个复杂一点的例子,input节点的作用仅仅是传递他们的输入值,也可以看成函数f(x)=x。

因此上图的计算过程可以写为f(5,3)=(5*3) +(5+3) = 23. 这里需要注意的是节点c和d没有依赖关系,因此他们的执行顺序是不确定。当然不管谁先执行都会得到正确的结果。

继续复杂化数据流图。现在节点b的值传递给了节点e,节点e就不是简单的加运算了,而是求和运算。

2.数据流图的依赖关系

在数据流图中,节点之间的某些类型链接是不允许的,例如造成循环依赖(circular dependency)的链接。

首先什么是依赖?如上图,假如节点c因为某个异常没有输出,那么最终节点e的计算结果就不正确了,那么节点e就依赖节点c。实际上节点a出现异常,节点e也没法计算,因此节点a和b也是节点e的依赖节点。

什么是独立节点了?假如两个节点的输出彼此必须要来自对方的任何信息,那么就称这两个节点相互独立。如上图节点a和节点b是独立的;节点c和节点d也是独立的。独立节点的计算可以不分先后的。

循环依赖:假如两个节点相互需要依赖对方,就形成循环依赖。也就是有向图中出现了环路。

由于循环依赖容易造成软件的异常,tensorflow中真正的循环依赖是无法表示的。实际使用中,可以通过对数据流图进行有限次的复制,然后 把本轮迭代的输出与下轮的输入串联,这称为数据流图的展开(unrolling)。如下图所示:

3.tensorflow中怎么定义数据流图

当你掌握了各种数学概念,并学会如何实现它们时,对tensorflow核心工作模式的理解将有助于你踏实地开展工作。而它的工作模式只有两个步骤:定义数据流图和运行数据流图。

先看一个简单的例子。

用于表示该数据流图的tensorflow代码如下:

import tensorflow as tf #导入tensorflow库,并赋予它一个别名tf,方便后续使用。

a = tf.constant(5,name="input_a")

b = tf.constant(3,name="input_b") #定义了input节点,引用了operation: tf.constant(). tensorflow中每个节点都被称为一个operation(简记为op),name可以用于对所创建的节点进行标识。

c = tf.mul(a,b,name="mul_c")

d = tf.add(a,b,name="add_d") #定义节点c和d。注意我们无需专门对边进行定义,tensorflow在创建节点时已经包含了相应的op完成计算所需的全部输入。tensorflow会自动绘制必要的链接。

e=tf.add(c,d,name="add_e)

以上完成了一个tensorflow的数据流图定义,但是它仅仅时定义,不会自己运算。要想得到输出结果,我们需要运行数据流图。

sess=tf.Session()

sess.run(e)

Session对象在运行时负责对数据流图进行监督,并且时运行数据流图的主要接口。如果我们只想的到节点c的结果,需要使用如下代码

sess.run(c) #这个输出不会导致整个数据流图都计算一遍,而是只运行到节点c为止。

最后,我们建议运行一下sess.close()函数。虽然运算完成后会自动关闭,但手动运行一次该函数,不失为一个良好的编程习惯。

本文重点介绍了数据流图的概念和实现方式。为了不让问题复杂化,我们使用了标量作为数据流图的输入。下一次我们重点讨论以下张量(或者说矩阵)的数据流图的实现。

发表评论:

控制面板
您好,欢迎到访网站!
  查看权限
网站分类
最新留言
    友情链接