TensorFlow核心机制:深入解析tf.Graph与tf.Session
本文深入解析TensorFlow两大核心组件:计算图(tf.Graph)与会话(tf.Session)。详细阐述如何通过tf.Graph构建神经网络的数据流与依赖关系,以及利用tf.Session执行具体计算、管理变量初始化的完整流程。结合代码示例说明节点生成、变量初始化及sess.run()参数用法,帮助开发者理解TensorFlow静态计算图的设计哲学与运行机制。
TensorFlow系统概述
TensorFlow编程系统

TensorFlow工具链及其背后的深度学习理论构成了一个紧密耦合的整体。通常意义上的系统是具备独立处理复杂功能能力的实体,其核心逻辑是将输入转化为期望的输出。许多传统系统呈现线性特征,类似工厂流水线,即输入经过固定处理流程后得到输出。这类系统由多个具备特定功能且特性稳定的基础部件组成,设计者通过特定的连接方式实现部件间的数据交互与信息交换,从而协同完成既定任务。
任何稳健的系统都依赖于稳定且独立的单一功能部件,并需配备高效的内部通信机制,以确保系统能够安全、健康地运行。
现实世界中许多系统是预先设定且不可更改的线性结构,例如工厂流水线。这类系统缺乏自我调整能力,无法对外部环境变化做出响应,因此不具备所谓的“智能”。
深度学习(神经网络)之所以展现智能特性,关键在于其内置的反馈机制。深度学习包含一套评估输出的评价函数(即损失函数)。在评估完成后,系统通过特定算法(如梯度下降法)更新网络参数,旨在优化输出结果。

综上所述,神经网络的系统架构主要包含以下核心要素:
- 输入数据
- 系统主体(即神经网络结构),涵盖网络构建策略、执行逻辑、变量维护机制、模型存储与恢复等关键问题
- 损失函数
- 反馈机制:具体训练方式
明确上述组成部分后,即可通过流程化方式将其组合,使系统对输入数据进行学习并调整参数。由于系统具备反馈机制,其组合方式必然包含循环结构。
TensorFlow的设计理念根植于神经网络本身。因此,在学习TensorFlow之前,建立对神经网络的全面且深刻的理解至关重要。如下图所示,展示了TensorFlow的执行示意流程。

计算图与会话的核心角色
在上述要素中,系统本身相关的问题最为关键,即如何构建并执行一个神经网络。在TensorFlow中,使用计算图(Graph)来构建网络结构,使用会话(Session)来具体执行网络运算。深入理解这两者,有助于掌握TensorFlow的设计思路与运行机制。
tf.Graph:构建网络结构
图(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默认会自动创建一张计算图,因此代码中的前两行可以省略。默认情况下,这张默认计算图是空的。

在执行完 `img = tf.constant(1.0, shape=[1,5,5,3])` 后,计算图中生成一个节点(node)。每个节点由名称(name)、操作类型(op)、输入(input)及属性(如类型、形状、值)组成,整个计算图由众多这样的节点构成。对于 `tf.constant()` 函数,仅生成一个节点;但对于如 `tf.Variable(initializer, name)`(注意其第一个参数为初始化器)等函数,则会生成多个节点(后续将详细讲解)。
执行完 `img = tf.constant(1.0, shape=[1,5,5,3])` 后,计算图中增加了一个节点(此处仅展示name、op、input属性,因每个节点属性较多)。

继续添加代码:
img = tf.constant(1.0, shape=[1,5,5,3])
k = tf.constant(1.0, shape=[3,3,3,1])
代码执行后的计算图如下所示:

需要注意的是,若未对节点进行显式命名,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)
该变量使用一个常量作为初始化器。我们先观察此时的计算图:

如图所示,执行 `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")
得到的计算图如下:

可以看出,变量读取是通过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()` 函数后,计算图如下:

`tf.global_variables_initializer()` 生成了一个名为init的节点,该节点将所有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())来执行计算图。在 `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内容请搜索本站以前的文章或继续浏览下面的相关文章,希望大家以后多多支持本站!
免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。









