
3.1.2 TensorFlow 1.x与TensorFlow 2.x的区别
本书中关于TensorFlow的所有例子均是基于TensorFlow 2.x之上的。如果读者没有接触过TensorFlow 1.x,那么也不需要特意去学习TensorFlow 1.x,避免做无用功。作为一经推出就受欢迎的机器学习开源框架,也面临着其他开源框架的竞争,如FaceBook推出PyTorch,由于相对TensorFlow 1.x而言,有很强的易用性,因此一直是TensorFlow的有力竞争者。
所以,2018年,在TensorFlow被推出3年时,Google正式发布了TensorFlow 2.0,抛弃了原有的架构,整合了过去几年中,各领域为TensorFlow贡献的组件,将它们打包为一个综合平台,如图3-4所示,支持了从模型训练到模型部署的整个机器学习流程。

图3-4 综合平台
在TensorFlow 2.0中,主要关注简单性与易用性这两方面内容,重点有以下更新。
● 使用Keras作为高层API,配合Eager Execution,使用动态计算图搭建模型,可以快速、轻松地进行模型搭建。
● 增强模型部署能力,训练出模型,可以在其他平台、移动端、嵌入式设备、浏览器端,甚至其他语言平台部署并使用。
● 清理冗余与废弃的API,使整体流程更加清晰,平缓学习曲线。
● 提供更多、更强大的实验工具,为使用者提供方便的调试功能。
下面将介绍TensorFlow 2.x相对于TensorFlow1.0的改变。
1.使用Keras作为高级API
在TensorFlow1.x中,最为人诟病的是,搭建神经网络有许多API可以使用,但使用上都不直观和方便。例如,用户可以选择使用tf.slim,tf.layers,tf.contrib.layers中的一种组装神经网络后,加入session中再进行运行,使得使用者经常困惑和有选择困难,无法区分哪种情况使用哪种API,而且修改网络模型也不方便。Keras作为一个流行的高级深度学习API,可以用非常直观的方式构建深度学习网络,将输入从一个模块传递到下一个模块,其中模块分别代表神经网络中的全连接层、卷积层、池化层等具体网络层。
在TensorFlow 2.0中,Keras成为TensorFlow的官方高级API,与TensorFlow无缝集成,可以被直接使用。这样做的好处就是,当面对一个问题时,如果Keras足以胜任,那么用户可以使用Keras的高级API来快速实现相关功能。如果用户需要做一些特殊处理,则可以使用TensorFlow的API自定义网络的隐藏层。这就在易用性和可定制性之间取得了很好的平衡。
2.默认使用Eager Execution
在TensorFlow最初设计中,要运行一个模型,需要先搭建静态计算图,并加入会话(session),然后调用“session.run()”执行计算机图。这种方式在性能和并发性上都有出色的表现,但是学习曲线较陡,调试也比较困难(因为无法立即和直观观察结果)。而另一个机器学习框架PyTorch则采用了动态图方案,可以让每一步代码都立即得到结果,所以尽管PyTorch的效率不如TensorFlow,但得益于简单、直观的流程与方式,使得PyTorch对于新加入机器学习的学习者来说,更具有吸引力。
所以,在TensorFlow 1.4中,官方团队就引入了Eager Execution(即刻执行)的方式来降低学习难度,在保留高性能的同时,整体体验上模仿PyTorch的便捷性。但当时,这只是作为可选操作,用户可以自主选择是否使用。在TensorFlow 2.0中,正式将已经成熟的Eager Execution作为默认编码方式。
3.精简API
在TensorFlow 1.x中,有一个让人困惑的情况是,面对一个问题,有时候难以确定到底要使用哪个API,因为有非常多的API可以完成类似的功能,这主要是由于以下原因造成的。在TensorFlow 1.x的发展过程中,添加了非常多的API包,同时又有很多API被标注废弃,相同功能的API被反复重命名,导致TensorFlow 1.x的API体系非常复杂和混乱,备受使用者诟病。针对这个弊端,TensorFlow 2.0对API体系进行了彻底更新,大量的冗余API被彻底放弃,或放入其他包中,还有一部分被易用的API替换。这些大刀阔斧的修改使得TensorFlow 2.0更易用,但也不再兼容TensorFlow 1.0代码,TensorFlow官方提供了详尽的升级文档与升级脚本来指导用户升级。
4.使用function替代session
在TensorFlow 2.0中,使用了动态计算图加Eager Execution作为默认机制,并且废弃了session这个概念,使得模型的搭建过程和普通编程方式更为相似。不过,这在使TensorFlow 2.0更易用的同时,也在一定程度上牺牲了执行效率。为了提高运行速度,TensorFlow 2.0引入了tf.function这个概念,使用Python的装饰符@tf.function可以自动地将函数转换为计算图。这种被转化出来的图,也称为tf.AutoGraph。
5.取消全局变量
TensorFlow 1.x创建的全局变量,在调用tf.Variable()创建时,这个变量会被放到一个默认图中。这就导致对应的变量超过它的生命周期(如在Python中应该被垃圾回收)时,依然会存在于默认图中。当使用人员试图去恢复使用这个变量时,就必须知道变量的名字。在实际模型搭建与训练过程中,TensorFlow的API会自行创建很多变量,而用户无法完全得知这些变量的名字。在TensorFlow1.x中,引入了一些方法来试图解决这个问题,但是没有获得很好的效果。
在TensorFlow 2.0中,摒弃了TensorFlow 1.x中的种种方法,采用变量跟踪机制,使用动处理变量。当TensorFlow不再引用一个变量时,该变量会被自动回收。