深度学习的局限性和未来

深度学习的局限性和未来

按:本文来自 Keras 作者 François Chollet,同时也是根据他撰写的《Deeping Learning with Python》一书第 9 章第 2 节改编的

作者注:这篇文章的受众是已经有深度学习经验的人(例如读过本书第 1 章至第 8 章的人)。 我们假设读者已经具有一定知识储备。

深度学习的几何学视角

深度学习最令人惊讶之处就在于它十分简单。十年前,没有人指望由梯度下降方法训练的简单参数模型就可以在机器感知问题上获得惊人的结果。现在,事实证明,你只需要一个有足够多参数的模型,并且在足够大的数据集上使用梯度下降进行训练。正如 Feynman 曾经描述宇宙那样,「它并不复杂,只是很多而已」。

在深度学习中,一切都是一个向量,即一切都是几何空间中的一个点。模型输入(可以是文本,图像等)和目标首先被「矢量化」,即变成一些初始输入矢量空间和目标矢量空间。深度学习模型中的每一层对通过它的数据进行简单的几何变换。同时,模型的层次链形成一个非常复杂的几何变换,分解成一系列简单的几何变换。这种复杂的转换尝试将输入空间一次一个点得映射到目标空间。这种转换是通过层的权重进行参数化的,权重根据模型当前执行的情况进行迭代更新。这种几何变换的一个关键特征是它必须是可微分的,这是为了使我们能够通过梯度下降学习它的参数。直观地说,这意味着从输入到输出的几何变形必须平滑且连续——这是一个重要的约束条件。

这种复杂的几何变换应用到输入数据的整个过程可以用三维的形式进行可视化,将其想象成一个人试图将揉成团的纸球恢复平整:皱巴巴的纸球是模型开始时的输入数据的复本。人对纸球的每个操作相当于一层简单几何转换的操作。完整的抚平(纸球)动作顺序是整个模型的复杂转换。深度学习模型是用于解开高维数据复杂流形的数学机器。

深度学习的神奇之处在于:将语义转化为矢量,转化为几何空间,然后逐渐学习将一个空间映射到另一个空间的复杂几何转换。你需要的只是足够高维数的空间,以便捕捉原始数据中全部的关系范围。

深度学习的局限性

用这个简单策略实现的应用程序空间几乎是无限的。然而,现有的深度学习技术对于更多的应用程序完全无能为力——即使提供了大量的人工注释数据。例如,你可以尝试收集成千上万甚至百万的关于软件产品特征的英文描述的数据集,由产品经理编写,以及由工程师团队开发的相应的源代码来满足这些要求。即使有了这些数据,你也无法训练深入的学习模式去简单地阅读产品说明并生成适当的代码库。这只是其中的一个例子。一般来说,无论你投入多少数据,深度学习模型都无法实现任何需要推理的东西,如编程或科学方法的应用——长期规划和类似算法的数据操作。即使使用深度神经网络学习排序算法也是非常困难的。

这是因为深度学习模型仅仅是将一个向量空间映射到另一个向量空间的简单连续几何变换链。它可以做的全部就是将一个数据流形 X 映射到另一个流形 Y,假设存在从 X到 Y 的可学习连续变换的话,并且可以使用密集的 X:Y 采样作为训练数据。因此,尽管深度学习模型可以被解释为一种程序,反过来说的话,大多数程序不能被表达为深度学习模型——对于大多数任务来说,要么没有相应的实际大小的深度神经网络来解决任务,或者存在这样的神经网络,但它可能无法学习,即相应的几何变换可能太复杂,或者可能没有合适的数据可用来学习它。

通过堆叠更多层并使用更多训练数据来扩展当前的深度学习技术,只能在表面上缓解一些问题。它不能解决深度学习模型在他们可以表示的内容种类非常有限的基本问题,并且大多数被期望可学习的程序不能被表示为数据流形的连续几何变形。

拟人化机器学习模型的风险

当代人工智能的一个非常现实的风险是人们误解了深度学习模型的作用,并高估了他们的能力。人类思维的一个基本特征是我们的「心智理论」,我们倾向于将意向,信仰和知识投射到我们身边的事物上。在我们的意识中,在岩石上画一个笑脸石头就突然变「快乐」了。应用于深度学习,这意味着当我们能够「基本成功」的训练模型以生成用于描述图片的标题时,我们就会相信该模型能够「理解」图片的内容以及「理解」它所生成的字幕。然后,当训练数据中出现的图像类别轻微偏离时,我们会非常惊讶地发现模型开始生成完全荒谬的标题。

深度学习的局限性和未来

尤其是「对抗性样本」值得强调,这些例子是一个深度学习网络的输入样本,旨在诱骗模型对它们进行错误分类。你已经意识到,可以在输入空间中进行梯度上升以生成最大化某个闭环过滤器激活的输入,这是我们在第 5 章中介绍的过滤器可视化技术的基础,以及第 8 章的 Deep Dream 算法。同样,通过梯度上升,人们可以稍微修改图像以最大化给定类的类别预测。通过拍摄一张熊猫的图片并添加一个「长臂猿」梯度,我们可以得到一个神经网络,将这只熊猫归类为长臂猿。这证明了这些模型的脆弱性,以及它们的输入——输出映射与我们人类自身认知之间的深刻差异。

深度学习的局限性和未来

总之,深度学习模型并不理解他们的输入,至少没有人类意识上的理解。我们人类对图像,声音和语言的理解是基于我们作为人类的感觉运动体验——正如地球上的生物所表现的一样。机器学习模型无法获得这些经验,因此无法以与人类一致的视角来「理解」他们的输入。 通过注释大量的训练样例来训练我们的模型,我们让他们学习在特定数据集上,将数据映射到人类概念的几何变换,但这个映射只是我们头脑中原始模型的简单概要,这是我们作为人类实体的体验得来的——它就像镜子里的一个模糊的形象。

深度学习的局限性和未来

作为一名机器学习实践者,请始终注意这一点,永远不要陷入这样一个陷阱,即相信神经网络理解他们所执行的任务——他们不会的,至少不会以对我们有意义的方式理解。不同于我们想教他们的任务,他们被训练来执行更为狭窄的任务:仅仅将训练集输入逐点映射到训练目标中。向他们展示任何偏离训练数据的东西,他们将给出最荒谬的结果。

局部泛化与极限泛化

深度学习模型中从输入到输出的直接几何变形,与人类思考和学习的方式之间几乎是完全不同的。这不仅仅是人类从自身的经验中学习而不是通过明确的训练实例来学习的问题。除了学习过程不同之外,基本表征的性质也存在根本差异。

人类能做的远远不只是像深度神经网络或昆虫那样把即时刺激映射成即时反应。人们维持着关于目前处境、关于他们自己和其他人的复杂抽象模型,并且可以使用这些模型来预测不同的可能发生的未来并执行长期规划。他们能够将已知的概念合并在一起,来表示他们以前从未经历过的事物,例如描绘穿着牛仔裤的马,或想象如果他们中了彩票就会做什么。这种处理假设的能力,扩展了我们的心智模型空间,使其远远超出我们可以直接体验到的事物空间,总而言之,进行抽象和推理,可以说是人类认知的决定性特征。我称之为「极限泛化」:这是一种在面对未经历的情况时,使用很少的数据甚至根本没有新的数据就能适应新情况的能力。

这与深度网络所做的形成鲜明对比,我称之为「局部泛化」:如果新输入与训练时看到的略有不同,则由深度网络执行的从输入到输出的映射立马失去意义。例如,来思考这样一问题,想要学习使火箭在月球上着陆的合适的发射参数。如果你要使用深层网络来完成这项任务,无论是使用监督学习还是增强学习进行训练,你都需要用数千乃至数百万次的发射试验进行训练,也就是说,你需要将模型置于密集的输入采样点空间,以便学习从输入空间到输出空间的可靠映射。

相比之下,人类可以利用他们的抽象能力来提出物理模型——火箭科学——并得出一个确切的解决方案,只需一次或几次试验即可获得月球上的火箭的发射参数。同样,如果你开发了一个控制人体的深度网络,要它能够在城市中安全地驾驶汽车并不被其他汽车撞,那么这个网络将不得不「死亡」数千次在各种场景中,直到它可以推断出汽车和危险并制定适当的回避措施。放到一个新的城市,网络将不得不重新学习已知的大部分知识。另一方面,人类就不必通过死亡来学习安全的行为,这要归功于他们对假设情境的抽象建模的能力。

深度学习的局限性和未来

局部泛化:模式识别级别的泛化能力; 极限泛化:由抽象和推理得到的泛化能力

总之,尽管我们在机器感知方面取得了进展,但我们离人类级别的 AI 还很远:我们的模型只能执行局部泛化,要适应一种新场景必须与原始数据联系的很紧密,而人类认知能够极限泛化,快速适应全新的情况,或为长期的未来情况做出规划。

引申

以下是您应该记住的内容:到目前为止,深度学习的唯一真正成功之处就是在给定大量人工注释数据的情况下,使用连续几何变换将空间 X 映射到空间 Y 的能力。做好这件事对于每个行业来说都是一件改变行业游戏规则的事儿,但它离人类级别的 AI 还有很长的路要走。

为了解除这些局限性并开始与人类大脑进行竞争,我们需要从简单的输入到输出映射转向推理和抽象。计算机程序可能是对各种情况和概念进行抽象建模的一个合适的基础。我们之前书中已经说过,机器学习模型可以被定义为「可学习程序」;目前我们能学习的程序属于所有可能程序中非常狭窄和特定子集。但是如果我们能够以模块化和可重用的方式学习任何程序呢?

鉴于我们所了解到的深度神经网络的工作机制、局限性以及当前的研究状况,我们是否可以预见到神经网络在中期之内将如何发展呢?这里分享一些我的个人想法。请注意我并没有能预测未来的水晶球,所以我所做的大部分预测可能都将失败。这完全就是一篇预测性的帖子,我之所以分享这些推测并不是希望它们在不久的未来会被证明是正确的,而是因为这些预测在当前看来非常有趣而且具有实践性的。

总的来说,我预见的几个主要方向是:

  • 与通用计算机程序更接近的模型,建立在比我们当前可微分层要丰富得多的基元之上——这也是我们如何令模型获得推理和抽象的策略,而这一点也是当前模型的根本弱点。
  • 使上述成为可能的新式学习策略——它可以使得模型摆脱当前的可微分变换。
  • 需要更少的人类工程师参与的模型——无休止地调参不应该成为你工作的一部分。
  • 对以前学习的特征和架构进行更大和更系统化的复用;基于可复用和模块化子程序的元学习系统(Meta-learning systems)。

此外值得注意的是,我的这些思考并不是针对已经成为监督式学习主力的深度学习。恰恰相反,这些思考适用于任何形式的机器学习,包括无监督学习、自我监督学习和强化学习。你的标签来自于哪里以及你的训练循环是什么样的,这些都不重要。这些机器学习的不同分支只是同一构造的不同方面。接下来让我们开始深入探讨。

模型即程序

正如我们在前一篇文章中所提到的,我们在机器学习领域可以预期的一个转变发展是,从纯粹模式识别并且只能实现局部泛化能力(Local generalization,见上篇)的模型,转向能够实现抽象和推理的模型,也就是可以达到终极的泛化能力。目前人工智能程序能够进行的基本推理形式,都是由人类程序员硬编码的:例如依靠搜索算法、图形处理和形式逻辑的软件。具体而言,比如在 DeepMind 的 AlphaGo 中,大部分的「智能」都是由专业程序员设计和硬编码的(如蒙特卡洛树搜索),从数据中学习只发生在专门的子模块(价值网络和策略网络)。但是在将来,这样的人工智能系统很可能会被完全学习,而不需要人工进行参与。

有什么办法可以做到这一点?让我们来考虑一个众所周知的网络类型:递归循环神经网络(RNN)。重要的一点是,递归循环神经网络比前馈网络的限制来的少。这是因为递归循环神经网络不仅仅是一种几何变换:它们是在 for 循环内重复应用的几何变换。时序 for 循环本身是由人类开发者硬编码的:它是网络的内置假设。自然地,递归神经网络在它们可以表征的内容上依然非常有限,主要是因为它们执行的每一步仍然只是一个可微分的几何变换,而它们从当前步到下一步传送信息的方式是通过连续几何空间(状态向量)中的点。

现在,设想一下神经网络将以类似的方式「编程」,比如 for 循环编程基元,但不仅仅是一个带有硬编码的几何内存硬编码 for 循环,而是一大组编程基元,然后模型可以自由操纵这些基元以扩展它们的处理功能,例如 if 分支、while 循环、变量创建、长期记忆的磁盘存储、排序操作和高级数据结构(如列表、图和散列表等)等等。这样的网络可以表征的程序空间将远远大于当前深度学习模型可以表征的空间,并且其中一些程序甚至可以取得优越的泛化能力。

总而言之,我们将远离「硬编码算法智能」(手工软件),以及「学习几何智能」(深度学习)。我们将拥有提供推理和抽象能力的形式化算法模块,以及提供非正式直觉和模式识别功能的几何模块。整个系统只需要很少的人工参与即可完成学习。

我认为人工智能相关的一个子领域可能即将迎来春天,那就是程序合成(Program synthesis),特别是神经程序合成(Neural program synthesis)。程序合成包括通过使用搜索算法(比如在遗传编程中可能是遗传搜索)来自动生成简单的程序,用以探索可能程序的巨大空间。当找到与需求(需求通常以一组输入-输出对进行提供)相匹配的程序时,搜索将停止。正如你所想的,它是否让你想起了机器学习:给出输入-输出对作为「训练数据」,我们找到一个将输入映射到输出的「程序」,并且能将它泛化到其它输入。不同之处在于,我们不是在硬编码程序(神经网络)中学习参数值,而是通过离散搜索过程生成源代码。

我一定会非常期待在接下来的几年内这个子领域会再次迎来第二个春天。特别是,我期待在深度学习和程序合成之间出现一个交叉子领域,在该领域我们不会采用通用语言生成程序,而是增强了一套丰富的算法原语的生成神经网络(几何数据处理流),例如 for 循环等等。这应该比直接生成源代码更加容易处理和有用,它将大大扩展机器学习可以解决的问题范围——我们可以根据适当的训练数据自动生成程序空间。符号 AI(Symbolic AI) 和几何 AI(Geometric AI)的融合,当代递归神经网络可以看做是这种混合算法几何模型的开山鼻祖。

深度学习的局限性和未来
依靠几何基元(模式识别与直觉)和算法基元(推理、搜索和存储)的学习程序

超越反向传播和可微分层

如果机器学习模型变得更像是一段程序,那么它们将变得不再可微——当然这些程序仍然会将连续的几何层作为子程序进行使用,这都是可微的,但是整个模型却不会。因此,在固定的硬编码网络中使用反向传播来调整权重值无法成为将来训练模型的首选办法——至少它无法像现在这样独占鳌头。我们需要找出能有效训练非微分系统的方法。目前的方法包括有遗传算法、进化策略、某些强化学习方法和交替方向乘子法(Alternating direction method of multipliers, ADMM)。自然而然的,梯度下降法哪儿也不会去——梯度信息对于优化可微分参数函数总是有用的。但是我们的模型肯定会比单纯的可微参数函数来的更加强大,因此它们的自主改善(「机器学习」中的「学习」)需要的将不仅仅是反向传播。

此外,反向传播是端到端的学习模式,这对于学习良好的链式转换是一件好事情,但在计算效率上却非常低效,因为它没有充分利用深度神经网络的模块化特性。为了提高效率,有一个通用的策略:引入模块化以及层次结构。所以我们可以通过引入分离的训练模块以及它们之间的一些同步机制,以分层的方式组织起来,从而使得反向传播计算更加高效。DeepMind 近期的工作「合成梯度」在某种程度上反映出了这一策略。我预期不久的将来在这一块将有更多的工作开展。

我们可以预见的一个未来就是,这些模型将变得全局不可微分(但将具有局部可微分性),然后通过有效的搜索过程而不是梯度策略进行训练。另一方面,通过利用一些更高效版本的反向传播以发挥梯度下降策略的最大优点,局部可微分区域将得到更快的训练速度。

自动化机器学习

在将来,模型架构将能够通过学习实现,而不是需要由工程师手工设置。并且自动化学习架构与使用更丰富的基元和程序式机器模型(Program-like machine learning models)将结合在一起。

目前深度学习工程师大部分工作都是使用 Python 脚本来处理数据,然后花费很多的时间来调整深度网络的架构和超参数以获得一个还过得去的模型——或者说甚至获得一个性能最先进的模型,如果这个工程师是够雄心勃勃的话。毋庸置疑,这样的做法并非最佳的,但是此时深度学习技术依然可以发挥一定的效用。不过不幸的是,数据处理部分却很难实现自动化,因为它通常需要领域知识以及对工程师想要的效果有非常清晰的高层次理解。然而,超参数调整是一个非常简单的搜索过程,并且我们已经知道了工程师在这种情况下想要取得什么效果:它由正在被微调的网络的损失函数定义。设置基本的「AutoML」系统已经很常见了,它将负责大部分模型的调整。我甚至在几年前设置了自己的模型并赢得了 Kaggle 竞赛。

在最基本的层面上,这样的系统可以简单地调整栈中堆叠的层数、顺序以及每一层中的单元或者说滤波器的数量。这通常是通过类似于 Hyperopt 这样的库来完成的,我们在《Deep Learning with Python》的第 7 章中曾讨论过这点。但我们的志向可以更加远大,并尝试从零开始学习适当的架构,然后尽可能减少限制条件。这可以通过强化学习或者遗传算法来实现。

另一个重要的 AutoML 方向是与模型权重一起联合学习模型架构。由于从头开始训练一个全新的架构,并且还要在每次尝试中对架构进行微调是非常耗时和低效的,所以一个真正强大的 AutoML 系统可以在通过训练数据反向调整模型特征的同时设法改进体系结构,从而消除所有的计算冗余。当我正在撰写这些内容时,这些方法已经开始出现了。

当这种情况发生时,机器学习工程师的工作不会消失,恰恰相反,工程师将在价值创造链上走上高地。他们将开始投入更多精力来打造真正反映业务目标的复杂损失函数,并深入理解他们的模型如何影响他们所部署的数字生态系统(例如,负责消费模型预测结果以及产生模型训练数据的用户),而这些问题目前只有巨头公司才有暇顾及。

终生学习和模块化子程序复用

如果模型变得越来越复杂并且建立在更丰富的算法基元之上,那么这种增加的复杂度将需要在不同任务之间实现更好地复用性,而不是每当我们有了新任务或者新数据集之后还需要从头开始训练新模型。事实上,许多数据集都因为数据量不够大而不足以支持从头训练新的复杂模型,并且需要利用来自先前数据集中的信息。就像你不需要在每次打开一本新书时都重新学习一遍英语一样。此外,由于当前任务与以前遇到的任务之间可能存在大量的重叠,因此对每个新任务都从头开始训练模型的做法非常低效。

此外,近年来反复出现的一个显著的观测结果是,训练相同的模型以同时执行几个松散连接的任务,将产生一个对每个任务都更好的模型。例如,训练相同的神经机器翻译模型以覆盖从英语到德语、法语到意大利语的翻译,将得到一个比单独训练来得更好的模型。又比如与图像分割模型一起训练图像分类模型,共享相同的卷积核,从而产生一个在两项任务中都表现更好的模型,等等。这一点非常直观:这些看起来似乎不相关的任务之间总是存在着信息重叠,因此联合训练模型比起只在某一特定任务上训练的模型,可以获取与每项单独任务有关的大量信息。

我们目前沿着跨任务模型复用(Model reuse across tasks)的方向所做的工作就是,利用预训练权重模型来处理常见任务,例如视觉特征提取。你将在第 5 章看到这一点。在将来,我希望这种泛化能力能实现更佳的普适性:我们不仅会复用以前学过的特征(子模型的权重值),还会复用模型架构和训练过程。随着模型变得越来越像程序,我们将开始重用程序子程序(Program subroutines),比如人类编程语言中的函数和类。

想想今天软件开发的过程:一旦工程师解决了一个特定的问题(例如 Python 中的 HTTP 请求问题),他们会将其打包为一个抽象且可以重用的库。这样未来面临类似问题的工程师可以通过简单地搜索现有的库,然后下载并在项目中使用它来解决问题。相类似地,在未来元学习(Meta-learning)系统将可以通过筛选高级可重用块的全局库来组装全新的程序。

当系统发现自己为几个不同任务开发了类似的程序子程序时,如果能够具备「抽象」的能力,即子程序的可重用版本,然后就将其存储到全局库种。这样的过程将实现抽象的能力,这是实现「终极泛化」的必要组成部分:在不同任务和领域发现有用的子程序可以被认为「抽象」了一些问题解决方案的某些方面。这里「抽象」的定义与软件工程中的抽象概念相似。这些子程序可以是几何的(具有预训练表征的深度学习模块)也可以是算法的(更接近当代软件工程师使用的软件库)。

深度学习的局限性和未来

元学习器能够使用可复用基元(算法和几何)快速开发针对特定任务的模型,从而实现“极端泛化”。

相关推荐