[TensorFlow系列-22]:基本元素与运行机制 - TensorVariableOperationSessionPlaceholderGraph静态与动态数据流图的比较
Posted 文火冰糖的硅基工坊
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[TensorFlow系列-22]:基本元素与运行机制 - TensorVariableOperationSessionPlaceholderGraph静态与动态数据流图的比较相关的知识,希望对你有一定的参考价值。
作者主页(文火冰糖的硅基工坊):文火冰糖(王文兵)的博客_文火冰糖的硅基工坊_CSDN博客
本文网址:https://blog.csdn.net/HiWangWenBing/article/details/120401689
目录
第3章 构建数据流图:动态数据流图(tensorflow 2.0)
第4章 构建数据流图:静态数据流图(tensorflow 1.0)
第1章 TensorFlow的基本元素概述
1.1 基本元素组成
上述的基本概念是学习和理解tensorflow的基础元素,神经网络也是在上述基本概念和元素的基础之上构建的。因此有必要总结一下这些基本元素。
2.2 Tensorflow是Python的库
#环境准备
import numpy as np
import tensorflow as tf
print("hello world")
print("tensorflow version:", tf.__version__)
hello world
tensorflow version: 2.4.0
- Tenorflow框架和应用程序是python的程序
- Tenorflow是Python的库,可以通过import导入
第2章 Tensorflow程序初探
a = tf.constant(1.0, dtype=tf.float32)
b = tf.Variable(2.0, dtype=tf.float32 ,trainable=True)
c = a + b
d = tf.add(a,b)
print(a)
print(b)
print(c)
print(d)
tf.Tensor(1.0, shape=(), dtype=float32) <tf.Variable 'Variable:0' shape=() dtype=float32, numpy=2.0> tf.Tensor(3.0, shape=(), dtype=float32) tf.Tensor(3.0, shape=(), dtype=float32)
上述的程序,虽然简单,却展现了Tensorflow最核心的概念:
张量、变量、数据类型、操作、数据流图
2.1 张量Tensor(对象)
张量tensor在Tensorflow中是通过tf.constant() 来定义的。
张量tensor在Tensorflow用来表达和存放输入样本数据的数据结构。
张量的各种运算,本质是就是对样本数据的各种处理。
a = tf.constant(1.0, dtype=tf.float32)
这里的constant不表示常量,而是指张量。
之所以用“constant”表示,应该说,这是一个历史遗留问题,很显然,用tensor来表示更加的合理和复合它的本意,Pytorch就使用了tensor这样有针对性的词汇。
当然,并不是说“constant”一点道理也没有。
用constant定义的tensor通常用于定义样本数据,而样本数据在模型训练时,相对于需要不断改变数值的模型的w,b参数,就是一个常量。
constant定义的tensor对象,其数据直接存放在tensor中,如下下图所示:
tf.Tensor(1.0, shape=(), dtype=float32)
2.2 变量Variable(对象)
Variable对象是在普通Tensor对象基础之上的进一步封装。
专门用于表达和存放神经网络的w,b参数,也用于存放中间运行结果的数据。
b = tf.Variable(2.0, dtype=tf.float32 ,trainable=True)
trainable:是Variable特有的一个属性,表明该参数是否需要自动求导数,或者说是否是模型训练的参数。
Variable定义的对象,其数据存放在数据区,这是因为Variable对象是对constant对象进一步的封装。
<tf.Variable 'Variable:0' shape=() dtype=float32, numpy=2.0>
2.3 数据类型的指定
C、C++语言,如int x = 10; 其数据类型是在数据定义时,通过在变量名前加限定词,如int来指明数据的类型。
不同于C、C++语言,Tensor和Variable对象的数据的数据类型,是通过对象的属性:dtype来指定的。如dtype=tf.float32。
2.4 数据操作/运算
c = a + b
d = tf.add(a,b)
其中,操作符"+"和tf.add都是对数据a和b的操作和运算。
由于a和b是复杂数据类型,在面向对象中,操作符"+"不在时基础的数值运算,而是进行了运算符的重载 ,与tf.add是等效的。
与pytorch不同,tensorflow并没有为Tensor和Variable对象,定义如add,sub等数值运算的成员函数。因此不能执行如c = a.add(b) 这样的运算。
a = tf.constant(1.0, dtype=tf.float32)
b = tf.Variable(2.0, dtype=tf.float32 ,trainable=True)
c = a + b
d = tf.add(a,b)
print(a)
print(b)
print(c)
print(d)
tf.Tensor(1.0, shape=(), dtype=float32) <tf.Variable 'Variable:0' shape=() dtype=float32, numpy=2.0> tf.Tensor(3.0, shape=(), dtype=float32) tf.Tensor(3.0, shape=(), dtype=float32)
上述执行的结果:
c = 3.0, d = 3.0
上述执行结果是tensorflow2.0的结果,这与Pytorch、python语言、C/C++语言的执行结果是一致的。
实际上tensorflow1.0的时候,并非是这个结果,在执行c = a+b语句时,tensorflow1.0并不能得到执行结果,只是构建c = a+b的静态的数据流图,并没有进行实际的运算。
这里涉及到一个核心的概念:构建静态或动态的数据流图。
上述代码的执行结果是:动态数据流图的执行结果。
第3章 构建数据流图:动态数据流图(tensorflow 2.0)
Tensorflow2.0在默认情况下,采用了动态数据流图的设计。
在Tensorflow 2.0, c = a+b语句,会隐含的执行如下的操作:
(1)自动:构建动图数据流图和相应的上下文
(2)自动:动态创建执行动态图的session以及相应的上下文
(3)自动:在session中执行数据流图,获得执行结果。
(4)自动:把执行结果存放到tensor和Variable对象中。
(5)自动:释放session、动图数据图的上下文内存空间。
上述的过程,全部有编译器自动完成,不需要程序员参与。
很显然,使用动态图,程序的编程更加的自然、简单,直接得到运行结果:
a = tf.constant(1.0, dtype=tf.float32)
b = tf.Variable(2.0, dtype=tf.float32 ,trainable=True)
c = a + b
d = tf.add(a,b)
print(a)
print(b)
print(c)
print(d)
tf.Tensor(1.0, shape=(), dtype=float32) <tf.Variable 'Variable:0' shape=() dtype=float32, numpy=2.0> tf.Tensor(3.0, shape=(), dtype=float32) tf.Tensor(3.0, shape=(), dtype=float32)
实际在,在Tensorflow 1.0时,数据流的执行并不像上述那样,如此的直观、自然和简单。
要想得到a,b,c,d的值,是需要执行额外的代码。
第4章 构建数据流图:静态数据流图(tensorflow 1.0)
4.1 静态数据流图的构建
在tensorflow 1.0, c = a+b只是构建了一个如下的数据流图
叶子节点:a,b
运算节点:+
输出节点或边:c
在tensorflow 1.0, c = a+b语句,会隐含的执行如下的操作:
- 自动:构建动图数据流图和相应的上下文
此时的执行结果如下
静态图构建后的执行结果是:
a,b都是tensor或variable,而不是a和b的数值1.0和2.0
c是“add”操作,而不是add后的结果。
4.2 静态数据流图的执行:session
(1)session的创建
Session是tensor1.0的概念,session的作用如下;
- 手工:创建执行静态图的session以及相应的上下文
- 手功:能在session中执行数据流图,获得执行结果。
- 自动:把执行结果存放到tensor和Variable对象中。
- 手工:关闭session
- 自动:释放动图数据图的上下文内存空间。
在静态图中,前三个手工步骤,必须需要程序员来完成,如下图所示:
只有通过session的执行,才能获得a,b,c的数值。
a=1.0, b=2.0, c = 3.0, d = 3.0
(2)通过with语句,减少手工执行sess.close()
with tf.Session() as sess:
print(sess.run(a))
print(sess.run(b))
print(sess.run(c))
print(sess.run(d))
#运算结束后,编译器启动调用sess的析构函数,自动执行sess.close()
4.3 placeholder
在构建静态图中,输入节点是不需要提供数值,只需要节点的数据类型即可。
数值只有在session执行时才需要提供数据。为此Tensorflow定义了一个新的数据结构placeholder。
(1)placeholder数据对象的定义
(2)在session中给placeholder数据对象提供实际的数据
通过字典的方式,给placeholder数据对象赋值, 如下所示:
feed_dict = {a:[1,2,3], b: [True, False]}
4.4 静态图对象
由于静态图示静态创建,不会编译器动态的创建与释放。
因此就可以通过代码,获取当前动图图的信息,并可以展现当前图中所有的运算。
即当前静态图中,所有的函数表达式以及他们之前的关系,这是动态图所不具备的一个特征!!
第5章 动态图和静态图的比较
静态图 | 动态图 | |
优点 |
|
|
缺点 |
|
|
应用场景 | 模型部署 | 模型开发 |
作者主页(文火冰糖的硅基工坊):文火冰糖(王文兵)的博客_文火冰糖的硅基工坊_CSDN博客
本文网址:https://blog.csdn.net/HiWangWenBing/article/details/120401689
以上是关于[TensorFlow系列-22]:基本元素与运行机制 - TensorVariableOperationSessionPlaceholderGraph静态与动态数据流图的比较的主要内容,如果未能解决你的问题,请参考以下文章
[TensorFlow系列-17]:TensorFlow基础 - 张量的索引与切片