Andrej Karpathy 提出 Software 2.0

我有时看到人们将神经网络称为「机器学习工具箱中的另一个工具」。它们有利有弊,,有时你可以用它们来赢得 Kaggle 比赛。 不幸的是,这种解释完全只见树木不见森林。 神经网络不仅仅是另一个分类器,它们代表了我们开发软件的方式发生根本性转变的开始。这就是「软件 2.0」!

Software 1.0 的「经典技术栈」是我们都熟悉的 —— 它是用 Python、C++ 等语言编写的。它由程序员编写的对计算机的显式指令组成。 通过编写每一行代码,程序员可以识别程序空间中具有某些理想行为的特定点。

image

相比之下,软件 2.0 是用更抽象、对人类不友好的语言编写的,例如神经网络的权重。 没有人参与编写这段代码,因为有很多权重(典型的网络可能有数百万),直接在权重中编码有点困难(我试过)。

image

相反,我们的方法是在理想程序的行为上指定一些目标(例如,「满足输入输出示例对的数据集」,或「赢得围棋比赛」),编写代码的粗略框架(即 一个神经网络架构),它识别要搜索的程序空间的一个子集,并使用我们可以支配的计算资源来搜索该空间以寻找有效的程序。 在神经网络的情况下,我们将搜索限制在程序空间的连续子集内,通过反向传播和随机梯度下降可以使搜索过程(有点令人惊讶)高效。

image

为了使类比更明确,在 Software 1.0 中,人工设计的源代码(例如一些 .cpp 文件)被编译成二进制文件,以执行有用的工作。 在 Software 2.0 中,源代码通常包括 1) 定义理想行为的数据集和 2) 给出代码粗略框架的神经网络架构,但有许多细节(权重)需要填充。 训练神经网络将数据集编译成二进制文件——最终的神经网络。 在当今大多数实际应用中,神经网络架构和训练系统越来越标准化为商品,因此大多数活跃的「软件开发」都采取管理、增长、处理和清理标记数据集的形式。 这从根本上改变了我们迭代软件的编程范式,因为团队分为两部分:2.0 程序员(数据标记者)编辑和增长数据集,而一些 1.0 程序员维护和迭代周围的训练代码基础设施, 分析、可视化和标签界面。

事实证明,现实世界中的大部分问题都具有这样的特性,即收集数据(或更一般地说,确定所需的行为)比显式编写程序要容易得多。 由于这一点以及我将在下面介绍的软件 2.0 程序的许多其他好处,我们正在见证整个行业的巨大转变,许多 1.0 代码正在移植到 2.0 代码中。 软件(1.0)正在吞噬世界,现在AI(软件2.0)正在吞噬软件。

正在进行的过渡

让我们简要地研究一下这种持续转变的一些具体例子。 在过去几年中,我们在每个领域都看到了改进,当时我们放弃了通过编写显式代码来解决复杂问题的尝试,而是将代码转换为 2.0 堆栈。

  • 视觉识别(Visual Recognition)过去由工程特征组成,最后在顶部撒上一些机器学习(例如 SVM)。 从那时起,我们通过获取大型数据集(例如 ImageNet)并在卷积神经网络架构的空间中进行搜索,发现了更强大的视觉特征。 最近,我们甚至不相信自己可以手动编写架构代码,我们也开始搜索这些架构。
  • 语音识别(Speech Recognition)过去涉及大量预处理、高斯混合模型和隐马尔可夫模型,但如今几乎完全由神经网络组成。 1985 年弗雷德·耶利内克 (Fred Jelinek) 引用的一句非常相关且经常被引用的幽默名言是:「每次我解雇一名语言学家,我们的语音识别系统的性能都会提高」。
  • 语音合成(Speech Synthesis)历来采用各种拼接机制,但如今最先进的模型是产生原始音频信号输出的大型 ConvNet(例如 WaveNet)。
  • 机器翻译通常是采用基于短语的统计技术的方法,但神经网络正在迅速成为主导。 我最喜欢的架构是在多语言环境中训练的,在这种环境中,单个模型可以将任何源语言翻译成任何目标语言,并且在弱监督(或完全无监督)的环境中进行训练。
  • 游戏(Game)。 明确手工编码的围棋下棋程序已经开发了很长时间,但 AlphaGo Zero(一个查看棋盘原始状态并下棋的 ConvNet)现在已成为迄今为止最强的棋手。 我希望我们会在其他领域看到非常相似的结果,例如 DOTA 2,或星际争霸。
  • 数据库(Database)。 人工智能之外的更多传统系统也看到了过渡的早期迹象。 例如,“学习索引结构的案例”用神经网络取代了数据管理系统的核心组件,在速度上比缓存优化的 B 树高出 70%,同时节省了一个数量级的内存。

你会注意到我上面的许多链接都涉及在谷歌完成的工作。 这是因为谷歌目前处于将大量自身代码重写为 Software 2.0 代码的最前沿。 「统御一切的一个模型」提供了这可能是什么样子的早期草图,其中各个领域的统计强度合并为对世界的一致理解。

软件 2.0 的好处

为什么我们更愿意将复杂的程序移植到 Software 2.0 中? 显然,一个简单的答案是它们在实践中效果更好。 但是,还有很多其他方便的理由更喜欢这个堆栈。 让我们来看看 Software 2.0(想想:ConvNet)与 Software 1.0(想想:生产级 C++ 代码库)相比的一些好处。 软件 2.0 是:

  • 计算齐次(Computationally homogeneous)。 一个典型的神经网络,从一开始,就由两个操作的三明治组成:矩阵乘法和零阈值 (ReLU)。 将其与经典软件的指令集进行比较,后者明显更加异构和复杂。 因为您只需为少量核心计算原语(例如矩阵乘法)提供 Software 1.0 实现,所以更容易做出各种正确性/性能保证。
  • 容易烧纸到芯片上(Simple to bake into silicon)。 作为必然结果,由于神经网络的指令集相对较小,因此在更接近硅的情况下实现这些网络要容易得多,例如 使用定制 ASIC、神经形态芯片等。 当低能智能在我们周围无处不在时,世界将会改变。 例如,小型、廉价的芯片可以配备预训练的卷积神经网络(ConvNet)、语音识别器和 WaveNet 语音合成网络,所有这些都集成在一个可以附加到东西上的小型原脑中。
  • 恒定的运行时间。 典型神经网络前向传递的每次迭代都采用完全相同的 FLOPS 数量。 基于您的代码在某些庞大的 C++ 代码库中可能采用的不同执行路径,可变性为零。 当然,您可以拥有动态计算图,但执行流程通常仍然受到很大限制。 这样我们也几乎可以保证永远不会发现自己陷入意外的无限循环。
  • 持续使用内存。 与上述相关,任何地方都没有动态分配的内存,因此交换到磁盘的可能性也很小,或者您必须在代码中寻找内存泄漏。
  • 它非常便携。 与经典二进制文件或脚本相比,矩阵乘法序列在任意计算配置上运行起来要容易得多。
  • 它非常敏捷。 如果您有一个 C++ 代码,并且有人希望您将它的速度提高一倍(如果需要,以牺牲性能为代价),那么针对新规范调整系统将是非常重要的。 然而,在 Software 2.0 中,我们可以使用我们的网络,删除一半的通道,重新训练,然后——它以两倍的速度运行,但效果更差。 这是魔法。 相反,如果你碰巧获得了更多的数据/计算,你可以通过添加更多的通道和重新训练来立即让你的程序运行得更好。
  • 模块可以融合成一个最佳整体。 我们的软件通常被分解为通过公共功能、API 或端点进行通信的模块。 但是,如果两个原本单独训练的 Software 2.0 模块交互,我们可以很容易地反向传播整个模块。 想一想,如果您的 Web 浏览器可以自动重新设计 10 层的低级系统指令以实现更高的网页加载效率,那该有多神奇。 或者,如果您导入的计算机视觉库(例如 OpenCV)可以根据您的特定数据自动调整。 对于 2.0,这是默认行为。
  • 它比你好。 最后,也是最重要的是,神经网络是一段比你我在大部分有价值的垂直领域中能想出的任何代码都更好的代码,目前至少涉及与图像/视频和声音/语音有关的任何事情 .

软件 2.0 的局限性

软件 2.0 也有一些自身的缺点。 在优化结束时,我们得到了运行良好的大型网络,但很难说是如何工作的。 在许多应用领域,我们将面临使用我们理解的 90% 准确度模型或我们不理解的 99% 准确度模型的选择。

软件 2.0 可能会以不直观和令人尴尬的方式失败,或者更糟糕的是,它们可能会「悄无声息地失败」,例如,在他们的训练数据中默默地采用偏差,当它们的大小很容易达到数百万时,很难正确分析和检查这些偏差 大多数情况下。

最后,我们仍在发现这个堆栈的一些特殊属性。 例如,对抗性示例和攻击的存在突出了该堆栈的非直觉性。

在 2.0 堆栈中编程

软件 1.0 是我们编写的代码。 软件 2.0 是基于评估标准(例如“正确分类此训练数据”)的优化编写的代码。 程序不明显但可以反复评估其性能的任何设置(例如,您是否正确分类了一些图像?您赢得了围棋比赛吗?)将受到这种转变的影响,因为优化可以 找到比人类能写的更好的代码。

image

我们看待趋势的视角很重要。 如果您将 Software 2.0 视为一种新兴的编程范式,而不是简单地将神经网络视为机器学习技术类别中的一个相当不错的分类器,那么外推就会变得更加明显,并且很明显还有很多工作要做。

特别是,我们已经建立了大量的工具来帮助人们编写 1.0 代码,例如具有语法高亮、调试器、分析器、go to def、git 集成等功能的强大 IDE。在 2.0 堆栈中, 编程是通过积累、处理和清理数据集来完成的。 例如,当网络在某些困难或罕见的情况下失败时,我们不会通过编写代码来修复这些预测,而是通过包含这些情况的更多标记示例。 谁将开发第一个 Software 2.0 IDE,它有助于积累、可视化、清理、标记和采购数据集的所有工作流? 也许 IDE 根据每个示例的损失冒出网络怀疑被错误标记的图像,或者通过使用预测播种标签来协助标记,或者根据网络预测的不确定性建议有用的示例进行标记。

同样,Github 是一个非常成功的 Software 1.0 代码之家。 Software 2.0 Github 有空间吗? 在这种情况下,存储库是数据集,提交由标签的添加和编辑组成。

传统的包管理器和相关的服务基础设施,如 pip、conda、docker 等,帮助我们更轻松地部署和组合二进制文件。 我们如何有效地部署、共享、导入和使用 Software 2.0 二进制文件? 神经网络的 conda 等价物是什么?

短期内,软件 2.0 将在任何可以重复评估且成本低廉且算法本身难以明确设计的领域中变得越来越普遍。 有许多令人兴奋的机会来考虑整个软件开发生态系统以及它如何适应这种新的编程范式。 而且从长远来看,这种范式的未来是光明的,因为越来越清楚的是,当我们开发 AGI 时,它肯定会用 Software 2.0 编写。