基于深度学习的代码注释自动生成技术研究文献综述

 2023-08-07 15:39:32
  1. 文献综述(或调研报告):

3.1 代码注释生成技术

Haiduc等人[8,9]将IR方法应用到代码注释自动生成上,利用向量空间模型(VSM)和潜在语义索引(LSI)方法,取得了一定的成果;Vassallo等人[19]采用VSM模型,分别表示了源代码文本和Stack OverFlow网站上的“Qamp;A”开发人员讨论内容,并计算源代码与讨论内容之间的余弦相似度,将相似度高的代码-讨论内容对匹配为代码和其注释;Panichella等人[20]使用启发式和向量空间来处理和分析与类,函数和参数有关的描述和错误报告,并通过计算余弦相似度进行匹配。但总体上看,IR方法对已有代码库的依赖较大,仅考虑代码库中出现的具体代码,而没有获取代码中附带的其他信息[21],与机器学习方法相比性能较差。而针对代码注释的自动生成,已经有不少机器学习的相关研究成果被提出。神经机器翻译(NMT)[10],作为一种将自然语言(如汉语)转化为另一种自然语言(如英语)的技术,其思路可以被迁移到代码注释生成的任务中:首先需要同时对代码和注释构建语言模型,然后利用循环神经网络(RNN)对大型java语料库提取的特征进行学习,就可以利用该程序理解模型自动产生注释。近几年有不少人尝试对类似的问题提出解决方案,他们利用的语言模型可以为我们提供思路和灵感,例如,Li Wei等人[4]尝试为新闻报道自动生成评论,他们使用graph2seq的语言模型,将文章表示为图形结构,以便机器学习部分可以更好的理解文章的内部结构和主题之间的联系,实验结果证明此方法生成的评论更加连贯和翔实;Alon等人[5]先将程序解析为AST,对于程序中的每个元素(变量名、方法名、表达式类型)提取路径,利用word2vec模型得到变量的表示,在变量名预测,方法名预测等任务中取得了良好的效果;Hu等人[1]利用AST表示程序,使用SBT将其化为序列后,利用seq2seq模型,附加了LSTM和attention机制,相较于使用代码token序列的方法提升了近10个百分点;Ben-Nun等人[18]将基于图的程序理解模型用于程序生成和代码模型检测中,提出了一种基于图和代码的中间表示(intermediate representation)的程序向量表示inst2vec,该模型首先通过LLVM对代码进行编译得到代码的中间表示(LLVM IR),该中间表示中不含数据流和控制流信息,接着作者将控制流和数据流信息引入已经得到的中间表示中,构建了上下文流图(contextual flow graph,XFG)基于该图构建RNN得到向量表示,该向量在程序理解的任务中取得了较好的效果。

在机器学习模型方面,Dzmitry Bahdanau等人[6]和Ilya Sutskever等人[7]针对传统RNN在长依赖情况中,梯度在反向传播过程中容易消失或者爆炸的问题,分别提出了LSTM和GRU(门控循环单元)的方法来解决问题;Bhoopchand等人[12]针对动态语言(如Python)IDE的代码建议功能中,标准LSTM模型难以引用与较多token有关的标识符的问题,提出了一种预定义标识符类别的指针网络,来增强一般的神经语言模型,取得了较好的标识符预测精度和代码预测准确性;尽管seq2seq模型常采用基于解码器-译码器的RNN,但CNN也可以用于解码器-译码器结构[23],使用CNN代替RNN的一个好处是在训练期间CNN可以完全并行化所有元素的计算,从而更有效的利用GPU等硬件。Allamanis等人[14]将函数表示为token序列,在序列上进行卷积并引入了注意力机制CNN来序列中的关键信息,并引入了指针网络来解决OoV的问题,在Java的方法名预测任务上取得了较好的效果;

3.2 代码相关的语言模型

目前,对编程语言建立的模型分为两种:基于序列的模型和基于结构的模型。

基于序列的模型可以将源程序划分为字符序列、token(词素)序列和API(程序接口序列)。基于字符序列的方法将程序识别为一个个字符组成的序列。Cummins等人[11]在字符级别构建了LSTM的语言学习模型,并利用该模型构建了程序生成工具CLgen,这种方法的好处是总字符的个数是确定的,因此在程序理解中不会出现OoV(Out of Vocabulary)现象,但缺点是:由于由字符表示,程序序列过长,特征难以学习,并且程序中的token和调用的API信息损耗较大,难以被利用在程序理解中;基于token序列的方法将程序在字符之上,识别为token序列,将不同的token编号,写入字典中,这样处理程序后,就可以得到源程序token的特征向量,并通过解码器生成注释。White等人[13]使用RNN模型对程序代码的token序列建模,该模型在Java的代码补全任务中取得了72.2%的准确率;程序中调用的API序列可以在一定程度上反应程序的功能,基于这一点,在利用token序列的网络模型中,可以将提取的API序列信息作为辅助输入,来帮助解码器更好的生成注释,Hu等人[15]对基于seq2seq的语言模型进行了改进,使其除了token序列外,还将API中包含的信息输入到神经网络中辅助生成注释,结果表明,该方法的BLEU指标相比Iyer等人的方法的指标在代码注释生成上提升了20个百分点,这种基于API的改进方法在上述三种代码注释自动生成的方法中取得了最好的效果。

编程语言有着非常清晰,无二义的结构,这是编程语言与自然语言的一大不同,基于结构的模型期望能够将程序表示为结构而不是简单的序列,从而更好的表达程序的语法和结构,减少信息的损耗从而提高生成注释的质量。基于结构的语言模型可以利用AST(抽象语法树),图和执行过程。AST(抽象语法树)是一种程序代码的抽象表达形式,其中树中的每一个结点都代表一个代码片段,其中非叶子节点表示非终结符(如If语句,赋值语句,For语句等),叶子节点表示终结符(如变量名,方法名等),由于一般的树遍历方法不可还原(如单前序,中序遍历等无法还原树),在代码注释生成中,采用SBT(基于结构遍历)方法来将AST转化为线性结构,利用seq2seq模型来生成注释,如Hu等人[1,2]的研究;根据程序中的数据流动,可以利用图的结构进行建模,如控制流图和数据依赖图,图中的节点表示程序中的元素(程序的token或变量,以及程序中指针(pointer)的内存地址),图中的边表示节点之间的依赖关系或者数据流动情况。Fernandes等人[17]提出了将基于序列和图的模型相结合的程序表示方法,该方法仍先通过LSTM对token序列进行编码以得到每个token的向量表示,然后利用图神经网络对程序中的数据流和控制流进行建模,并将token的向量作为图中结点的初始值,最后以神经网络输出的向量为程序表示,根据该向量生成注释;此外,还有基于执行过程的程序模型,该方法需要监视程序执行轨迹(execution traces)是程序执行过程中的中间结果,例如执行过程中的子程序和参数,或者执行过程中程序各个变量值的变化情况,Reed等人[19]针对此提出了神经程序解释器(neural programmer-interpreters,NPI),该方法试图产生一个能够模拟程序运行过程的模型,该模型由基于RNN的组合神经网络构成,包含一个RNN内核,一个键值对存储单元和一个领域相关的解码器,该文档将API调用轨迹作为训练数据进行有监督训练,如此该模型能够模拟程序运算运行过程,表示出不同的程序。但是,由于程序中的API调用轨迹规模巨大,十分复杂,尤其是在一些较大的程序中,而目前的研究所用的程序较为简单,想要对大规矩的程序分析运行轨迹较为复杂,这就是分析API模型的局限性。

3.3 现状分析

包括向量空间模型(VSM)和潜在语义索引(LSI)在内的IR方法的问题在于:

(1)当输入代码的标识符和函数名称不正常时,无法从其中提取标识类似代码片段的关键字。

剩余内容已隐藏,您需要先支付 10元 才能查看该篇文章全部内容!立即支付

发小红书推广免费获取该资料资格。点击链接进入获取推广文案即可: Ai一键组稿 | 降AI率 | 降重复率 | 论文一键排版