雷锋网按:本文作者黄文坚,ppmoney 大数据算法总监,《 tensorflow 实战》作者。本文节选自《 tensorflow 实战》第二章。
在下周二(2月28日)雷锋网硬创公开课栏目将会推出黄文坚老师的公开课《深度学习之经典卷积神经网络的技术浅析》(),欢迎大家报名!点击了解详情
google 近日发布了 tensorflow 1.0 候选版,这第一个稳定版将是深度学习框架发展中的里程碑的一步。自 tensorflow 于 2015 年底正式开源,距今已有一年多,这期间 tensorflow 不断给人以惊喜。在这一年多时间,tensorflow 已从初入深度学习框架大战的新星,成为了几近垄断的行业事实标准。
主流深度学习框架对比
深度学习研究的热潮持续高涨,各种开源深度学习框架也层出不穷,其中包括 tensorflow、caffe、keras、cntk、torch7、mxnet、leaf、theano、deeplearning4、lasagne、neon 等等。然而 tensorflow 却杀出重围,在关注度和用户数上都占据绝对优势,大有一统江湖之势。表 2-1 所示为各个开源框架在github上的数据统计(数据统计于 2017 年 1 月 3 日),可以看到 tensorflow 在 star 数量、fork 数量、contributor 数量这三个数据上都完胜其他对手。
究其原因,主要是 google 在业界的号召力确实强大,之前也有许多成功的开源项目,以及 google 强大的人工智能研发水平,都让大家对 google 的深度学习框架充满信心,以至于 tensorflow 在 2015 年 11 月刚开源的第一个月就积累了 10000+ 的 star 。其次,tensorflow 确实在很多方面拥有优异的表现,比如设计神经网络结构的代码的简洁度,分布式深度学习算法的执行效率,还有部署的便利性,都是其得以胜出的亮点。如果一直关注着 tensorflow 的开发进度,就会发现基本上每星期 tensorflow 都会有1万行以上的代码更新,多则数万行。产品本身优异的质量、快速的迭代更新、活跃的社区和积极的反馈,形成了良性循环,可以想见 tensorflow 未来将继续在各种深度学习框架中独占鳌头。
表2-1 各个开源框架在 github 上的数据统计
观察表2-1还可以发现,google、microsoft、facebook 等巨头都参与了这场深度学习框架大战,此外,还有毕业于伯克利大学的贾扬清主导开发的 caffe,蒙特利尔大学 lisa lab 团队开发的 theano,以及其他个人或商业组织贡献的框架。另外,可以看到各大主流框架基本都支持 python,目前 python 在科学计算和数据挖掘领域可以说是独领风骚。虽然有来自 r、julia 等语言的竞争压力,但是 python 的各种库实在是太完善了,web 开发、数据可视化、数据预处理、数据库连接、爬虫等无所不能,有一个完美的生态环境。仅在数据挖据工具链上,python 就有 numpy、scipy、pandas、scikit-learn、xgboost 等组件,做数据采集和预处理都非常方便,并且之后的模型训练阶段可以和 tensorflow 等基于 python 的深度学习框架完美衔接。
表 2-1 和图 2-1 所示为对主流的深度学习框架 tensorflow、caffe、cntk、theano、torch 在各个维度的评分,本书 2.2 节会对各个深度学习框架进行比较详细的介绍。
表2-2 主流深度学习框架在各个维度的评分
图2-1 主流深度学习框架对比图
各深度学习框架简介
在本节,我们先来看看目前各流行框架的异同,以及各自的特点和优势。
tensorflow
tensorflow 是相对高阶的机器学习库,用户可以方便地用它设计神经网络结构,而不必为了追求高效率的实现亲自写 c++或 cuda 代码。它和 theano 一样都支持自动求导,用户不需要再通过反向传播求解梯度。其核心代码和 caffe 一样是用 c++编写的,使用 c++简化了线上部署的复杂度,并让手机这种内存和cpu资源都紧张的设备可以运行复杂模型(python 则会比较消耗资源,并且执行效率不高)。除了核心代码的 c++接口,tensorflow 还有官方的 python、go 和 java 接口,是通过 swig(simplified wrapper and interface generator)实现的,这样用户就可以在一个硬件配置较好的机器中用 python进行实验,并在资源比较紧张的嵌入式环境或需要低延迟的环境中用 c++部署模型。swig 支持给 c/c++代码提供各种语言的接口,因此其他脚本语言的接口未来也可以通过 swig 方便地添加。不过使用 python 时有一个影响效率的问题是,每一个 mini-batch 要从 python 中 feed 到网络中,这个过程在 mini-batch 的数据量很小或者运算时间很短时,可能会带来影响比较大的延迟。现在 tensorflow 还有非官方的 julia、node.js、r 的接口支持,地址如下。
julia: http://github/malmaud/tensorflow.jl
node.js: http://github/node-tensorflow/node-tensorflow
r: http://github/rstudio/tensorflow
tensorflow 也有内置的 tf.learn 和 tf.slim 等上层组件可以帮助快速地设计新网络,并且兼容 scikit-learn estimator 接口,可以方便地实现 evaluate、grid search、cross validation 等功能。同时 tensorflow 不只局限于神经网络,其数据流式图支持非常自由的算法表达,当然也可以轻松实现深度学习以外的机器学习算法。事实上,只要可以将计算表示成计算图的形式,就可以使用 tensorflow 。用户可以写内层循环代码控制计算图分支的计算,tensorflow 会自动将相关的分支转为子图并执行迭代运算。tensorflow 也可以将计算图中的各个节点分配到不同的设备执行,充分利用硬件资源。定义新的节点只需要写一个 python 函数,如果没有对应的底层运算核,那么可能需要写 c++或者 cuda 代码实现运算操作。
在数据并行模式上,tensorflow 和 parameter server 很像,但 tensorflow 有独立的 variable node,不像其他框架有一个全局统一的参数服务器,因此参数同步更自由。tensorflow 和 spark 的核心都是一个数据计算的流式图,spark 面向的是大规模的数据,支持 sql 等操作,而 tensorflow 主要面向内存足以装载模型参数的环境,这样可以最大化计算效率。
tensorflow 的另外一个重要特点是它灵活的移植性,可以将同一份代码几乎不经过修改就轻松地部署到有任意数量 cpu 或 gpu 的 pc、服务器或者移动设备上。相比于 theano,tensorflow 还有一个优势就是它极快的编译速度,在定义新网络结构时,theano 通常需要长时间的编译,因此尝试新模型需要比较大的代价,而 tensorflow 完全没有这个问题。tensorflow 还有功能强大的可视化组件 tensorboard,能可视化网络结构和训练过程,对于观察复杂的网络结构和监控长时间、大规模的训练很有帮助。tensorflow 针对生产环境高度优化,它产品级的高质量代码和设计都可以保证在生产环境中稳定运行,同时一旦 tensorflow 广泛地被工业界使用,将产生良性循环,成为深度学习领域的事实标准。
除了支持常见的网络结构(卷积神经网络(convolutional neural network,cnn)、循环神经网络(recurent neural network,rnn))外,tensorflow 还支持深度强化学习乃至其他计算密集的科学计算(如偏微分方程求解等)。tensorflow 此前不支持 symbolic loop,需要使用 python 循环而无法进行图编译优化,但最近新加入的 xla 已经开始支持 jit 和 aot,另外它使用 bucketing trick 也可以比较高效地实现循环神经网络。tensorflow 的一个薄弱地方可能在于计算图必须构建为静态图,这让很多计算变得难以实现,尤其是序列预测中经常使用的 beam search。
tensorflow 的用户能够将训练好的模型方便地部署到多种硬件、操作系统平台上,支持 intel 和 amd 的 cpu,通过 cuda 支持 nvidia 的 gpu (最近也开始通过 opencl 支持 amd 的 gpu,但没有 cuda 成熟),支持 linux 和 mac,最近在 0.12 版本中也开始尝试支持 windows。在工业生产环境中,硬件设备有些是最新款的,有些是用了几年的老机型,来源可能比较复杂,tensorflow 的异构性让它能够全面地支持各种硬件和操作系统。同时,其在 cpu 上的矩阵运算库使用了 eigen 而不是 blas 库,能够基于 arm 架构编译和优化,因此在移动设备(android 和 ios)上表现得很好。
tensorflow 在最开始发布时只支持单机,而且只支持 cuda 6.5 和 cudnn v2,并且没有官方和其他深度学习框架的对比结果。在 2015 年年底,许多其他框架做了各种性能对比评测,每次 tensorflow 都会作为较差的对照组出现。那个时期的 tensorflow 真的不快,性能上仅和普遍认为很慢的 theano 比肩,在各个框架中可以算是垫底。但是凭借 google 强大的开发实力,很快支持了新版的 cudnn (目前支持cudnn v5.1),在单 gpu 上的性能追上了其他框架。表 2-3 所示为 给出的各个框架在 alexnet 上单 gpu 的性能评测。https://github/soumith/convnet-benchmarks
表2-3 各深度学习框架在 alexnet 上的性能对比
目前在单 gpu 的条件下,绝大多数深度学习框架都依赖于 cudnn,因此只要硬件计算能力或者内存分配差异不大,最终训练速度不会相差太大。但是对于大规模深度学习来说,巨大的数据量使得单机很难在有限的时间完成训练。这时需要分布式计算使 gpu 集群乃至 tpu 集群并行计算,共同训练出一个模型,所以框架的分布式性能是至关重要的。tensorflow 在 2016 年 4 月开源了分布式版本,使用 16 块 gpu 可达单 gpu 的 15 倍提速,在 50 块 gpu 时可达到 40 倍提速,分布式的效率很高。目前原生支持的分布式深度学习框架不多,只有 tensorflow、cntk、deeplearning4j、mxnet 等。不过目前 tensorflow 的设计对不同设备间的通信优化得不是很好,其单机的 reduction 只能用 cpu 处理,分布式的通信使用基于 socket 的 rpc,而不是速度更快的 rdma,所以其分布式性能可能还没有达到最优。
google 在 2016 年 2 月开源了 tensorflow serving,这个组件可以将 tensorflow 训练好的模型导出,并部署成可以对外提供预测服务的 restful 接口,如图 2-2 所示。有了这个组件,tensorflow 就可以实现应用机器学习的全流程:从训练模型、调试参数,到打包模型,最后部署服务,名副其实是一个从研究到生产整条流水线都齐备的框架。这里引用 tensorflow 内部开发人员的描述:“ tensorflow serving 是一个为生产环境而设计的高性能的机器学习服务系统。它可以同时运行多个大规模深度学习模型,支持模型生命周期管理、算法实验,并可以高效地利用 gpu 资源,让 tensorflow 训练好的模型更快捷方便地投入到实际生产环境”。除了 tensorflow 以外的其他框架都缺少为生产环境部署的考虑,而 google 作为广泛在实际产品中应用深度学习的巨头可能也意识到了这个机会,因此开发了这个部署服务的平台。tensorflow serving 可以说是一副王牌,将会帮 tensorflow 成为行业标准做出巨大贡献。
图2-2 tensorflow serving 架构
tensorboard 是 tensorflow 的一组 web 应用,用来监控 tensorflow 运行过程,或可视化 computation graph。tensorboard 目前支持五种可视化:标量(scalars)、图片(images)、音频(audio)、直方图(histograms)和计算图(computation graph)。tensorboard 的 events dashboard 可以用来持续地监控运行时的关键指标,比如 loss、学习速率(learning rate)或是验证集上的准确率(accuracy);image dashboard 则可以展示训练过程中用户设定保存的图片,比如某个训练中间结果用 matplotlib 等绘制(plot)出来的图片;graph explorer 则可以完全展示一个 tensorflow 的计算图,并且支持缩放拖曳和查看节点属性。tensorboard 的可视化效果如图 2-3 和图 2-4 所示。
图2-3 tensorboard 的 loss 标量的可视化
图2-4 tensorboard 的模型结构可视化
tensorflow 拥有�...