Software is eating the world, but Neural Network is going to eat software.
软件正在吞噬世界,而神经网络将吞噬软件。
最初听说Karpathy这里提的软件2.0相关概念时,是在吴教授采访Hinton,Hinton无意中提到的一段关于当前高校计算机科学领域的不足,还有未来的发展方向。
他提到现在各大高校里,特别是计算机科学学院,并不缺各种编程大牛。只是现在的情况是,因为神经网络的普适性,所以实际上可能未来最重要的并不是如何来编一个程序,而是如何将数据展示给神经网络,来训练出来高性能网络。
这次看到这个软件2.0的概念时,感到很兴奋,因为这将Hinton提到趋势系统性地扩展,不光只从所需人才,还从计算、硬件、以及便利性展示了一个宏伟的前景。
软件2.0
现在可能大多数人还只是把神经网络当做是"机器学习工具箱中的一个工具",很多教科书里也是这样来介绍。包括有名的西瓜书,实际对神经网络的介绍只有一章,而深度学习只有2页。
这些想法会说:神经网络有它的优点和缺点,擅长处理某些任务,你有时可以用它来赢得kaggle比赛。
但可惜的是,如果只是这样子来看待神经网络,那就是捡了芝麻,丢了西瓜。因为神经网络代表的并不仅仅只是另一种分类器,它更代表着写软件方式的根本性转变的开始。而转变的结果就是软件2.0。
首先来介绍一下软件1.0吧。它也就是我们所熟悉的,程序员用一种语言比如Python或者C++,组合里面各种指令,写出一行行程序,使得程序执行一些行为。
相比之下,软件2.0则不是用编程语言写的了,而是用神经网络的权重写的。人们并不会参与编写这种程序中去,因为一个大的神经网络有太多权重了(成百上千万)。
而我们能做的,是对程序的行为提出一些要求,然后设置约束 (比如用一个有输入输出对的数据集),让神经网络自己搜寻程序空间,得到满足约束的结果。而其中神经网络搜索的手段,就是熟悉的反向传播还有随机梯度下降了。
事实上,对于很多现实问题来说,往往收集数据要比老老实实编程序容易得多。很大一部分的程序员,未来可能不再是维护复杂的软件库,写繁杂的程序,或者分析运行时间。而是收集、清理、操作、标准、分析、还有可视化喂给神经网络的数据 (我觉得这样的程序员2.0,可以叫做训网员了)。
虽然这样说,但软件2.0并不是说要取代软件1.0,而只是渐渐把之前软件1.0主要负责的任务取代过来。事实上,我们也需要1.0的底层架构,来训练2.0的代码。
下面来看写些,软件2.0的实例吧。
一些实例
视觉识别,比起过去那种用手工特征的分类器,现在大多数成功的分类器都是CNN家族里的架构,而最近一些研究更进了一步,开始自动搜寻架构了。
语音识别,过去要用有很多预处理过程的,高斯混合模型还有隐马尔科夫模型,但现在几乎都完全是神经网络了。
语音合成,过去的处理方法包括各种各样的拼接技术,但现在的模型就直接是一个大型CNN网络(比如WaveNet)输出音频数据。
机器翻译,过去最好的是基于短语的统计机器翻译(Phrase-based Statistical Machine Translation, PSMT),但是现在神经网络已是主流 (PSMT已沦为基准的基准了)。其中最有意思的,当然就是谷歌的多语言翻译系统,一个模型就几乎可以在任何语言之间进行翻译,还做到了Zero-Shot。此外,最近ICLR2018那篇,非监督学习的机器翻译也是赚足了眼球。
机器人学,长期以来都是把问题分成各个小的部分,感知、姿态估计、计划、控制... 这些模块之间用各种显式的程序和算法来处理。虽然现在也并没有太大的进展,但至少根据UC Berkeley还有Google的一些研究,暗示着可能软件2.0可以取代所有这些代码,取得更好的成果。(之前在机器人实验室,看有些基于神经学习的行走机器人相关研究时,机器人自己学习走路真的很令人震惊。)
游戏,这个就不用多说了。这也是各种媒体爆料最多的一块了,从AlphaGo Zero现在的独孤求败,到之前DOTA2虐职业玩家,已经有了很多发展。
软件2.0的好处
为什么我们会想把复杂的程序转成软件2.0呢?
一个简单的答案当然就是,因为这样工作性能更好。然而除此之外,其实也有很多便利的地方,使得我们更加青睐于软件2.0。
来看看软件2.0(比如一个CNN网络)和软件1.0(一个产品级的C++代码库)的比较。软件2.0会有这些好处:
计算均一性。一个典型的神经网络,通常只有两种操作: 矩阵运算和在0处阈值化(ReLU)。而传统的软件里面,操作就各种各样而且更加复杂了。
容易烧录进硅芯片。作为一个必然的结果,因为神经网络的指令集相对比较小,所以用硅片来实现这些网络会变得很简单,比如说定制的ASICs,神经形态(neuromorphic)芯片等等。而当这些低能耗的智能芯片普及时,那么世界将会发生很大的变化。想想未来一些便宜的小芯片里面,已经集成了预训练好的CNN网络、WaveNet语言生成网络,我们可以把它们用到任何东西上面去,就让人兴奋。
固定的运行时间。每一次网络的前馈迭代都只会使用同样的运算量。而且以这种方式,也不会进入意料之外的无限循环。
固定的内存使用量。没有动态分配的内存,所以内存溢出这样你需要在你代码里注意的东西也会减少。
跨平台能力强。比起传统的二进制文件或者脚本,一系列的矩阵相乘更容易在任意计算结构上运行。
非常灵敏。假如入你有一个C++程序,突然被要求让它运行速度加快一倍,那么为了满足这个新要求而改写代码,是件很麻烦的事情。而如果是神经网络,你只需移除一半的通道,重新训练一下,速度就变成原来的两倍了,只是性能会下降一些。反过来说,如果你突然有了更多数据或者计算量,那么你就可以增加通道,然后重训练,提高性能。
各个模块可以组成一个最优化的整体。现在的软件一般都是分成各个模块,然后用API这样的公共函数来交流。然而,如果是软件2.0的话,最初分别训练的模块,如果组合起来,很容易就能用反向传播来优化整个模型。
很好上手。深度学习很浅,这是Karpathy说的一个玩笑。指的是现在学习深度学习,你并不需要像核物理一样有一个博士学位,你只需最基础的线代、高数、python知识,然后在网上上点课,就能上手了。当然,这里说的只是上手,要成为大师的话,还是需要一些功夫的。
它通常做的要比你好。最后同样也是最重要的一点,一般神经网络比你想到的代码要好的多,至少现在已经在和图像/视频、声音/语言、还有文本有关的任务上已经是这样了。
软件2.0的不足
软件2.0也不都是一些好的地方,它也有自己的不足。
通常在优化后,会得到一个庞大的神经网络,性能很好,但是却很难解释为什么好。所以对于很多应用领域,我们需要选择是用90%准确,但能理解的模型;还是99%准确,但却不能理解的模型。
还有,软件2.0会出现一些预料之外,而且很尴尬的错误(之前微软的Tay),甚至更坏,“什么也不做”。却又很难去对它们进行分析和检测。
最后,现在仍发现软件2.0还有很多奇怪的特性。比如说对抗性样本的存在,以及用这个来进行的攻击。
最后
如果你把神经网络想成是软件,而不仅仅是个比较好的分类器的话,很明显它一下子就有了很多优点,而且有很大的潜力改变软件世界。
长期来看,软件2.0的未来是光明的,因为现在大家心里越来越清楚,当我们想要开发AGI(强人工智能),它必然是使用软件2.0来写出的。
最后的最后,关于个人的发展方面,我们可以更加关注于如何来利用数据和神经网络来实现自己的任务,使自己能够成为软件2.0的先驱者。