摘要:在2017云栖大会深圳峰会开源专场上,阿里云容器服务技术专家车漾做了题为《在阿里云上构建机器学习应用》的精彩演讲,车漾首先从2016年深度学习最火的两个应用AlphaGo与Prisma谈起,从宏观层面分享了机器学习以及深度学习所做的事情,并就Prisma的发展故事谈起,为大家介绍了应该学会以工程思想思考和解决问题,并着重介绍了阿里云基于容器服务的机器学习解决方案架构设计以及如何借助阿里云快速搭建自己的机器学习应用,精彩不容错过。
以下内容根据嘉宾演讲视频以及PPT整理而成。
在2016年有两个深度学习应用使得深度学习这个概念走入了平常百姓家,大家开始意识到深度学习技术好像和我们的生活开始产生联系了。第一件事情就是AlphaGo战胜了围棋世界的高手李世石,它向我们证明了一件事情:计算机不但具有强大的运算能力,它甚至开始学会学习了,更可怕的是计算机的学习能力是一种纵向深入的学习能力,也就是随着计算机看到的数据越来越多,随着时间的不断往前发展,计算机有可能成为某个领域的专家,在围棋中是这样,在其他的领域,比如医学等领域也都会有同样的影响。可以说,AlphaGo是第一个使我们真正意识到机器学习具有一种自我演进能力的应用。
第二件事情就比较有意思了,Prisma这款应用是2016年度苹果APP Store的排到第一名的最佳手机应用,这款手机应用其实也是基于深度学习技术来实现的,它所做的事情就是像将自己家小区后院的照片传上去,然后指定一个绘画大师的作品,比如指定梵高的《星空》这个作品,将两者合成一张新的图片。
合成后的这个图片的特点就是内容还是楼下的小区,但是这张图片的风格看起来就是梵高画出来的了。那么如果使用机器学习的语言来解释一下这是如何做的就是实际上这个应用做了两件事情:第一件事情就是从这张梵高的画中学习出来一个函数f(),这个函数f()的价值是什么呢?其实就是反应了梵高这幅画作的风格,这就是机器学习所做的第一件事情,从这张画作学习到了一个能够反应梵高风格的函数。其实比如说产生整个图片的工作需要花费10个小时的话,上面说的这个产生f()函数的这件事情需要花费9个小时,甚至是9个小时55分钟。而最后将这个函数f()求出来之后,将楼下小区的照片这个X赋值到f()函数中,就产生了一个新的图片,其实剩下的仅有的5分钟就是用来做这件事情的。
讲到这里大家应该就能理解所谓机器学习是在做什么,应该怎样去转换这张图片。这时候可能大家会产生一个疑问,其实早在2010年就已经滤镜程序了,通过一个滤镜打上去其实也可以产生这样的效果,这个滤镜程序和深度学习的画像有什么区别呢?其实两者之间的区别就在于这个f(),这里面最大的区别就是f()是如何产生的,传统的滤镜技术是依靠一个程序员实现的,让他去理解这个画像的风格是什么样的,他自己去手敲代码去实现f()这个函数,而机器学习则是由机器自己从这个图片中提取信息并且计算出f()。这种区别产生的影响有两个:第一个就是程序员写一个梵高画的风格的程序可能需要花费两周的时间,如果再来一个毕加索就可能还需要两周的时间,也就是产生的成本比较高,这是第一个影响,第二个影响是什么呢?就是理解性问题,第一种使用滤镜的方式对于画的理解并不是梵高的理解,而是编写程序的程序员的理解,所以在这里面需要为大家解释清楚的就是机器学习和加滤镜的区别就是机器学习的本质,也就是这个规律是机器自己学习到的,并不需要人来教,人只需要给它数据集就可以了。
这个厉害的深度学习算法实际上并不是Prisma这个公司的创始人发明的,而是在2015年,也就是Prisma大火的前一年,三个德国的数据科学家发明了这个算法并且利用这个算法创办了自己的创业公司叫做DeepArt,它所能做的事情就是提供一个网站让用户将自己的图片上传上去并选择一个风格,经过3到5个小时的计算产生处一个有自己图片内容的大师风格的作品。这个网站上线之后效果还算不错,有一些人愿意花100多欧元去得到这样一幅作品,但是并没有大火。
而在2016年年初的时候,一个俄罗斯的软件工程师看到了这个论文并且也看到了DeepArt所做的产品,这个俄罗斯的工程师就认为他们做的产品存在问题。那么这个网站之所以没有火起来是为什么呢?俄罗斯工程师进行了思考,他发现原有产品中存在两个问题,第一个问题就是产生图片的时间太长了,5到6个小时,没有人愿意去等这么长的时间;第二个问题就是DeepArt只提供了一个网站,大家都知道网站无法得到高频的访问,我们需要有个电脑才能去进行登录再访问,所以使用起来的效果并不好。所以这个俄罗斯工程师就想开发一个手机APP,并使得手机APP能够达到的效果是将图片上传上去之后等待10到20秒就能够得到已经选好风格的图片,所以他就开始研究如何让图片转换的时间变短。其实就像刚才提到的,在这里机器学习主要做两件事情,第一件就是去求解代表风格的函数,第二件事情就是利用将值赋给这个函数去计算出最后的结果值,也就是说在做风格转换时的工作就是去解这个方程去求出绘画风格。如果能够像数据库一样将风格函数持久化地存储到硬盘上,每一次生成新图片的时候都将函数从硬盘上进行加载而免去了计算的过程,就可以将原来的6小时变成几分钟甚至更短的时间,实现后这个时间缩短达到了20秒。这个俄罗斯工程师实际上并不是机器学习方面的专家,但是他找到了问题的症结,并在此基础之上使用了一个月的时间开发出了这套Prisma的APP,这个APP在欧洲一上线在大概两周的时间内就有了三千万的下载量。如下图所示,梅德韦杰夫也是Prisma的忠实粉丝。当时在8月份的时候,在欧洲人普遍对于艺术有较高的鉴赏能力的情况下,他们都认为这个应用比较能够打动内心。
刚才讲述的这个故事实际上是想告诉大家一个道理,我们现在正处于AI即将到来的时代,但是AI时代并不只属于数据科学家、AI科学家以及这些程序员们。AI的技术是非常重要的一件事情,但比这件事情更重要的是如何利用AI技术转化出相应的产品,实现数据、技术和产品之间的联动,真正能够将AI技术应用到大家的日常生活中,像Prisma一样应用AI来为大家创造价值,讨得大家的欢心,这个才是最重要的,也是需要大家一起去思考的事情。也许你并不是AI的专家,但是也应该去思考如何才能将AI应用起来。实际上重要的是我们的想法,如果你有自己的想法,再利用一些开源的工具,加上阿里云的资源就可以很容易地构建属于自己的深度学习的应用。
我们所处的是一个开源的时代,很多深度学习和机器学习的学习库实际上都是开放的,包括谷歌的TensorFlow、微软的CNTK、Caffe、Mxnet等这些都是开源的机器学习库,如果大家想去学习这些开源库,其实有很多相关的资源可以参考。
在这里主要介绍一下TensorFlow,TensorFlow是2015年谷歌开源的一套机器学习库,其在深度学习方面非常好用,目前在GitHub上面大约有5万颗星,其实也是大家开始深度学习一个非常好的起点,它的最大特点是虽然不算性能最好,但是最为简单。
在这里想和大家说的是关于刚才提到的风格转换这件事情实际上有很多个实现,依赖于不同的机器学习库,包括TensorFlow、Mxnet、Torch以及Caffe等,在分享的最后也会给大家看一下一些使用这些库实现应用的代码。
有了这些机器学习库和机器学习的代码可以供大家进行学习,剩下的就是让大家了解一下如何构建自己的机器学习以及深度学习的应用。刚才提到了整个机器学习的流程从大的方面可以分为两个部分,一部分可以称之为求解方程,第二部分可以称为给方程赋值。所以在机器学习的流程中的第一部分就是训练,根据数据如何去训练出这个机器学习模型,实际上就是在求解这个方程。而第二步当这个方程解完之后,就可以给方程赋予新的值让它去做预测。具体来看,第一步在求解方程中最重要的也是机器学习最核心的事情就是数据和计算量,首先需要准备数据并且上传到云上,这是在云上进行机器学习的最重要的起点。第二步就是需要开发自己的训练程序,这个训练程序所做的事情就是根据数据来进行训练、求解方程,并对于程序的正确性进行确认。第三步,当我们具有大规模数据的时候,就可以执行一些训练,刚开始时可能做的是单机,但是在真正进行训练的时候,可能因为性能的需求、数据量的需求可能需要使用GPU以及分布式的训练,这个时候就是第三步执行训练任务,在执行完训练任务之后有一个很重要的工作就是导出这个训练模型,导出这个训练方程。在最后将这些应用到在线预测中,就是相当于对于方程进行赋值,这就是真正的工作流程。
然后向大家先介绍一下阿里云基于容器服务的机器学习解决方案架构。如下图所示的解决方案是以容器服务为核心的,在这里面所有服务是以容器作为载体的,容器服务贯穿整个机器学习的整个生命周期,包括开发、训练、预测以及数据处理,并且这个解决方案很好地集成了阿里云已有的机器学习能力,比如弹性计算、高性能计算以及弹性GPU计算、VPC网络以及共享存储、运维以及镜像等能力。使大家的深度学习应用能够无缝地和阿里云的服务进行集成,这就是这个方案所能够带来的好处。
那么这个事情具体是如何实现的呢?首先第一步是需要准备数据,因为我们知道像在阿里云上做深度学习的话,上传数据最简单的方式是通过OSS,这就可以通过OSS命令或者图形客户端的拖拽方式将数据上传上去。同时如果数据量非常巨大,那么OSS还提供了一套传输上G数据的解决方案,这样就可以支持大规模的运算。
第二步就是开始创建云端的实验开发环境,利用图形应用,在这里是使用阿里云的图形管理界面来创建Jupyter的一套开发测试环境。如果大家曾实现过深度学习的编程可能就会知道Jupyter是一套比较好的交互式的文本,可以在上面写自己的查询代码然后以交互的方式知道每一步执行的结果是什么样子。这里面同时还加入了TensorBoard,TensorBoard具有针对TensorFlow的一些支持,可以将整个学习的过程包括最后求解的方程所求的数值解与真实解之间的误差是多少以图形化的方式展示出来。可以通过这个观察整个误差的发展情况,以此来判断整个的学习过程是不是在正确的方向上。搭建完成环境后的第一个步骤就是构建应用。
当程序写完之后,下一步做的事情就是构建云端训练,也就是如何在云上面将真正的程序跑起来,因为这个程序可能是分布式,那么这里面支持的是什么呢?其实通过图形用户化的界面就可以去指定这里面使用到的是单机训练还是多机训练,以及这个程序所需要的依赖是什么。而这里面最重要的是方程的解,这可以通过阿里分布式存储解决方案帮助去将checkpoint和模型保存成为可持久化的数据,同时利用TensorBoard去监控整个训练的过程。
这里稍微提一下如何使用TensorFlow去保存模型。TensorFlow提供了两种保存模型的方式,第一种方式是Checkpoint,Checkpoint实际上是最常用的保存方式,其最常用的场景就是当进行训练的时候,有时总会因为一些莫名其妙的原因使得整个进程都崩掉了,这时候中间的结果就会丢失了,而Checkpoint的好处就是比如做一千步训练或者多少步训练的时候,就可以将数据保存到一个固定的Checkpoint里面,如果中间崩掉的时候就可以从Checkpoint点重新开始训练,这是Checkpoint的最主要的应用场景。当然由于TensorFlow在最早的时候就将Checkpoint提供出来,所以很多的TensorFlow用户也会使用Checkpoint来做Session,实际上其原理就是将原来训练的结果保存下来,在另外的地方加载下来之后重新再计算一遍f(),也就是在加载之后进行一次运算起到了预测的作用。
现在大家比较常用的一种方式是利用model进行预测,也就是TensorFlow提供了一套预测框架是基于GRTC的TensorFlow Serving,并且它是使用C++完成的,它所接受的数据类型是export类型,而不是Checkpoint类型,所以它有一套特殊的编程API可以把自己的这套model导出,并且由TensorFlow Serving直接进行加载,通过不同的Java客户端、Go客户端、Python客户端甚至Android和IOS客户端来访问它实现预测,它所做的也是TensorFlow相应的运算的方程求解的过程。
最后的一件事情是当一些Checkpoint运算成功结束之后,Checkpoint保留出来之后就可以进行在线运算和预测的过程。这里还是通过前端的UI指定预测类型以及预测应该用是应该怎样去部署的,可以选择使用GPU还是CPU,选择使用Hadoop TensorFlow的预测方式还是选择使用自定义的预测方式以及通过Checkpoint的预测方式,这些都是支持的。同时也支持运维期间需要的负载均衡和弹性伸缩的能力,这样可以看到将一个正常的图片放进去,选择不同的Checkpoint以及不同的风格类型的时候,能够产生不同的运算结果。
那么如何在阿里云的这套环境上面进行开发测试呢,首先进去前端控制台,描述应用的名字,然后从多个应用框架进行选择,是使用TensorFlow 1.0还是TensorFlow 0.12还是其他更多的框架。在这里面由于需要监控训练集,所以需要写上需要监控的日志目录是什么。当选择创建之后,就可以看到创建出来两个中心节点,一个是Jupyter的开发测试环境,输入密码之后就可以使用Jupyter执行并看到执行的结果以及训练的过程。当训练完成之后就可以通过TensorBoard看整个训练的结果是什么样子,是不是能够达到最终的目标值的Cost越来越小。在TensorBoard上可以看到训练的趋势是什么样子,其精确度是在向什么样的方向发展,还可以看到在TensorFlow里面进行运算时整个数据组织是什么样的结构。
当程序开发结束之后,开始进行训练。这时就需要指定训练输入的数据集,以及预处理的模型,这里的框架有多种选择,还可以指定预定义的框架,这里面还可以选择是不是支持GPU,然后还有指定数据需要写入到哪个数据件里面以及数据来源是什么,还需要指定总共训练的次数以及需要保存的地点是在什么位置,都是需要一些规约来定义这些事情的。
整个方案的最大特点就是速度会非常快,就是可以快速地在这套解决方案上搭建出来自己的机器学习小应用。这里面做的事情首先会从GitHub上将应用下载下来,然后这里面的规约就会自动安装自定义的Python依赖,之后就开始调用GPU资源并启动,开始构建网络,之后真正开始进行训练。当将Checkpoint指定到一个更好的位置的时候就会将云的产生数据存放到分布式存储上。当拥有这些数据之后就可以进行预测,预测的具体内容包括把之前计算过的东西保存下来,之后根据保存的数据和模型提供一个Read API,这里面并没有TensorFlow Serving这个标准框架而是自己实现了使用Python写的框架,并使用Checkpoint方式加载应用。并且如果需要使用负载均衡可以提供更多的实例的数量,并指定加载数据的模型数据卷以及阿里云的弹性的SLB负载均衡服务,就会很快地将服务提进来。当将服务提进来之后还是通过路由列表,通过阿里云提供的负载均衡访问端点进行访问。它所能提供的东西就是在这里上传一个图片,然后根据所指定的不同的风格进行转换就可以得到不同的风格图片,基本上就实现了与Prisma相似的功能。也就是说在现有的开源技术上,就可以在阿里云上构建自己的一个小应用,并且可以提供一站式运维的体验。甚至在阿里云上不仅可以转换图片的风格,现在还可以转化视频的风格。
总结
最后总结一下,大家可以看到阿里云基于容器的机器学习解决方案的最大特点就是相对而言比较简单,能够根据一些开源的东西以及一些已有的服务快速地构建一套机器学习应用,并且使应用与阿里云上的NAS,OSS,SLB以及简单日志服务等都可以做到无缝集成,只需要通过将他们加在一起就可以了,这是这套方案的第一个优势就是比较简单并且快速。
第二个好处就是优化,与容器服务团队进行合作的还有一个比较有名的就是阿里云的高性能计算团队,像对于阿里妈妈这些的优化都是他们团队做的,他们会提供一些特定场景性能优化的TensorFlow和Caffe的一些镜像,针对一些特定的场景进行性能优化,而不是百分百的优化。另外一件事情就是这套方案在持续集成和持续交付这件事情上是比较有经验的。其实可以将机器学习看做两部分,第一部分可以看做实验科学,需要不断地去尝试,找出最佳的组合来做推演;第二部分其实是交付的科学,如何将模型交付到机器上,如何进行A/B Test,而这件事情又是容器服务团队非常擅长的事情,既可以帮助优化性能,又能够帮助优化流程。
第三件事情就是定制化,阿里云希望能够通过为用户提供更大的灵活性,比如增加自己定义的镜像以及operator等来满足高级用户的需求,并平衡灵活性和自动化之间的关系。