TensorFlow编程模型

来源:互联网 发布:暴风影音mac无法播放字幕 编辑:程序博客网 时间:2024/06/01 10:05

楼主学TensorFlow也有一段时间了,也是从小白走到了菜鸟阶段。网上有不少TensorFlow教程,但感觉好多都没把编程模型完全说清楚,今天楼主就来总结一下这几天的学习成果,出一个TensorFlow编程模型的教程

 

 

1.引言

TensorFlow翻译成中文大致就是“向量流”的意思,这很大程度上反映了TensorFlow的编程模型:让向量数据在计算图里流动

那么在编程时至少有这几个过程:1.构建图,2.启动图,3.给图喂数据并获取结果。

下面的讲解也将按这个流程展开。

 

 

2.构建图

TensorFlow里图的类型是tf.Graph,它包含着计算节点和tensor的集合。

这里引用了两个新概念:tensor和计算节点。我们先介绍tensor

 

一开始我们就介绍了,我们需要把数据喂给启动的图才能获取计算结果。那么问题来了,在构建图时用什么表示中间计算结果?这个时候tensor的概念就需要引入了。

类型是tf.Tensor,代表某个计算节点的输出,一定要看清楚是“代表”。它主要有两个作用:

1.      构建不同计算节点之间的数据流

2.      在启动图时,可以设置某些tensor的值,然后获取指定tensor的值。这样就完成了计算的输入输出功能。

如下代码所示:

inputImage=tf.placeholder(tf.float32,[32,32,3],"inputImage")processedImage=tf.image.per_image_standardization(inputImage,"processedImage")


这里inputImage和processedImage都是tensor类型。它们代表着计算节点输出的数据,数据的值具体是多少我们在启动图的时候才知道。上面两个方法调用楼主都传递了一个字符串,它是计算节点的名字,最好给节点命名,这样我们可以在图上调用get_tensor_by_name(name)获取对应的tensor对象,十分方便。(tensor名字为“<计算节点名字>:<tensor索引>”)

创建tensor时,需要指定类型和shape。对不同tensor进行计算时要求类型相同,我们可以使用tf.cast进行类型转换。同时也要求shape(向量维度)满足运算的条件,我们可以使用tf.reshape改变shape

 知道tensor的概念后,计算节点的概念也就清楚了。其功能为:对tensor进行计算、创建tensor或进行其他操作,类型是tf.Operation。获取节点对象的方法为get_operation_by_name(name)。

构建图的方法有的返回的是tensor对象,有的是节点对象,大家看文档时要注意 。

 

好,下面回到构建图上。既然了解tensor和计算节点的概念了,构建图自然也简单了,看下面的代码:

g=tf.Graph()with g.as_default():    input_data=tf.placeholder(tf.float32,[None,2],"input_data")    input_label=tf.placeholder(tf.float32,[None,2],"input_label")    w1=tf.Variable(tf.truncated_normal([2,2]),name="w1")    b1=tf.Variable(tf.zeros([2]),name="b1")    output=tf.add(tf.matmul(input_data,w1),b1,name="output")    cross_entropy=tf.nn.softmax_cross_entropy_with_logits(logits=output,labels=input_label)    train_step=tf.train.AdamOptimizer().minimize(cross_entropy,name="train_step")    initer=tf.global_variables_initializer()    saver=tf.train.Saver()


上面的代码中我们创建了一个图,并在上面添加了很多节点。网上的教程大多不会先实例化一个图对象,而是直接开始创建节点或tensor,这样的话所有的节点将加入默认的图里,我们可以通过调用get_default_graph()获取默认的图。

Input_data,input_label,w1,b1,output,cross_entropy都是tensor类型,train_step,initer,是节点类型。至于saver,文档上说是ASaverDef proto,楼主也不太清楚是什么,反正用它保存或载入模型就对了。

有几类tensor或节点比较重要,下面介绍一下:

1.      placeholder

上面提到过,我们可以通过启动图时指定某些tensor的值,完成输入功能。这类tensor就是placeholder,它代表一个要输入的值。在启动图并获取某个tensor的值时,如果这个tensor依赖某个未指定值的placeholder,代码会抛出异常。

2.      variable

在对机器学习模型进行训练时,我们需要不断调整模型的状态,这个状态就由variable来保存。创建variable时我们需要给一个初始值。

3.      initializer

每次启动图都需要初始化变量,虽然在创建变量时指定了初始值,但我们还是需要先运行一下初始化节点。使用未初始化的节点进行计算会产生异常

 

 

3.启动图

启动图比较简单,不过要引入session的概念。

图的每个运行实例都必须在一个session里,session为图的运行提供环境。Session的类型是tf.Session,在实例化session对象时我们需要给它传递一个图对象,如果不显示给出将使用默认的图。Session有一个graph属性,我们可以通过它获取session对应的图。

代码如下:

 

numOfBatch=10datas=np.zeros([numOfBatch,2],np.float32)labels=np.zeros([numOfBatch,2],np.float32)sess=tf.Session(graph=g)graph=sess.graphsess.run([graph.get_operation_by_name("initer")]) dataHolder=graph.get_tensor_by_name("input_data:0")labelHolder=graph.get_tensor_by_name("input_label:0")train=graph.get_operation_by_name("train_step")out=graph.get_tensor_by_name("output:0")for i inrange(200):   result=sess.run([out,train],feed_dict={dataHolder:datas,labelHolder:labels})   if i%100==0:       saver.save(sess,"./moules")sess.close()

代码都比较简单,就不介绍了。不过要注意2点:1.别忘记运行初始化节点,2.别忘记close掉session对象以释放资源。

 

 

4.给图喂数据并获取结果

我们看下面代码

for i inrange(200):    result=sess.run([out,train],feed_dict={dataHolder:datas,labelHolder:labels})

这里主要用到了session对象的run方法,它用来运行某个节点或tensor并获取对应的值。我们一般会一次传递一小部分数据进行mini-batch梯度下降来优化模型。

我们需要把我们需要运行的节点或tensor放入一个列表,然后作为第一个参数(不考虑self)传递给run方法,run方法会返回一个计算结果的列表,与我们传递的参数一一对应。

如果我们运行的节点依赖某个placeholder,那我们必须给这个placeholder指定值,怎么指定代码里面很清楚,给关键字参数feed_dict传递一个字典即可,字典里的元素的key是placeholder对象,value是我们指定的值。值的数据的类型必须和placeholder一致,包括shape。值本身的类型是numpy数组。

这里再解释一个细节,我们在定义placeholder时代码如下:

input_data=tf.placeholder(tf.float32,[None,2],"input_data")input_label=tf.placeholder(tf.float32,[None,2],"input_label")

shape为[None,2],这是什么意思?这说明数据第一个维度是不确定的,然后TensorFlow会根据我们传递的数据动态推断第一个维度,这样我们就可以在运行时改变batch的大小。比如一个数据是2维,一次传递10个数据对应的tensor的shape就是[10,2]。可不可以把多个维度指定为None?理论上不可以!

 

5.总结

好像没什么好总结的了。。。本文的定位是TensorFlow小白了解编程模型,想要了解更多还是看API文档吧:https://www.tensorflow.org/api_docs/

 

多谢大家耐心阅读,别忘了给楼主的CSDN点赞[小乖]