254页PPT!这是一份写给NLP研究者的编程指南

机器之心编辑部、赤乐君。算法

最近 AllenNLP 在 EMNLP2018 上作了一个主题分享,名为「写给 NLP 研究者的编程指南」(Writing Code for NLP Research)。该演讲从写原型和写模块两方面介绍了 NLP 研究该如何复制别人的代码、测试本身的代码块、记录及分享研究等,总之在研究者也要高效码代码的年代,这是一份浓缩的实践经验。docker

这分内容干货满满,仅仅只是看了 slide 就知道是很是有意思的一次演讲了。slide 共有 254 页之多,在「赤乐君」知乎专栏分享内容的基础上,机器之心为你们介绍 NLP 及深度学习研究者的编程指南。编程

读者能够直接下载 PPT 了解详细内容,其中每一页 PPT 都带有简要的备注,根据这些备注能够将全部 PPT 以及整场演讲串联起来。安全

下面是整个分享的大纲。经过此次演讲,你能够学到如何写代码来促进你的研究,以及可复现的实验。固然读者最好仍是知道一点 NLP 相关的知识,由于这一份分享会以深度学习中的 NLP 问题做为案例。此外,可以大体读懂 Python 代码也是很好的背景,这篇文章都是以 Python 接口调用 DL 框架为例。模块化

这里有两种写研究代码的模式,一种是写原型,一种是写组件。做为一名研究者,大多数时候咱们都但愿写原型,可是在没写好组件前是写很差原型的。而经过原型设计,有时候作出来的东西又是但愿下次再复用的组件。所以这是编写代码的两种模式,它们并不独立。工具

咱们先从写原型的方式开始介绍。oop

写原型

当咱们开始写一个原型代码的时候,咱们要作到下面三点。
性能

1. 写代码要快

2. 跟踪实验结果

3. 分析模型结果

快速开发

要作到快速编程,不要从头开始写全部内容,而是使用框架。这里的框架不只指 tensorflow 或 pytorch 之类的框架,也能够理解为模板。好比上图中若是写 training loop 的部分,已经有人写好了。咱们只要看懂后,直接拿来用就行,没有必要从头开始本身写全部部分。

上面提到的一些内容,都是能够找到现成框架来套用的。不少时候咱们在编程时遇到的问题不是构建模型,而是数据读取、预处理和写训练循环等部分。若是有人把你想用的东西模块化了,还等什么,直接拿来用啊!

固然拿来用也是有步骤的,首先咱们应该得到基线模型的性能,这也是一个很好的研究实践。基线模型多是别人的代码,你要是能修修改改就更好了。其次复现 SOTA 基线结果对于理解模型和作更多的研究是很是有帮助的。

要想快速开发,另外一个建议就是先复制,再重构。要记住,咱们是在写原型,不用在意什么可用性,先把代码写 work 了再说。若是实现的效果不错的话,再回去重构。

另外,咱们要有好的编程习惯。好比起有意义的变量名,写注释帮助理解。记住,咱们是写给人看的,不是机器!此外在使用基线模型作试验的时候,咱们能够如今小数据集上作测试,并确保模型能准确读取数据。

若是在作原型设计时,咱们将 LSTM 写死了(hard-code),那么在咱们但愿使用 Transformer 等模块的时候就须要从新改代码。所以使用多态能够借助更高级的抽象扩展代码,这样在换模块时就能只修改少许代码。

跟踪实验结果

在写原型的时候你须要运行不少东西,这致使很难追踪发生了什么以及对应的代码部分。

能够准备一个 Excel 表格,来记录实验结果。

黑箱对比对于上下文理解有帮助,但不能深刻理解两个结果之间的关系,由于有太多的变量在同时变化。咱们须要每次仅改变一个变量,能够在代码中设置「开关」,将开关配置一些全局状态/依赖注入。

每次只改变一个部分,方便跟踪实验结果的变化其缘由在于哪里。


这里光是 embedder,咱们就有不少种选择。

使用设定文件来记录模型的改变,方便咱们之后查询当时的设定。

分析模型结果

在训练的时候,可视化对于分析模型表现是很是重要的。这个技能必须掌握。

Tensorboard 能够提供不少分析结果。

Tensorboard 能帮咱们找到优化的 bug。好比上图中的 embedding 梯度有两个数量级的差异。

缘由在于 embedding 的梯度是稀疏梯度,即只有一部分会被更新。可是 ADAM 中的动量系数是针对整个 embedding 计算的,因此解决方法是直接引入特定的优化器:DenseSparseAdam。

在解释你的模型的预测输出时,好的展现是静态预测;更好的展现是交互地查看预测;最好的展现是交互地查看内部过程。

对于预测结果,若是能够作到交互式的方式来查看的话,是最好的。

开发组件

与写原型不一样,开发可重复使用的组件有不少要注意的地方。咱们的代码须要写清楚,这样就能聚焦于建模决策,而不考虑代码到底在作什么。

Code Reveiw 是必不可少的。Review 的时候,不只能发现错误,还能提升代码的可读性。


若是咱们不是软件开发人员的话,对于持续整合 以及构建自动化 这两个词可能比较陌生。一般咱们只说持续整合的时候,也包含了构建自动化的意思。想要作到这点,要多写测试才行。

固然,若是咱们不是开发一个不少人都会用到的库,上面这些步骤是用不到的。不过测试很重要,若是是原型开发,也要作一些最基本的测试。

如上对读取的数据进行测试,看是否正确。这里在进行单元测试时经常使用的就是 assert 语句,若是程序有问题,运行到这边就天然会报错,这样可让咱们尽快找到错误。

如上所示,固然咱们也可使用 assert 语句检查维度是否一致。这在模型运算部分常常会用到,例如判断每一个卷积层输出结果的尺寸和深度等。能够看到这两种测试的代码都不会不少。因此不要犯懒了,好好写测试吧。

关于 AllenNLP 库的一些介绍,这里就不花时间讨论了,感兴趣的能够看 slide 中 p141~p205 的部分。下面直接进入分享的部分。

分享研究

简化安装的流程,令代码运行在任何平台,使用隔离的环境。

下面是使用 Docker 的一些优势。

用 docker 开发的好处不用多说,你们想必也已经都知道了。固然,缺点也是有的。

至于 Python 的包管理系统,AllenNLP 采用了 ANACONDA。

Docker 是不错,但不适合作本地开发,这样的话,使用一些本地的包管理系统反而更方便。

最后作个总结。

  • 快速开发原型(要安全)

  • 写安全的产品代码(要快)

  • 好的流程有利于作出好的研究

  • 使用正确的抽象

  • 查看 AllenNLP(广告)

此次分享的 slide 看了几遍,不少地方看得本身脸上发热,不写测试什么的说到了痛处。如今人工智能领域对于算法工程师的要求已经不是能掉个包,谈谈研究那么简单了,工程实践能力已经变得愈来愈重要。写优秀的代码,作优秀的研究,两者是一个互相促进的过程。

相关文章
相关标签/搜索