什么是计算图
1.什么是计算图:
一个机器学习任务的核心是模型的定义以及模型的参数求解方式,对这两者进行抽象之后,可以确定一个唯一的计算逻辑,将这个逻辑用图表示,称之为计算图。计算图表现为有向无环图,定义了数据的流转方式,数据的计算方式,以及各种计算之间的相互依赖关系等。
2.计算图的基本组成
TensorFlow的计算图粒度比较细,由节点和有向边组成(后来也加入了层)。相比之下,腾讯的开源机器学习平台Angel,其计算图的粒度较粗,由层(Layer)组成。很明显,粒度越细,灵活性越好;粒度越粗,开发效率越高。用Angel手动搭建模型,层层堆叠,几行代码就够了。
3.节点和有向边
3.1 节点
基于梯度下降求解的机器学习问题,一般分为前向求值和后向求梯度两个过程。其中,前向过程由用户指定,包括模型定义,目标函数、损失函数、激活函数的选取等;后向的计算过程,包括计算梯度,更新梯度等,在优化器中已经由TensorFlow实现,用户不必关心。
前向图中的节点,根据功能主要分为计算节点(Operation)、存储节点(Variable)和数据节点(Placeholder)3类。
Operation:对应无状态的计算或控制操作,主要负责算法逻辑表达或者流程控制。
Variable:对应有状态的变量操作,通常用来存储模型参数。
Placeholder:用于定义输入数据的类型和形状等属性,是对数据的统一抽象。
后向图中的节点,也可以分为3类,如下:
梯度:迭代过程中,模型参数的梯度。
参数更新操作:根据优化器的优化算法,结合梯度更新相应的模型参数。
更新后的参数:更新后的模型参数,用于模型的下一轮训练。
3.2 边
计算图中的边是有向边,定义了操作之间的关系,分为两类:一类用来传输数据,称为数据边;另一类用来定义依赖关系,称为控制边。
所有的节点都通过数据边或者控制边连接,其中入度为0的节点没有前置依赖,可以立即执行;入度大于0的节点,要等待其依赖的所有节点执行结束之后,才可以执行。
4.计算图的运行
TensorFlow中可以定义多个计算图,不同计算图上的张量和运算相互独立,因此每一个计算图都是一个独立的计算逻辑。
4.1 图的启动
启动计算图的第一步是创建一个会话(Session)对象,如果没有任何的创建参数,会话构造器将启动默认图。一个Session可以运行多个计算图,一个计算图也可以在多个Session中运行。
4.2 运行方式
简单来说,计算图的运行参考了拓扑排序的思想,可以分为如下4个步骤:
以节点名称作为关键字、入度作为值,创建一张哈希表,并将此计算图中的所有节点放入哈希表中。为此计算图创建一个可执行节点队列,将哈希表中入度为0的节点加入该队列,并从节点哈希表中删除这些节点。依次执行队列中的每一个节点,执行成功之后将此节点输出指向的节点的入度减1,更新哈希表中对应节点的入度。重复(2)和(3),直至可执行队列为空。对于步骤(3)来说,可执行队列中的节点在资源允许的情况下,是可以并行执行。TensorFlow有灵活的硬件调度机制,来高效利用资源。
4.3 硬件调度
在实现上,TensorFlow 将图形定义转换成分布式执行的操作,以充分利用可用的计算资源(如CPU或GPU)。一般你不需要显式指定使用CPU还是GPU,TensorFlow 能自动检测。如果检测到 GPU,TensorFlow 会尽可能地利用找到的第一个 GPU 来执行操作。
如果机器上有超过一个可用的 GPU,除第一个外的其它GPU默认是不参与计算的。为了让TensorFlow使用这些 GPU,开发者可以用with tf.device语句将Operation明确指派给特定的CPU或GPU 来执行。
资料来源:https://baijiahao.baidu.com/s?id=1647171594329693218&wfr=spider&for=pc
参考文献:
《深入理解TensorFlow架构设计与实现原理》 彭靖田、林健、白小龙
http://www.tensorfly.cn/tfdoc/get_started/basic_usage.html
https://blog.csdn.net/dcrmg/article/details/79028032
tf程序中,系统会自动创建并维护一个默认的计算图,计算图可以理解为神经网络(Neural Network)结构的程序化描述。如果不显式指定所归属的计算图,则所有的tensor和Operation都是在默认计算图中定义的,使用tf.get_default_graph()函数可以获取当前默认的计算图句柄。
tf中可以定义多个计算图,不同计算图上的张量和运算是相互独立的,不会共享。计算图可以用来隔离张量和计算,同时提供了管理张量和计算的机制。计算图可以通过Graph.device函数来指定运行计算的设备,为TensorFlow充分利用GPU/CPU提供了机制。
使用 g = tf.Graph()函数创建新的计算图;
在with g.as_default():语句下定义属于计算图g的张量和操作
在with tf.Session()中通过参数 graph = xxx指定当前会话所运行的计算图;
如果没有显式指定张量和操作所属的计算图,则这些张量和操作属于默认计算图;
一个图可以在多个sess中运行,一个sess也能运行多个图
# -*- coding: utf-8 -*-) import tensorflow as tf a=tf.constant([1.0,2.0]) b=tf.constant([1.0,2.0]) result = a+b print(a.graph is tf.get_default_graph()) # 输出为True,表示tensor a 是在默认的计算图中定义的 print(result.graph is tf.get_default_graph()) # 输出为True, 表示 Operation result 是在默认的计算图中定义的 print 'a.graph = {0}'.format(a.graph) print 'default graph = {0}'.format(tf.get_default_graph())
创建多个计算图
# -*- coding: utf-8 -*-) import tensorflow as tf # 在系统默认计算图上创建张量和操作 a=tf.constant([1.0,2.0]) b=tf.constant([2.0,1.0]) result = a+b # 定义两个计算图 g1=tf.Graph() g2=tf.Graph() # 在计算图g1中定义张量和操作 with g1.as_default(): a = tf.constant([1.0, 1.0]) b = tf.constant([1.0, 1.0]) result1 = a + b with g2.as_default(): a = tf.constant([2.0, 2.0]) b = tf.constant([2.0, 2.0]) result2 = a + b # 在g1计算图上创建会话 with tf.Session(graph=g1) as sess: out = sess.run(result1) print 'with graph g1, result: {0}'.format(out) with tf.Session(graph=g2) as sess: out = sess.run(result2) print 'with graph g2, result: {0}'.format(out) # 在默认计算图上创建会话 with tf.Session(graph=tf.get_default_graph()) as sess: out = sess.run(result) print 'with graph default, result: {0}'.format(out) print g1.version # 返回计算图中操作的个数
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律