白话TensorFlow +实战系列(一) 详解Tensor与Flow

TensorFlow作为目前最欢迎的深度学习框架(是的,你没看错,是最受欢迎,GitHub上已超越Caffe),是由Google开源的一个计算框架,该框架已经很好的集成了深度学习的各种算法,所以说是非常方便,并且与Keras也兼容,再加上Google强大的资源,可以说选TensorFlow进行深度学习是非常明智的。TensorFlow这个名字是由Tensor(张量)与Flow(流)两部分组成,一看就知道这两部分格外重要,不然Google也不会随便拿来命名,是吧。所以接下来就挨个详细解剖这俩部分。

Tensor,翻译成张量,是TensorFlow中管理数据的形式,其中Tensor并不保存真正的数据,他保存的是得到这些数字的计算过程。刚开始接触TensorFlow的话,很不容易明白这是什么吧,你可以换个方式理解,从tensor的功能上可以把他看作成多维数组(只是用于理解,并不等同于数组!后面会解释道),比如,一个shape=[2,3]的张量可以理解成一个大LIST中有两个小list,例如,大LIST=[[1,2,3],[4,5,6]]。而每一个小list由三个数据构成,list1=[1,2,3],list2=[4,5,6],高维度的Tensor依此类推,大LIST套小list,环环套。再次说明一下,这个只是为了理解,张量并不等同于列表!

张量是TensorFlow中基本的数据结构,我们可以用TensorFlow定义一个W(关于TensorFlow定义变量的方法以后会讲,现在直接运用)

《白话TensorFlow +实战系列(一) 详解Tensor与Flow》
《白话TensorFlow +实战系列(一) 详解Tensor与Flow》

我们通过tf.constant把W定义成了一个shape=(2,3)的张量,当我们直接打印W时,会发现并没有像数组那样直接打印出来,而是一个关于Tensor的解释。如图:

《白话TensorFlow +实战系列(一) 详解Tensor与Flow》
《白话TensorFlow +实战系列(一) 详解Tensor与Flow》

由图可以看见,关于Tensor的解释主要由三个属性组成:名字(name)、维度(shape)、类型(type)。其中第一个属性名字给出了这个张量是怎么来的,”Const:0″表示的是这个张量由计算节点Const(关于节点的解释下面介绍Flow的时候给出)输出的第一个结果得来;第二个属性shape给出了这个张量的维度信息,shape=(2,3)说明了张量是个二维数组,也可理解为一个2 x 3的矩阵;第三个属性说明了张量的数据类型,TensorFlow支持14种不同的类型:浮点型float(tf.float32, tf.float64), 整数型int(tf.int8, tf.int16, tf.int32, tf.int64, tf.int128), 布尔型(tf.bool),复数(tf.complex64, tf.complex128),值得注意的一点时,当两个张量进行运算时,数据类型要相同,不然TensorFlow会报错。由此可见我们定义的W并非简单的数组。

这时候可能就会有个疑问,既然张量保存的计算过程,那如何得到张量里的数据呢?或者如何将张量print出来,而不是仅仅是打印关于Tensor的解释呢?

这个就涉及到TensorFlow的第二个关键点,Flow(流)的解释了。Flow可以理解成各个张量计算相互转化的过程,而TensorFlow计算过程是基于一个叫计算图的的方式进行的。一个简单的计算图如下:

《白话TensorFlow +实战系列(一) 详解Tensor与Flow》
《白话TensorFlow +实战系列(一) 详解Tensor与Flow》

图中的圆圈a与b、以及矩形add是计算图中的一个节点,节点的含义指的是TensorFlow中的计算过程!这个简单的计算图代码如下:

《白话TensorFlow +实战系列(一) 详解Tensor与Flow》
《白话TensorFlow +实战系列(一) 详解Tensor与Flow》

看到这里可能会有疑问了,add节点很好理解,代表的是节点a与节点b相加的计算过程。但是a与b明明都是由tf.constant函数定义的张量,怎么会在计算图中表示节点呢?怎么会是计算过程呢?这个恰恰就刚好解释了TensorFlow中张量与数组之间的区别。还记得之前我说张量保存的计算过程吧,再看上面打印张量W的图:

《白话TensorFlow +实战系列(一) 详解Tensor与Flow》
《白话TensorFlow +实战系列(一) 详解Tensor与Flow》

当我们打印张量W的时候,得到的结果是一个Tensor的解释,其中第一个属性名字(name)表示的是该张量由节点Const的第一个输出而来。正是这个原因,当我们用tf.Variable或者tf.constant定义变量或者常量的时候,我们其实定义的是一个特殊的计算过程,而这个计算过程我们可以理解为恒定的输出某个数。所以这就可以很好的理解为什么a与b在计算图中是一个节点了,并且张量为什么是一个计算过程了。

既然张量是一个计算过程,而我们明明想要的是张量里的数据,那我们到底要怎样才能得到我们想要的结果呢?

这就回到了用TensorFlow进行编程时特有的形式了。编程时,我们首先要做的就是构建计算图,其目的是定义计算图中的所有计算,注意此时的计算图并没有执行的功能,要想将定义好的计算图执行运算,要用到TensorFlow中的会话来进行,创建会话用tf.Sess(),具体代码如图:

《白话TensorFlow +实战系列(一) 详解Tensor与Flow》
《白话TensorFlow +实战系列(一) 详解Tensor与Flow》

上面有几点需要注意下:1)tf.global_variables_initializer()这个函数的作用是初始化所有变量,TensorFlow中要求将定义好的变量进行初始化,可以当成是固定模式,没什么好过多说的。2)with tf.Session() as sess: 这个是创建会话用到的,也可以理解为固定模式,3)经过a+b后形成的y也是一个张量,而通过会话中sees.run(y)执行后,此时打印的张量为为:

《白话TensorFlow +实战系列(一) 详解Tensor与Flow》

也就是说,张量经过会话执行运算后,这时候就是计算结果了,而非一个Tensor。

经过上面的解释,相信已经可以很好的理解Tensor以及TensorFlow进行编程的形式了。

首发博客地址~

本人水平有限,如有不正确的地方,欢迎指正~

    原文作者:LoYr
    原文地址: https://zhuanlan.zhihu.com/p/26318479
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞