本文为GoogleBrain工程师周越峰在QConShanghai2017和DevFest2017的演讲实录,由GDG整理发布。我叫周岳峰,谷歌大脑工程师,从事TensorFlow和TensorFlow分布式开发,利用机器学习优化TensorFlow研究项目。今天先给大家分享一个深度学习的例子,然后简单介绍一下什么是TensorFlow,以及TensorFlow的一些高级特性,包括一些即将发布甚至还没有完成的特性。如果我有时间,我会花一些时间。篇幅侧重于介绍新功能。在***时间,我将简单介绍一下GoogleBrain的两个研究项目。机器学习今天,我们看到机器学习改变了我们的世界。机器科学家使用深度学习方法来检测糖尿病和视网膜病变。其中,检测视网膜病变的准确率可达95%,甚至超过了眼科医生91%的准确率。速度。机器学习的准确率可与机器和人类专家相媲美。同时,机器学习也可以用于自动驾驶的方向,可以让交通更安全、更高效。其次,机器学习可以克服语言障碍,实现更便捷的沟通交流。我们知道,传统的机器翻译系统需要匹配不同的语言短语,通过一些复杂甚至手写的规则将一种语言转换成另一种语言。语言,这种系统非常庞大不利于维护,准确率不够高,所以最近出现了一种基于神经网络的方法,我们用TensorFlow实现了,用这种方法来缩小机器之间的差距和人工翻译,可以使翻译更加准确和自然。同样,机器学习也能给人类带来快乐。它可以自动修改照片,突出人物前景,虚化背景等功能。我们很快就会在手机上看到这个功能。接下来看看机器学习在行业中的应用。第一个例子是INSTACART,这是一种杂货当天送货服务。客户通过网络应用程序从许多本地零售商那里选择所需的产品并购买杂货。这个软件有很多客户。顾客在购买时面临一个问题,就是从数以百万计的零售店或产品中选择自己想要的商品,因此INSTACART建立了一套深度学习模型,用于最有效地对产品listing进行排序,这种方法为购物者节省了很多花在搜索产品上的时间。第二个例子是优步。UBER使用TensorFlow和基于TensorFlow的开源项目构建了一个名为“Michelangelo”的系统,这是一个内部机器学习平台。谷歌希望借助这个平台,让内部使用AI像他们要求像开车旅行一样方便。该系统涵盖数据管理、数据获取和模型训练、评估、部署等,该系统不仅支持TensorFlow深度学习,还支持其他机器学习模型。第三个例子是KEWPIE,它使用TensorFlow构建人工智能系统来提高婴儿食品的质量,并对食品进行人工智能分析,从而识别产品中可接受的成分并剔除产品中不可接受的成分。这保证了婴儿食品的质量。什么是TensorFlow实现以上所有功能的基本框架就是TensorFlow。我们在2015年底开源了TensorFlow,希望把它做成一个可以服务于所有人的机器学习平台。我们想让它成为一个快速、灵活、生产就绪的框架。可以很方便的做研究,也可以快速部署到生产环境。TensorFlow本质上是一个大规模的计算框架,它的操作被抽象成一个操作向量图。就像在这里看到一个操作图,上面的节点代表操作或者状态。当我们完成一些计算或结束一些状态时,我们的数据从一个节点流向另一个节点。该图可以用任何语言构建。图构建完成后,我们将其传递给TensorFlow核心进行编译、优化和执行。TensorFlow还支持很多硬件平台,从最初的CPU和GPU到即将到来的CLOUDCPU,以及对Android、iOS甚至嵌入式设备的支持。在我们将TensorFlow开源到Github之后,这两年围绕TensorFlow涌现出很多活跃的开源社区。现在我们有超过67,000个star,超过17,000个Github项目名称包括TensorFlow。TensorFlow不断出现在各种大学课程和在线课程中,许多大学也在开发基于TensorFlow的课程。此外,我们还发布了TensorFlow中文网。您可以将其用作TensorFlow入门的初级教程,名为https://tensorflow.google.cn。TensorFlow的新特性现在让我们看看TensorFlow最重要的特性。首先是EagerExecution,EagerExecution是一种新的编程模式,我在上一张幻灯片中展示了基于TensorFlow的静态图。EagerExecution解决了静态图中的一些问题。它解决了什么问题?首先,它可以节省很多代码,就像上图一样。其次,通过EagerExecution写代码可以第一时间发现错误,相比以前可以大大提高写代码和查错的效率。三是可以用Tensor写控制流,不用TF做循环,甚至做判断。最重要的一点是,如果图是用其他语言写的,那么把图传给TensorFlow核心就相当于写了另一段代码。看到这张幻灯片就是一个简单的例子,充分说明了EagerExecution的简单性。今年的谷歌I/O大会上公布了第二代TPU。我们的第二代TPU可用于推理和训练。TPU可以实现非常高的字典操作。我们甚至可以将多代TPU组合成一个像超级计算机一样的计算核心。借助二代TPU,我们可以在20小时内完整训练出RESNET-50模型。以前如果我们只做一个TPU训练,可能需要一周的时间来训练这个模型。今天,第二代TPU将发布到谷歌云,发布给大家使用。再说说TensorFlow上层API。除了神经网络训练速度,大家也很关注如何使用TensorFlow上层API更方便的创建神经网络。Keras是这些API之一,它支持许多后端。相信很多观众都用过Keras。本质上,Keras更像是一种API开发规范。TensorFlow有一个TF就是Keras,但它只是一种实现API规范的方式。它使用自定义TensorFlow后端。有了这个后端,我们可以将Keras与Estimators或Secving集成,这将为分布式提供更好的支持。TensorFlow中还引入了一个概念叫做Estimators,这是一个相对轻量级的API,在谷歌内部生产环境中被广泛使用。其中Estimators提供了很多模型供大家使用,称为CannedEstimators。他们的关系是这样的:Estimators和tf.keras的上层封装了一个CannedEstimator,可以用来封装各种模型。如果你习惯了Keras的接口,我们提供了一个上层的API转换工具,叫做model_to_estimator,当你有了一个编译好的Keras模型后,你可以调用这个model_to_estimator得到一个Estimator,从而将Keras转换成一个Estimator。Estimator还提供了分布式训练的接口。如果你使用TensorFlow进行分布式训练,你可能对我们的分布式模式很熟悉。我们的Estimator为分布式训练提供了良好的支持。只要你编写一个独立的代码,它就可以帮助你构建一个可以在不同机器上执行的程序。训练程序可以通过调用Estimator.train来完成,在这个执行过程中,只要调用它的Estimator.evaluate,整个集群就可以开始训练了。你可以看看这些API的文档:TF、KERAS、TFLAYERS等,我们也在官网发布了一个改进的程序员指南,希望你可以看看。下一个功能是TensorFlowLite,它是在移动设备上运行的TensorFlow的一个子集。移动设备现在无处不在,而且越来越重要。在移动设备上,我们可以判断野外狗的品种,或者判断植物是否有病害。利用人工智能,我们可以在移动设备上做一些应用,所以我们推出了TensorFlowLite。为什么我们经常在移动设备上使用它?做?除了刚才提到的应用场景,为什么要在移动设备上进行推理呢?这是因为我们经常需要在一些特殊的环境下做一系列的推理。很多时候,尤其是在野外,我们的网络带宽非常低。网络延迟非常高。如果每次推理都向远程服务器发送请求,则对移动设备的电池容量要求很高。尽管市场对移动设备完成推理的需求迫切,但也存在诸多挑战。最重要的挑战是移动设备的内存、计算资源和带宽是有限的。从编程的角度来看,由于平台受到高度抑制,开发变得越来越复杂。比如在Android上,我们可以用CPU或者指令来写底层代码,而在IOS上,我们有一些自己的平台和工具。不同平台的工具让??我们的硬件和API开发,甚至不同的API让我们的开发变得更加复杂,所以我们设计了TensorFlowLite。与TensorFlowLite相比,TensorFlow主要侧重于一些大型设备。TensorFlowLite使小型设备应用程序更加高效。现在让我们通过一个小例子看看TensorFlowLite是如何工作的。这就是TensorFlowLite的生命周期。首先,我们以标准方式运行TensorFlow。运行后得到Graphdef和Checkpoint。我们通过TensorFlowLite提供一个转换器,将其转换成TensorFlowLite的模型格式。使用TensorFlowLite格式的模型,我们可以将其传输到移动设备。连接到TensorFlowLite显示器允许将模型加载到移动设备上。如果我们的显示直接调度了NeonKerels,如果是在其他设备上,我们也可以使用硬件加速器接口,为自己的硬件定义一些优化。下一个特性是InputPipeline,初学者和专家都会感兴趣,因为InputPipeline使用起来非常痛苦。它主要有两种模式,一种是Feeding,优点是可以和python灵活处理零距离,但是性能较差。而单线程运行,每一步训练都要等待数据处理完成,对于GPU来说效率很低。还有一种方式效率更高,就是把数据处理变成一系列的操作。这使用队列作为数据存储的临时空间。我们把预处理后的数据和一些中间预处理后的数据放在Queues中,通过python来控制Queues的输入和控制。但是有个问题,这个python有一个weightinterpreterlock,所以让这个Queues的输入性能受到很大的限制。还有一个问题就是我们写的数据处理模块不能通用,训练的时候没办法改变输入的数据。所以我们开发了一套InputPipeline,由于种种原因,所以设计成一个惰性链表。因为我们很多数据看起来都差不多,而且数据量可以比较大,所以我们可以定义为LAZY。我们将其定义为惰性列表后,自然可以使用函数式编程语言中的map和filter来定义预处理流水线,我们可以看到很多语言的map和filter的操作。现在让我们来看看它的界面。我们还有第二个接口,叫做Iterator,可以方便的取出edements数据。就像很多通用编程语言中的迭代器一样,我们可以为这个迭代器配置不同的数据。这是PPT上的例子。你可以看看。LearnToLearn在神经网络解决问题的同时,神经网络也会给我们带来一些新的问题,即我们需要在设计神经网络架构时投入大量的专业知识和时间投入。例如,这是谷歌的图像分类之一。NET架构,这个神经网络架构从最初的卷积架构设计到现在的复杂架构。经过研究人员多年的实验,反复改进,才实现了如此复杂的模型。与其让研究人员守在电脑前,不如利用强大的计算资源,让机器自动找到好的神经网络架构?在谷歌,我们采用一种方法,就是利用RNN循环神经网络生成子网络。这个想法的来源是因为我们可以将一个神经网络映射成一个训练好的序列。RNN非常擅长解决这类问题,所以我们使用RNN生成一个子网络,我们用真实数据训练这个子网络。RNN的控制器根据训练的准确程度进行更新。在下一次迭代中,RNN将输出更高精度的子网络。这是一个RNN迁移架构的例子,看似复杂但其实并不难理解。我们也尝试使用相同的方法生成优化函数,然后将生成的优化函数与常用函数进行比较。从这张表我们可以看出生成的函数超过了现有函数的准确率,但是这些生成的函数非常不直观,所以我们开始想有没有更直观的方法来处理learn2learn的问题,于是我们想到了进化算法,或者说遗传算法。既然一个简单的单细胞生物可以进化成一个非常复杂的具有独立思考能力的多细胞生物,那么我们是不是可以把同样的理论应用到模型的构建上,所以我们设计了这样一个算法,在每一次开始的时候,我们建立一个包含1,000个训练有素的模型的种群,在每个进化步骤中从1,000个模型中随机选择两个模型,并比较它们的准确率。模型会留下来,模型会重现。他们复制的方式是创建模型的副本并简单地修改模型。看起来像是基因突变。我们将训练这个突变的副本并将其放入种群中。这是分布式训练的细节。有很多种模型变化。我们刚才说了一些结构上的变化,有的甚至会保持不变,但是我们会多训练它或者重新训练它,因为初始化变化很重要。选择变异来模拟均匀分布概率。一起来看看进化时间的最新进展吧。图中横轴代表时间,纵轴代表精度。其中的每个点代表种群中的一个模型,灰色的点就是被淘汰的模型。右上角的蓝点是存活模型,经过三天的训练后处于这个位置。经过三天的训练,可以获得比较高的准确率。经过十天的训练,可以看到准确率已经到了停止期,也就是我们找到了一个理想的模型。DevicePlacement让我们来看看另一个名为DevicePlacement的研究项目,它使用强化学习来做DevicePlacement。目前,机器学习使用大量模型和大量数据。这就需要我们有很多的设备。共同训练模型。例如,翻译后的模型非常大。我们通常使用128个GPU进行训练。下面简单介绍一下Deviceplacement。设备放置是将计算与设备相匹配。目前,我们正在使用一些人工方法甚至是简单的算法。我们的设置算法要求我们对设备和模型有充分的了解。该算法不是简单地从一个模型扩展到另一个模型。但是现在很时髦的做法是把基于这些规则的系统改造成基于机器学习的系统,所以我们也用了类似的方法。我们使用强化学习来解决这个Deviceplacement模型,我们受到learn2learn方法的启发,创建了一个类似的模型。我们有一个使用神经网络作为输入的网络,并告诉网络它有多少计算资源。该网络将告诉我们神经模型。让我们运行放置的神经模型并根据运行时间调整神经网络,我们使用类似的机器翻译架构。由于模型比较大且速度慢,我们使用数据并行进行训练。之后,让我们看看训练结果。这是设备放置在神经翻译系统中的结果。上面的白点代表运行在CPU上的节点,下面的彩色点代表运行在不同GPU上的节点。大约20%的改进,但仍然很难理解。这个阶段在输入端使用CPU,后面使用GPU。***两张图可以看出,在我们的神经翻译系统上,每个GPU的操作都非常平衡,而右边人类专家设计的操作非常不平衡,在GPU2上耗时非常长,在GPU2上耗时非常少其他GPU,不过这也是可以理解的,因为专家设计一般只考虑一部分。在InceptionV3中,我们的结果不是很平衡。但可能是因为InceptionV3中存在一些过度的依赖,我们的结果在InceptionV3中还是有整体运行时提升的。后来我们做了一些分析,发现是因为在数据copy的时候,我们花的时间比较少。所以总的来说,它有一个运行时改进。我们在TheEnd中谈到了两个例子。我们探索了如何使用算法或机器学习来优化机器学习模型,并取得了一些进展。我们相信在不久的将来,如果有更好的计算资源,未来所有的架构都将由计算机生成。谷歌已经给了你探索的第一步。我希望每个人都能参与其中。我会在这里停止,谢谢大家!
