当前位置: 首页 > 资讯

谷歌I/O走进TensorFlow开源模型世界:从图像识别到语义理解

机器之心       2017-05-23

你知道你可以使用 TensorFlow 来描述图像、理解文本和生成艺术作品吗?来这个演讲,你体验到 TensorFlow 在计算机视觉、自然语言处理和计算机艺术生成上的最新项目。我将分享每个领域内我最偏爱的项目、展示你可以在家尝试的实时演示以及分享你可以进一步学习的教育资源。这个演讲不需要特定的机器学习背景。


谷歌I/O走进TensorFlow开源模型世界:从图像识别到语义理解


在进入正题之前,Gordon先谈了谈他对可复现的研究(reproducible research)的看法。他说我们现在理所当然地认为我们可以使用深度学习做到很多事情。在2005年的时候,他用了6个月时间试图使用神经网络来做基本的图像分类——识别分辨细胞是否感染了疾病。虽然那时候已经有很多不错的软件库可用了,但他们仍然还是要手动编写许多神经网络代码。最后,六个月时间过去了,这些优秀工程师打造的网络才开始在二元分类任务上表现得足够好一点。


而今天,你再也不需要这么苦恼了。今天,一个优秀的Python开发者加一点TensorFlow背景知识,并且愿意使用开源的模型,那么仅需要几天时间就能实现远远超过之前 6 个月所能达到的效果。当然,这要归功于大学、公司、开发者等慷慨的分享,这也已经为我们的社会带来了很大的价值。


Gordon举了一个例子说明。他说过去8个月有三种新的医学图像应用都依赖于一种被称为Inception的深度学习神经网络模型,这些应用都实现了非常卓越的表现,有望在人类的生命健康方面提供方便实用的帮助。


既然深度学习这么有用?那么深度学习是怎么工作的呢?首先我们先来看看一个可以将图像分类为「猫」或「狗」的模型。通过这个模型,我们可以看到深度学习与Gordon在2005年的工作有什么不同。


Gordon解释说,在2005年时,为了开发图像分类器,他编写了Python代码来提取图像的特征。首先他需要构思这个图像分类器需要怎样的特征(比如:线、形状、颜色),甚至还可能需要OpenCV这样的库来做人脸检测。


而使用深度学习时,可以直接为模型输入原始像素,让模型自己去寻找分类所需的特征。“深度学习”之所以被称为“深度”,是因为它具有多个层,数据在这些层中进行处理,最后得到分类结果。


TensorFlow是由谷歌设计的一个深度学习框架,拥有很多优点,包括快速灵活可扩展的开源机器学习库、可用于研究和生产、可以运行在 CPU、GPU、TPU、安卓、iOS 和树莓派等硬件和系统上。


谷歌I/O走进TensorFlow开源模型世界:从图像识别到语义理解


Gordon将在这个演讲中为我们主要解读以下 4 个重要研究:


谷歌I/O走进TensorFlow开源模型世界:从图像识别到语义理解


此外,Gordon还提到了一些其它使用TensorFlow实现的研究成果:


谷歌I/O走进TensorFlow开源模型世界:从图像识别到语义理解


谷歌的这些研究中有一些仍然是当前最佳的,但他们仍然开源了相关的代码,任何人都可以免费尝试复现这些结果。那谷歌为什么还要开源呢?毕竟有的研究是非常具有商业价值的。Gordon 说:“一个重要的理由是可以激励别人继续推进你的想法。”同时,这也能帮助降低开发者的进入门槛,能让更多人参与进来。


要实现可复现的(reproducible)开源,你需要共享你的代码和数据集。代码方面,要做到可复现,你应该共享你所有的代码,包括训练、推理和验证的代码。数据集方面,你应该说明你所用的数据集,你对数据集的处理方式等等。最好能提供一个试用数据集(toy dataset),让人们可以轻松验证你的模型。


预训练的检查点(pretrained checkpoint)也很重要。pretrained checkpoint 是为了保存模型训练过程中一些列状态,这样其他研究者就可以完全复制之前的研究过程,从而避免被随机化(在深度学习中极为常见)等其他因素干扰。


Gordon还谈到了Docker。很多时候,你的开发环境需要大量的依赖包。通过共享一个Docker容器,你可以让其他人快速尝试你的想法。


开发深度学习模型,当然可以选择自己写代码。在TensorFlow中,你可以轻松编写代码,实现模型。这里给出了两个示例:


谷歌I/O走进TensorFlow开源模型世界:从图像识别到语义理解


这段代码使用Keras+TensorFlow的组合。Keras是用来构建神经网络的API,它具有简单高效的特性,允许初学者轻松地建立神经网络模型;同时,Keras也可以使用TensorFlow作为运行的后端,极大地加速了开发与训练的过程。


谷歌I/O走进TensorFlow开源模型世界:从图像识别到语义理解


首先我们使用Keras中的Sequential类初始化一个用于存放任意层网络的模型,我们可以简单地认为这个类创建了一个杯子,我们的任务就是用适当的内容将这个杯子填满。接着在代码中不断地调用add方法按照顺序添加我们需要的神经网络层 (layer)。我们可以看到短短的几行代码便可以创建一个MNIST神经网络分类器。你只需要专注于以下几个方面:将数据按照神经网络的输入(代码中为一行 model.add(Dense(512, activation=’relu’, input_shape=(784,)))格式处理好,选择适当的激活函数(不仅是relu,你也可以尝试tanh或是softmax来快速比较不同激活函数对神经网络结果的影响),是否添加Dropout层来减轻学习过程中的过拟合现象。


当模型构建好之后,我们便可以快速地使用compile方法来编译模型,其中的损失函数loss、优化方法optimizer均可以自由选择。最后,使用类似于sklearn机器学习工具包中的fit方法即可开始训练我们的模型。


谷歌I/O走进TensorFlow开源模型世界:从图像识别到语义理解


TensorFlow有一个非常出色可视化工具TensorBoard,可以协助你的开发。


谷歌I/O走进TensorFlow开源模型世界:从图像识别到语义理解


除了自己动手开发,你也可以利用别人写好的代码,这也是开源的好处,也是本演讲所关注的重点。


Inception


Gordon 首先介绍的模型是Inception。


谷歌I/O走进TensorFlow开源模型世界:从图像识别到语义理解


Inception 的结构


比如如果你想识别一张照片,你可以直接在谷歌的云平台上直接调用该模型的 API 来帮你完成。当然,你可以通过使用开源模型的方式来实现:


谷歌I/O走进TensorFlow开源模型世界:从图像识别到语义理解

上面的这一点代码就实现了前面幻灯片上的Inception模型,可以看到,代码量非常少。


谷歌I/O走进TensorFlow开源模型世界:从图像识别到语义理解


这是该模型在 Gordon 自己拍摄的一张照片上所得到的结果。效果不好,主要是因为这个模型所预训练的数据集来自于 ImageNet。ImageNet 中包含了大量的图像,但其中大部分都是猫、狗、花、艺术品等等,对上图照片的场景经验不足。


谷歌I/O走进TensorFlow开源模型世界:从图像识别到语义理解


而有了合适的数据集,Inception 能得到非常好的表现,甚至能够分辨出狗的品种。


谷歌I/O走进TensorFlow开源模型世界:从图像识别到语义理解


也许你对识别狗不感兴趣,但你也可以用深度学习做其它事情,比如迁移学习。迁移学习的概念很简单。举个例子,假如你已经训练好了一个可以识别狗的模型,但你想要识别上面照片中的城市。如果有迁移学习,你就不需要从头开始在新数据集上训练你的模型,你可以去掉你原来模型的最后一层,然后换上新的一层再训练。这样就能将原来需要数周的训练时间减省到了几十秒。


TensorFlow for Poets 展示这样实现图像模型的方式。希望在更多领域看到这样的例子。实际上,在github.com/tensorflow/models 中,有很多模型公开可用。


谷歌I/O走进TensorFlow开源模型世界:从图像识别到语义理解


接下来,Gordon 对大名鼎鼎的Deep Dream进行了介绍。


Deep Dream何以成为可能。Gordon解释说,一是因为数据和计算机计算能力的极大增长,而是因为人们设计出了更加有效的算法,三是这些算法能自动学习到合适的特征(feature)。


要提取出图像的特征,我们需要用到卷积。卷积就像是一个滤波器。比如下图,左边是一张曼哈顿的照片,中间是一个3×3的滤波器,右边是处理后的图像,只能大概看到一些建筑的边。


如果你查看Deep Dream的代码,你会看到很多,下面给出了其中一些关键的代码:首先我们从卷积神经网络中的某一层中选出一些列filter(不同的filter会包含是分不同的特征:如猫、狗、甚至是梵高的向日葵,这取决于你用什么内容来训练),接着利用这些filter定义好损失函数,不断地利用TensorFlow中自动求导的功能更新原先的图片。通过这几行代码,我们委托TensorFlow不断地找出原始图片中的一些区域(这些区域的特征恰好与某些filter匹配),接着TensorFlow利用filter的信息来修改原始的图片从而生成DeepDream的效果。


风格迁移即是将一张艺术画作的风格应用到一张照片的内容上,处理流程如下所示:


谷歌I/O走进TensorFlow开源模型世界:从图像识别到语义理解


而且值得注意的是,现在你已经可以实时地给视频执行风格迁移了!


语言


语言也是一个非常重要的领域。Gordon将为我们讲解SyntaxNet系列,其中最新的是Parsey Saurus,这也是目前最准确的文本处理器之一。同样,这也是开源的,可以通过TensorFlow使用。那么模型是怎么处理文本的呢?Gordon用例子进行了说明。


假设有一个句子“I love NYC.”你可以使用谷歌云的自然语言API来对这个句子进行处理,可以拖拽式地操作。


谷歌I/O走进TensorFlow开源模型世界:从图像识别到语义理解


当然,你也可以在TensorFlow中使用Docker安装环境,快速地尝试SyntaxNet。


还记得去年的Parsey McParseface,那是当时最先进的自然语言处理模型,而现在Parsey Saurus已经超越了它。这两者的区别在于Parsey McParseface是在词层面上工作的,而Parsey Saurus则是工作在字符的层面上。在字符层面上的学习允许模型更加精细的处理文字,例如可以学习到词素这样最小单位的语言信息或是更好地处理生僻的字词。


使用这些模型,你甚至可以像人一样分析没有实际意义语句的结构,比如:“The gostak distims the doshes.”这个句子是毫无意义的,但我们却能够理解这个句子的结构。比如说,我们能够轻松理解其中各个词的词性,比如我们知道distims是动词,而gostak和doshes则是名词。


在syntaxnet container中,使用Interactive Text Analyzer也能得到同样的结论。


你也可以询问distims这个动作的执行者是什么?


Parsey Saurus还能告诉你更多。


下面列出了对该句子的一些分析结果:


谷歌I/O走进TensorFlow开源模型世界:从图像识别到语义理解


也可以得到该句子的依存树:


谷歌I/O走进TensorFlow开源模型世界:从图像识别到语义理解


除此之外,你还可以下载在不同语言(40多种)上预训练过的模型。这正是开源的价值。


这个有很多非常好的用例。


如果有一个已有的系统,你可以更轻松地在这之上实现提升。

你可以将其用作一个新系统的基础。让你不需要再重头开始训练,就能获得已有的词性标注等功能。

然后,Gordon又简单介绍了Release++的概念。这个概念来自 Magenta 的博客,表示他们不仅共享了自己的代码,还提供了预训练的模型和Docker容器。也就是说,你可以直接使用他们的模型达到同样的效果。