建站服务器
引言:alphago在2017年年初化身master,在弈城和野狐等平台上横扫中日韩围棋高手,取得60连胜,未尝败绩。alphago背后神秘的推动力就是tensorflow——google于2015年11月开源的机器学习及深度学习框架。
tensorflow在2015年年底一出现就受到了极大的关注,在一个月内获得了github上超过一万颗星的关注,目前在所有的机器学习、深度学习项目中排名第一,甚至在所有的python项目中也排名第一。本文将带我们简单了解下tensorflow,并与其他主流深度学习框架进行了对比。
本文选自《tensorflow实战》。
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的接口支持。
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上的性能追上了其他框架。下图为https://github.com/soumith/convnet-benchmarks给出的各个框架在alexnet上单gpu的性能评测。
目前在单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 serving19,这个组件可以将tensorflow训练好的模型导出,并部署成可以对外提供预测服务的restful接口,如图2-2所示。有了这个组件,tensorflow就可以实现应用机器学习的全流程:从训练模型、调试参数,到打包模型,最后部署服务,名副其实是一个从研究到生产整条流水线都齐备的框架。这里引用tensorflow内部开发人员的描述:“tensorflow serving是一个为生产环境而设计的高性能的机器学习服务系统。它可以同时运行多个大规模深度学习模型,支持模型生命周期管理、算法实验,并可以高效地利用gpu资源,让tensorflow训练好的模型更快捷方便地投入到实际生产环境”。除了tensorflow以外的其他框架都缺少为生产环境部署的考虑,而google作为广泛在实际产品中应用深度学习的巨头可能也意识到了这个机会,因此开发了这个部署服务的平台。tensorflow serving可以说是一副王牌,将会帮tensorflow成为行业标准做出巨大贡献。
tensorflow serving架构
tensorboard是tensorflow的一组web应用,用来监控tensorflow运行过程,或可视化computation graph。tensorboard目前支持5种可视化:标量(scalars)、图片(images)、音频(audio)、直方图(histograms)和计算图(computation graph)。tensorboard的events dashboard可以用来持续地监控运行时的关键指标,比如loss、学习速率(learning rate)或是验证集上的准确率(accuracy);image dashboard则可以展示训练过程中用户设定保存的图片,比如某个训练中间结果用matplotlib等绘制(plot)出来的图片;graph explorer则可