ACTA Scientiarum Naturalium Universitatis Pekinensis
具有选择性局部注意力和前序信息解码器的代码生成模型
梁婉莹1,2 朱佳1,2,† 吴志杰1,2 颜志文1,2 汤庸1,2 黄晋1,2 余伟浩1,2
1. 华南师范大学计算机学院, 广州 510631; 2. 广州市大数据智能教育重点实验室, 广州 510631; † 通信作者, E-mail: jzhu@m.scnu.edu.cn
摘要 提出一种基于语法的代码生成模型, 该模型具有选择性局部注意力和包含前序信息的长短期记忆(LSTM)神经网络解码器, 通过更改上下文向量的计算范围, 并在解码过程中融合更多的前序信息, 增强单词之间的相关性。在 Hearthstone 和 Django两个数据集上进行的代码生成实验证实了所提模型的有效性, 与最新的模型相比, 所提模型不仅表现出更出色的准确率和双语评估学习成绩, 还可以使计算工作量最小化。关键词 代码生成; 抽象语法树; 包含前序信息的长短期记忆神经网络(LSTM); 选择性局部注意力
代码生成是机器翻译的一个分支问题, 比自然语言生成或翻译[1]要求更高。代码符合规定的文法以及格式时, 才能被机器真正识别并运行。随着机器学习领域的发展, 人们逐渐找到代码生成的解决方案。Brown等[2]提出仅依赖于统计分析的统计机器翻译模型(statistical machine translation, SMT), 尽管其准确率相对较低, 却是当时代码生成问题的新突破。随后, 基于 Seq2seq[3]框架的神经机器翻译模型(neural machine translation, NMT)[4]被提出, 可以从自然语言序列映射到目标代码序列, 支持可变长度的输入和输出, 在翻译、对话和单词概括中表现出色。之后, 一些研究人员尝试使用指针网络来改进NMT模型, 例如致力于解决输出严重依赖于输入问题的潜伏预测器网络(latent predictor networks, LPN)[1]、通过长短期记忆单元(Long-short Term Memory, LSTM)[5]生成多层树的代码逻辑形
式的Seq2tree模型[6]、基于句法神经网络的Seq2seq模型(syntactic neural network model, SNM)[7]、抽象语法网络(abstract syntax networks, ASN)模型[8]、基于语义分析和代码生成的抽象解析器(TRANX)[9]、采用 Transformer[10]架构并捕获长依赖性句子的Treegen[11]模型以及基于语法结构的卷积神经网络(CNN decoder model)解码器模型[12]。
上述模型的双语评估研究指标(BLEU)和准确率上逐渐得到提高, 但在代码生成方面仍存在以下缺陷: 首先, 传统的序列到序列(Seq2seq)模型(如
[1] LPN模型 和SNM模型[7])的解码器包含的结构信息较少, 可能导致前序信息对当前运算的影响不足,使得当前向量在抽象语法树中位置选择错误; 其次,单纯使用软注意力(即将所有编码器输出向量置入上下文向量的计算中), 会导致输入序列的先验语义向量被后验语义向量覆盖, 缺乏对输出语法与模型特征[1]之间模块化或紧密耦合的考虑。
针对以上问题, 本文提出一种基于语法的代码生成模型。该模型具有选择性局部注意力和带有前序信息的长短期记忆单元解码器PI-LSTM (preorder information LSTM), 使用序列到序列(Seq2-seq)的编码–解码框架。在编码器部分, 使用门控循环单元(gate recurrent unit, GRU)[13]作为计算单元。与SNM模型中的朴素LSTM相比, GRU相对简单高效, 在减少训练时间的同时, 对准确率或双语评估学习成绩的BLEU分数产生可忽略的负面影响, 适用于训练大规模的预处理数据。在注意力机制部分, 为了增强上下文之间的相关性, 我们使用选择性局部注意力机制, 可以根据预设或输入语句的长度采用不同的注意力机制, 从而减少无关单词对当前单词权重计算的干扰。与单纯使用软注意力机制相比, 选择性局部注意力可以更好地适应不同大小的数据集。在解码器部分, 为了包含更多的结构信息, 我们使用基于朴素LSTM改进的PI-LSTM作为解码器计算单元。通过对输出值的二次更新, PILSTM提升了前序信息在解码运算中的参与度, 更好地修正了解码运算, 减少了模型在抽象语法树中生成错误分支的可能性。
1 代码生成1.1 SNM 模型
基于句法神经网络的Seq2seq 模型(SNM)[7]是目前最具代表性的代码生成模型。SNM模型不必恢复原有的基础语法, 只需要集中精力学习现有语法规则之间的可组合性[7]。它配备了标准的递归神经网络(RNN)[14]解码器, 允许更多的神经连接反映抽象语法树的递归结构。SNM模型应用双向LSTM (bidirection-lstm)[15]编码器、lstm解码器和软注意力来训练给定的预处理数据集, 与2017年前推出的模型相比, SNM模型的准确率非常出色。
1.2 抽象语法树
抽象语法树(abstract syntax tree, AST)[16]是领域专用语言(即代码)的树型结构。AST仅用于代码摘要, 不代表实际语法的每个细节, 其每个节点都代表源代码中的一个分支。抽象语法树有两个特征: 1) 不依赖具体的语法, 在解析输入语句时, 系统会构造相同的语法树, 且该语法树给编译器后端提供一个清晰、统一的接口; 2) 构造语法树时不依赖语言的细节, 并且, 针对不同的语言有不同的表示形式[7]。
2 编码器–解码器代码生成模型
代码生成是不定长输入到不定长输出的转换过程。本文提出的基于语法的代码生成模型如图1所示。该模型具有GRU编码器、选择性局部注意力以及 PI-LSTM解码器。模型根据输入序列的第一个单词, 生成目标抽象语法树的主干, 然后通过编码器–解码器的计算, 逐步将语法树主干填充成完整语法树。编码器对输入序列中的每个单词进行编码, 并将编码输出传送到选择性局部注意力机制中,计算上下文向量。解码器接收到上下文向量后, 使用PI-LSTM 计算并解码, 得到最终输出。
2.1 底层语法驱动
代码生成模型多数以抽象语法树(AST)为基础。在计算机科学和语言学中, 句法分析(或语法解析)[17]是一种对由一系列单词组成的输入文本的语法结构进行分析和确定的过程。底层语法驱动程序包含一组生产规则, 并通过固有的几个生产规则,生成头节点和多个子节点, 从而生成相应的树结构,如图2所示。如果输入序列中的第一个单词是“if”,模型则以“If→expr [test] stmt * [body] stmt * [or else]”的形式生成主干AST。然后使用 GENTO-KEN 和APPLYRULE, 分别在非终端节点和终端节点上进行操作, 前者通过添加终端令牌来填充可变终端节点, 后者将生产规则应用于当前派生树, 最终达成扩展和填充空值语法树的目的。