这篇文章改编自我写的《Python深度学习》(Manning Publications 出版)一书第九章第三节的内容。
这是一篇关于深度学习的当前局限性及其未来的两部分系列文章的一部分。您可以在这里阅读第一部分:深度学习的局限性。
根据我们对深度网络工作原理、局限性以及当前研究现状的了解,我们能否预测中期内事情的发展方向?以下是一些纯粹的个人想法。请注意,我没有水晶球,所以我预见的很多事情可能不会成为现实。这完全是一篇推测性的文章。我分享这些预测并不是因为我希望它们在未来被证明是完全正确的,而是因为它们在现在很有趣且可操作。
在高层次上,我认为有希望的主要方向是
- 更接近通用计算机程序的模型,建立在比我们当前可微层丰富得多的原语之上——这就是我们如何实现*推理*和*抽象*,这是当前模型的根本弱点。
- 使上述成为可能的新的学习形式——允许模型摆脱仅仅是可微变换的限制。
- 需要较少人类工程师参与的模型——无休止地调整旋钮不应该是你的工作。
- 更大程度、系统地重用先前学习的特征和架构;基于可重用和模块化程序子例程的元学习系统。
此外,请注意,这些考虑因素并不特定于迄今为止一直是深度学习的主要内容的监督学习——相反,它们适用于任何形式的机器学习,包括无监督、自监督和强化学习。你的标签来自哪里或你的训练循环是什么样子根本不重要;这些不同的机器学习分支只是同一结构的不同方面。
让我们深入探讨一下。
模型作为程序
正如我们在上一篇文章中提到的,我们可以在机器学习领域期待的一个必要的转型发展是从执行纯粹的*模式识别*并且只能实现*局部泛化*的模型,转向能够进行*抽象*和*推理*的模型,这些模型可以实现*极端泛化*。目前能够进行基本推理的人工智能程序都是由人类程序员硬编码的:例如,依赖搜索算法、图形操作、形式逻辑的软件。例如,在 DeepMind 的 AlphaGo 中,大部分展示出来的“智能”都是由专家程序员设计和硬编码的(例如,蒙特卡洛树搜索);从数据中学习只发生在专门的子模块(价值网络和策略网络)中。但在未来,这样的人工智能系统很可能是完全学习的,无需人类参与。
实现这一目标的途径是什么?考虑一种众所周知的网络类型:RNN。重要的是,RNN 的局限性比前馈网络略少。这是因为 RNN 不仅仅是一个几何变换:它们是在 for
循环中*重复应用的几何变换*。时间 for
循环本身是由人类开发人员硬编码的:它是网络的内置假设。当然,RNN 在它们可以表示的内容方面仍然受到极大的限制,主要是因为它们执行的每一步仍然只是一个可微分的几何变换,并且它们在步骤之间传递信息的方式是通过连续几何空间(状态向量)中的点。现在,想象一下神经网络将以类似的方式“增强”编程原语,例如 for
循环——但不是一个具有硬编码几何内存的硬编码 for
循环,而是一大组编程原语,模型可以自由地操作以扩展其处理功能,例如 if
分支、while
语句、变量创建、用于长期存储的磁盘存储、排序运算符、高级数据结构,如列表、图形和哈希表等等。这样的网络可以表示的程序空间将比当前深度学习模型可以表示的程序空间大得多,并且其中一些程序可以实现卓越的泛化能力。
简而言之,我们将不再一方面是“硬编码的算法智能”(手工制作的软件),另一方面是“学习的几何智能”(深度学习)。我们将转而采用形式算法模块和几何模块的混合,前者提供*推理和抽象*能力,后者提供*非正式的直觉和模式识别*能力。整个系统将在很少或没有人为干预的情况下学习。
我认为可能即将蓬勃发展的人工智能相关子领域是*程序合成*,特别是神经程序合成。程序合成是通过使用搜索算法(可能是遗传搜索,如遗传编程)来探索可能的程序的巨大空间来自动生成简单程序。当找到与所需规范匹配的程序时,搜索停止,通常以一组输入-输出对的形式提供。正如您所看到的,它非常类似于机器学习:给定作为输入-输出对提供的“训练数据”,我们找到一个与输入到输出相匹配的“程序”,并且可以泛化到新的输入。不同之处在于,我们不是在硬编码程序(神经网络)中学习参数值,而是通过离散搜索过程生成*源代码*。
我绝对希望这个子领域在未来几年内看到新一轮的兴趣浪潮。特别是,我希望看到深度学习和程序合成之间的交叉子领域的出现,在这个子领域中,我们不会完全用通用语言生成程序,而是生成*增强*了丰富的算法原语集的神经网络(几何数据处理流),例如 for
循环等等。这应该比直接生成源代码更容易处理和更有用,并且它将极大地扩展可以用机器学习解决的问题的范围——我们可以根据适当的训练数据自动生成的程序空间。符号人工智能和几何人工智能的融合。当代的 RNN 可以被视为这种混合算法-几何模型的史前祖先。
图: *一个依赖于几何原语(模式识别、直觉)和算法原语(推理、搜索、记忆)的学习程序。*
超越反向传播和可微层
如果机器学习模型变得更像程序,那么它们将不再是可微的——当然,这些程序仍然会利用连续的几何层作为子程序,这些层将是可微的,但模型作为一个整体将不再是可微的。因此,使用反向传播来调整固定、硬编码网络中的权重值,不可能成为未来训练模型的首选方法——至少,它不可能是全部。我们需要找到有效地训练不可微系统的方法。目前的方法包括遗传算法、“进化策略”、某些强化学习方法和 ADMM(交替方向乘子法)。当然,梯度下降不会消失——梯度信息对于优化可微参数函数总是有用的。但我们的模型肯定会变得越来越雄心勃勃,而不仅仅是可微参数函数,因此它们的自动开发(“机器学习”中的“学习”)将需要更多的东西,而不仅仅是反向传播。
此外,反向传播是端到端的,这对于学习良好的链式转换来说是一件好事,但是效率相当低下,因为它没有充分利用深度网络的模块化。为了提高效率,有一个万能的秘诀:引入模块化和层次结构。因此,我们可以通过引入具有某种同步机制的解耦训练模块,并以分层方式组织,从而提高反向传播本身的效率。这种策略在一定程度上反映在 DeepMind 最近关于“合成梯度”的工作中。我希望在不久的将来会有更多沿着这些方向进行的工作。
可以想象,在未来,全局不可微(但具有可微部分)的模型将使用不利用梯度的有效搜索过程进行训练(生长),而可微部分将通过利用一些更高效的反向传播版本利用梯度来更快地训练。
自动化机器学习
在未来,模型架构将是学习的,而不是由工程师手工制作的。自动学习架构与使用更丰富的原语集和类似程序的机器学习模型齐头并进。
目前,深度学习工程师的大部分工作是用 Python 脚本来处理数据,然后冗长地调整深度网络的架构和超参数,以获得一个可行的模型——甚至,如果工程师有雄心壮志的话,还可以获得一个最先进的模型。不用说,这不是一个最佳设置。但人工智能也可以在这方面提供帮助。不幸的是,数据处理部分很难自动化,因为它通常需要领域知识以及对工程师想要实现的目标有清晰的高级理解。然而,超参数调整是一个简单的搜索过程,我们已经知道工程师在这种情况下想要实现的目标:它是由正在调整的网络的损失函数定义的。建立基本的“AutoML”系统来处理大部分模型旋钮调整已经是一种常见的做法。几年前,我甚至建立了自己的系统来赢得 Kaggle 比赛。
在最基本的层面上,这样的系统只是简单地调整堆栈中的层数、它们的顺序以及每一层中的单元或过滤器的数量。这通常是通过 Hyperopt 等库来完成的,我们在第 7 章中讨论过(注:《Python深度学习》)。但我们也可以更有雄心,尝试从头开始学习一个合适的架构,并尽可能减少约束。例如,这可以通过强化学习或遗传算法来实现。
另一个重要的 AutoML 方向是将模型架构与模型权重一起学习。因为每次我们尝试稍微不同的架构时都从头开始训练一个新模型的效率非常低下,所以一个真正强大的 AutoML 系统将设法在模型的特征通过训练数据上的反向传播进行调整的同时进化架构,从而消除所有计算冗余。在我写这些文字的时候,这种方法已经开始出现了。
当这种情况开始发生时,机器学习工程师的工作不会消失,而是工程师将在价值创造链中向上移动。他们将开始投入更多精力来设计真正反映业务目标的复杂损失函数,并深入了解他们的模型如何影响部署它们的数字生态系统(例如,消费模型预测并生成模型训练数据的用户)——目前只有最大的公司才能考虑这些问题。
终身学习和模块化子程序重用
如果模型变得更加复杂并构建在更丰富的算法原语之上,那么这种增加的复杂性将需要在任务之间进行更高的重用,而不是每次遇到新任务或新数据集时都从头训练一个新模型。事实上,许多数据集不包含足够的信息来从头开发一个新的复杂模型,因此有必要利用以前遇到的数据集中的信息。就像你不会每次打开一本新书都从头开始学习英语一样,那是不可能的。此外,由于当前任务和以前遇到的任务之间存在很大重叠,因此对每个新任务从头开始训练模型是非常低效的。
此外,近年来反复出现的一个显著观察结果是,训练一个“相同”的模型同时执行几个松散连接的任务会导致模型在“每项任务”上都“更好”。例如,训练一个相同的神经机器翻译模型来同时覆盖英语到德语翻译和法语到意大利语翻译,将产生一个在每对语言上都更好的模型。联合训练图像分类模型和图像分割模型,共享相同的卷积基础,会产生一个在两项任务上都更好的模型。等等。这是相当直观的:这些看似不相关的任务之间总是“有一些”信息重叠,因此联合模型比仅针对该特定任务训练的模型可以访问有关每个单独任务的更多信息。
我们目前在跨任务模型重用方面所做的是利用预训练的权重来执行常见功能的模型,例如视觉特征提取。您在第 5 章中看到了这一点。在未来,我希望这种方法的通用版本将变得司空见惯:我们不仅会利用以前学习的特征(子模型权重),还会利用模型架构和训练程序。随着模型变得越来越像程序,我们将开始重用“程序子例程”,就像在人类编程语言中找到的函数和类一样。
想想今天的软件开发过程:一旦工程师解决了特定问题(例如,Python 中的 HTTP 查询),他们就会将其打包成一个抽象且可重用的库。未来遇到类似问题的工程师可以简单地搜索现有库,下载一个并在他们自己的项目中使用。类似地,在未来,元学习系统将能够通过筛选全局的高级可重用块库来组装新程序。当系统发现自己在为几个不同的任务开发类似的程序子例程时,如果能够想出一个“抽象的”、可重用的子例程版本,并将其存储在全局库中。这样的过程将实现“抽象”能力,这是实现“极端泛化”的必要组成部分:在不同任务和领域中被发现有用的子例程可以说是“抽象”了问题解决的某些方面。这种“抽象”的定义类似于软件工程中的抽象概念。这些子例程可以是几何的(具有预训练表示的深度学习模块)或算法的(更接近于当代软件工程师操作的库)。
图: *能够使用可重用原语(算法和几何)快速开发特定于任务的模型,从而实现“极端泛化”的元学习器。*
总之:长期愿景
简而言之,以下是我对机器学习的长期愿景
- 模型将更像程序,并且将具有远远超出我们目前使用的输入数据的连续几何变换的能力。这些程序可以说更接近于人类对其周围环境和自身保持的抽象心智模型,并且由于其丰富的算法性质,它们将能够实现更强的泛化能力。
- 特别是,模型将融合提供形式推理、搜索和抽象能力的“算法模块”,以及提供非正式直觉和模式识别能力的“几何模块”。AlphaGo(一个需要大量手动软件工程和人为设计决策的系统)提供了一个早期示例,说明了符号和几何人工智能之间的这种融合是什么样的。
- 它们将是自动“生长”的,而不是由人类工程师手工制作的,使用存储在可重用子例程的全局库中的模块化部件——该库是通过在数千个以前的 任务和数据集。随着元学习系统识别出常见的解决问题的模式,它们将被转换成可重用的子例程——就像当代软件工程中的函数和类一样——并添加到全局库中。这实现了“抽象”的能力。
- 这个全球库和相关的模型生长系统将能够实现某种类似人类的“极端泛化”:给定一个新任务、一个新情况,该系统将能够使用非常少的数据组装一个适合该任务的新工作模型,这得益于 1) 泛化能力强的丰富类程序原语和 2) 处理类似任务的丰富经验。就像人类可以通过很少的游戏时间来学习玩复杂的新电子游戏一样,因为他们有许多以前游戏的经验,并且因为从这些先前经验中得出的模型是抽象的和类似程序的,而不是刺激和行动之间的基本映射。
- 因此,这种不断学习的模型生长系统可以被解释为 AGI——人工通用智能。但不要指望会出现任何奇点机器人末日:那纯粹是幻想,来自于对智力和技术的一系列深刻误解。然而,这种批评不属于这里。
@fchollet,2017 年 5 月