Tensor(张量)意味着N维数组,Flow(流)意味着基于数据流图的计算。TensorFlow的运行机制属于“定义”和“运行”相分离。模型的构建只是相当于定义了一个图结构(代表一个计算任务),图中有多个操作节点,每个节点可以有一个或多个tensor作为输入,也会输出1个或多个tensor,只有通过session启动一个会话,并通过feed机制把数据填充进去,数据以tensor的形式进行流动,整个计算任务才能被启动。
用with关键字在程序结束之后会自动关闭
对TensorFlow中图的理解
一个操作对象(Operation)是TensorFlow图中的一个节点, 可以接收0个或者多个输入Tensor, 并且可以输出0个或者多个Tensor,Operation对象是通过op构造函数(如tf.matmul())创建的。
具体参考:
https://www.jianshu.com/p/b547c163e202
https://blog.csdn.net/sinat_26745777/article/details/84350681
和图相关的常用函数
https://blog.csdn.net/lenbow/article/details/52181159
class tf.Graph tensorflow中的计算以图数据流的方式表示,一个图包含一系列表示计算单元的操作对象以及在图中流动的数据单元以tensor对象表现
tf.Graph() 建立一个空图
tf.Graph.as_default() 一个将某图设置为默认图,并返回一个上下文管理器,如果不显式添加一个默认图,系统会自动设置一个全局的默认图。所设置的默认图,在模块范围内所定义的节点都将默认加入默认图中
tf.Graph.as_graph_def(from_version=None, add_shapes=False) 返回一个图的序列化的GraphDef表示,序列化的GraphDef可以导入至另一个图中(使用 import_graph_def()) #在把图进行pb封装时会用到
tf.reset_default_graph() #重置默认图,加载图之间应该先重置默认图,因为不重置在封装多个图时可能会加载别人的图
tf.Graph.get_operation_by_name(name) 根据名称返回操作节点 tf.Graph.get_operation_by_name(name).output[0] 获得相应名称操作节点其输出tensor中为0的tensor
tf.Graph.get_tensor_by_name(name) 根据名称返回tensor数据
所以访问计算图中的V1节点,就只能使用tf.get_default_graph().get_tensor_by_name("v1:0")的方式。
很多人可能并不理解这个:0,这是一个operation的输出。也就是说变量节点的输出只有一个,所以用0表示引用计算图中这个变量节点的输出tensor。
tf.Graph.get_operations() 返回图中的操作节点列表
加载持久化模型的方式
结合:http://www.mamicode.com/info-detail-2424278.html
第一种:通过saver加载saver = tf.train.Saver() saver.restore
通过这种方式加载需要注意
1)程序前面得有 Variable 供 save or restore 才不报错否则会提示没有可保存的变量
2)这种方式只是持久化模型中变量的值加载到当前代码计算图中的变量中去。属于当前代码计算图已经定义,因此还必须在加载之前创建模型,变量是当前代码计算图中变量集合的一个子集,必须是一种严格包含的关系。
第二种:通过import_meta_graph
这种方式完全不允许当前代码计算图已经定义的变量节点和要加载的持久化模型中的节点存在冲突,因为它不仅加载参数还会加载整个图结构。
第三种:使用pb文件的方式。
即使持久化模型中的变量节点和当前代码计算图中定义的变量节点发生冲突,也没有问题,没有任何关系。因为pb文件的方式加载进来的计算图,会全部加上import/前缀。也就是说,从命名空间上就隔开了这种冲突。所以,使用别人的模型,最好的方式就是用pb文件。因为不会有冲突的可能!
但是,有一个弊端就是,import命名空间下的变量不能参与到当前的训练
同时,你使用v1=tf.get_variable(name="v1",shape=[1])方式,会在当前代码的计算图中生成一个新的变量节点V1_1,并非加载的持久化模型中的变量节点V1。此时,就会出现函数功能失效。也就是,你希望调用get_variable函数使得:python的变量v1和计算图中的变量节点v1是绑定的,但是情况并非如此,绑定的是变量节点v1_1。
所以访问计算图中的V1节点,就只能使用tf.get_default_graph().get_tensor_by_name("v1:0")的方式。
封装成pb文件的好处:
1、它具有语言独立性,可独立运行,封闭的序列化格式,任何语言都可以解析它,它允许其他语言和深度学习框架读取、继续训练和迁移 TensorFlow 的模型。
2、实现了创建模型与使用模型的解耦。
3、保存为 PB 文件时候,模型的变量都会变成固定的,导致模型的大小会大大减小。
4、避免造成命名的冲突。