1 Dive into TensorFlow系列-静态图运行原理

接触过TensorFlow v1的朋友都知道,训练一个TF模型有三个步骤:定义输入和模型结构,创建tf.Session实例sess,执行sess.run()启动训练 。不管是因为历史遗留代码或是团队保守的建模规范,其实很多算法团队仍在大量使用TF v1进行日常建模 。我相信很多算法工程师执行sess.run()不下100遍 , 但背后的运行原理大家是否清楚呢?不管你的回答是yes or no,今天让我们一起来探个究竟 。
学习静态图运行原理能干什么?掌握它对我们TF实践中的错误排查、程序定制、性能优化至关重要,是必备的前置知识 。
一、何为静态图?众所周知,TensorFlow程序有两种运行选择,即静态图模式与动态图模式 。
1.1 静态图静态图采用声明式编程范式(先编译后执行),根据前端语言(如python)描述的神经网络结构和参数信息构建固定的静成计算图,静态图在执行期间不依赖前端语言,而是由TF框架负责调度执行,因此非常适合做神经网络模型的部署 。用户定义的静态图经序列化后用GraphDef表达,其包含的信息有:网络连接、参数设置、损失函数、优化器等 。
有了完整的静态图定义后,TF编译器将计算图转化成IR(中间表示) 。初始IR会经TF编译器一系列的转换和优化策略生成等价的计算图 。编译器前端转换和优化包括:自动微分、常量折叠、公共子表达式消除;编译器后端与硬件相关,其转换和优化包括:代码指令生成和编译、算子选择、内存分配、内存复用等 。
综上所述,静态图的生成过程可用下图简要概适:

1 Dive into TensorFlow系列-静态图运行原理

文章插图
1.2 动态图动态图采用命令式编程范式 , 即编译与执行同时发生 。动态图采用前端语言的解释器对用户代码进行解析,然后利用TF框架的算子分发功能,使得算子立即执行并向前端返回计算结果 。当模型接收输入数据后,TF开始动态生成图拓扑结构,添加输入节点并将数据传输给后续节点 。如果动态图中含有条件控制逻辑,会立即计算逻辑判断结果并确定后续数据流向,因此动态图完整的拓扑结构在执行前是未知的 。另外,当模型根据新的batch训练时,原有的图结构则失效,必须根据输入和控制条件重新生成图结构 。
综上所述,动态图生成过程可用下图简要概括:
1 Dive into TensorFlow系列-静态图运行原理

文章插图
1.3 比较为了方便大家深入理解动/静态图原理及异同点,梳理相关信息如下表:
 静态图动态图即时获取中间结果否是代码调试难度难易控制流实现方式TF特定语法可采用前端语言语法性能多种优化策略,性能好优化受限,性能差内存占用内存占用少内存占用多部署情况可直接部署不可直接部署二、Session是干啥的?2.1 Session定义tf.Session代表用户程序和C++运行时之间的连接 。一个Session类对象session可以用来访问本机计算设备,也可访问TF分布式运行时环境中的远程设备 。session也能缓存tf.Graph信息,使得相同计算逻辑的多次执行得以高效实现 。
tf.Session的构造方法定义如下:
def __init__(self, target='', graph=None, config=None):"""Creates a new TensorFlow session.If no `graph` argument is specified when constructing the session,the default graph will be launched in the session. If you areusing more than one graph (created with `tf.Graph()` in the sameprocess, you will have to use different sessions for each graph,but each graph can be used in multiple sessions. In this case, itis often clearer to pass the graph to be launched explicitly tothe session constructor.Args:target: (Optional.) The execution engine to connect to.Defaults to using an in-process engine. See@{$distributed$Distributed TensorFlow}for more examples.graph: (Optional.) The `Graph` to be launched (described above).config: (Optional.) A [`ConfigProto`](https://www.tensorflow.org/code/tensorflow/core/protobuf/config.proto)protocol buffer with configuration options for the session."""super(Session, self).__init__(target, graph, config=config)# NOTE(mrry): Create these on first `__enter__` to avoid a reference cycle.self._default_graph_context_manager = Noneself._default_session_context_manager = None我们来看一下__init__()方法的三个参数:
?target:默认为空,代表session仅可访问本机上的计算设备 。如果设置grpc://样式的URL,则可以访问TF server对应机器的计算设备 。?graph:默认执行当前default graph中的op算子 。如果用户程序中包含多个计算图,则在创建session时必须指定是哪个计算图 。?config:通过指定tf.ConfigProto来控制session的行为 。常见的配置选项有:设备退化allow_soft_placement、分布式集群配置cluster_def、图优化策略graph_options.optimizer_options、GPU内存逐步增长gpu_options.allow_growth 。2.2 Session.run()tf.Session.run()实际是调用tf.BaseSession.run()方法,其函数签名如下:

推荐阅读