Tensorflow中的图(tf.Graph)和会话(tf.Session)的实现


Posted in Python onApril 22, 2020

Tensorflow编程系统

Tensorflow中的图(tf.Graph)和会话(tf.Session)的实现

Tensorflow工具或者说深度学习本身就是一个连贯紧密的系统。一般的系统是一个自治独立的、能实现复杂功能的整体。系统的主要任务是对输入进行处理,以得到想要的输出结果。我们之前见过的很多系统都是线性的,就像汽车生产工厂的流水线一样,输入->系统处理->输出。系统内部由很多单一的基本部件构成,这些单一部件具有特定的功能,且需要稳定的特性;系统设计者通过特殊的连接方式,让这些简单部件进行连接,以使它们之间可以进行数据交流和信息互换,来达到相互配合而完成具体工作的目的。

对于任何一个系统来说,都应该拥有稳定、独立、能处理特殊任务的单一部件;且拥有一套良好的内部沟通机制,以让系统可以健康安全的运行。

现实中的很多系统都是线性的,被设计好的、不能进行更改的,比如工厂的流水线,这样的系统并不具备自我调整的能力,无法对外界的环境做出反应,因此也就不具备“智能”。

深度学习(神经网络)之所以具备智能,就是因为它具有反馈机制。深度学习具有一套对输出所做的评价函数(损失函数),损失函数在对神经网络做出评价后,会通过某种方式(梯度下降法)更新网络的组成参数,以期望系统得到更好的输出数据。

Tensorflow中的图(tf.Graph)和会话(tf.Session)的实现

由此可见,神经网络的系统主要由以下几个方面组成:

  • 输入
  • 系统本身(神经网络结构),以及涉及到系统本身构建的问题:如网络构建方式、网络执行方式、变量维护、模型存储和恢复等等问题
  • 损失函数
  • 反馈方式:训练方式

定义好以上的组成部分,我们就可以用流程化的方式将其组合起来,让系统对输入进行学习,调整参数。因为该系统的反馈机制,所以,组成的方式肯定需要循环。

而对于Tensorflow来说,其设计理念肯定离不开神经网络本身。所以,学习Tensorflow之前,对神经网络有一个整体、深刻的理解也是必须的。如下图:Tensorflow的执行示意。

Tensorflow中的图(tf.Graph)和会话(tf.Session)的实现

那么对于以上所列的几点,什么才是最重要的呢?我想肯定是有关系统本身所涉及到的问题。即如何构建、执行一个神经网络?在Tensorflow中,用计算图来构建网络,用会话来具体执行网络。深入理解了这两点,我想,对于Tensorflow的设计思路,以及运行机制,也就略知一二了。

图(tf.Graph):计算图,主要用于构建网络,本身不进行任何实际的计算。计算图的设计启发是高等数学里面的链式求导法则的图。我们可以将计算图理解为是一个计算模板或者计划书。

会话(tf.session):会话,主要用于执行网络。所有关于神经网络的计算都在这里进行,它执行的依据是计算图或者计算图的一部分,同时,会话也会负责分配计算资源和变量存放,以及维护执行过程中的变量。

接下来,我们主要从计算图开始,看一看Tensorflow是如何构建、执行网络的。

计算图

在开始之前,我们先复习一下Tensorflow的几种基本数据类型:

tf.constant(value, dtype=None, shape=None, name='Const', verify_shape=False)
tf.Variable(initializer, name)
tf.placeholder(dtype, shape=None, name=None)

复习完毕。

graph = tf.Graph()
with graph.as_default():
 img = tf.constant(1.0, shape=[1,5,5,3])

以上代码中定义了一个计算图,在该计算图中定义了一个常量。Tensorflow默认会创建一张计算图。所以上面代码中的前两行,可以省略。默认情况下,计算图是空的。

Tensorflow中的图(tf.Graph)和会话(tf.Session)的实现

在执行完img = tf.constant(1.0, shape=[1,5,5,3])以后,计算图中生成了一个node,一个node结点由name, op, input, attrs组成,即结点名称、操作、输入以及一系列的属性(类型、形状、值)等组成,计算图就是由这样一个个的node组成的。对于tf.constant()函数,只会生成一个node,但对于有的函数,如tf.Variable(initializer, name)(注意其第一个参数是初始化器)就会生成多个node结点(后面会讲到)。

那么执行完img = tf.constant(1.0, shape=[1,5,5,3])后,计算图中就多一个node结点。(因为每个node的属性很多,我只表示name,op,input属性)

Tensorflow中的图(tf.Graph)和会话(tf.Session)的实现

继续添加代码:

img = tf.constant(1.0, shape=[1,5,5,3])
k = tf.constant(1.0, shape=[3,3,3,1])

代码执行后的计算图如下:

Tensorflow中的图(tf.Graph)和会话(tf.Session)的实现

需要注意的是,如果没有对结点进行命名,Tensorflow自动会将其命名为:Const、Const_1、const_2......。其他类型的结点类同。

现在,我们添加一个变量:

img = tf.constant(1.0, shape=[1,5,5,3])
k = tf.constant(1.0, shape=[3,3,3,1])
kernel = tf.Variable(k)

该变量用一个常量作为初始化器。我们先看一下计算图:

Tensorflow中的图(tf.Graph)和会话(tf.Session)的实现

如图所示:
执行完tf.Variable()函数后,一共产生了三个结点:

  • Variable:变量维护(不存放实际的值)
  • Variable/Assign:变量分配
  • Variable/read:变量使用

图中只是完成了操作的定义,但并没有执行操作(如Variable/Assign结点的Assign操作,所以,此时候变量依然不可以使用,这就是为什么要在会话中初始化的原因)。

我们继续添加代码:

img = tf.constant(1.0, shape=[1,5,5,3])
k = tf.constant(1.0, shape=[3,3,3,1])
kernel = tf.Variable(k)
y = tf.nn.conv2d(img, kernel, strides=[1,2,2,1], padding="SAME")

得到的计算图如下:

Tensorflow中的图(tf.Graph)和会话(tf.Session)的实现

可以看出,变量读取是通过Variable/read来进行的。

如果在这里我们直接开启会话,并执行计算图中的卷积操作,系统就会报错。

img = tf.constant(1.0, shape=[1,5,5,3])
k = tf.constant(1.0, shape=[3,3,3,1])
kernel = tf.Variable(k)
y2 = tf.nn.conv2d(img, kernel, strides=[1,2,2,1], padding="SAME")
with tf.Session() as sess:
  sess.run(y2)

这段代码错误的原因在于,变量并没有初始化就被使用,而从图中清晰的可以看到,直接执行卷积,是回溯不到变量的值(Const_1)的(箭头方向)。

所以,在执行之前,要进行初始化,代码如下:

img = tf.constant(1.0, shape=[1,5,5,3])
k = tf.constant(1.0, shape=[3,3,3,1])
kernel = tf.Variable(k)
y2 = tf.nn.conv2d(img, kernel, strides=[1,2,2,1], padding="SAME")
init = tf.global_variables_initializer()

执行完tf.global_variables_initializer()函数以后,计算图如下:

Tensorflow中的图(tf.Graph)和会话(tf.Session)的实现

tf.global_variables_initializer()产生了一个名为init的node,该结点将所有的Variable/Assign结点作为输入,以达到对整张计算图中的变量进行初始化。
所以,在开启会话后,执行的第一步操作,就是变量初始化(当然变量初始化的方式有很多种,我们也可以显示调用tf.assign()来完成对单个结点的初始化)。
完整代码如下:

img = tf.constant(1.0, shape=[1,5,5,3])
k = tf.constant(1.0, shape=[3,3,3,1])
kernel = tf.Variable(k)
y2 = tf.nn.conv2d(img, kernel, strides=[1,2,2,1], padding="SAME")
init = tf.global_variables_initializer()
with tf.Session() as sess:
  sess.run(init)
  # do someting....

会话

在上述代码中,我已经使用会话(tf.session())来执行计算图了。在tf.session()中,我们重点掌握无所不能的sess.run()。

一个session()中包含了Operation被执行,以及Tensor被evaluated的环境。

tf.Session().run()函数的定义:

run(
  fetches,
  feed_dict=None,
  options=None,
  run_metadata=None
)

tf.Session().run()函数的功能为:执行fetches参数所提供的operation操作或计算其所提供的Tensor。

run()函数每执行一步,都会执行与fetches有关的图中的所有结点的计算,以完成fetches中的任务。其中,feed_dict提供了部分数据输入的功能。(和tf.Placeholder()搭配使用,很舒服)

参数说明:

  • fetches:可以是图中的一个结点,也可以是一个List或者字典,此时候返回值与fetches格式一致;该参数还可以是一个Operation,此时候返回值为None。
  • feed_dict:字典格式。给模型输入其计算过程中所需要的值。

当我们把模型的计算图构建好以后,就可以利用会话来进行执行训练了。

在明白了计算图是如何构建的,以及如何被会话正确的执行以后,我们就可以愉快的开始Tensorflow之旅啦。

参考链接

https://jacobbuckman.com/

https://danijar.com/what-is-a-tensorflow-session/

http://looop.cn/?p=3365

到此这篇关于Tensorflow中的图(tf.Graph)和会话(tf.Session)的实现的文章就介绍到这了,更多相关Tensorflow tf.Graph tf.Session内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Python 相关文章推荐
Python的Bottle框架中返回静态文件和JSON对象的方法
Apr 30 Python
Python实现复杂对象转JSON的方法示例
Jun 22 Python
Python列表和元组的定义与使用操作示例
Jul 26 Python
机器学习python实战之手写数字识别
Nov 01 Python
今天 平安夜 Python 送你一顶圣诞帽 @微信官方
Dec 25 Python
Python Paramiko模块的使用实际案例
Feb 01 Python
python如何爬取个性签名
Jun 19 Python
解决python xlrd无法读取excel文件的问题
Dec 25 Python
如何使用Python实现斐波那契数列
Jul 02 Python
Django ORM 自定义 char 类型字段解析
Aug 09 Python
python实现跨excel sheet复制代码实例
Mar 03 Python
Python如何定义有默认参数的函数
Aug 10 Python
Django实现图片上传功能步骤解析
Apr 22 #Python
Django框架配置mysql数据库实现过程
Apr 22 #Python
jupyter notebook 实现matplotlib图动态刷新
Apr 22 #Python
解决matplotlib.pyplot在Jupyter notebook中不显示图像问题
Apr 22 #Python
查看jupyter notebook每个单元格运行时间实例
Apr 22 #Python
Django数据结果集序列化并展示实现过程
Apr 22 #Python
jupyter notebook中新建cell的方法与快捷键操作
Apr 22 #Python
You might like
PHP中用hash实现的数组
2011/07/17 PHP
Smarty的配置与高级缓存技术分享
2012/06/05 PHP
Laravel框架实现定时发布任务的方法
2018/08/16 PHP
PHP中有关长整数的一些操作教程
2019/09/11 PHP
PHP反射原理与用法深入分析
2019/09/28 PHP
用javascript实现的仿Flash广告图片轮换效果
2007/04/24 Javascript
纯js实现瀑布流展现照片(自动适应窗口大小)
2013/04/08 Javascript
解析瀑布流布局:JS+绝对定位的实现
2013/05/08 Javascript
js获取当月最后一天实例代码
2013/11/19 Javascript
IE10中flexigrid无法显示数据的解决方法
2015/07/26 Javascript
浅谈JS中json数据的处理
2016/06/30 Javascript
JavaScript中的splice方法用法详解
2016/07/20 Javascript
setTimeout学习小结
2017/02/08 Javascript
vue2.0实战之使用vue-cli搭建项目(2)
2017/03/27 Javascript
Angular.js项目中使用gulp实现自动化构建以及压缩打包详解
2017/07/19 Javascript
Vue组件化开发思考
2018/02/02 Javascript
vue自动化表单实例分析
2018/05/06 Javascript
小程序ios音频播放没声音问题的解决
2018/07/11 Javascript
jquery.pager.js实现分页效果
2019/07/29 jQuery
通过实例解析JavaScript for in及for of区别
2020/06/15 Javascript
Python实现的一个自动售饮料程序代码分享
2014/08/25 Python
跟老齐学Python之模块的加载
2014/10/24 Python
Python基于PycURL实现POST的方法
2015/07/25 Python
Python 实现简单的电话本功能
2015/08/09 Python
用python写的一个wordpress的采集程序
2016/02/27 Python
python利用正则表达式提取字符串
2016/12/08 Python
对dataframe数据之间求补集的实例详解
2019/01/30 Python
Python实现图像的垂直投影示例
2020/01/17 Python
解决pytorch 交叉熵损失输出为负数的问题
2020/07/07 Python
python PyAUtoGUI库实现自动化控制鼠标键盘
2020/09/09 Python
基于python实现复制文件并重命名
2020/09/16 Python
苹果香港官方商城:Apple香港
2016/09/14 全球购物
车贷收入证明范本
2014/01/09 职场文书
职业生涯规划设计步骤
2014/01/12 职场文书
合伙开公司协议书范本
2014/10/28 职场文书
优秀共产党员推荐材料
2014/12/18 职场文书