不是我不明白,这世界变化快 ——《不是我不明白》崔健
IT系统的困境
IT技术是用来管理和处理信息的技术,IT系统是使用IT技术构建的系统。经过几十年的发展,IT系统越来越复杂,动辄几百万上千万行代码。然而,现代IT系统依然非常脆弱,一个业务上的变化,就可能导致一个子系统的重新设计;而一个颠覆性业务模式的出现,可能会导致整个IT系统被替换。
当我们在观察或了解昆虫以及其他低等生物时,会产生一种毛骨悚然的感觉:活动热闹非凡,可家里一个人都没有!——丹尼尔·丹尼特
设计实现IT系统的最大挑战来自于需求的变化。各种编程语言、设计模式,以及软件工程实践等,都在试图解决这个挑战。当前,用效率最高的软件开发方式——使用具有高级抽象能力的编程语言,采用响应式编程(Reactive Programming)范式和微服务架构,引入DevOps和持续交付等工程实践等开发一个新需求,也要以天为单位;如果要开发一个新的组件,可能需要以周为单位;而如果要开发一个全新的业务模式,至少要以月为单位。
对大部分程序员来说,各种新技术层出不穷,每一项都打着提高开发效率的旗号,然而事实是:程序员的工作并没有因为技术的进步而减少,相反,我们感觉自己越来越累,不仅要学习新技术,同时还要应对越来越频繁的需求变化。
于2000年左右出现的电子商务颠覆传统零售行业大概用了10年时间,2006年左右出现的社交网络颠覆门户网站大概用了五六年的时间,2012年左右出现的共享经济颠覆传统商业模式大概用了3年时间。一个合理但未经验证的猜想是:颠覆性业务模式的出现频率以及颠覆速度似符合摩尔定律,即每18个月,颠覆性业务模式的出现频率和颠覆速度会提高一倍。
不管我们使用什么样的编程语言,采用什么样的架构,引入什么样的工程实践,一个业务需求的生命周期都要包含产品规划、业务分析、方案设计、开发、测试、上线。这样的研发周期,在不远的未来,将无法跟上业务需求变化的速度。
自然的启示
《自私的基因》一书提到,基因为了将自己的遗传信息传递下去,进化出各种载体——即生物体——以应对环境的变化,让基因得以生存并传递下去。对于一些早期的生物载体,基因通过硬编码的方式,将一些复杂功能固化到生物体的遗传信息中。比如有一种名为“掘地蜂”的昆虫,在产卵时会严格遵照预定的程序:
- 用自己的刺麻痹一只蟋蟀;
- 将蟋蟀拖到挖好的洞口;
- 进洞查看,确保安全;
- 回到洞口,把麻痹的蟋蟀拖进洞;
- 产卵;
- 密封洞口,走人。
这套程序看起来非常复杂,我们不禁要感叹,一个简单的生物体,竟然可以完成这么复杂的事情。然而,当掘地蜂进入洞穴查看时,实验人员将麻痹的蟋蟀移动几英寸,等掘地蜂从洞口出来,并不会直接将移动过的蟋蟀拖进洞,而是将其拖到洞口,然后再一次进洞检查。如果期间蟋蟀又一次被移动,哪怕只是一英寸,掘地蜂也会重复前面的过程。正如丹尼特所说:看起来“活动热闹非凡,可家里一个人都没有!”
《机器人叛乱》对这一观点提出了进一步的扩展。为了让生物载体能够更好地适应快速变化的环境,基因发展出了弱约束目标。相比硬编码复杂行为,基因只是给其载体下达要完成的目标,而不再是具体的操作计划,由载体针对当时的环境做出符合目标的最佳选择。如果基因会说话,基因会给我们的大脑发出类似的指令:“事情发展太快,没办法一一详述,大脑,你只需在考虑我们的通用目标(生存和繁殖)前提下,做你认为最好的选择。”
生物体适应能力越来越强,同时也导致环境变化越来越快,反过来迫使我们不得不发展出更强的适应能力,就像进入正反馈的自动控制系统,系统开始进入不稳定状态,直到崩溃,然后重新寻找平衡。
IT系统的转折点
程序员之于IT系统,就如同基因之于载体。基因在生物进化早期也遇到过这样的困难,尽管进化出了非常复杂的生物载体,但是对于颠覆性的环境变化(比如火山爆发、地壳运动、彗星撞地球等),这些载体依然表现的不堪一击。
5亿年前的寒武纪大爆发,大量生物出现在地球上,基因像是想通过这样的方式,发展出复杂的载体,来应对变化的环境,然而,复杂并没有带来期望的适应能力。结果大家都知道了,6500万年前,基因进化出来的最复杂、最具有统治力的载体——恐龙——灭绝了。今天我们发明了新语言、新框架、新实践,期望通过这样的方式可以更快的开发出更复杂的系统。然而,再复杂的系统,面对不停变化的混沌世界,依然不堪一击。
是时候换个思路了。
我们也该考虑类似基因的弱约束目标,让IT系统具备一定的自主性,可以根据人类制定的目标,做出它认为最优的决策。具备自主性的IT系统,能够根据人类制定的目标,针对复杂业务变化,做出认为的最优选择。 这就是未来的IT系统。
DITS - Differentiable IT System
目前最有希望能够让IT系统具备自主性的技术,来自深度学习。深度学习通过建立层级化表征的方式,让计算机可以从经验中学习并理解这个世界。
[^1]深度学习和经典机器学习方法的最大区别在于,深度学习不需要某个领域的专家来设计特征提取规则,可以在输入数据和业务目标之间实现端到端的模型训练。对于深度学习的使用者来说,只需要准备好训练数据,设定好训练目标(即设定Loss Function,损失函数),确定深度神经网络的结构,然后进行训练,就可以得到满足目标的神经网络模型。
这其中的魔法发生在训练过程中。我们可以将复杂的神经网络用计算图的方式表达出来。在神经网络的末端,也就是输出层,通过损失函数计算出实际值和目标值之间的差别。得益于微积分中的链式法则,损失函数的结果误差可以在计算图中反向传播(Back Propagation),一层一层的调整神经网络参数,让神经网络在下一次的计算中距离目标更近一步。[^2]
在反向传播的过程中,每一层网络参数的修正值是通过计算误差和参数之间的梯度得到的。一个函数在某个点存在梯度,需要在这一点保证函数可微分,也就是本文题目中的Differentiable。所以,深度神经网络的学习能力,来自神经网络的可微分性(Differentiable)。
如果我们能够让IT系统具备可微分性,IT系统就可以基于人类指定的业务目标,从历史数据中学习,并不断更新自己,从而具备自主性。当变化来临,系统可以在没有人类参与的情况下自主学习并调整,最终适应变化。写出具有可微分性程序的编程方式,叫做可微分编程(Differentiable Programming)。[^3]这样的IT系统,称之为“可微分IT系统”,即DITS,Differentiable IT System。
当前,大部分AI技术只是作为独立的服务存在,用来辅助传统IT系统,比如图像识别、语音识别、自然语言处理等。而DITS本身就是一个AI系统,或者说,是一个内建AI能力的IT系统。
现在,我们经常使用A/B测试来改进程序,然而开发A/B测试代码、设计策略、收集反馈、分析、修改代码,一系列过程下来我们发现,用户点击红色按钮的比例比蓝色按钮多出30%,于是我们决定按钮使用红色。这就是所谓数据驱动的产品运营。
而对于DITS来说,我们可以设定弱约束目标为提高用户点击按钮的比例。每当用户执行一次操作,DITS就会计算这次操作和期望目标之间的差别,调整内部神经网络参数,从而自主地改进用户体验。更进一步,DITS甚至还可以对不同的用户展示不同的颜色,比如对于喜欢点红色按钮的用户展示红色,对于喜欢点蓝色按钮的用户展示蓝色。
这还只是一个具备自我学习能力的IT系统所做事情的一个简单例子,对于更复杂的业务场景,DITS所能做的,会超出我们的想象。
实现DITS
基于可微分性构造计算机程序,让计算机具备学习能力,目前是深度学习领域的热点。早期的尝试来自于DeepMind在2014年发表的神经图灵机(Neural Turing Machine,NTM)[^4],2016年DeepMind在Nature上发表了NTM的更新版本,可微分神经计算机(Differentiable Neural Computer,DNC)[^5]。DNC已经可以根据一些零散的路线信息,推测出地图上个点之间的连接情况,并计算最短路径。
另外一些基于记忆网络(Memory Network)的尝试也已经取得一些突破,比如Facebook在ICLR 2017上发表的递归实体网络(Recurrent Entity Network)[^6]可以通过所有Facebook提出的bAbI测试。
伦敦大学学院(University College London,UCL)的研究人员实现了一种具有可微分性的Forth语言解释器[^7],程序员编写Forth程序时,可以留下一些空白(slot),这些空白会被解释器在运行时填充,并且在运行过程中,解释器会根据程序的输入和输出调整这些空白部分的逻辑。
在工程领域,这一编程方式还处于早期阶段,尚不成熟,但已经有很多人在这一方向上做出尝试[^8],以及ThoughtWorks的开源项目DeepLearning.scala和DeepDarkFantasy。
要想完整的实现DITS,还需要很多努力,尤其是要想用DITS替代目前已有的复杂IT系统,还需要很长的一段路。不过,变革已然在酝酿之中。
在计算机被建造出来的早期,大部分人认为那只是学术领域的玩具,是只有书呆子模样的黑客们才能掌握的黑科技。然而,不过几十年的时间,计算机就完全改变了我们的生活。
今天的AI技术,包括Differentiable Programming和DITS,就像50年前的编程技术一样,还处于黑科技的范畴。然而,我们也许不用再等50年,就会看到今天的黑科技,将再一次改变世界。
One More Thing
《机器人叛乱》一书提到,“某些行为服务于载体的目标,它们未必有助于实现基因的目标”。那么,作为人类未来的信息载体——DITS——也会出现目标冲突的情况,到时候,我们人类要何去何从呢?