一年一度的谷歌开发者大会 Google I/O 在山景城成功举行,在首日的
Keynote 中
,谷歌宣布了一系列新的硬件、应用、基础研究等。而作为 AI First 的开发者大会,Google I/O 也自然安排了许多有关机器学习开发的内容,比如《
教程 | 如何使用谷歌 Mobile Vision API 开发手机应用
》。当然毋庸置疑,TensorFlow 也是本届 I/O 大会的关键核心之一。当地时间 18 日下午,谷歌 TensorFlow 开发者支持 Josh Gordon 带来了一场主题为《开源 TensorFlow 模型(Open Source TensorFlow Models)》的 Session,介绍了一些最流行的 TensorFlow 模型,并鼓励了开源。机器之心在本文中对这一 Session 进行了整理介绍,其中部分内容也提供了机器之心文章的参考链接,希望能为你的扩展阅读提供帮助。
演讲主题:
你知道你可以使用 TensorFlow 来描述图像、理解文本和生成艺术作品吗?来这个演讲,你体验到 TensorFlow 在计算机视觉、自然语言处理和计算机艺术生成上的最新项目。我将分享每个领域内我最偏爱的项目、展示你可以在家尝试的实时演示以及分享你可以进一步学习的教育资源。这个演讲不需要特定的机器学习背景。
在进入正题之前,Gordon 先谈了谈他对可复现的研究(reproducible research)的看法。他说我们现在理所当然地认为我们可以使用深度学习做到很多事情。在 2005 年的时候,他用了 6 个月时间试图使用神经网络来做基本的图像分类——识别分辨细胞是否感染了疾病。虽然那时候已经有很多不错的软件库可用了,但他们仍然还是要手动编写许多神经网络代码。最后,六个月时间过去了,这些优秀工程师打造的网络才开始在二元分类任务上表现得足够好一点。
而今天,你再也不需要这么苦恼了。今天,一个优秀的 Python 开发者加一点 TensorFlow 背景知识,并且愿意使用开源的模型,那么仅需要几天时间就能实现远远超过之前 6 个月所能达到的效果。当然,这要归功于大学、公司、开发者等慷慨的分享,这也已经为我们的社会带来了很大的价值。
Gordon 举了一个例子说明。他说过去 8 个月有三种新的医学图像应用都依赖于一种被称为 Inception 的深度学习神经网络模型,这些应用都实现了非常卓越的表现,有望在人类的生命健康方面提供方便实用的帮助。机器之心对这三种应用都进行过深度报道,参阅:
既然深度学习这么有用?那么深度学习是怎么工作的呢?首先我们先来看看一个可以将图像分类为「猫」或「狗」的模型。通过这个模型,我们可以看到深度学习与 Gordon 在 2005 年的工作有什么不同。
Gordon 解释说,在 2005 年时,为了开发图像分类器,他编写了 Python 代码来提取图像的特征。首先他需要构思这个图像分类器需要怎样的特征(比如:线、形状、颜色),甚至还可能需要 OpenCV 这样的库来做人脸检测。
而使用深度学习时,可以直接为模型输入原始像素,让模型自己去寻找分类所需的特征。「深度学习」之所以被称为「深度」,是因为它具有多个层,数据在这些层中进行处理,最后得到分类结果,更多介绍可参阅《
入门 | 智能时代每个人都应该了解:什么是深度学习?
》
TensorFlow 是由谷歌设计的一个深度学习框架,拥有很多优点,包括快速灵活可扩展的开源机器学习库、可用于研究和生产、可以运行在 CPU、GPU、TPU、安卓、iOS 和树莓派等硬件和系统上。
Gordon 将在这个演讲中为我们主要解读以下 4 个重要研究:
当然,一直关注深度学习研究前沿的机器之心也已经对这些研究进行过完整报道:
此外,Gordon 还提到了一些其它使用 TensorFlow 实现的研究成果;
你想的没错,机器之心依然报道过这些研究:
谷歌的这些研究中有一些仍然是当前最佳的,但他们仍然开源了相关的代码,任何人都可以免费尝试复现这些结果。那谷歌为什么还要开源呢?毕竟有的研究是非常具有商业价值的。Gordon 说:「一个重要的理由是可以激励别人继续推进你的想法。」同时,这也能帮助降低开发者的进入门槛,能让更多人参与进来。
要实现可复现的(reproducible)开源,你需要共享你的代码和数据集。代码方面,要做到可复现,你应该共享你所有的代码,包括训练、推理和验证的代码。数据集方面,你应该说明你所用的数据集,你对数据集的处理方式等等。最好能提供一个试用数据集(toy dataset),让人们可以轻松验证你的模型。
预训练的检查点(pretrained checkpoint)也很重要。pretrained checkpoint 是为了保存模型训练过程中一些列状态,这样其他研究者就可以完全复制之前的研究过程,从而避免被随机化(在深度学习中极为常见)等其他因素干扰。
Gordon 还谈到了 Docker。很多时候,你的开发环境需要大量的依赖包。通过共享一个 Docker 容器,你可以让其他人快速尝试你的想法。
开发深度学习模型,当然可以选择自己写代码。在 TensorFlow 中,你可以轻松编写代码,实现模型。这里给出了两个示例:
这段代码使用 Keras + TensorFlow 的组合。Keras 是用来构建神经网络的 API,它具有简单高效的特性,允许初学者轻松地建立神经网络模型;同时,Keras 也可以使用 TensorFlow 作为运行的后端,极大地加速了开发与训练的过程。
首先我们使用 Keras 中的 Sequential 类初始化一个用于存放任意层网络的模型,我们可以简单地认为这个类创建了一个杯子,我们的任务就是用适当的内容将这个杯子填满。接着在代码中不断地调用 add 方法按照顺序添加我们需要的神经网络层 (layer)。我们可以看到短短的几行代码便可以创建一个 MNIST 神经网络分类器。你只需要专注于以下几个方面:将数据按照神经网络的输入(代码中为一行 model.add(Dense(512, activation='relu', input_shape=(784,)))格式处理好,选择适当的激活函数(不仅是 relu,你也可以尝试 tanh 或是 softmax 来快速比较不同激活函数对神经网络结果的影响),是否添加 Dropout 层来减轻学习过程中的过拟合现象。
当模型构建好之后,我们便可以快速地使用 compile 方法来编译模型,其中的损失函数 loss、优化方法 optimizer 均可以自由选择。最后,使用类似于 sklearn 机器学习工具包中的 fit 方法即可开始训练我们的模型。
TensorFlow 有一个非常出色可视化工具 TensorBoard,可以协助你的开发。
除了自己动手开发,你也可以利用别人写好的代码,这也是开源的好处,也是本演讲所关注的重点。
Inception
Gordon 首先介绍的模型是 Inception。
Inception 的结构
比如如果你想识别一张照片,你可以直接在谷歌的云平台上直接调用该模型的 API 来帮你完成。当然,你可以通过使用开源模型的方式来实现:
上面的这一点代码就实现了前面幻灯片上的 Inception 模型,可以看到,代码量非常少。
这是该模型在 Gordon 自己拍摄的一张照片上所得到的结果。效果不好,主要是因为这个模型所预训练的数据集来自于 ImageNet。ImageNet 中包含了大量的图像,但其中大部分都是猫、狗、花、艺术品等等,对上图照片的场景经验不足。
而有了合适的数据集,Inception 能得到非常好的表现,甚至能够分辨出狗的品种。
也许你对识别狗不感兴趣,但你也可以用深度学习做其它事情,比如迁移学习。迁移学习的概念很简单。举个例子,假如你已经训练好了一个可以识别狗的模型,但你想要识别上面照片中的城市。如果有迁移学习,你就不需要从头开始在新数据集上训练你的模型,你可以去掉你原来模型的最后一层,然后换上新的一层再训练。这样就能将原来需要数周的训练时间减省到了几十秒。
TensorFlow for Poets 展示这样实现图像模型的方式。希望在更多领域看到这样的例子。实际上,在 https://github.com/tensorflow/models 中,有很多模型公开可用。
你也可以设计你自己的实验:
接下来,Gordon 对大名鼎鼎的 Deep Dream 进行了介绍。参阅机器之心文章《
深度 | 揭秘谷歌 Deep Dream 的前世今生
》。
Deep Dream 何以成为可能。Gordon 解释说,一是因为数据和计算机计算能力的极大增长,而是因为人们设计出了更加有效的算法,三是这些算法能自动学习到合适的特征(feature)。
要提取出图像的特征,我们需要用到卷积。卷积就像是一个滤波器。比如下图,左边是一张曼哈顿的照片,中间是一个 3×3 的滤波器,右边是处理后的图像,只能大概看到一些建筑的边。
随着层数的增多,模型识别出的特征会越来越高级:
如果你查看 Deep Dream 的代码,你会看到很多,下面给出了其中一些关键的代码:首先我们从卷积神经网络中的某一层中选出一些列 filter(不同的 filter 会包含是分不同的特征:如猫、狗、甚至是梵高的向日葵,这取决于你用什么内容来训练),接着利用这些 filter 定义好损失函数,不断地利用 TensorFlow 中自动求导的功能更新原先的图片。
通过这几行代码,我们委托 TensorFlow 不断地找出原始图片中的一些区域(这些区域的特征恰好与某些 filter 匹配),接着 TensorFlow 利用 filter 的信息来修改原始的图片从而生成 DeepDream 的效果。
使用深度学习,你还能做风格迁移。对此 Gordon 并未做太多介绍,感兴趣的读者可参阅《
神经风格迁移研究概述:从当前研究到未来方向(附论文和代码)
》。在这里,Gordon 顺带提及了一下 Magenta,参阅《
深度 | 人工智能改变 MIDI 创作:谷歌 Magenta 项目是如何教神经网络编写音乐的?》