软件 2.0 | karpathy

关注▲AI解忧杂货店▲  和大家一起成

作者:Andrej Karpathy | 日期:2017年11月12日

 

 

我有时会看到人们把神经网络仅仅视为“你机器学习工具箱中的另一个工具”。它们有优缺点,有时在某些地方有效,有时你甚至可以用它们赢得 Kaggle 比赛。不幸的是,这种理解完全忽略了本质。神经网络不仅仅是另一个分类器,它们标志着我们开发软件方式的根本性转变。它们就是软件 2.0。

软件 1.0 的“经典堆栈”是我们都很熟悉的 — 它使用像 Python、C++ 等语言编写。它由程序员写给计算机的显式指令组成。通过编写每一行代码,程序员在程序空间中标识出具有某种期望行为的具体点。

相比之下,软件 2.0 是用更加抽象、人类难以直接使用的语言编写的,比如神经网络的权重。因为权重数量庞大(典型的网络可能有数百万个),所以没有人直接参与编写这些代码(我试过)。

相反,我们的方法是为一个理想的程序的行为指定一些目标(例如,“满足一个输入输出对的数据集”,或“赢得一场围棋比赛”),编写一个粗略的代码框架(即一个神经网络架构),以确定一个程序空间的子集进行搜索,并利用我们现有的计算资源在这个空间中寻找一个能够工作的程序。在神经网络的情况下,我们将搜索限制在一个程序空间的连续子集内,而在这个子集中,通过反向传播和随机梯度下降,搜索过程(令人惊讶的是)可以变得高效。

为了使这个类比更加明确,在 Software 1.0 中,人类编写的源代码(例如一些.cpp 文件)被编译成二进制文件,从而执行有用的任务。在 Software 2.0 中,源代码通常包括 1)定义期望行为的数据集,以及 2)提供代码大致框架的神经网络架构,但其中许多细节(权重)需要填充。训练神经网络的过程就是将数据集编译成二进制——最终的神经网络。在当今大多数实际应用中,神经网络架构和训练系统正日益标准化为一种商品,因此大部分活跃的“软件开发”实际上表现为整理、扩展、调整和清理带标签的数据集。这从根本上改变了我们迭代软件的编程范式,因为团队被分成了两部分:2.0 程序员(数据标注人员)负责编辑和扩展数据集,而少数 1.0 程序员则维护和迭代周围的训练代码基础设施、分析、可视化和标注界面。

事实证明,现实世界中的许多问题具有这样一个特性:收集数据(或更一般地说,识别出期望的行为)要显著比显式编写程序更容易。由于这一点以及我将在下面进一步阐述的 Software 2.0 程序的许多其他优势,我们正在见证整个行业中一场大规模的转型,大量 1.0 代码正在被移植到 2.0 代码中。软件(1.0)正在吞噬世界,而现在 AI(Software 2.0)正在吞噬软件。

Ongoing transition  持续转型

让我们简要考察一下这场持续转型的一些具体实例。在这些领域中,我们已经看到近年来的进步,当我们放弃试图通过编写显式代码来解决复杂问题,而是将代码迁移到 2.0 架构上时,效果尤为明显。

视觉识别过去主要依赖人工设计的特征,再加上一些机器学习方法(例如 SVM)。此后,我们通过获取大量数据集(例如 ImageNet)并在卷积神经网络架构空间中进行搜索,发现了更强大的视觉特征。最近,我们甚至不再信任自己手动编写架构,也开始对这些架构进行搜索。

语音识别过去需要大量的预处理、高斯混合模型和隐马尔可夫模型,但如今几乎完全依赖神经网络技术。有一句非常相关且常被引用的幽默引言,据说是 Fred Jelinek 在 1985 年说的:“每次我解雇一名语言学家,我们的语音识别系统的性能就会上升”。

语音合成过去通常采用各种拼接机制,但如今最先进的模型是大型卷积网络(例如 WaveNet),它们直接生成原始音频信号输出。

机器翻译通常采用基于短语的统计方法,但神经网络正在迅速成为主流。我最喜欢的架构是在多语言环境下训练的,其中单个模型可以从任何源语言翻译到任何目标语言,并且在弱监督(或完全无监督)环境下也表现良好。

游戏。 长期以来,人们开发了显式的手动编码围棋程序,但 AlphaGo Zero(一种查看棋盘原始状态并进行落子的卷积网络)现在已成为该游戏最强的玩家。我预计在其他领域也会看到类似的结果,例如 DOTA 2 或星际争霸。

数据库。 在人工智能之外,更传统的系统也在看到转型的早期迹象。例如,“ The Case for Learned Index Structures” 用神经网络替代了数据管理系统的核心组件,在速度上比优化缓存的 B 树快高达 70%,同时节省了数量级的内存。

你会注意到我上面的许多链接都涉及谷歌的工作。这是因为谷歌目前正处于将自己大部分系统重写为 Software 2.0 代码的前沿。“One model to rule them all”提供了一个早期的草图,展示了这可能是什么样子,其中各个领域的统计力量被整合成一个对世界的一致理解。

软件 2.0 的优势

为什么我们应该更倾向于将复杂的程序移植到 Software 2.0?显然,一个简单的答案是它们在实际应用中表现更好。然而,还有许多其他方便的理由让我们更喜欢这个技术栈。让我们看看 Software 2.0(比如:一个卷积网络)相比 Software 1.0(比如:一个生产级的 C++代码库)的一些优势。Software 2.0 是:

计算上同构。 典型的神经网络在第一顺序上仅由两个操作组成:矩阵乘法和零阈值操作(ReLU)。相比之下,经典软件的指令集要显著更加异构和复杂。由于你只需要为少量核心计算原语(例如矩阵乘法)提供 Software 1.0 的实现,因此更容易做出各种正确性/性能的保证。

易于集成到硅芯片中。 作为推论,由于神经网络的指令集相对较小,因此实现这些网络更接近硅芯片,例如使用定制的 ASIC、神经形态芯片等会显著更容易。当低功耗智能广泛普及于我们周围时,世界将发生改变。例如,小型、低成本的芯片可以预装一个训练好的 ConvNet、一个语音识别器和一个 WaveNet 语音合成网络,全部集成在一个小型原型大脑中,可以连接到各种设备上。

运行时间恒定。 典型的神经网络前向传播的每次迭代所消耗的 FLOPS 数量完全相同。在一些庞大的 C++代码库中,你的代码可能有不同的执行路径,但基于这些路径的执行时间几乎没有变化。当然,你也可以使用动态计算图,但通常执行流程仍然受到显著限制。这样我们几乎可以保证不会陷入意外的无限循环。

内存使用恒定。 与上面提到的类似,整个过程中没有动态分配的内存,因此也很少出现需要交换到磁盘或者在代码中查找内存泄漏的情况。

高度可移植。 一系列矩阵乘法相比传统的二进制文件或脚本,在任意计算配置上运行要简单得多。

它非常灵活。 如果你有一段 C++代码,而有人希望你把它速度提升一倍(如果需要的话,可以牺牲一些性能),那么要根据新的规格调整系统将是非常困难的。然而,在 Software 2.0 中,我们可以把网络拿出来,去掉一半的通道,重新训练,结果——它运行速度正好是原来的两倍,效果略差一些。这简直就像是魔法。相反,如果你恰好获得了更多的数据或计算资源,你只需增加更多的通道并重新训练,就可以立刻让程序表现得更好。

模块可以融合成一个最优的整体。 我们的软件通常被分解成多个模块,这些模块通过公开的函数、API 或端点进行通信。然而,如果两个原本独立训练的 Software 2.0 模块相互作用,我们就可以轻松地对整个系统进行反向传播。想想看,如果你的网络浏览器能够自动重新设计 10 层之下的系统指令以提高网页加载效率,那会有多神奇。或者,如果你导入的计算机视觉库(例如 OpenCV)能够根据你的特定数据自动优化,那又会有多棒。在 Software 2.0 中,这就是默认的行为。

它比你写的更好。 最后,而且最重要的是,在目前至少涉及图像/视频和声音/语音等任何有价值的应用领域中,神经网络是一段比你或我能够写出的代码更优的程序。

Software 2.0 的局限性

2.0 栈也有一些自身的缺点。在优化结束时,我们得到了表现良好的大型网络,但很难理解它们是如何工作的。在许多应用领域,我们将面临一个选择:使用一个我们理解的 90%准确的模型,或者使用一个我们不理解但准确率高达 99%的模型。

2.0 栈可能会以非直观且尴尬的方式失败,或者更糟,它们可能会“静默失败”,例如通过在训练数据中静默地采纳偏见,而这些偏见在大多数情况下网络规模很容易达到数百万时,很难进行正确的分析和检查。

最后,我们仍在发现这个堆栈的一些奇特特性。例如,对抗样本和攻击的存在突显了这个堆栈的非直观性。

在 2.0 堆栈中编程

软件 1.0 是我们编写的代码。软件 2.0 是基于某种评估标准(如“正确分类这些训练数据”)进行优化所生成的代码。很可能在任何程序不明显但可以反复评估其性能的场景(例如——你是否正确分类了一些图像?你是否在围棋游戏中获胜?)中,都会发生这种转变,因为优化过程可以找到比人类编写更好的代码。

我们看待趋势的视角很重要。如果你将软件 2.0 视为一种新出现的编程范式,而不是仅仅将其视为机器学习技术中表现良好的分类器,那么这些趋势的推断会更加明显,也清楚地表明还有大量工作需要完成。

特别是,我们已经构建了大量的工具来帮助人类编写 1.0 代码,例如具有语法高亮、调试器、性能分析工具、跳转到定义、git 集成等功能的强大 IDE。在 2.0 堆栈中,编程是通过积累、处理和清理数据集来完成的。例如,当网络在某些困难或罕见情况下出错时,我们不是通过编写代码来修复这些预测,而是通过包含更多这些情况的标注示例。谁会开发第一个 Software 2.0 的 IDE,来帮助完成数据集的积累、可视化、清理、标注和获取的整个工作流?也许 IDE 会根据每个样本的损失情况上浮网络认为可能标注错误的图像,或者通过用预测结果来初始化标注来协助标注工作,或者根据网络预测的不确定性建议有用的示例进行标注。

同样,Github 是 Software 1.0 代码非常成功的托管平台。是否也有空间存在一个 Software 2.0 的 Github?在这种情况下,仓库是数据集,提交记录由对标签的添加和编辑组成。

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

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

https://karpathy.medium.com/software-2-0-a64152b37c35

如果觉得内容不错,欢迎你点一下「在看」,或是将文章分享给其他有需要的人^^

相关好文推荐:

心智的空间 | karpathy

“通用智能根本不存在”?Yann LeCun 与 Demis Hassabis 正面开撕

可验证性 | karpathy

动物 vs 幽灵 | karpathy

2025年 LLM 年度回顾 | karpathy

让 AI 真正拥有“长时记忆”的开端

0条留言

留言