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 相关文章推荐
Eclipse + Python 的安装与配置流程
Mar 05 Python
Python基于select实现的socket服务器
Apr 13 Python
基于python实现的抓取腾讯视频所有电影的爬虫
Apr 22 Python
Django框架教程之正则表达式URL误区详解
Jan 28 Python
Python SqlAlchemy动态添加数据表字段实例解析
Feb 07 Python
python使用threading.Condition交替打印两个字符
May 07 Python
解决Django加载静态资源失败的问题
Jul 28 Python
使用Python制作一个打字训练小工具
Oct 01 Python
Python Process多进程实现过程
Oct 22 Python
如何基于python实现不邻接植花
May 01 Python
Django2.1.7 查询数据返回json格式的实现
Dec 29 Python
baselines示例程序train_cartpole.py的ImportError
May 20 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 ob_start()控制浏览器cache、生成html实现代码
2010/02/16 PHP
Thinkphp中数据按分类嵌套循环实现方法
2014/10/30 PHP
PHP+MYSQL实现用户的增删改查
2015/03/24 PHP
php递归遍历删除文件的方法
2015/04/17 PHP
TNC vs BOOM BO3 第三场2.13
2021/03/10 DOTA
初学prototype,发个JS接受URL参数的代码
2006/09/25 Javascript
优化网页之快速的呈现我们的网页
2007/06/29 Javascript
自用js开发框架小成 学习js的朋友可以看看
2010/11/16 Javascript
原生javascript获取元素样式属性值的方法
2010/12/25 Javascript
Jvascript学习实践案例(开发常用)
2012/06/25 Javascript
javascript 正则表达式相关应介绍
2012/11/27 Javascript
JS 实现点击a标签的时候让其背景更换
2013/10/15 Javascript
javascript表单验证使用示例(javascript验证邮箱)
2014/01/07 Javascript
解决用jquery load加载页面到div时,不执行页面js的问题
2014/02/22 Javascript
JS实现鼠标单击与双击事件共存
2014/03/08 Javascript
浅谈Sizzle的“编译原理”
2015/04/14 Javascript
JS实现无限级网页折叠菜单(类似树形菜单)效果代码
2015/09/17 Javascript
Angular2表单自定义验证器的实现
2016/10/19 Javascript
javascript完美实现给定日期返回上月日期的方法
2017/06/15 Javascript
Angular利用trackBy提升性能的方法
2018/01/26 Javascript
Vue父子组建的简单通信之控制开关Switch的实现
2018/06/04 Javascript
vue 录制视频并压缩视频文件的方法
2018/07/27 Javascript
vue 实现购物车总价计算
2019/11/06 Javascript
python OpenCV学习笔记之绘制直方图的方法
2018/02/08 Python
Python简单过滤字母和数字的方法小结
2019/01/09 Python
Python语法分析之字符串格式化
2019/06/13 Python
如何使用Python自动控制windows桌面
2019/07/11 Python
python爬虫破解字体加密案例详解
2021/03/02 Python
HTML5中的进度条progress元素简介及兼容性处理
2016/06/02 HTML / CSS
运动服饰每月订阅盒:Ellie
2018/04/29 全球购物
献爱心活动总结
2014/05/07 职场文书
企业晚会策划方案
2014/05/29 职场文书
员工试用期自我鉴定范文
2014/09/15 职场文书
老干部局2015年度工作总结
2015/10/22 职场文书
初中数学课堂教学反思
2016/02/17 职场文书
MySQL查看表和清空表的常用命令总结
2021/05/26 MySQL