Page 210 - 《软件学报》2021年第7期
P. 210
2128 Journal of Software 软件学报 Vol.32, No.7, July 2021
(out of vocabulary)问题,即需要生成的注释可能含有未在代码中出现的单词.(2) 代码注释的可读性问题,使用
贪心或者束搜索(beam search)策略进行解码时,其生成的句子可能会出现不通顺的问题.(3) 代码注释和代码的
长度并不相等,通常来讲,代码注释的长度要远小于代码的长度.
4.2 已有工作的分析
4.2.1 基于经典编码器-解码器模型的方法
当前这类方法主要基于编码器-解码器结构(encode-decoder structure),有时又被称为序列到序列模型
(sequence to sequence model).具体来说,编码器的作用是将源代码编码为固定长度的向量表示,解码器的作用是
将源代码的向量表示进行解码,并生成代码注释.不同的编码器-解码器的主要区别在于代码的输入形式和神经
网络的结构.一般来说,常见的结构包括:CNN(convolutional neural network)和 RNN(recurrent neural network).其
中,LSTM(long short term memory)是最常见的一种 RNN 网络,其考虑了 3 个门控,即输入门控、遗忘门控和输出
门控.主要是为了解决长序列训练过程中的梯度消失和梯度爆炸问题.GRU(gated recurrent unit)可以缓解 LSTM
中存在的结构复杂和实现复杂的问题,并可以有效地减少模型训练时所需的时间开销.GRU 仅考虑了两个门控,
即更新门控和重置门控.同时,研究人员还会在 RNN 上进一步考虑注意力机制(attention mechanism),其可以为
编码器/解码器的相关序列中更为相关的词素赋予更高的权重取值,以进一步缓解长序列训练中存在的相关
问题.
Iyer 等人 [10] 首次对这类方法展开研究,并提出 CODE-NN 方法,在编码和解码时均基于 LSTM 和注意力机
制.在 Allamanis 等人 [54] 提出的方法中,编码器使用 CNN 和注意力机制,解码器使用 GRU.通过使用卷积操作,有
助于检测出局部时序不变(local time-invariant)特征和长程主题注意(long-range topical attention)特征.Zheng 等
人 [55] 提出一种新颖的注意力机制,即代码注意力(code attention)机制.该机制通过利用代码段的领域特征(例如
symbols 和标识符)来理解代码结构.通过关注这些具体领域特征,代码注意力机制可以更好地理解代码段的结
构信息.Liang 和 Zhu [56] 基于 Code-RNN 进行编码,从代码中抽取特征并构建向量表示.在解码时使用 Code-GRU.
Hu 等人 [13] 提出 DeepCom 方法,该方法通过抽象语法树(abstract syntax tree,简称 AST)来分析 Java 方法的
结构和语义信息,随后将 AST 转换成序列.为了更好地表示 AST 内的结构信息,且确保转换后的序列没有歧义,
他们提出一种新的 AST 遍历方法 SBT(structure-based traversal).SBT 将节点包含的子树包含在一对括号内.借
助括号可以有效地表示出 AST 的结构,并且可以无歧义地将转换后的序列恢复成转换前对应的 AST.除此之外,
为了进一步解决 OOV 问题,他们提出一种表示未知词素的新方法.在他们分析的 AST 转换后的序列中包含 3
类节点:终端节点、非终端节点和括号.其中,未知词素隶属于终端节点,因此,该方法使用未知词素的类型来代替
之前使用的通用词素值UNK.随后,他们基于 DeepCom 方法 [57] ,进一步提出 Hybrid-DeepCom 方法,该方法主要
进行了 3 方面的改进,首先综合使用了代码信息和 AST 转换后的序列信息,其次基于驼峰命名规范,通过将标识
符进一步细分为多个单词来缓解 OOV 问题.最后,该方法使用束搜索来生成代码注释.Kang 等人 [58] 在 Hu 等
人 [13] 研究工作的基础上,分析了使用预训练的词嵌入是否能够提升模型的性能.他们发现,使用基于 code2vec [47]
或 GloVe [59] 的预训练的词嵌入并不一定能提升性能.
LeClair 等人 [60] 提出了 ast-attendgru 方法,该方法考虑了两类代码信息:基于单词的表示(即将代码简单视为
文本)和基于 AST 的表示.他们考虑的模型包括两个单向的 GRU 层:其中一层用于处理代码中的单词,另一层用
于处理 AST.随后,借助注意力机制来识别出这两层中的重要单词.之后,合并基于注意力机制输出的向量,以创
建上下文向量.最后,基于该上下文向量生成代码注释.
Ahmad 等人 [61] 利用 Transformer 模型来生成代码注释.Transformer 模型是一种基于多头自注意力的序列到
序列模型,它可以有效地捕获长程依赖(long-range dependencies).
已有的针对代码变更生成提交消息的方法 [21,29] 在生成的提交消息内仅包含代码变更的内容和变更位置,
并且生成的提交消息较为冗长,除此之外,这些方法对代码变更的提交原因关注得较少,而这一类信息可以通过
分析已有的代码变更来获取.
Loyola 等人 [62] 首先初步证实了这种类型方法的可行性.Jiang 等人 [46,63] 针对代码变更来生成提交消息,他们