颠覆式编程:软件2.0

本文由OneFlow社区翻译并编辑
译者按:在近四年前,特斯拉 AI 部门负责人 Andrej Karpathy 提出了“软件2.0”的概念,分析和推测了神经网络将如何深刻地改变开发生态。在软件2.0下,程序建模的工作不再由程序员显式指定,而是使用数据训练神经网络来完成。在人类难以提取规则又数据量足够的领域,如计算机视觉、语音识别、语音合成、自动驾驶等,软件2.0的开发方式正在逐渐占据统治地位。原作者近四年前的分析和推测,如今已经被越来越多的事实验证,我们有理由相信,原作者所预测的软件2.0的“令人兴奋的机会”和“光明的未来”,也正以出其不意的速度来到我们身边。
原文链接:https://karpathy.medium.com/software-2-0-a64152b37c35


我发现,有时候人们会把神经网络当作“不过是机器学习工具箱中的工具之一而已”。它有优点也有缺点,在某些领域有用,并且可以帮助你打赢 Kaggle 比赛。很不幸,这种观点完全是只见树木,不见森林。神经网络可不只是又一种分类器而已,它代表着一种根本转变的开始,这种转变与我们如何开发软件有关。它就是软件2.0。

我们对软件1.0已经比较熟悉 — 它们由计算机语言(如 Python、C++ 等)所开发。
由程序员显式指定计算机指令。随着编写一行行代码,程序员在整个程序空间中可以确定一个符合期待行为的点。

颠覆式编程:软件2.0_第1张图片

与之对比的,软件2.0由更抽象、人类更难理解的语言(比如说,神经网络中的权重)开发。没人可以直接参与这种代码的编写,因为它涉及到大量的权重(往往上百万数量级),并且(我试过)直接编写权重某种意义上是很困难的。

颠覆式编程:软件2.0_第2张图片

取而代之的是,我们为程序的行为指定目标(比如,“符合数据集中样本的输入输出对”,又或者“赢得围棋比赛”),并写好程序的骨架(比如神经网络的结构),这样就在整个程序空间中确定了一个可以用于搜索的子集,然后就可以使用我们所有的计算资源在这个空间中搜索可用的程序。

对于神经网络而言,我们将搜索限制在程序空间的一个连续的子集上,并且,使用反向传播和 SGD 方法进行搜索,,(出人意料地)这种搜索方式挺有效。

颠覆式编程:软件2.0_第3张图片

更具体地对比,软件1.0是将人工设计的源码(比如 .cpp 文件)编译为可以有效工作的二进制文件。而软件2.0的源码通常由两部分组成:1)定义了目标行为的数据集 2)给定代码大致结构,但是需要填充细节的神经网络结构。训练神经网络的过程,就是将数据集编译成二进制文件的过程 — 得到最终的神经网络。时至今日,大多数实际应用中,神经网络的结构及训练系统已经日益标准化为一种商品,所以,大部分活跃的“软件开发”工作某种形式上变成了组织、增加、调整和清理带标签的数据集。这从根本上改变了我们迭代软件的编程范式,将开发团队分成了两拨:软件2.0的程序员(数据标记员)负责编辑和扩大数据集,而另一小撮人,维护着与训练有关的基础设施以及分析、可视化和标注等接口。

事实证明,对于真实世界中的很多问题,采集数据(更泛化地说,确定期待的行为)比显式地写程序要容易得多。
由于以上以及以下我将要介绍的软件2.0的诸多好处,我们正在见证工业界大量代码从软件1.0迁移至软件2.0的重大转变。软件1.0吞噬着整个世界,软件2.0(AI)在吞噬软件1.0。

转变进行时

让我们来看看这场转变中的具体领域的例子。我们会发现,在过去几年,对于这些领域,我们放弃了尝试通过显式写代码的方式去解决复杂问题,取而代之的,是转向了软件2.0。

图像识别:图像识别之前常常是由特征工程组成的,只是在最后加入一点点机器学习(比如:SVM)。
之后,通过使用更大的数据集(比如 ImageNet)和在卷积神经网络结构空间中进行搜索,我们发现了更强大的视觉特征。最近,我们甚至不再相信自己手写的网络结构,而开始用类似的方法搜索(最优网络结构)。

语音识别:以前的语音识别工作,涉及到大量的预处理工作、高斯混合模型和隐式马尔科夫模型,但是现在,几乎只需要神经网络。还有一句与之非常相关的搞笑名言,是 1985 年 Fred Jelinek 所说:“每当我开除一个语言学家,我的语音识别系统的性能就会提高一点”。

语音合成:历史上,语音合成一直采用各种拼接技术,但是现在,SOTA(State Of The Art) 类型的大型卷积网络(比如 WaveNet)可以直接产生原始音频信号输出。

机器翻译:机器翻译的实现之前常常采用基于短语的统计方法,但是神经网络正迅速占领了统治地位。我最喜欢的网络结构就与多语言训练有关:一个模型就可以把任意源语言翻译成任意目标语言,并且是无监督学习的(或者只需要很弱的监督)。

游戏:很长一段时间里,人们通过手写围棋程序来进行游戏对战,但如今,AlphaGo Zero(一种观察棋盘原始状态并对战的卷积网络)成为了围棋领域最强玩家。我预测在其它领域,如 DOTA 2、星际争霸,也会有类似的结果。

数据库:更多的本处于 AI 领域之外的传统系统,也显露出向软件2.0转变的早期迹象。比如,“索引结构学习案例”里,使用神经网络替代了原有的数据管理核心组件,其速度最高比做了缓存优化的 B树快70%,同时还省了一个数量级的内存。

你可能注意到了上面很多链接的工作是 Google 做的。这是因为目前 Google 就是将大量自己的代码转变为软件2.0的排头兵。“一个万能的模型”所描绘的草图是:将原本散落在各个领域的基于统计的效果,融合成一个整体来理解世界。

软件2.0的好处

为什么我们更倾向于把复杂程序移植到软件2.0?显然,一个简单的答案是实践证明它的效果更好。然而,还有很多其它的理由值得我们选择软件2.0。让我们看看软件2.0(卷积神经网络为代表)与软件1.0(生产级别的C++代码库为代表)相比的好处,对于软件2.0:

同质化计算:一个典型的神经网络仅有两种操作组合而成:矩阵乘法和激活函数(ReLu)。传统软件里的指令与之相比,明显会更加复杂和异构。由于只要用软件1.0的方法实现非常少部分的核心代码(比如矩阵乘法),正确性/性能验证都会容易很多。

对芯片更友好: 因为神经网络所需要的指令集相对更小,作为推论,在芯片上实现它们将会更容易,比如,使用自定义 ASIC 芯片
、neuromorphic chips 等等。当低能耗的智能设备充斥在我们周围时,这个世界也将为此改变。比如,把预训练卷积网络、语音识别、WaveNet 语音合成网络装载到便宜又小巧的设备中,这样你可以用它连接其它东西。

常量级的运行时间:一个典型的神经网络的每次前向迭代,需要的计算量(FLOPs)是高度一致的。在你手写的复杂 C++ 代码中会出现的各种执行分支,在软件 2.0 中是不存在的。当然,你也许会有动态图的需求,但是执行流通常也是被严格限制了。即使在这种情况下,我们几乎也能保证,不会陷入未预料的无限循环之中。

常量级的内存消耗:和上面一点相关,因为没有动态分配内存的需要,所以几乎没有可能需要与硬盘进行 swap,代码中也没内存泄漏的可能。

高度可移植:同传统的二进制文件或脚本相比,一连串的矩阵乘法操作要更容易运行在各种计算机环境下。

敏捷开发:如果你在写 C++,并且有人希望你开发速度提高2倍(可以牺牲性能的前提下),那么为适配新要求而调整系统可不是一件小事。然而,在软件2.0中,我们只需要移除掉(计算图中)一半的路径,然后重新训练,就能得到精确度差一点点,但训练快两倍的结果。这很神奇。反过来说,只要你得到了更多的数据和算力,你可以马上通过扩大计算图和重训练的方法,得到更好的实际效果。

融合模块以求最优:普通软件通常被分解成多个模块,各个模块中间通过共有函数、API 或者端到端的方式通信。然而,对于软件2.0,如果一开始2个相交互的模块是独立训练的,我们之后也很容易在整个系统中进行反向传播。想想看,如果你的浏览器可以自动设计底层指令,从而提高加载页面的速度;或者说你导入的计算机视觉库(比如 OpenCV)可以根据你的特定数据,自动调整行为;这将多么美妙。在软件2.0中,这些都是基本操作。

比你更优秀:最后,也是最重要的一点,在很多垂直领域中,神经网络产生的代码要比你或者我写的代码好。就目前而言,起码在图像、视频、语音这些领域中是这样的。

软件2.0的缺点

软件2.0也有一些缺点。当优化完成后,我们可以得到实践中很有效的巨大网络,但是很难解释它为什么有效。在许多领域,我们可以选择比较好理解但是只有90%精度的模型;或者选择不理解,但是有99%精度的模型。

软件2.0会出现不直观的、尴尬的错误,甚至更糟糕的,还可能“默默出错”。比如,如果在训练时默默地采纳了具有偏差的数据,当数据数量大到百万级别时,再想分析和检查原因,就变得非常困难了。

最后,软件2.0的奇怪特性也在不断出现。比如,对抗样本和攻击样本的存在,使得软件2.0的不可解释性问题变得更加突出。

软件2.0编程

软件1.0的代码,是我们手写的代码。软件2.0的代码,是基于评估准则(比如“把训练数据正确分类”)优化得来的。对于那些原理不明显,但是可以反复评估表现的程序,都适用于这种转变,因为与人写的代码相比,优化方法找到的代码要好得多。

颠覆式编程:软件2.0_第4张图片

眼光很重要。当你意识到神经网络不仅仅是机器学习工具集中一种好用的分类器,而把软件2.0当作崭露头角的全新编程范式时,可以外推的事情就变得显而易见了,还有大量的工作可以去做。

具体而言,我们已经发明了大量辅助程序员做软件1.0开发的工具,比如强大的 IDE,它可以具备很多功能,像语法高亮、调试器、profiler、符号跳转、集成 git 等等。软件2.0中,编程工作变成了积累、调整、清理数据集。比如,当某些极端情况下,神经网络失效了,我们并不会去通过写代码来修复问题,而是导入更多这种情况下的数据就可以了。

谁将开发第一款软件2.0的 IDE?它应该可以在数据集相关的所有工作流中都发挥作用,包括积累数据、可视化、清洗数据、标记数据、生产数据。也许这种 IDE,会根据每个样本的 loss,把网络怀疑被错误标注的图像给拎出来,或者通过预测提示应该选用的标签的方式辅助标注数据,再或者依据网络预测的不确定性,推荐适合标注的样本。

类似的,Github 是软件1.0时代非常成功的网站。是否有可能出现软件2.0时代的 Github?软件2.0时代,仓库将是数据集,而 commit 是由增加和编辑数据标签组成的。

传统的包管理工具和部署手段,比如 pip、conda、docker 等帮助我们更轻松地部署和安装软件。在软件2.0时代,如何更有效地部署、分享、导入和运行软件呢?在神经网络中,与 conda 对等的东西又会是什么呢?

简而言之,在可以低成本反复评估、并且算法难以显式设计的领域,软件2.0都将日益流行起来。当我们考虑整个开发生态以及如何适配这种新的编程范式时,会发现很多令人兴奋的机会。长远来看,这种编程范式拥有光明的未来,因为越来越确认的是:当我们某天要开发通用人工智能时,一定是使用软件2.0。

作者信息

颠覆式编程:软件2.0_第5张图片

I am the Sr. Director of AI at Tesla, where I lead the team responsible for training neural networks for the Autopilot. This includes data labeling, neural network training, the science of making it work, and deployment in production running on our custom inference chip. A full build of Autopilot neural networks involves 48 networks that take 70,000 GPU hours to train over 10M+ images/videos. These networks are deployed in production on our customer fleet of 1M vehicles, where they output 1,000 distinct tensors (predictions) at each time step to help drive the car. Before Tesla I was a founding member and research scientist at OpenAI, where I worked on generative models and deep reinforcement learning. I received my PhD from Stanford, where my thesis focused on convolution/recurrent neural network architectures for processing images and text. While at Stanford I designed and was the primary instructor for the first deep learning class Stanford - CS 231n, “Convolutional Neural Networks for Visual Recognition”. The class became one of the largest at Stanford and has grown from 150 enrolled in 2015 to 750 students two years later, including 1M+ people who have followed my 2016 lecture videos online. I have a passion for neural networks/AI, automation, education, and increasing human/environmental prosperity.

你可能感兴趣的:(社区新闻,深度学习,机器学习)