【深度学习】村通网之——谈谈Tensorflow Eager Execution机制之静态图和动态图的区别(一)
文章目录
- 前言
- 介绍
- 搭建静态图
- 搭建动态图
前言
随着TensorFlow 1.4 Eager Execution的出现,TensorFlow的使用出现了革命性的变化。
介绍
我很早就听说过这样一句话:对于深度学习框架来说,在学术界中,PyTorch更受欢迎,在工业界中,Tensorflow更受欢迎。当时很不解,后来才知道,究其原因,不是因为PyTorch生态比Tensorflow优秀,是因为早期的PyTorch可以构建动态图,可以像正常程序一样去编写或者进行调试。而早期的Tensorflow只能构建静态图,网络的forward和backward都是黑箱操作,想在中间加一个print输出过程中结果都很麻烦,需要创建sess,然后通过sess.run()将数据feed进去,然后在fetch中得到中间结果。这个过程非常麻烦。
静态图(代表:早期的Tensorflow):只有定义好一个完整的网络结构(Graph),才能开始执行整个图(创建session,通过参数graph=xxx指定当前会话运行的计算图),且在运行过程中不能对图进行修改(比如添加网络结点、删除结点等操作)。整个过程和C语言编译很像,一旦构图完成开始执行训练,就不能对网络结构进行改变。
动态图(代表:PyTorch和1.4及以上版本的Tensorflow) :在动态图中,可以用各种逻辑控制语法(比如if else等),按照代码顺序执行,且可以在模型中间输出,整个过程和顺序执行的代码没什么两样。在前向传播中,一边执行一边生成本次的计算图,直到到最后一层生成完整的图,再进行反向传播。所以动态图每次喂入数据都会重新构建。这样有一个缺点,就是执行速度会比静态图稍慢。
我们可以总结为以下两点:
静态图: 声明式编程。一次构建,多次使用;构建过程稍微繁琐;性能好,速度快。
动态图: 命令式编程。图的构建很灵活,可以用Python的控制流;方便debug;操作可立即获得执行结果,无需等待图全部构建完成。
所以早期学术界更偏爱PyTorch动态图强大的debug能力,工业界更偏爱Tensorflow静态图快速稳定的能力。
随着Tensorflow 1.4版本的推出,Eager Execution终于出现了,这个版本在兼容老版本的基础上,将动态图机制加入到了Tensorflow中,使其像PyTorch一样能够构建动态图,从此Tensorflow既能构建动态图也能构建静态图。而对于这个Eager Execution版本,通俗的讲,有以下几个亮点:
- 无需placeholder和feed,可以直接使用numpy数组作为输入
- 可以立即执行Operation,例如输入图像数据(numpy数组),立即输出卷积结果,并将结果转换为numpy。即可以将老版本中定义静态图的Operation直接当做函数来立即执行一个Operation。(老版本需要先利用Operation定义静态图,然后到Session中执行不可变的静态图,并且获取Operation的结果需要通过sess.run()和feed,非常麻烦)。
- 动态图特性使得Tensorflow可以使用python的if语句和循环语句来控制模型的结构,而不用通过tf.cond这种难用的函数来控制模型的解构。
- 动态图特性使得模型更便于调试,模型的运行过程与代码的运行过程一致。而在老版本的静态图中,网络的forward与backward都是黑箱操作,想加个print来输出过程中的变量都很难。
- 梯度的计算和更新也变成函数的调用,可由开发者自己调用,这就意味着开发者可以自己重写反向传播的方式,更大限度的针对模型进行优化。
以上亮点来自:【最新TensorFlow1.4.0教程01】TF1.4.0介绍与动态图机制 Eager Execution使用
目前Tensorflow2.0已经将Eager Execution作为Tensorflow的默认执行模式,这即意味着Tensorflow如同PyTorch那样,由编写静态计算图完全转向动态计算图,这使得开发者可以更简洁高效地搭建原型。当然你可以选择不使用eager模式,自己构建计算图。
搭建静态图
我使用的Tensorflow版本是1.6.0,不同的tf版本,代码可能稍有差异。
我们先使用tf搭建一个静态图:
import tensorflow as tf
import numpy as np# 获得默认图,如果不用with语句显式指定所归属的计算图,
# 则所有的tensor和Operation都是在默认计算图中定义的,
# 使用tf.get_default_graph()函数可以获取当前默认的计算图句柄。
g=tf.get_default_graph()x=[[2.]]
x=np.asarray(x)result=tf.matmul(x,x)print(result)# 在graph=g上创建session声明
with tf.Session(graph=g) as sess:print(sess.run(result))
输出:
Tensor("MatMul:0", shape=(1, 1), dtype=float64)
[[4.]]
可以看到,第一个print并没有输出result的计算结果,而是输出了一个Operation对象(Matmul对象)。第二个print才通过sess.run()语句输出了计算结果。那我想直接在第一个print的位置得到result可以吗?可以,请看下面的动态图。
搭建动态图
上述的Eager Execution特性的实现,只需要在代码顶部加上这两行即可,其他的操作兼容老版本API:
import tensorflow.contrib.eager as tfe
tfe.enable_eager_execution()
例子:
import tensorflow as tf
import numpy as np
import tensorflow.contrib.eager as tfe# 使用动态图机制
tfe.enable_eager_execution()x=[[2.]]
x=np.asarray(x)
result=tf.matmul(x,x)print("{}".format(result))# 动态图不能使用自定义的session
# 因为在创建动态图的过程中,默认也建立一个session。所有的代码都在该session中进行,而且该session具有进程相同的生命周期。
# with tf.Session() as sess:
# print(sess.run(result))
输出:
[[4.]]
从动态图的代码和输出结果可以看出:
第一,我们直接在模型定义过程中使用print了result,从结果可以看出,可以直接输出result的值,而在静态图中输出的是Operation的对象,即动态图的操作在python代码中被调用后,其操作立即被执行,张量赋值也是如此。
第二,我们可以注意到,动态图不再需要tf.Session() 来建立对话了,因为在创建动态图的过程中,Tensorflow会默认建立一个session和graph。所有的张量和操作都属于计算图graph,所有的代码都在该session中进行,而且该session具有进程相同的生命周期。这也就是为什么不用写sess.run()就能得到计算结果的原因。而这表明一旦使用动态图就无法实现静态图中关闭session的功能。这是动态图的不足之处:无法实现多session操作,这使得在一个进程中同时跑多个模型成为困难的事情(在静态图中,我们可以创建多个sess与graph使用多个模型,不同计算图上的张量和运算都不会共享,计算图可以用来隔离张量和计算,使得模型之间相互无影响)。如果当前代码只需要一个session来完成的话,建议优先选择动态图Eager来实现。
针对第二点,我们做个实验,我们在动态图中,创建一个新graph,在graph中指定张量和操作,然后创建相对应的session执行,看看动态图中能否存在第二个session:
import tensorflow as tf
import numpy as np
import tensorflow.contrib.eager as tfe# 使用动态图机制
tfe.enable_eager_execution()x=[[2.]]
x=np.asarray(x)m=tf.matmul(x,x)print("{}".format(m))g1 = tf.get_default_graph()
print(g1)# 实验部分
g2 = tf.Graph()
with g2.as_default():x2=[[3.]]x2=np.asarray(x2)result2=tf.matmul(x2,x2)with tf.Session(graph=g2) as sess:print(sess.run(result2))
结果报错:
RuntimeError: The Session graph is empty. Add operations to the graph before calling run().
说明在动态图中不能手动创建session,就算创建了,也是无效的,所以在使用动态图的时候,无法实现多session的操作。
【深度学习】村通网之——谈谈Tensorflow Eager Execution机制之静态图和动态图的区别(一)相关推荐
- 【深度学习】村通网之——谈谈Tensorflow Eager Execution机制之新特性示例(二)
文章目录 前言 直接使用operation进行卷积操作 自动计算梯度(导数) 计算所有参数的梯度 计算所有变量的梯度 使用Python程序流程控制模型流程 自动优化 前言 本文是[深度学习]村通网之- ...
- 深度学习系列笔记——贰 (基于Tensorflow Keras搭建的猫狗大战模型 一)
猫狗大战是著名的竞赛网站kaggle几年前的一个比赛,参赛者得到猫狗各12500张图片,作为训练集,另外还会得到12500张猫和狗的图片,作为验证.最后提交结果至kaggle平台,获得评测分数. 本篇 ...
- 深度学习(五十六)tensorflow项目构建流程
tensorflow项目构建流程 博客:http://blog.csdn.net/hjimce 微博:黄锦池-hjimce qq:1393852684 一.构建路线 个人感觉对于任何一个深度学习库 ...
- 深度学习主流框架介绍(PyTorch、TensorFlow、Keras、Caffe、Theano、MXNET)
深度学习主流框架介绍(PyTorch.TensorFlow.Keras.Caffe.Theano.MXNET) 1.Theano Theano是最早的深度学习框架之一,由 Yoshua Bengio ...
- win10系统的深度学习环境搭建以win10+rtx2060+tensorflow为例/K210的win10系统的深度学习环境搭建/有无显卡均可安装
win10系统的深度学习环境搭建以win10+rtx2060+tensorflow为例 K210的win10系统的深度学习环境搭建 有无显卡均可安装 一 软件准备 1.Anaconda3 软件介绍:A ...
- regl fake-3d 静态图变动态图, 使用深度信息图片
原文链接: regl fake-3d 静态图变动态图, 使用深度信息图片 上一篇: regl 水纹波动效果 下一篇: regl 圆形色盘 https://tympanus.net/codrops/20 ...
- 【深度学习系列】用PaddlePaddle和Tensorflow实现经典CNN网络AlexNet
上周我们用PaddlePaddle和Tensorflow实现了图像分类,分别用自己手写的一个简单的CNN网络simple_cnn和LeNet-5的CNN网络识别cifar-10数据集.在上周的实验表现 ...
- 怎样快速上手深度学习?谷歌官方推荐的 TensorFlow 2 “豹书”来了!
TensorFlow 作为谷歌主导的开源深度学习框架,以其强大的性能和完善的生态支持,在开发者社群和工程实践中广为流行. 无数AI大厂.创业公司和个人开发者们都在使用 TensorFlow 开发和部署 ...
- 深度学习进阶:多分类与TensorFlow
学习目标 目标 知道softmax回归的原理 应用softmax_cross_entropy_with_logits实现softamx以及交叉熵损失计算 应用matmul实现多隐层神经网络的计算 应用 ...
最新文章
- 【每日一题】 面试题 17.14. 最小K个数
- 函数作用域,匿名函数
- 一段基于Jsoup和Dom4j的海报爬取小程序
- 直播进行中|谁在玩转数字中国?腾讯里约带你启动数字化转型之旅
- 应用的生命周期各个程序运行状态时代理的回调
- Oracle的dbms_output包的put()和put_line()的区别只是有没有回车换行吗?
- 解决wordpress后台管理访问速度慢的问题
- 【原】unity3D之Draw Call
- 简单的java项目中获取配置文件的值
- html5回到顶部代码,JS返回顶部实例代码
- matlab影像阿伯斯投影,D3.js 世界地图(一)投影方式
- 蔡勒公式与Python
- 将SolidWorks物料清单导出到Excel时可带缩略图了!
- 移动硬盘打不开,换一台电脑就又可以打开了
- 【SpringBoot整合NoSql】-----ElasticSearch的安装与操作篇
- 记自己开发的淘宝客优惠券
- 智能管家---1.项目搭建
- 有一个已经排好序的数组。现输入一个数,要求按原来的规律将它插入数组中。(c语言)
- it是什么?(详细解释)
- 【算法java版11】:实现求s = a + aa + aaa + aaaa + aa...a 的值,其中a是一个数字,几个数相加由键盘控制