《30天吃掉那只 TensorFlow2.0》 2-2 三种计算图

简介: 《30天吃掉那只 TensorFlow2.0》 2-2 三种计算图

2-2 三种计算图

c401c620b54746db85149dc684a88103.jpg

有三种计算图的构建方式:静态计算图,动态计算图,以及Autograph.


在TensorFlow1.0时代,采用的是静态计算图,需要先使用TensorFlow的各种算子创建计算图,然后再开启一个会话Session,显式执行计算图。


而在TensorFlow2.0时代,采用的是动态计算图,即每使用一个算子后,该算子会被动态加入到隐含的默认计算图中立即执行得到结果,而无需开启Session。


使用动态计算图即Eager Excution的好处是方便调试程序,它会让TensorFlow代码的表现和Python原生代码的表现一样,写起来就像写numpy一样,各种日志打印,控制流全部都是可以使用的。


使用动态计算图的缺点是运行效率相对会低一些。因为使用动态图会有许多次Python进程和TensorFlow的C++进程之间的通信。而静态计算图构建完成之后几乎全部在TensorFlow内核上使用C++代码执行,效率更高。此外静态图会对计算步骤进行一定的优化,剪去和结果无关的计算步骤。


如果需要在TensorFlow2.0中使用静态图,可以使用@tf.function装饰器将普通Python函数转换成对应的TensorFlow计算图构建代码。运行该函数就相当于在TensorFlow1.0中用Session执行代码。使用tf.function构建静态图的方式叫做 Autograph.


一,计算图简介


计算图由节点(nodes)和线(edges)组成。

节点表示操作符Operator,或者称之为算子,线表示计算间的依赖。

实线表示有数据传递依赖,传递的数据即张量。

虚线通常可以表示控制依赖,即执行先后顺序。


二,静态计算图


在TensorFlow1.0中,使用静态计算图分两步,第一步定义计算图,第二步在会话中执行计算图。


TensorFlow 1.0静态计算图范例


import tensorflow as tf
#定义计算图
g = tf.Graph()
with g.as_default():
    #placeholder为占位符,执行会话时候指定填充对象
    x = tf.placeholder(name='x', shape=[], dtype=tf.string)  
    y = tf.placeholder(name='y', shape=[], dtype=tf.string)
    z = tf.string_join([x,y],name = 'join',separator=' ')
#执行计算图
with tf.Session(graph = g) as sess:
    print(sess.run(fetches = z,feed_dict = {x:"hello",y:"world"}))

TensorFlow2.0 怀旧版静态计算图


TensorFlow2.0为了确保对老版本tensorflow项目的兼容性,在tf.compat.v1子模块中保留了对TensorFlow1.0那种静态计算图构建风格的支持。

可称之为怀旧版静态计算图,已经不推荐使用了。

import tensorflow as tf
g = tf.compat.v1.Graph()
with g.as_default():
    x = tf.compat.v1.placeholder(name='x', shape=[], dtype=tf.string)
    y = tf.compat.v1.placeholder(name='y', shape=[], dtype=tf.string)
    z = tf.strings.join([x,y],name = "join",separator = " ")
with tf.compat.v1.Session(graph = g) as sess:
    # fetches的结果非常像一个函数的返回值,而feed_dict中的占位符相当于函数的参数序列。
    result = sess.run(fetches = z,feed_dict = {x:"hello",y:"world"})
    print(result)
b'hello world'


三,动态计算图


在TensorFlow2.0中,使用的是动态计算图和Autograph.


在TensorFlow1.0中,使用静态计算图分两步,第一步定义计算图,第二步在会话中执行计算图。

动态计算图已经不区分计算图的定义和执行了,而是定义后立即执行。因此称之为 Eager Excution.

Eager这个英文单词的原意是"迫不及待的",也就是立即执行的意思。


# 动态计算图在每个算子处都进行构建,构建后立即执行
x = tf.constant("hello")
y = tf.constant("world")
z = tf.strings.join([x,y],separator=" ")
tf.print(z)
hello world
# 可以将动态计算图代码的输入和输出关系封装成函数
def strjoin(x,y):
    z =  tf.strings.join([x,y],separator = " ")
    tf.print(z)
    return z
result = strjoin(tf.constant("hello"),tf.constant("world"))
print(result)
hello world
tf.Tensor(b'hello world', shape=(), dtype=string)

四,TensorFlow2.0的Autograph


动态计算图运行效率相对较低。


可以用@tf.function装饰器将普通Python函数转换成和TensorFlow1.0对应的静态计算图构建代码。


在TensorFlow1.0中,使用计算图分两步,第一步定义计算图,第二步在会话中执行计算图。


在TensorFlow2.0中,如果采用Autograph的方式使用计算图,第一步定义计算图变成了定义函数,第二步执行计算图变成了调用函数。


不需要使用会话了,一些都像原始的Python语法一样自然。


实践中,我们一般会先用动态计算图调试代码,然后在需要提高性能的的地方利用@tf.function切换成Autograph获得更高的效率。


当然,@tf.function的使用需要遵循一定的规范,我们后面章节将重点介绍。

import tensorflow as tf
# 使用autograph构建静态图
@tf.function
def strjoin(x,y):
    z =  tf.strings.join([x,y],separator = " ")
    tf.print(z)
    return z
result = strjoin(tf.constant("hello"),tf.constant("world"))
print(result)
hello world
tf.Tensor(b'hello world', shape=(), dtype=string)
import datetime
# 创建日志
import os
stamp = datetime.datetime.now().strftime("%Y%m%d-%H%M%S")
logdir = os.path.join('data', 'autograph', stamp)
## 在 Python3 下建议使用 pathlib 修正各操作系统的路径
# from pathlib import Path
# stamp = datetime.datetime.now().strftime("%Y%m%d-%H%M%S")
# logdir = str(Path('./data/autograph/' + stamp))
writer = tf.summary.create_file_writer(logdir)
#开启autograph跟踪
tf.summary.trace_on(graph=True, profiler=True) 
#执行autograph
result = strjoin("hello","world")
#将计算图信息写入日志
with writer.as_default():
    tf.summary.trace_export(
        name="autograph",
        step=0,
        profiler_outdir=logdir)
#启动 tensorboard在jupyter中的魔法命令
%load_ext tensorboard
#启动tensorboard
%tensorboard --logdir ./data/autograph/


07f1bd1eb3a6421391fffa48f66f92ce.png

当然现在,有更新了,显示的图的路径会更大,并且分开显示,也可以在在线的colab体验一下代码的结果


cd5458d7f63446baac1d0b525c86a6cf.png

相关文章
|
机器学习/深度学习 监控 算法
【tensorflow】连续输入的神经网络模型训练代码
【tensorflow】连续输入的神经网络模型训练代码
|
机器学习/深度学习 TensorFlow 算法框架/工具
【tensorflow】连续输入的线性回归模型训练代码
  get_data函数用于生成随机的训练和验证数据集。首先使用np.random.rand生成一个形状为(10000, 10)的随机数据集,来模拟10维的连续输入,然后使用StandardScaler对数据进行标准化。再生成一个(10000,1)的target,表示最终拟合的目标分数。最后使用train_test_split函数将数据集划分为训练集和验证集。
|
7月前
|
机器学习/深度学习 JSON PyTorch
图神经网络入门示例:使用PyTorch Geometric 进行节点分类
本文介绍了如何使用PyTorch处理同构图数据进行节点分类。首先,数据集来自Facebook Large Page-Page Network,包含22,470个页面,分为四类,具有不同大小的特征向量。为训练神经网络,需创建PyTorch Data对象,涉及读取CSV和JSON文件,处理不一致的特征向量大小并进行归一化。接着,加载边数据以构建图。通过`Data`对象创建同构图,之后数据被分为70%训练集和30%测试集。训练了两种模型:MLP和GCN。GCN在测试集上实现了80%的准确率,优于MLP的46%,展示了利用图信息的优势。
101 1
|
机器学习/深度学习 存储 自然语言处理
|
7月前
|
机器学习/深度学习 数据可视化 PyTorch
基于TorchViz详解计算图(附代码)
基于TorchViz详解计算图(附代码)
272 0
|
存储 索引 Python
《30天吃掉那只 TensorFlow2.0》 4-1 张量的结构操作
《30天吃掉那只 TensorFlow2.0》 4-1 张量的结构操作
《30天吃掉那只 TensorFlow2.0》 4-1 张量的结构操作
|
机器学习/深度学习 TensorFlow 算法框架/工具
《30天吃掉那只 TensorFlow2.0》 一、TensorFlow的建模流程
《30天吃掉那只 TensorFlow2.0》 一、TensorFlow的建模流程
《30天吃掉那只 TensorFlow2.0》 一、TensorFlow的建模流程
|
机器学习/深度学习 TensorFlow 算法框架/工具
《30天吃掉那只 TensorFlow2.0》 2-3 自动微分机制
《30天吃掉那只 TensorFlow2.0》 2-3 自动微分机制
《30天吃掉那只 TensorFlow2.0》 2-3 自动微分机制
|
TensorFlow 算法框架/工具 C++
《30天吃掉那只 TensorFlow2.0》 4-4 AutoGraph的机制原理
《30天吃掉那只 TensorFlow2.0》 4-4 AutoGraph的机制原理
《30天吃掉那只 TensorFlow2.0》 4-4 AutoGraph的机制原理
|
机器学习/深度学习 API TensorFlow
《30天吃掉那只 TensorFlow2.0》 三、TensorFlow的层次结构
《30天吃掉那只 TensorFlow2.0》 三、TensorFlow的层次结构
《30天吃掉那只 TensorFlow2.0》 三、TensorFlow的层次结构