1. 首页
  2. TensorFlowNews

Tensorflow从入门到精通(二):附代码实战

1.Tensor介绍

Tensor(张量)是Tensorflow中最重要的数据结构,用来表示Tensorflow程序中的所有数据。Tensor本是广泛应用在物理、数学领域中的一个物理量。那么在Tensorflow中该如何理解Tensor的概念呢?

实际上,我们可以把Tensor理解成N维矩阵(N维数组)。其中零维张量表示的是一个标量,也就是一个数;一维张量表示的是一个向量,也可以看作是一个一维数组;二维张量表示的是一个矩阵;同理,N维张量也就是N维矩阵。

在计算图模型中,操作间所传递的数据都可以看做是Tensor。那Tensor的结构到底是怎样的呢?我们可以通过程序1-1更深入的了解一下Tensor。

程序1-1

#导入tensorflow模块

import tensorflow as tf

a = tf.constant([[2.0,3.0]] ,name=”a”)

b = tf.constant([[1.0],[4.0]] ,name=”b”)

result = tf.matmul(a,b,name=”mul”)

print(result)

>> Tensor(“mul_3:0”, shape=(1, 1), dtype=float32)

程序1-1的输出结果表明:构建图的运算过程输出的结果是一个Tensor,且其主要由三个属性构成:Name、Shape和Type。Name代表的是张量的名字,也是张量的唯一标识符,我们可以在每个op上添加name属性来对节点进行命名,Name的值表示的是该张量来自于第几个输出结果(编号从0开始),上例中的“mul_3:0”说明是第一个结果的输出。Shape代表的是张量的维度,上例中shape的输出结果(1,1)说明该张量result是一个二维数组,且每个维度数组的长度是1。最后一个属性表示的是张量的类型,每个张量都会有唯一的类型,常见的张量类型如图1-1所示。


Tensorflow从入门到精通(二):附代码实战

图1-1 常用的张量类型


我们需要注意的是要保证参与运算的张量类型相一致,否则会出现类型不匹配的错误。如程序1-2所示,当参与运算的张量类型不同时,Tensorflow会报类型不匹配的错误:

程序1-2:

import tensorflow as tf

m1 = tf.constant([5,1])

m2 = tf.constant([2.0,4.0])

result = tf.add(m1,m2)

TypeError: Input ‘y’ of ‘Add’ Op has type float32 that does not match type int32 of argument ‘x’.

正如程序的报错所示:m1是int32的数据类型,而m2是float32的数据类型,两者的数据类型不匹配,所以发生了错误。所以我们在实际编程时,一定注意参与运算的张量数据类型要相同。

2 常量、变量及占位符

Tensorflow中对常量的初始化,不管是对数值、向量还是对矩阵的初始化,都是通过调用constant()函数实现的。因为constant()函数在Tensorflow中的使用非常频繁,经常被用于构建图模型中常量的定义,所以接下来,我们通过程序1-3了解一下constant()的相关属性:程序2-1:

import tensorflow as tf

a = tf.constant([2.0,3.0],name=”a”,shape=(2,0),dtype=”float64″,verify_shape=”true”)

print(a)

>> Tensor(“a_11:0”, shape=(2, 0), dtype=float64)

如程序2-1所示,函数constant有五个参数,分别为valuenamedtypeshapeverify_shape。其中value为必选参数,其它均为可选参数。Value为常量的具体值,可以是一个数字,一维向量或是多维矩阵。Name是常量的名字,用于区别其它常量。Dtype是常量的类型,具体类型可参见图2-2Shape是指常量的维度,我们可以自行定义常量的维度。

verify_shape是验证shape是否正确,默认值为关闭状态(False)。也就是说当该参数true状态时,就会检测我们所写的参数shape是否与value的真实shape一致,若不一致就会报TypeError错误。如:上例中的实际shape(2,0),若我们将参数中的shape属性改为(2,1),程序就会报如下错误:

TypeError: Expected Tensor’s shape: (2, 1), got (2,).

Tensorflow还提供了一些常见常量的初始化,如:tf.zerostf.onestf.filltf.linspacetf.range等,均可以快速初始化一些常量。例如:我们想要快速初始化N维全0的矩阵,我们可以利用tf.zeros进行初始化,如程序1-4所示:

程序2-2:

import tensorflow as tf

a=tf.zeros([2,2],tf.float32)

b=tf.zeros_like(a,optimize=True)

with tf.Session() as sess:

    print(sess.run(a))

print(sess.run(b))

>> [[ 0.  0.]

 [ 0.  0.]]

[[ 0.  0.]

 [ 0.  0.]]

程序2-2向我们展示了tf.zerostf.zeros_like的用法。其它常见常量的具体初始化用法可以参考Tensorflow官方手册:https://www.tensorflow.org/api_guides/python/constant_op

此外,Tensorflow还可以生成一些随机的张量,方便快速初始化一些随机值。如:tf.random_normal()tf.truncated_normal()tf.random_uniform()tf.random_shuffle()等。如程序1-5所示,我们以tf.random_normal()为例,来看一下随机张量的具体用法:

程序2-3:

import tensorflow as tf

random_num=tf.random_normal([2, 3], mean=-1, stddev=4,

dtype=tf.float32,seed=None,name=’rnum’)

with tf.Session() as sess:

print(sess.run(random_num))

>> [[-2.71897316  1.04246855 -3.12996817]

    [-1.34851456 -0.13599336  4.60532522]]

随机张量random_normal()有shapemeanstddevdtypeseedname六个属性。shape是指张量的形状,如上述程序是生成一个23列的tensormean是指正态分布的均值;stddev是指正太分布的标准差;dtype是指生成tensor的数据类型;seed是分发创建的一个随机种子;而name是给生成的随机张量命名。

Tensorflow中的其它随机张量的具体使用方法和属性介绍,可以参见Tensorflow官方手册https://www.tensorflow.org/api_guides/python/constant_op。这里将不在一一赘述。

除了常量constant(),变量variable()也是在Tensorflow中经常会被用到的函数。变量的作用是保存和更新参数。执行图模型时,一定要对变量进行初始化,经过初始化后的变量才能拿来使用。变量的使用包括创建、初始化、保存、加载等操作。首先,我们通过程序2-4了解一下变量是如何被创建的:

程序2-4:

import tensorflow as tf

A = tf.Variable(3, name=”number”)

B = tf.Variable([1,3], name=”vector”)

C = tf.Variable([[0,1],[2,3]], name=”matrix”)

D = tf.Variable(tf.zeros([100]), name=”zero”)

E = tf.Variable(tf.random_normal([2,3], mean=1, stddev=2, dtype=tf.float32))

程序2-4展示了创建变量的多种方式。我们可以把函数variable()理解为构造函数,构造函数的使用需要初始值,而这个初始值是一个任何形状、类型的Tensor。也就是说,我们

既可以通过创建数字变量、一维向量、二维矩阵初始化Tensor,也可以使用常量或是随机常量初始化Tensor,来完成变量的创建。

当我们完成了变量的创建,接下来,我们要对变量进行初始化。变量在使用前一定要进行初始化,且变量的初始化必须在模型的其它操作运行之前完成。通常,变量的初始化有三种方式,如程序2-5所示:

程序2-5:

#初始化全部变量:

init = tf.global_variables_initializer()

with tf.Session() as sess:

    sess.run(init)

#初始化变量的子集:

init_subset=tf.variables_initializer([b,c], name=”init_subset”)

with tf.Session() as sess:

    sess.run(init_subset)

#初始化单个变量:

init_var = tf.Variable(tf.zeros([2,5]))

with tf.Session() as sess:

    sess.run(init_var.initializer)

程序2-5说明了初始化变量的三种方式:初始化全部变量、初始化变量的子集以及初始化单个变量。首先,global_variables_initializer()方法是不管全局有多少个变量,全部进行初始化,是最简单也是最常用的一种方式;variables_initializer()是初始化变量的子集,相比于全部初始化化的方式更加节约内存;Variable()是初始化单个变量,函数的参数便是要初始化的变量内容。通过上述的三种方式,我们便可以实现变量的初始化,放心的使用变量了。

我们经常在训练模型后,希望保存训练的结果,以便下次再使用或是方便日后查看,这时就用到了Tensorflow变量的保存。变量的保存是通过tf.train.Saver()方法创建一个Saver管理器,来保存计算图模型中的所有变量。具体代码如程序2-6所示:

程序2-6:

import tensorflow as tf

var1 = tf.Variable([1,3], name=”v1″)

var2 = tf.Variable([2,4], name=”v2″)

#对全部变量进行初始化

init = tf.initialize_all_variables()

#调用Saver()存储器方法

saver = tf.train.Saver()

#执行图模型

with tf.Session() as sess:

    sess.run(init)

    #设置存储路径

    save_path = saver.save(sess,”test/save.ckpt”)

我们要注意,我们的存储文件save.ckpt是一个二进制文件,Saver存储器提供了向该二进制文件保存变量和恢复变量的方法。保存变量的方法就是程序中的save()方法,保存的内容是从变量名到tensor值的映射关系。完成该存储操作后,会在对应目录下生成如图2-1所示的文件:

Tensorflow从入门到精通(二):附代码实战

2-1 保存变量生成的相应文件

Saver提供了一个内置的计数器自动为checkpoint文件编号。这就支持训练模型在任意步骤多次保存。此外,还可以通过global_step参数自行对保存文件进行编号,例如:global_step=2则保存变量的文件夹为model.ckpt-2

那如何才能恢复变量呢?首先,我们要知道一定要用和保存变量相同的Saver对象来恢复变量。其次,不需要事先对变量进行初始化。具体代码如程序2-7所示:

程序2-7:

import tensorflow as tf

var1 = tf.Variable([0,0], name=”v1″)

var2 = tf.Variable([0,0], name=”v2″)

saver = tf.train.Saver()

module_file = tf.train.latest_checkpoint(‘test/’)

with tf.Session() as sess:

    saver.restore(sess,module_file)

    print(“Model restored.”)

本程序示例中,我们要注意:变量的获取是通过restore()方法,该方法有两个参数,分别是session和获取变量文件的位置。我们还可以通过latest_checkpoint()方法,获取到该目录下最近一次保存的模型。

以上就是对变量创建、初始化、保存、加载等操作的介绍。此外,还有一些与变量相关的重要函数,如:eval()等。

认识了常量和变量,Tensorflow中还有一个非常重要的常用函数——placeholderplaceholder是一个数据初始化的容器,它与变量最大的不同在于placeholder定义的是一个模板,这样我们就可以session运行阶段,利用feed_dict的字典结构给placeholder填充具体的内容,而无需每次都提前定义好变量的值,大大提高了代码的利用率。Placeholder的具体用法如程序2-8所示:

程序序2-8

import tensorflow as tf

a = tf.placeholder(tf.float32,shape=[2],name=None)

b = tf.constant([6,4],tf.float32)

c = tf.add(a,b)

with tf.Session() as sess:

    print(sess.run(c,feed_dict={a:[10,10]}))  

程序2-8演示了placeholder占位符的使用过程。Placeholder()方法有dtypeshapename三个参数构成。dtype是必填参数,代表传入value的数据类型;shape是选填参数,代表传入value的维度;name也是选填参数,代表传入value的名字。我们可以把这三个参数看作为形参,在使用时传入具体的常量值。这也是placeholder不同于常量的地方,它不可以直接拿来使用,而是需要用户传递常数值。

最后,Tensorflow中还有一个重要的概念——fetchFetch的含义是指可以在一个会话中同时运行多个op。这就方便我们在实际的建模过程中,输出一些中间的op,取回多个tensorFetch的具体用法如程序2-9所示:

程序2-9

import tensorflow as tf

a = tf.constant(5)

b = tf.constant(6)

c = tf.constant(4)

add = tf.add(b, c)

mul = tf.multiply(a, add)

with tf.Session() as sess:

    result = sess.run([mul, add])

print(result)

>> [50,10]

程序2-10展示了fetch的用法,即我们利用sessionrun()方法同时取回多个tensor值,方便我们查看运行过程中每一步op的输出结果。

程序2-10

import tensorflow as tf

var1 = tf.Variable([0,0], name=”v1″)

var2 = tf.Variable([0,0], name=”v2″)

Saver = tf.train.Saver()

module_file = tf.train.latest_checkpoint(‘test/’)

with tf.Session() as sess:

    saver.restore(sess,module_file)

    print(“Model restored.”)

小结:本节旨在让大家学会Tensorflow的基础知识,为后边实战的章节打下基础。主要介绍了Tensor的概念,以及Tensorflow中的常量、变量、占位符、feed等知识点。




Tensorflow从入门到精通(二):附代码实战


磐创AI:http://www.panchuangai.com/ 智能客服:http://www.panchuangai.com/ TensorFlow:http://panchuang.net 推荐关注公众号:磐创AI

原创文章,作者:fendouai,如若转载,请注明出处:http://panchuang.net/2018/03/29/0614a93e8f/

发表评论

电子邮件地址不会被公开。

联系我们

400-800-8888

在线咨询:点击这里给我发消息

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息