深度|不要只看论文,缺乏工程实践才是深度学习研究的瓶颈
选自dennybritz
机器之心编译
参与:微胖、杜夏德
学术界面临的研究瓶颈不仅来自各种技术,还包括社区文化和研究流程等问题。本文提到当下发表的大部分论文中 90% 的内容都是他人的研究成果,剩下的 10% 不过是研究者测试自己的假设,而且这种形式的论文很少会带来惊喜。就连 Andrej Karpathy 都十分赞同的文中一个观点:读论文不会太在意它的结果,只是为了获得灵感。
读研时,我研究的是 NLP 和信息提取,我几乎将所有时间都花在编码研究思路上。这就是有一个不喜欢接触代码导师(这样的导师估计占所有导师的 95%)的研究生所做的事。当我对问题(problems)表示担心时,总会听到这样的话「这只是一个工程问题;继续。」后来我才意识到这句话的真实含义:「我认为,一篇论文提到了这点就通不过同行评议」。这种心态似乎在学术界普遍存在。但作为一个工程师,我不禁注意到缺乏工程实践如何会让我们停滞不前。
我会拿我熟悉的深度学习社区作为一个例子,但这也可能适用于其他社区。作为研究人员的社区,我们都有一个共同的目标:推动该领域发展。推进当前最先进的技术。有很多方法做到这一点,但是,最常见的是发表论文。绝大多数发表的论文都是渐进式的,我没有贬低的意思。我相信,研究当然是渐进的,也就是说,新成果是建立在别人过去所做的基础之上的。而且这就是它应该的样子。说得具体一点,我读过的大多数论文的内容中有 90% 都是现有的东西,包括数据集、预处理技术、评估标准、基线模型架构等等。作者们通常会再添加一些新的东西,展示一下做了哪些超越现有基线的改进。
目前来看,这么做也没什么错。问题不在于这个过程本身,而是如何实施。在我看来,这里面有两个突出的问题,都可以用「工程实践(just engineering)」来解决。1、浪费研究时间;2、缺乏精确性和可重复性。逐一展开。
浪费研究时间(站在他人肩膀上的不易)
研究者都是经过高度训练的专业人士。很多人都花了几年到几十年的时间才拿到博士学位,成为各自领域的专家。只有那些人花大部分时间做他们擅长的事——通过提出新的技术来进行创新,才有意义。就像你不想让一个训练有素的外科医生每天花几个小时从纸质表格上输入病人的数据一样。但他们每天做的几乎就是这些事情。
在一个理想状态里,一个有想法的研究者能够轻松以已有成果为基础(亦即上文提到的论文 90% 的内容),剩下 10% 的内容用于测试研究者的假设。(我发现,也有例外,如果你正在做的研究真的很新,但是大部分发表的研究都不属于这个例外)。在实践中,几乎没有什么真正新东西。研究者花上几周的时间重复做数据的预处理和后处理,一遍又一遍地部署,调试基线模型。这些工作通常包括追踪相关论文的作者,弄清楚他们用的到底是什么技巧。论文往往不会提到细节(fine print),因为这会让结果看起来没那么令人印象深刻。在这个过程中,研究者会引入数十个混杂变量(confounding variables),这基本上会让比较变得没什么意义。然而后面还有更多没意义的事情。
我意识到,在他人成果基础上做研究的难易性是决定你正在做的是什么研究的主要因素。大多数研究者都是在自己的研究基础上一遍一遍做研究。当然有人可能会说,这是因为他是某个特定子领域的专家,所以,只有继续关注类似的问题才有意义。虽然不是完全没道理,但我认为,这么做没什么意义(尤其是深度学习领域,里面很多子领域之间联系非常紧密,以至于其间的知识迁移可以做的很好)。我相信,主要的原因是从实验的角度看,在自己工作的基础上做研究是最容易的。它能带来更多的论文发表,并让周转时间变得更快。基线已经用熟悉的代码部署好了,评估已经设置好了,相关工作也写好了,等等。而且这么做,竞争更少——其他人没法能接触到你的实验装置也就没法轻易和你竞争。如果这与在他人成果上做研究一样容易,我们可能会在发表的研究中看到更多的多样性。
并非都是坏消息。当然,有几个趋势正朝着正确的方向发展。发表代码越来越普遍。像 OpenAI 的 gym(以及 Universe)那样的软件包确保了至少评估和数据集能够做到效率化(streamlined)。Tensorflow 等深度学习框通过部署低水平基元(primitives)移除了大量潜在混杂变量。有人说,我们还有很多能做的事情没做到。试想一下,如果我们有标准化的框架、标准的数据库、标准的代码库和编码风格、严格的自动评估框架和在完全相同的数据集上运行的实体,研究效率又会如何。从工程角度来看,所有这些都是简单的事情,但是可能会产生巨大的影响。
我认为,我们低估了这一事实:我们是在和纯软件打交道。听起来似乎显而易见,但是,兹事体大。在诸如医学或心理学领域,设计牢牢加以控制的实验几乎不可能,工作量也相当庞大。而软件领域基本上是自由的。这一领域比我们绝大多数所认为的那样还要独特。但是,我们并没有这么做。我相信,这些变化(以及许多其他变化)还未发生的原因之一在于动机不对称。说实话,几乎所有研究人员更关心论文发表、引证率以及可授予终身教职的聘任制度,而不是真地推进这个领域。他们对有利于自己的现状很满意。
缺乏精确性(rigor)
第二问题与第一个问题密切相关。上文也暗示过了。就是缺乏精确性和可重复性。理想状态是,研究人员可以控制住所有无关变量,采用新的技术,然后展示各种基线的改善情况(在显著边际内)。貌似显而易见?好吧,如果你碰巧读了很多深度学习方面的论文,那么,你会觉得这个理想状态就像直接源自科幻电影。
实践中,当每个人采用不同框架和流程再度实现技术时,比较会变得没有意义。几乎每个深度学习模型在使用过程中都会存在很多会影响结果的「隐藏变量」,包括加进代码中的不明显的模型超参数,data shuffle seeds,变量初始化器以及其他论文通常不会提及的东西,但是,很明显它们会影响最终测量结果。当你用一个不同的框架重新使用你的 LSTM,预处理数据并写下几千行代码,你创造了多少混杂变量?我猜几百甚至几千个吧。如果你可以证明较之基准模型,有 0.5% 的边际改进,你怎么证明它们之间的因果关系?你咋知道这个结果就是结合某些混杂变量的结果?
我本人根本不相信论文结果。我读论文更多是为了获取灵感——关注论文的想法,而不是结果。这不是个应然问题。如果所有的研究人员都发布代码,会怎么样?会解决问题?实际上,并非如此。将 1 万条代码未入文献的代码放到 Github 上,说「在这里,运行这个指令,复制我的结果。」,这和生产人们愿意阅读、理解、证实和以此为基础进行研究的代码不是一回事。这就像望月新一证明 ABC 猜想,除了他,没人看得懂。
再一次,「不过是个工程问题(just engineering)」有望解决这个难题。解决方案和问题 1(标准代码、数据组、评估实体等)解决方案差不多,但问题也差不多。实际上,发表具有可读性的代码,可能并不最有利于研究人员。如果人们找到 bug 怎么办?需要收回论文吗?除了为你效劳的单位做公关,没有其他清楚的好处,发表代码是在冒险。