Keras 之父讲解 Keras:几行代码就能在分布式环境训练模型 | Google I/O 2017

作为号称是 TensorFlow 最好用、对新手最友好的 API,一起来看看它的神通在哪里。

Francois Chollet:对许多使用场景而言,canned estimator 是相当不错的选择。但如果你要做的事并没有现成的 canned estimator,怎么办?如果需要写自己的定制模型呢?这时,就到了 Keras API 派上用场的时候。

什么是 Keras API?

简而言之,它就是一个用于创建 TensorFlow 模型的高级 API,你可以与它一起使用 estimator class 以及 experiment class。

众所周知,TensorFlow 的特点是非常低级的编程界面,你大多数时间花在矩阵、矢量乘法上。这使它成为一件非常强力的深度学习工具。但对于创建十分复杂先进的模型,这种操作方式说不上“理想”。

在谷歌,我们相信,未来深度学习将存在于每一个普通 IT 开发者的工具箱中,不再局限于机器学习专家。原因很简单:每个开发者都需要做出更智能的应用。

为了让这成为现实,我们需要降低深度学习的使用门槛,搞出每一个人都能用的工具,而不应该只有专家才能用深度学习解决问题。

我有一个问题想让大家思考:

如果设计一个没有任何束缚限制的深度学习界面,它应该是什么样的?

深度学习的核心理念很容易理解,它的实现也不应该复杂。对于模型核心部件,与其从头实现所有功能,应该让开发者利用现存部件,快速搭建数据处理流水线;就像乐高积木那样。这正是我们设计 Keras 的理念——成为“深度学习的乐高”。 

Keras 能做什么?

下面,我来讲讲 Keras 都能做什么。

首先,我不建议把 Keras 看做是 codebase、框架或库,它只是个高级 API。它有不同的实现,最主要的当然是 TensorFlow,但还有基于其它平台的——目前有 Theano、MXnet 和 Java;对更多框架的支持正在路上。

有一个特点,是 Keras 区别于其他所有深度学习操作界面的地方,让它鹤立鸡群——那就是用户体验。说白了,Keras 的精髓就是它对用户体验的执着,让开发者用着更舒服、简化工作流。尤其在于提供易于使用的组件、符合直觉的推理、更好的报错方面。因而,Keras 降低了操作难度,降低使用者的认知负担。

当然,让深度学习变得更简单,同时意味着更多的人能上手。Keras 的终极目标,是让尽可能更多人接触、使用深度学习。

直到现在,Keras API 的 TensorFlow 实现,是以外部开源资源库的形式存在的。但现在,我们把 Keras API 直接整合入 TensorFlow 项目中,这样能与你的已有工作流无缝结合。至此,Keras 成为了 TensorFlow 内部的一个新模块:tf.keras,它包含完整的 Keras API。

“对于 TensorFlow 用户,这意味着你获得了一整套易于使用的深度学习组件,并能与你的工作流无缝整合。

对于 Keras 用户,这意味着一系列高级 TensorFlow 训练功能,比如分布式训练、分布式超参数优化。”

下面,我们一起来看看你的工作流会是什么样子。我会向大家展示一个简单但挺先进的例子。该例子中,我用 Keras API 定义模型,用 TensorFlow estimator 和 experiments 在分布式环境训练模型。

示例: 视频内容问答

这是一个视频问答问题。我们有一组 10 秒短视频组成的数据集,视频内容是人从事各种活动。一个深度学习模型将会观察这些视频的每一帧画面,进行理解,然后你可以用简短的自然语言问它视频内容。

 

本例子中,一个男人把纸板箱放进车的行李箱里。任务是回答这个人在做什么。模型会处理该视频和问题,试图在可能的答案中挑选出正确的那一个。这次,它的回答是“装货”。这个答案很有意思:如果仅仅看一帧画面,是得不出该结论的——这个人也有可能在卸货。所以,我们不仅要求模型能理解视频画面的内容,还要能理解每一帧画面的先后顺序。

放到三四年前,Keras 和 TensorFlow 诞生之前,这会是一个无比棘手的难题,全世界只有个位数的研究机构能处理。即便是一只由世界级专家学者、工程师组成的团队,也需要半年左右的时间来一点一点解决。而现在,所有具备基础 Python 编程技能的人都能借助工具处理该问题。我们这也是在使深度学习民主化。

下图便是我们的神经网络方案。它的结构可分为三个部分:

首先,一个分支会导入视频输入,把它转化为对视频内容编码的矢量。另一个分支导入问题,也把它转化为矢量。现在,你可以把视频矢量和问题矢量连结起来,在它们之上添加一个分类器。该分类器的任务,是从一堆潜在回答中,选出正确的那一个。

第一步,是把视频输入矢量转化为张量。一个视频只是一组连续的画面帧,每一帧都是一个图像。对于图像处理,你要做的全部的事,就是运行一个 CNN。

每个 CNN,会从每帧画面提取一个矢量表示。最后所得到的,是对每帧画面进行编码的矢量序列。当遇到一个序列,你会做什么?当然是用序列处理模块—— LSTM 把它跑一遍。LSTM 会把序列简化为一个单一矢量,该矢量编码了视频的所有信息,包括每一帧画面、以及它们的顺序。

下一步,使用类似的过程来处理问句。它是一个由词语组成的序列,需要用内嵌模块把每个词语映射为一个词矢量。你就获得了一个词向量序列,再用另一个 LSTM 层来简化。

当视频、问题的矢量表示都有了以后,就可以把它们连接起来,在上面添加一个用于选择正确答案的分类器。

这就是深度学习的魔力:把复杂的输入,比如视频、图像、语言、声音变成矢量,变成几何空间中的不同的点——把了信息变成了几何空间中的点,这就是深度学习的本质。

而当完成之后,你就可以用线性代数来处理几何空间,捕捉到到有趣的映射模式。在上面的例子中,该模型就是在学习一个视频、问题空间到答案空间的映射。而执行的方式,是把不同的信息处理模块组合起来。这是一个十分自然的操作:对象是图像,就用图像处理模块 CNN;对象是序列,就用序列处理模块 LSTM;如果需要从一组候选中选择一个,就用分类器。

因而,创建深度学习模型,在概念上和拼乐高积木是很相似的,前者的实现也应该这么简单。这张图,就是对我们的模型在 Keras 上的直观结构。

我们用一个按时间分布的层,把 CNN 应用于由输入视频和张量组成的时间轴上的每一帧画面。然后把输入导入 LSTM 层,前者被简化为单一张量。InceptionV3 CNN 会内置预训练的权重,这一点很重要,因为以目前的视频输入,靠我们自己是无法学习到有趣的视觉特征的。我们需要利用现有的、在大型数据集上学习到的视觉特征。这个例子里是 ImageNet。在深度学习里,这是一个常见的举措,而 Keras 使它变得更方便。问题的编码更加简单。把词语序列导入内嵌层(embedding layer),生成矢量序列,再用 LSTM 层简化为单一矢量。

代码演示

下面是视频编码机器人的完整代码,加起来只有几行,非常简洁。你从确认视频输入开始,高亮部分就是你的视频输入:

这是一个由合理帧数组成的序列。“None”就是帧数,它没有被定义,你可以不同的 batch 进行修改。每一帧画面的分辨率是 150*150。下一步,仅用一行我们就定义了整个 InceptionV3 模型。它装满了从 ImageNet 得到的预训练权重。所有这些已经内置于 Keras 中,你不需要做任何多余操作,仅此一行代码足矣。代码并不包含顶层,因为并不相关,但在顶部加入了 pooling,使得我们能从每一帧抓取一个矢量。

下一步,CNN 被设置为不可训练,意味它的参数表示并不会在训练中更新。这一步很重要,因为该 CNN 已经有了非常不错的表示,没必要更改。再强调一遍,这是深度学习的常用操作,把封住不再改动的预训练模型添加入流水线。在 Keras 中,这项操作变得十分简便。有了不再变动的 CNN 之后,我们用一个时间分配层(time distributed layer),把它在视频输入的时间轴上均衡分配。这样做的结果,是得到所有帧的张量,再导入 LSTM 层得到单一矢量。

如上图,问题处理就更加简单。最终的问题输入,被处理为整数序列。为什么是整数呢?每一个整数,都会用某些词汇映射到一个矢量。随后把整数序列导入嵌入层,这会把每个整数映射到一个矢量上。这些训练过的嵌入是模型的一部分。再把矢量序列导入 LSTM,简化为单一矢量。

这里有一个有意思的地方。通常使用 LSTM 的时候,有许多东西需要考虑、许多套路需要参考。但在这里,除了设置输入单位的数量,我们并没有做任何其他操作配置 LSTM 层——所有“最佳套路”,都已经成为 Keras 的默认设置。这是 Keras 的一大特点,已知的最佳方案被用于默认设置。对于开发者,这意味着模型直接就能用,不需要对所有参数都进行调参。

在完成对视频、问题的编码之后,你只需要用 concate up 把它们转化为单一矢量,然后在顶端加入两个密集层,它们会从备选词汇中选出一个作为答案。

下一步,使用输入和输出初始化 Keras 模型,本质上它是一个神经网络各层的图(a graph of layers)的容器。然后要确定训练设置,比如优化器、Adam 优化器和损失函数。到现在一切都很简单,我们已经定义了模型和训练设置。下面是在分布式环境训练模型,或许在 Cloud ML 上。

只用几行代码,你就可以用 TensorFlow Estimator 和 Experiment 类训练模型。所有需要你做的事,仅仅是写 experiment 函数,用内置的 get_estimator 方法在其中定义模型,并用模型来初始化 Estimator。有了 estimator 之后,再用它创建 Experiment,在其中你确认输入数据。

仅仅用几行非常直观、具有高度可读性的 Python 代码就可以实现,我们就定义了一个相当先进的模型、在分布式环境训练它,来解决视频问答难题。而这在几年前是完全难以想象的。

到这里,你应该已经看到,像 Keras 这样的 API 是如何推动 AI 民主化。这借助两个东西实现:

  • 其中一个,当然是 Keras API。为在 TensorFlow 中定义模型提供了易于使用、功能强大的工具。而且,每一层都有非常优秀的默认设置,让模型可以直接运行。
  • 另外一个,则是全新的高级 TensorFlow 训练 API:Estimator 和 Experiment。

把它们结合到一起,使得开发者们能够以相当小的时间、经历代价处理任何深度学习难题。

====================================分割线================================

本文作者:三川

本文转自雷锋网禁止二次转载,原文链接

时间: 2024-09-08 11:03:55

Keras 之父讲解 Keras:几行代码就能在分布式环境训练模型 | Google I/O 2017的相关文章

用“Keras”11行代码构建CNN

更多深度文章,请关注:https://yq.aliyun.com/cloud 卷积神经网络(CNN)是一种特殊的深层的神经网络模型,为什么说它是特殊的神经网络模型呢?一是它的神经元间的连接是非全连接的,另一点是因为同一层中某些神经元之间的连接的权重是共享的.它的这些特点成功的降低了网络模型的复杂度以及减少了权值的数量,这也使得它的网络结构更类似于生物神经网络.今天我们就来用keras来实现CNN,keras是基于Theano和TensorFlow的深度学习库. 我曾经演示过如何使用TensorF

不到 200 行代码,教你如何用 Keras 搭建生成对抗网络(GAN)

生成对抗网络(Generative Adversarial Networks,GAN)最早由 Ian Goodfellow 在 2014 年提出,是目前深度学习领域最具潜力的研究成果之一.它的核心思想是:同时训练两个相互协作.同时又相互竞争的深度神经网络(一个称为生成器 Generator,另一个称为判别器 Discriminator)来处理无监督学习的相关问题.在训练过程中,两个网络最终都要学习如何处理任务. 通常,我们会用下面这个例子来说明 GAN 的原理:将警察视为判别器,制造假币的犯罪分

【圣诞特辑】Keras+树莓派,130行代码找到圣诞老人

今天这篇文章是使用Keras在Raspberry Pi上运行深度神经网络的一个完整指南. 我把这个项目当做一个"不是圣诞老人"(Not Santa)检测器,教你如何实际地实现它(并且过程中乐趣无穷). 第一部分,我们说一下什么是"圣诞老人检测器"(可能你不熟悉热播美剧<硅谷>里的"不是热狗"识别App,现在已经有人把它实现了). 然后,我们将通过安装TensorFlow.Keras和其他一些条件来配置树莓派进行深度学习. 树莓派为深度

Keras之父:大多数深度学习论文都是垃圾,炒作AI危害很大

Keras之父.谷歌大脑人工智能和深度学习研究员François Chollet最新撰写了一本深度学习Python教程实战书籍<Python深度学习>,书中介绍了深度学习使用Python语言和强大Keras库,详实新颖. 近日,François Chollet接受了采访,就"深度学习到底是什么"."Python为何如此广受欢迎"."目前深度学习面临的主要挑战"等议题进行了回答.他认为,目前很多深度学习领域的论文都是无意义的,因为这些研

图片-关于学习《第一行代码》中发现的问题,不敢说是错误,应该是郭霖大神笔误。麻烦各位大神来教训晚辈。。。

问题描述 关于学习<第一行代码>中发现的问题,不敢说是错误,应该是郭霖大神笔误.麻烦各位大神来教训晚辈... _第一处问题:在fragment一章里关于动态加载fragment部分中,要添加的fragment类的代码如下 public class Fragment_3 extends Fragment { @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedIn

只需 130 行代码,用 GAN 生成二维样本的小例子

50行GAN代码的问题 Dev Nag 写的 50 行代码的 GAN,大概是网上流传最广的,关于GAN最简单的小例子.这是一份用一维均匀样本作为特征空间(latent space)样本,经过生成网络变换后,生成高斯分布样本的代码.结构非常清晰,却有一个奇怪的问题,就是判别器(Discriminator)的输入不是2维样本,而是把整个mini-batch整体作为一个维度是batch size(代码中batch size等于cardinality)那么大的样本.也就是说判别网络要判别的不是一个一维的

两千行代码的PHP学习笔记汇总_php技巧

本文汇总了PHP学习中常见的各类问题,约有两千多行代码,都是非常实用的技巧.分享给大家供大家参考.具体如下: //语法错误(syntax error)在语法分析阶段,源代码并未被执行,故不会有任何输出. /* [命名规则] */ 常量名 类常量建议全大写,单词间用下划线分隔 // MIN_WIDTH 变量名建议用下划线方式分隔 // $var_name 函数名建议用驼峰命名法 // varName 定界符建议全大写 // <<<DING, <<<'DING' 文件名建议

几行代码搞定一棵漂亮的树

程序名:JTree(树状控件)结合了XML的长处,使您只需几行代码就可以拥有像Windows的资源管理器一样的Treeview了. 之前,本人曾写过一个Treeview,但是,不够美观,这一版本,在外观上做了很大的改进,很漂亮.运行速度很快. 详细功能请见示例示例打包下载 JTree在onclick时,有两个值可以用: var myTree=new JTree("showTree","vogueType.xml");myTree.setPicPath("i

几行代码轻松搞定网页的简繁转换

简繁转换|网页 对网页进行简繁字体转换的方法一般有两种:一是使用<简繁通>这样的专业软件,另外一种是制作两套版本的网页.显然,这两种方法都较为麻烦,而且专业软件一般不能用于免费的空间.笔者在这里给大家提供一个非常简单的方法,只须在页面上添加几行代码就可以轻松搞定网页的简繁转换了.首先在http://www.knowsky.com/download/transform.js处下载用于简繁转换的js文件transform.js,复制到网站目录下,然后使用网页制作工具打开需要进行简繁转换的网页,