本文翻译来自Andrej Karpathy 软件2.0-关于深度学习架构

    我有时看到人们把神经网络称为“机器学习工具箱中的另一个工具”。他们有一些优点和缺点,他们在这里或那里工作,有时你可以用他们赢得卡格尔比赛。不幸的是,这一解释完全只见树木不见森林。神经网络不仅仅是另一个分类器,它代表了我们编写软件方式的根本转变的开始。它们是软件2.0。
    软件1的“经典栈”是我们所熟悉的——它是用Python、C++等语言编写的,它由程序员编写的计算机的明确指令组成。通过编写每一行代码,程序员用一些理想的行为识别程序空间中的一个特定点。

    1*CHcu2L0NmAZwCpQgmS1ByA.jpg

    相比之下,软件2.0可以用更抽象、更不友好的语言编写,比如神经网络的权重。没有人参与编写此代码,因为有很多权重(典型的网络可能有数百万个权重),直接用权重编码有点困难。

    1*6EB1Xue1wM_QP0IIzXphQA.png

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

    1*5NG3U8MsaTqmQpjkr_-UOw.png

    事实证明,现实世界中的大部分问题都具有这样一个特性,即收集数据(或者更普遍地说,识别一个理想的行为)比显式地编写程序要容易得多。在这些情况下,程序员将分成两个团队。2.0程序员手动地管理、维护、按摩、清理和标记数据集;每个标记的示例都逐字逐句地编程最终系统,因为数据集通过优化被编译成软件2.0代码。同时,1.0程序员维护周围的工具、分析、可视化、标记接口、基础设施和培训代码。

    正在进行的过渡
    让我们简单地检查一下这个正在进行的转换的一些具体例子。在这些领域中,我们都看到了过去几年的改进,我们放弃了通过编写显式代码来解决复杂问题,而是将代码转换到2.0堆栈中。

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

    你会注意到我上面的许多链接都是在谷歌完成的。这是因为谷歌目前正站在将大量内容重新写入软件2.0代码的最前沿。“一个模型来统治它们”提供了一个早期的草图,描述了这可能是什么样子的,其中各个领域的统计强度被合并成对世界的一致理解。

    软件2.0的好处
    **
    为什么我们更喜欢将复杂的程序移植到软件2.0中?显然,一个简单的答案是,它们在实践中表现得更好。然而,有很多其他方便的原因来选择这个堆栈。让我们来看看软件2(VC++:VANUNET)的一些好处,与软件1(想想:生产级C++代码库)相比。
    软件2.0是:

    • 计算上同质的。一个典型的神经网络在一阶上是由两个操作组成的:矩阵乘法和零阈值(ReLU)。与经典软件的指令集相比,它具有明显的异构性和复杂性。因为您只需要为少数核心计算原语(例如矩阵乘法)提供软件1.0实现,所以更容易做出各种正确性/性能保证。
    • 很容易烤成芯片。作为推论,由于神经网络的指令集相对较小,因此实现这些更接近硅的网络要容易得多,例如使用定制asic、神经形态芯片等。当低能智能在我们周围无处不在时,世界将发生变化。E、 例如,小而便宜的芯片可以配备一个预先训练好的ConvNet、一个语音识别器和一个WaveNet语音合成网络,所有这些都集成在一个小的原始大脑中,你可以把它们连接到东西上。
    • 持续运行时间。一个典型的神经网络前向过程的每次迭代都需要相同的失败次数。基于不同的执行路径,可以通过一些扩展的C++代码库来实现零变异性。当然,您可以使用动态计算图,但是执行流通常仍然受到很大的限制。这样,我们也几乎保证永远不会发现自己处于意外的无限循环中。
    • 持续使用内存。与上述相关的是,在任何地方都没有动态分配的内存,因此也几乎不可能切换到磁盘,或者在代码中查找内存泄漏。
    • 它携带方便。与经典二进制文件或脚本相比,矩阵乘法序列在任意计算配置上运行要容易得多。
    • 它非常敏捷。如果你有一个C++代码,有人希望你能使它快两倍(如果需要的话,如果性能需要),调整系统以适应新的规范是非常不重要的。然而,在软件2中,我们可以使用我们的网络,删除一半的信道,重新训练,然后在那里运行,速度快两倍,工作效率更差。这是魔法。相反,如果您碰巧获得了更多的数据/计算,您可以通过添加更多的通道和重新培训,立即使您的程序工作得更好。
    • 模块可以融合成一个最优的整体。我们的软件通常被分解成通过公共功能、api或端点进行通信的模块。然而,如果最初单独训练的两个软件2.0模块相互作用,我们可以很容易地在整个系统中进行反向传播。想想看,如果你的web浏览器能够自动重新设计低层的系统指令10层,从而在加载web页面时获得更高的效率,那将是多么令人惊奇。对于2.0,这是默认行为。
    • 比程序员强。最后,也是最重要的一点,神经网络是一个比你我在很多有价值的垂直领域所能想到的任何东西都好的代码,而这些垂直领域目前至少与图像/视频和声音/语音有关。

    软件2.0的局限性

    2.0堆栈也有其自身的一些缺点。

    • 在优化的最后,我们剩下的是运行良好的大型网络,但很难说是如何实现的。在许多应用领域中,我们可以选择使用我们理解的90%精确模型,或者使用我们不理解的99%精确模型。
    • 2.0堆栈可能会以不直观和令人尴尬的方式失败,或者更糟的是,它们可能会“无声地失败”,例如,在它们的训练数据中无声地采用偏差,这在大多数情况下很难正确地分析和检查它们的大小是否容易达到数百万。
    • 最后,我们仍然在发现这个堆栈的一些特殊属性。例如,对抗性例子和攻击的存在突出了这个堆栈的不直观性。

    在2.0堆栈中编程

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