Andrej Karpathy发文谈神经网络:这不仅仅是分类器,这是一种新的软件开发思想
雷锋网 (公众号:雷锋网) AI 科技评论按:有越来越多的传统编程语言(C、C++、Java)等程序员开始学习机器学习/深度学习,而对机器学习/深度学习的研究人员来说,编程也是必备技巧。那么传统程序员和深度学习专家对编程的软件的看法一样吗?计算机软件会在深度学习时代发生什么新的变化吗?
近日,计算机视觉领域大牛之一、李飞飞高徒、曾在OpenAI任研究科学家、现任特斯拉AI总监的 Andrej Karpathy 就发表了一篇博客,介绍了他眼中神经网络深度学习带来的“软件2.0”的全新开发思维。他相信这不仅是重要的软件开发变化趋势,正需要所有人都正视它、仔细思考它的优缺点。
雷锋网 AI 科技评论把Andrej Karpathy的这篇博客全文翻译如下。
软件2.0来了
有时候我会碰到这样的人,他们把神经网络看作“机器学习工具箱里的一个新工具”。深度学习有优点也有缺点,它们在挺多场景下都能发挥作用,有时候也能用深度学习在Kaggle的比赛中获胜。
然而不幸的是,这种观点其实是一叶障目不见泰山。神经网络并不仅仅是一类新的分类器,它们标志着人类编写软件的方式开始发生根本性的改变。这就是“软件2.0”(Software 2.0)。
“软件1.0”中经典的一层层结构大家都已经非常熟悉了,编写它们用的是Python、C++等等语言,包含的也就是程序员显式地写下的计算机命令。每写下一行代码,程序员就把程序空间中的某个具体的点定义为了一个需要的行为。
“软件2.0”则截然不同,它的呈现方式是神经网络的权重。人类程序员没法自己动手编写这类代码,因为它们是一大堆权重(典型的神经网络中可能有上百万个权重),直接把代码写成权重很困难(我试过)。实际上的做法是,人们对一个理想的程序的行为设定一些限制(比如通过带有成对的输入输出样本的数据集),然后用手头的计算资源在程序空间中搜索,找到一个能符合那些限制的程序。以神经网络为例,我们把搜索过程限定在程序空间的一个连续的子集当中,在这个子集里我们可以用反向传播和最速梯度下降的方法把搜索过程变得高效(有时候极为高效)。
事实上,真实世界中的很多问题都有这样一种特性,收集它们的数据要比明确地写下一行行程序容易得多。未来的程序员里相当大的一部分都不需要做维护复杂的代码库、编写复杂的程序以及分析程序运行时等等工作。他们要做的事情都会围绕着要喂给神经网络的数据:收集数据、清洗数据、操作数据、给数据加标签、分析数据、做数据可视化等等。
“软件2.0”并不会取代1.0(显而易见,训练和推理这样的软件2.0代码的“编译”过程需要很多1.0代码编写的基础架构支持),但是如今的软件1.0所完成的任务里将会有越来越高的比例被软件2.0替代。下面我们来看几个正在发生这种转换的例子来确认这个观点。
视觉识别
以前的做法是做特征工程,然后在最后面、最顶层用了一点点机器学习(比如SVM)。后来,我们(在卷积网络架构家族中)开发出了新的识别原理,找到了强大得多的图像分析程序;近期我们也已经开始探索更多的网络架构。
语音识别 以前需要很多的预处理、高斯混合模型以及隐马尔可夫模型,但今天几乎全都是由神经网络搞定的。
语音生成 历史上人们用过各种各样的音素拼接方式,而现在的顶级模型都是大规模卷积神经网络(比如WaveNet),它们可以直接生成原始的音频信号输出。
机器翻译
以往的通常做法是用一些基于短语的统计学技巧,但神经网络的方法很快就成为了主流。我自己最喜欢的架构是在多语言设置下训练的,不仅单独一个模型就可以从任意源语言翻译到任意目标语言,而且还可以是弱监督(甚至完全无监督)的。
机器人 这个领域的传统一直是把问题分解为感知、位姿预测、规划、控制、不确定建模等等模块,在中间层表征之上运用显式表征和算法。虽然完全离解决问题还有相当的距离,但UC伯克利和谷歌的研究人员都通过种种证据表明软件2.0可能会在表征所有这些代码上发挥出好得多的作用。
游戏 下围棋的程序已经存在了很久了,但是AlphaGo Zero(能够直接观察棋盘状态并下出一步棋的卷积神经网络)已经成为了目前最强的围棋棋手。我预计我们还能在其它领域看到非常类似的结果,比如DOTA2或者星际争霸。
可能有读者发现上面提到的很多研究都来自谷歌。这是因为谷歌目前就站在把大型软件重写成软件2.0代码的最前沿。“One model to rule them all”这篇论文里就给大家带来了一点早期感受,每个领域各自的统计力量可以联合起来形成对世界的一致理解。
软件2.0的好处
为什么我们应当主动把复杂的程序转换到软件2.0的形式呢?有个简单又明确的答案就是,它们在实际情况中的表现要更好。除此之外也有很多别的好原因选择这种模式。下面我们来把软件2.0(比如一个卷积神经网络)和软件1.0(比如一个生产级别的C++代码库)做个比较,看看有哪些好处。软件2.0的特点是:
计算同质化 。从第一阶来说,一个典型的神经网络是由矩阵乘法和零阈值(ReLU)像三明治那样一层接一层堆叠起来形成的。和传统软件的指令集相比,神经网络计算的同质化程度要高许多、计算复杂度也要高许多。由于用软件1.0实现神经网络时只需要为一小部分核心计算提供支持(比如矩阵乘法),那么需要保证计算的正确率、提高计算性能等等时就简单的多。
可以简单地集成进硅片中 。由于神经网络的指令集相对很小,就可以得到一个推论,那就是想要用更接近硅片的方式实现神经网络的时候就要简单得多,比如通过定制的ASIC、仿神经计算芯片等等。当低功耗的智能芯片环绕着我们的时候,整个世界将会变得大为不同。这些又小又便宜的芯片可以包含着训练过的卷积网络、语音识别器、WaveNet语音生成器等等,这样的小巧的原始大脑可以连接到任何东西上面。
恒定的运行时间 。神经网络典型的前向迭代过程总会需要同样的浮点运算量。运行在盘根错节的C++代码基础上的神经网络运算即便采用不同的路径运行,所需的计算量也不会有任何变化。当然了,计算图也可以是动态的,但执行的数据流总的来说还是有着非常大的限制、没法做出大幅度变化。这样一来,可以说我们几乎永远都不会意外地陷在无限的循环计算中出不来。
固定的内存使用量 。跟前一点类似,各个地方都没有动态分配的内存,所以几乎不会出现用硬盘做缓冲区的需求,也不会有什么需要追踪代码才能发现的内存泄露问题。
高可迁移性
。与传统二进制程序代码或者脚本相比,一系列的矩阵乘法操作想要运行在任意的计算硬件上要简单太多了。
非常灵活
。如果有一段C++代码的程序,然后有人想要把它的运行速度提升到原来的两倍那么快(如果需要的话也要付出一点执行效果代价),那么为新指标调整这个系统是一件非常困难的事情。然而,对于软件2.0来说,只需要去掉网络中一半的通道、重新训练一下,它就可以直接以原来的两倍的速度运行,只不过表现要差一点点。这就有点神奇了。反过来说,如果你刚好有更多的数据、更多的计算能力,你也只需要给程序中加入更多的通道、再重新训练一下,就可以提高它的表现。
可以融合多个模型达到全局最优
。目前的软件通常可以分解成不同的模块,它们通过公有函数、API或者终端相互沟通。不过,如果两个本来分别独立训练的软件2.0模块需要互动的话,可以很轻松地做全局反向传播。想想看,如果你的浏览器可以自动重新设计10层底层指令集来达到更高的网页加载效率的话,这将是多么惊人的一件事啊。而在软件2.0中,这会成为默认发生的一件事。
易学 。我喜欢开玩笑说“深度学习挺浅的”。因为深度学习并不是原子物理,你不需要先读一个博士学位才能做出来任何一件有意义的事情。理解深度学习背后的概念只需要基础的线性代数、微积分、Python以及CS231n中的几节课。当然了,在实践的过程中也还能学到许多精辟的见解和直觉,所以更准确的表述应该是:软件2.0的层层知识想学的话很容易入门,但是想成为高手也并不容易。
它要比你强 。最后,以及最重要的是,一个神经网络对应的代码要比你、我、甚至任何人能在某个很大的具体领域写出的代码都要好得多,目前神经网络至少就和图像/视频,声音/语音以及文本有关系。
软件2.0的限制
软件2.0的方法也有一些自己的缺点。优化之后我们得到的结果是运行表现出色、但非常难以解释的大规模网络。在许许多多的应用场景中我们都面临着这样的选择:是选那个我们能理解为什么但只有90%准确率的模型,还是选择那个有99%准确率但我们不理解的模型。
软件2.0的方法也可能带来反直觉的、令人尴尬的做法,甚至更糟。它们可能“悄悄地崩溃”,比如从训练数据中悄悄地学到了偏见。训练数据中的偏见又很难正确分析和检验,数据集的大小多数时候都是百万级起步的,进一步增大了这个困难。
最后,软件2.0中新的奇怪特性也在不断被研究人员们发现着。比如,对抗性样本和攻击的存在就体现出了软件2.0方法反直觉的本质。
最后的一点想法
如果你心中的神经网络是一种新的软件编写方法,而不仅仅是一类不错的分类器的话,那你很快就能发现它们有许许多多的优点,也有很大的潜力改变整个软件业态。
长期来看,软件2.0的未来非常明亮,对于通用人工智能的开发者来说这件事已经变得越来越明确,它一定会是用软件2.0写出来的。
那么软件3.0呢?那完全要看通用人工智能的发展如何了。
(完)
大家都能认可深度神经网络是新的思路新的做法,不过在Andrej Karpathy的这篇文章之前我们也不常细想它会对传统软件产生多大的影响。不过正如他在文中所说,“软件2.0”的前途还非常光明,雷锋网 AI 科技评论也期待着深度神经网络带来更大的改变。
via Medium
雷锋网版权文章,未经授权禁止转载。详情见。