Big Code != Big Vocabulary: Open-Vocabulary Models for Source Code
Remark
Conference: ICSE 2020
Full Paper: http://homepages.inf.ed.ac.uk/s1467463/documents/icse20-main-1325.pdf
Artifact: https://github.com/mast-group/OpenVocabCodeNLM
Summary
In this paper, the authors motivate the importance of both large vocabularies and out-of-vocabulary issues, providing an experimental study of how to address such issues on a large source code corpora. Firstly, vocabulary modeling choices have been studied. The experimental result shows that the only viable option is an open-vocabulary NLM. All other vocabulary choices result in large vocabularies, high OOV rates, and rare words. Then the authors present a new open-vocabulary NLM for source code. Experiments show that the open-vocabulary NLM can scale to corpora (13,362 projects) that 100 times larger than in previous work, and yields state-of-the-art on three programming languages (Java, C, Python).
Introduction
Q: 什么是out-of-vocabulary (OOV) 问题
A: 如果在训练集中没有出现已知的词汇,那么训练好的模型就无法预测它们。
Q: 为什么当NLP技术应用于编程语言时会面临词汇表大的问题?
A: 因为与自然语言不同,软件开发人员可以自由地创建他们喜欢的任何标识符,并且可以使它们任意复杂。随着新的标识符名称的激增,代码以远高于自然语言的速度引入新词汇。大型词汇表和词汇量不足问题严重影响了源代码的神经语言模型(NLMs),降低了它们的性能,使它们无法扩展。
Q: 为什么NLM无法处理特别大的词汇表?
A: (1) 训练时缓慢;(2) 与测试面临Out-of-vocabulary (OOV);(3) 稀有词汇的embedding接近初始值,因为它们很少被更新。
Dataset
code corpora from Java, C, and Python
Modeling Vocabulary
(1)过滤不重要的词汇 (数据显示每次过滤都能减小词汇表的大小)
- 非英语单词
- 空格和换行
- 注释
- 字符串文本
结论:做完这一步后词汇量很大,有一百多万个单词。
(2)单词分割
虽然开发人员可以随意创建新的标识符,但倾向于遵循约定。因此可以通过某种启发式规则来分割单词
- 分隔符
- 大小写
结论:分词是有效的,但是词汇量仍然很大(一百万个单词)。
(3)分割Subword
- 将数字词抽象为字符序列,词汇量小幅度下降,但OOV提高
- 使用Spiral token splitter后,词汇量下降26%,OOV仍然很高
结论:虽然这些策略是有效的,但还远远不够解决词汇表和OOV问题;词汇量仍在数十万范围内。
(4)使用Byte-Pair Encoding(BPE)方法分割Subword
- BPE分词法:用数据中不使用的字节替换最常出现的字节,例如把出现频率高的(S1,S2)替换成S1S2
结论:BPE非常有效地缩小了词汇表。大多数词汇都是频繁出现的,改进了embedding。
4. 基于subword units的模型
将词汇表缩小了三个数量级
Evaluation
作者在Java, C, Python语料库上对比了NLM, n-grams, ML等方法
RQ1:性能评价
A1: Open vocabulary NLMs是对源代码的有效模型,即使是在一个小的语料库上,也能产生最好的性能。
RQ2:大语料库上的表现
A2:开放词汇表NLMs可以扩展到100倍大的语料库,它们可以有效地利用增加的训练数据,而大型n-gram模型不具备这样的能力。
RQ3:不同程序语言上的表现
A3:结果适用于Java、C和Python。
RQ4: Dynamic Adaptation的效果
A4:yields the state of the art
RQ5: Bug的检测能力
(这个不好评价,这种训练方法不一定适合bug检测)
Some other thoughts
(-) 这篇文章似乎在处理代码的时候没有考虑用程序分析技术将代码处理成中间表示(AST, CFG),而是直接用自然语言处理方法处理程序语言,因此会面临词汇表特别大的问题(从语义的角度看,很多自定义变量仅名字不同,但它们的使用方法是一样的,可以抽象处理)。
(+) 直接用处理自然语言的方法来处理程序语言的好处也很明显,可以直接用于不同程序语言(Java, C, Python)。