Tensorflow Graphs and Sessions


dataflow的优势

dataflow
dataflow是并行计算的通用编程模型。在dataflow中,节点表示计算单位,edge表示计算消耗或产生的数据。例如,在TensorFlow图中,tf.matmul操作将对应于具有两个输入边(要乘以的矩阵)和一个输出边(乘法的结果)的单个节点。

并行:通过使用显式边来表示操作之间的依赖关系,系统很容易识别并行执行的操作。
分布式执行:通过使用显式边来表示在操作之间流动的值,TensorFlow可以跨越连接到不同机器的多个设备(CPU,GPU和TPU)对程序进行分区。TensorFlow在设备之间插入必要的通信和协调。
汇编:TensorFlow的XLA编译器可以使用数据流图中的信息来生成更快的代码,例如通过将相邻操作相互融合在一起。
可移植性:数据流图是模型中代码的语言无关表示。你可以在Python中构建数据流图,将其存储在SavedModel中,并将其还原为C++程序,以实现低延迟推理。

建立一个tf.graph()

大多数TensorFlow程序从数据流图构建阶段开始。 在此阶段,您调用构造新的tf.Operation(node)和tf.Tensor(edge)对象的TensorFlow API函数,并将它们添加到tf.Graph实例。 TensorFlow提供了一个默认图形,它是同一上下文中所有API函数的隐式参数。 例如:

调用tf.constant(42.0)创建一个单独的tf.Operation,产生值42.0,将其添加到默认图形,并返回一个表示常量值的tf.Tensor。

调用tf.matmul(x,y)创建一个单独的tf.Operation,将tf.Tensor对象x和y的值相乘,将其添加到默认图形,并返回一个表示乘法结果的tf.Tensor。

执行v=tf.Variable(0)向图形添加一个tf.Operation,它将存储在tf.Session.run调用之间持续的可写张量值。tf.Variable对象包装此操作,可以像张量一样使用,它将读取存储值的当前值。tf.Variable对象还有一些方法,如assign和assign_add,创建tf.Operation对象,在执行时,更新存储的值。(有关变量的更多信息,请参见Variables。)
调用tf.train.Optimizer.minimize会将运算和张量添加到计算梯度的默认图形上,并返回一个tf.Operation,当运行时,将这些梯度应用于一组变量。

大多数程序仅依赖于使用默认图。但是,更多高级用例处理多个图。高级API(如tf.estimator.Estimator API)代表你管理默认图形,比如可以为训练和评估创建不同的图。

Note:调用TensorFlow API中的大多数函数仅将操作和张量添加到默认图形,但不执行实际计算。而是组合这些函数,直到有一个表示整体计算的tf.Tensor或tf.Operation,例如执行梯度下降的一个步骤,然后将该对象传递给tf.Session来执行计算。 有关详细信息,请参见“执行tf.Session中的graph”一节。

命名操作

tf.Graph对象为其包含的tf.Operation对象定义一个命名空间。TensorFlow会自动为图形中的每个操作选择一个唯一的名称,但给出操作描述性名称可以使程序更易于阅读和调试。 TensorFlow API提供了两种覆盖名称操作:

每个API函数创建一个新的tf.Operation或返回一个新的tf.Tensor接受可选的名称参数。例如,tf.constant(42.0,name=“answer”)创建一个名为“answer”的新tf.Operation,并返回一个名为“answer:0”的tf.Tensor。如果默认图形已经包含一个名为“answer”的操作,TensorFlow将附加“_1”,“_2”等名称,以使其唯一。

tf.name_scope函数可以为在特定上下文中创建的所有操作添加名称范围前缀。 当前名称范围前缀是所有活动的tf.name_scope上下文管理器的名称的“/”分隔列表。如果在当前上下文中已经使用了名称范围,则TensorFlow会添加“_1”,“_2”等。 例如:

c_0 = tf.constant(0, name="c") # => operation named "c"

# Already-used names will be "uniquified".
c_1 = tf.constant(2, name="c") # => operation named "c_1"

# Name scopes add a prefix to all operations created in the same context.
with tf.name_scope("outer"):
c_2 = tf.constant(2, name="c") # => operation named "outer/c"

# Name scopes nest like paths in a hierarchical file system.
with tf.name_scope("inner"):
c_3 = tf.constant(3, name="c") # => operation named "outer/inner/c"

# Exiting a name scope context will return to the previous prefix.
c_4 = tf.constant(4, name="c") # => operation named "outer/c_1"

# Already-used name scopes will be "uniquified".
with tf.name_scope("inner"):
c_5 = tf.constant(5, name="c") # => operation named "outer/inner_1/c"

图形可视化器使用名称范围来对操作进行分组,并降低图形的视觉复杂性。有关详细信息,请参阅可视化图形。

请注意,tf.Tensor对象以产生张量作为输出的tf.Operation隐式命名。 张量名称的格式为<OP_NAME>:<i>,其中:
<OP_NAME>是生成它的操作的名称。
<i>是表示操作输出中该张量的索引的整数。

类似张量对象

许多TensorFlow操作将一个或多个tf.Tensor对象作为参数。 例如,tf.matmul需要两个tf.Tensor对象,并且tf.add_n获取n tf.Tensor对象的列表。 为方便起见,这些函数将接受一个类似张量的对象代替一个tf.Tensor,并使用tf.convert_to_tensor方法将其隐式转换为一个tf.Tensor。类似的包括以下元素:

tf.Tensor
tf.Variable
numpy.ndarray
list(和类似张量的对象的列表)
标量Python类型:bool,float,int,str

Note:默认情况下,TensorFlow将在每次使用相同的类似张量对象时创建一个新的tf.Tensor。 如果张量类物体较大(例如包含一组训练样本的numpy.ndarray),并且多次使用,则可能会耗尽内存。 为了避免这种情况,请手动在张量类对象上调用tf.convert_to_tensor一次,并使用返回的tf.Tensor。

在tf.Session中执行图

TensorFlow使用tf.Session类来表示客户端程序之间的连接-通常是Python程序,尽管类似的接口可用于其他语言—和C ++运行时。tf.Session对象提供对本地机器中的设备以及使用分布式TensorFlow运行时的远程设备的访问。它还缓存关于tf.Graph的信息,以便您可以多次高效地运行相同的计算。

创建一个tf.Session

如果你使用的是低级别的TensorFlow API,则可以为当前默认图形创建一个tf.Session,如下所示:
# Create a default in-process session.
with tf.Session() as sess:
# ...

# Create a remote session.
with tf.Session("grpc://example.org:2222"):
# ...

由于tf.Session占用物理资源(如GPU和网络连接),因此通常用作在退出块时自动关闭会话的上下文管理器(使用with块)。也可以创建一个会话而不使用with块,但是当你完成它释放资源后,你应该明确地调用tf.Session.close。
tf.Session.init 接受三个可选参数:

target:如果此参数为空(默认值),则session将仅使用本地计算机中的设备。 但是,您还可以指定一个grpc:// URL来指定TensorFlow服务器的地址,该服务器将会话访问该服务器所控制的计算机上的所有设备。 有关如何创建TensorFlow服务器的详细信息,请参阅tf.train.Server。例如,在常见的graph之间复制配置中,tf.Session以与客户端相同的过程连接到tf.train.Server。分布式TensorFlow部署指南介绍了其他常见情况。

graph: 默认情况下,新的tf.Session将被绑定到---并且只能在---当前的默认图中运行操作。 如果您在程序中使用多个图(有关详细信息,请参阅使用多个图编程),您可以在构建会话时指定一个显式的tf.Graph。
config: 此参数允许您指定一个控制会话行为的tf.ConfigProto。 例如,一些配置选项包括:

allow_soft_placement: 将其设置为True以启用“soft”设备布局算法,忽略尝试在GPU设备上放置仅CPU操作的tf.device注释,并将其放置在CPU上。
cluster_def:使用分布式TensorFlow时,此选项允许您指定计算中要使用的计算机,并提供作业名称,任务索引和网络地址之间的映射。有关详细信息,请参阅tf.train.ClusterSpec.as_cluster_def。
graph_options.optimizer_options:提供了优化tensorflow执行之前执行该控制图。
gpu_options.allow_growth:将其设置为True以更改GPU内存分配器,以便逐渐增加分配的内存量,而不是在启动时分配大部分内存。

使用tf.Session运行operation

tf.Session.run方法是运行tf.Operation或评估tf.Tensor的主要机制。 您可以将一个或多个tf.Operation或tf.Tensor对象传递给tf.Session.run,并且TensorFlow将执行计算结果所需的操作。
tf.Session.run要求您指定一个取出列表,它确定返回值,并且可以是tf.Operation,tf.Tensor或类似张量的类型,如tf.Variable。这些fetch确定必须执行整个tf.Graph的子图以产生结果:这是包含在提取列表中命名的所有操作的子图,以及其输出用于计算提取值的所有操作。例如,以下代码片段显示了tf.Session.run的不同参数如何导致执行不同的子图:

x = tf.constant([[37.0, -23.0], [1.0, 4.0]])
w = tf.Variable(tf.random_uniform([2, 2]))
y = tf.matmul(x, w)
output = tf.nn.softmax(y)
init_op = w.initializer

with tf.Session() as sess:
# Run the initializer on w.
sess.run(init_op)

# Evaluate output. sess.run(output) will return a NumPy array containing
# the result of the computation.
print(sess.run(output))

# Evaluate y and output. Note that y will only be computed once, and its
# result used both to return y_val and as an input to the tf.nn.softmax()
# op. Both y_val and output_val will be NumPy arrays.
y_val, output_val = sess.run([y, output])

tf.Session.run还可以选择使用feed的字典,它是从tf.Tensor对象(通常是tf.placeholder张量)到值(通常是Python标量,列表或NumPy数组)的映射,将替代这些张量 执行。 例如:

# Define a placeholder that expects a vector of three floating-point values,
'# and a computation that depends on it.
x = tf.placeholder(tf.float32, shape=[3])
y = tf.square(x)

with tf.Session() as sess:
# Feeding a value changes the result that is returned when you evaluate
y.
print(sess.run(y, {x: [1.0, 2.0, 3.0]}) # => "[1.0, 4.0, 9.0]"
print(sess.run(y, {x: [0.0, 0.0t, 5.0]}) # => "[0.0, 0.0, 25.0]"

# Raises tf.errors.InvalidArgumentError, because you must feed a value for
# a tf.placeholder() when evaluating a tensor that depends on it.
sess.run(y)

# Raises ValueError, because the shape of 37.0 does not match the shape
# of placeholder x.
sess.run(y, {x: 37.0})

tf.Session.run还接受一个可选选项参数,使你能够指定有关调用的选项,以及可选的run_metadata参数,可用于收集有关执行的元数据。 例如,您可以一起使用这些选项来收集有关执行的跟踪信息:

y = tf.matmul([[37.0, -23.0], [1.0, 4.0]], tf.random_uniform([2, 2]))

with tf.Session() as sess:
# Define options for the sess.run() call.
options = tf.RunOptions()
options.output_partition_graphs = True
options.trace_level = tf.RunOptions.FULL_TRACE

# Define a container for the returned metadata.
metadata = tf.RunMetadata()

sess.run(y, options=options, run_metadata=metadata)

# Print the subgraphs that executed on each device.
print(metadata.partition_graphs)

# Print the timings of each operation that executed.
print(metadata.step_stats)

GraphDef和MetaGraphDef

TensorFlow使用数据流图作为应用程序的便携式表示。tf.Graph包含两种相关信息:

graph structure: 图形的节点和边缘,指示单个操作如何组合在一起,但不规定如何使用它们。graph structure就像汇编代码:检查它可以传达一些有用的信息,但它不包含源代码传达的所有有用的上下文。
graph collection:TensorFlow提供了一种用于在tf.Graph中存储元数据集合的通用机制。tf.add_to_collection函数使您能够将list中的object与key(其中tf.GraphKeys定义了一些标准键)相关联,而tf.get_collection可以查找与一个键相关联的所有对象。 TensorFlow库的许多部分使用这个功能:例如,当你创建一个tf.Variable时,默认情况下将其添加到表示“全局变量”和“可训练变量”的集合中。 当您稍后创建一个tf.train.Saver或tf.train.Optimizer时,这些集合中的变量将用作默认参数。

tf.Graph可以保存为两种形式:

tf.GraphDef:这是图形结构的低级表示,包含其所有操作(如tf.NodeDef协议缓冲区)及其间的边界的描述。tf.GraphDef表示主要与低级API(例如tensorflow :: Session C ++ API)一起使用,通常需要额外的上下文(例如特定操作的名称)才能使用它。 tf.Graph.as_graph_def方法将tf.Graph转换为tf.GraphDef。

tf.train.MetaGraphDef:这是一个数据流图的更高级别的表示,其中包括一个tf.GraphDef和有助于理解图形的信息(如图形集合的内容)。tf.train.export_meta_graph函数将tf.Graph转换为tf.train.MetaGraphDef。 tf.train.Saver.save方法还可以写入一个tf.train.MetaGraphDef,它可以与保存的检查点一起使用,以恢复其保存点的训练过程的状态。

在大多数情况下,我们鼓励您使用tf.train.MetaGraphDef而不是tf.GraphDef。 在某些情况下,tf.GraphDef可能是有用的 - 例如,使用tf.import_graph_def或Graph Transform工具等函数执行低级图修改时,但tf.train.MetaGraphDef是一个更好的构建块高级应用程序。例如,SavedModel库使用tf.train.MetaGraphDef来打包tf.Graph和一组经过训练的模型参数,以便于服务。
如果你有一个tf.train.MetaGraphDef,tf.train.import_meta_graph函数将它加载到默认图形中。 调用此功能有两个主要功能:

1.它将从原始图形还原图的内容。 诸如tf.global_variables的APIs和API的默认参数(如tf.train.Optimizer.minimize)的工作方式将与原始图中的操作方式相同。
2.该函数返回一个tf.train.Saver,可用于从检查点恢复与图形关联的状态(训练参数等)。 tf.train.latest_checkpoint函数可以帮助从特定的检查点目录中找到最新的检查点。

如果您有一个tf.GraphDef,tf.import_graph_def函数可以将图形加载到现有的Python tf.Graph对象中。 要使用导入的图形,您必须知道tf.GraphDef中的操作或张量的名称。 tf.import_graph_def函数有两个主要功能可以帮助您使用导入的图形:

1.你可以通过传递可选的input_map参数,将导入的图形中的张量重新粘贴到默认图中的tf.Tensor对象。 例如,input_map使您能够导入在tf.GraphDef中定义的图片段,并将您正在构建的图中的张量静态连接到该片段中的tf.placeholder张量。
2.通过将其名称传递给return_elements列表,可以从导入的图形返回tf.Tensor或tf.Operation对象。

另外,你可以使用tf.device和tf.name_scope来控制导入节点的设备位置和名称。

可视化图

TensorFlow包括可以帮助您了解图形中的代码的工具。图形可视化器是TensorBoard的一个组件,可以在浏览器中直观呈现图形的结构。创建可视化的最简单的方法是在创建tf.summary.FileWriter时传递一个tf.Graph:
# Build your graph.
x = tf.constant([[37.0, -23.0], [1.0, 4.0]])
w = tf.Variable(tf.random_uniform([2, 2]))
y = tf.matmul(x, w)

# ...
loss = ...

train_op = tf.train.AdagradOptimizer(0.01).minimize(loss)

with tf.Session() as sess:
# sess.graph provides access to the graph used in a tf.Session.
writer = tf.summary.FileWriter("/tmp/log/...", sess.graph)

# Perform your computation...
for i in range(1000):
sess.run(train_op)
# ...

writer.close()

Note:如果使用tf.estimator.Estimator,则图形(和任何summaries)将自动记录到在创建estimator时指定的model_dir中。

然后,您可以打开tensorboard上的日志,导航到“graph”选项卡,并查看图形结构的高级可视化。 注意,典型的TensorFlow图 - 特别是具有自动计算梯度的训练图 - 具有太多的节点可以立即可视化。 图形可视化器利用名称范围将相关操作分组为“super”节点。 您可以点击任何这些super节点上的橙色“+”按钮来扩展子图。
minist_deep

使用多个图编程

Note:训练模型时,组织代码的常见方法是使用一个图来训练您的模型,以及用单独的图形评估或执行推理一个训练模型。 在许多情况下,推理图将与训练图不同:例如,在每种情况下,像dropout和批batch normalization这样的技术都使用不同的操作。此外,默认情况下,诸如tf.train.Saver这样的实用程序使用tf.Variable对象的名称(其名称基于底层tf.Operation)来标识保存的检查点中的每个变量。 编程时,您可以使用完全独立的Python进程构建和执行图形,也可以在同一过程中使用多个图形。 本节介绍如何在同一过程中使用多个图形。

如上所述,TensorFlow提供了在相同上下文中隐式传递给所有API函数的“默认图”。 对于许多应用程序,单个图形就足够了。 然而,TensorFlow还提供了操作默认图形的方法,这在更高级的使用案例中是有用的。 例如:

tf.Graph定义tf.Operation对象的命名空间:单个图中的每个操作必须具有唯一的名称。 如果所请求的名称已经被使用,TensorFlow将通过将“_1”,“_2”等附加到名称上来“唯一地”表示操作名称。 使用多个显式创建的图形可以更好地控制每个操作的名称。
默认图形存储有关添加到其中的每个tf.Operation和tf.Tensor的信息。 如果您的程序创建大量未连接的子图,则使用不同的tf.Graph构建每个子图可能会更有效,以便无关的状态可以被垃圾回收。

你可以使用tf.Graph.as_default上下文管理器来安装不同的tf.Graph作为默认图:
g_1 = tf.Graph()
with g_1.as_default():
# Operations created in this scope will be added to g_1.
c = tf.constant("Node in g_1")

# Sessions created in this scope will run operations from g_1.
sess_1 = tf.Session()

g_2 = tf.Graph()
with g_2.as_default():
# Operations created in this scope will be added to
g_2.
d = tf.constant("Node in g_2")

# Alternatively, you can pass a graph when constructing a tf.Session:

# sess_2 will run operations from g_2.
sess_2 = tf.Session(graph=g_2)

assert c.graph is g_1
assert sess_1.graph is g_1

assert d.graph is g_2
assert sess_2.graph is g_2

要检查当前的默认图形,请调用tf.get_default_graph,返回一个tf.Graph对象:

# Print all of the operations in the default graph.
g = tf.get_defaut_graph()
print(g.get_operations())


原文参考Tensorflow官网
https://www.tensorflow.org/programmers_guide/graphs

贝叶斯网络(Bayesian Networks)和决策图(Decision Graphs)是概率图模型的两种重要表示方法。 贝叶斯网络是一种有向无环图(DAG),用于表示变量之间的概率依赖关系。它由节点和边组成,节点代表变量,边代表变量之间的依赖关系。节点上的条件概率表(CPT)表示了每个变量在给定其父节点的情况下的条件概率分布。贝叶斯网络可以用于推理、预测和决策,能够有效地处理不确定性和复杂的因果关系。通过观察变量的取值,可以通过网络推理得到其他变量的后验概率分布。 决策图是一种扩展了贝叶斯网络的概率图模型,用于表示决策问题中的不确定性。它在贝叶斯网络的基础上增加了决策节点和价值节点。决策节点代表决策者可选择的行动,价值节点代表决策结果的效用或代价。决策图通过考虑不同决策和可能的事件后续产生的不确定性,帮助决策者进行最佳决策的评估。通过采用不同的策略,可以计算出每个决策的期望效用,并选择具有最高期望效用的决策。 贝叶斯网络和决策图是概率模型的重要工具,广泛应用于人工智能、机器学习和决策分析等领域。它们能够帮助我们理解和描述变量之间的关系,优化决策过程,并在不确定性环境中进行推理和预测。同时,对于复杂的问题,可以通过构建和学习这些概率图模型,得到更好的解释和决策支持。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值