[关闭]
@songying 2019-03-24T13:09:30.000000Z 字数 3078 阅读 1263

一文滤清 TensorFlow

博客文章

前言

初次接触 TensorFlow 时,被 TensorFlow 纷繁错杂的概念弄花了眼,不由生出 TensorFlow 好难的感觉 , 这也是 TensorFlow 难以上手的一大原因 。 本文采用由底到顶的方式描述 TensorFlow 的 API 架构,并对某一些点做深入描述,但没有展示全部细节(篇幅以及难度原因)。

API 结构一览

在上图中, 左边的部分是高层API, 高层API在牺牲部分灵活性的情况下可以帮助你快速的搭建模型; 右边的部分属于底层API, 灵活性较高,但模型的实现较为复杂,一个简单模型往往需要上千行代码。

本文之所以采用由底到顶的方法是因为在早期, TensorFlow 中只有底层 API, 后来,限于底层API的上手难度(尤其对比Pytorch),官方逐渐发布了高层API, 并在最近的核心API中将 Keras 视作主要高级 API, 不过这样一来, Estimator 的位置变得好尴尬啊。


数据流图 -- Graph

现有的深度学习框架如TensorFlow,pytorch等在内部实现中都采用了数据流图作为计算的核心抽象,原因在于基于声明式的数据流图更加适合神经网络, 而在API上,TensorFlow与PtyTorch采用了完全不同的策略,TensorFlow API 更偏向声明式编程,而Pytorch API 更加关注命令式编程,两者之间的讨论又是另一个故事了。

回到数据流图本身,其本质是由 Node有向边构成的有向无环图

由上可以看出,数据流图本质上描述的是数据的表示与算法逻辑, 其可以视为是 TensorFlow 的数据流部分;但是数据流图的创建,运行过程是十分复杂的, 因此TensorFlow 提供了 Session 来作为控制流来保证数据流图在创建,运行时的高效性和正确性。

从代码角度看,TensorFlow通过 tf.Graph API 来定义一个命名空间来定义数据流图, 如果你没有显式的定义图,TensorFlow会采用默认的Graph来作为数据流图。 理解 Graph 的最佳方法是将其想象成一个图抽象,其本身没有意义,有意义的是图上的计算逻辑与数据抽象。

数据承载者 -- 张量

上节已经提到,张量是数据流图上的数据载体,其在数据流图中往往是隐式的传递的,我们只能通过观察代码(或TensorBoard)来了解 张量 的流动。

在 TensorFlow 中定义了两种张量抽象: Tensor 和 SparseTensor, 前者表示的是稠密数据,后者表示的是稀疏数据(用于较少高维稀疏数据的内存占用)。

节点 -- Node

这里强调一点:Node 的输入,输出都为张量,一个节点对应的是一个具体的操作,而操作是模型功能的实际载体。 节点按照功能不同可以分为三种:

控制流:Session

前面提到,数据流图的构造,运行是极为复杂的,因此需要通过Session来控制整个数据流图的计算过程以保证计算的准确和高效。

我们将整个TensorFlow系统架构简单的分为两大部分:

Session 可以说是前端系统与后端系统的纽带, 你在实际编码时往往只需要 Session.run() , 此时,TensorFlow将定义好的图结构以及相关数据以某种数据形式传递给后端系统来进行图的构建,运行等真实计算操作。 由于 TensorFlow 对后端系统细节进行了封装,所以你无法看到相关流程,因此难以理解。 (此处推荐看[2]的第四章)

其实仅仅作为使用者而言, 你没有必要深究Session背后的实现细节,往往只需要三步走:

  1. sess = tf.Session() # 创建会话
  2. sess.run() # 运行会话,并填充数据
  3. sess.close() # 关闭会话

高级 API

在2018年年初, TensorFlow官方提供了 tf.datatf.estimator 两大高层API, 而在2018年年底的时候,再看官方文档时, TensorFlow 又添加了两大高层API : tf.kerastf.eager, 只能感慨:求求你,别变了,学不动了啊。马上TensorFlow 2.0 就要发布了, 感觉要吐血了,,噗噗噗。

tf.data -- 强大的数据读取机制

自2018年初,TensorFlow就鼓励开发者采用tf.data 作为新的读取方式,目前很多开源实现包括我自己写数据预处理的部分都会首选 tf.data ,早期的考古 API 已经被官方丢到了垃圾桶里了。

最强大的是,该 API 不仅可以与高层API Keras, Estimator 合作,还能与底层 API 进行交互,可以说是非常之强大了,推荐学使用。

tf.estimator

tf.estimator 本意是为了减轻开发者的负担,提供了封装好的高层API来加速模型的开发,并提供了一些基本的分类,回归模型,可以说非常良心了,用起来也是真的方便。 tf.estimator 依托于 tf.layers,提供了一定的灵活性,但我就不明白,有了 Keras 还要这玩意干啥?难道就是为了提供一些基线模型? 有懂的大佬麻烦现身指教一下。

tf.keras

我觉得Google这篇文章就完美的介绍了TensorFlow 中的Keras: 标准化Keras:TensorFlow 2.0中的高级API指南

总的来说,如果你需要自定义模型架构,那么请选择 Keras, 忘掉 Estimator;如果你只是想简单的跑一个简单模型,不想自定义模型架构,Estimator不失为一个好的选择。

tf.eager

2018年,深度学习领域动态图大行其道,迫于 PyTorch 追赶的压力, Google 实现了基于动态图的 Eager。 哎,真的学不动了啊。 不仅仅 TensorFlow 在向动态图领域渗透,PyTorch也开始向静态图领域伸出魔爪,可以预见的是,未来一定是动态图 + 静态图 并行。

目前还是先观察观察,TensorFlow的 Eager API 应该还会发生较大的变化,Keras 足够折腾了,真的。

最后

TensorFlow 2.0即将发布,这意味着TensorFlow已经进入成熟期,所以说,下一批同学真的幸福啊。 最后提一点建议,对于初学者而言,建议先使用 Keras, 采用从顶到底的学习方式,不然一上来就整一堆概念,真的巨难受啊。

Reference

[1] 《深入理解TensorFlow 架构设计与原理》 -- 推荐

[2] 《TensorFlow internals》 -- 推荐

[3] TensorFlow 官方网站

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注