Page 212 - 《软件学报》2021年第7期
P. 212

2130                                     Journal of Software  软件学报 Vol.32, No.7,  July 2021

                 器/解码器.随后基于评论者网络的反馈,对演员网络进行迭代调优,以不断提高生成的注释质量.最后用生成的
                 注释进行代码检索.Wei 等人        [75] 同时考虑了注释生成和代码生成问题,认为这两个任务之间具有一定的相关性.
                 他们提出了一种基于对偶学习的方法,通过利用这两个任务间的对偶性来同时训练模型.他们考虑了概率和注
                 意力权重间的对偶性,并设计了对应的正则化项以约束这种对偶性.
                 4.2.3  考虑其他信息来源
                    除了上述研究工作外,一些研究人员尝试着利用其他信息(例如 API 序列信息、与目标代码相似的代码段、
                 方法的上下文信息等)来进一步提升生成的注释质量.
                    开发人员经常会通过调用特定的 API 序列来实现某个功能.例如,使用 Java 编程语言实现打开文件这一功
                 能,就会使用固定的 API 序列.因此,与可能基于不同编码规范实现的代码相比,代码内的 API 序列会更为有规可
                 循.基于上述观察,Hu 等人      [76] 提出了 TL-CodeSum 方法,该方法首先完成 API 序列总结任务,通过该任务可以构
                 建出 API 知识与实现的功能描述间的映射.随后将该知识应用于代码的注释生成.
                    Zhang 等人  [77] 尝试着将基于深度学习和基于信息检索这两类方法进行了融合.具体地,他们提出了 Rencos
                 方法,该方法首先基于训练语料库训练出编码器-解码器模型.随后从语法(即将代码解析为 AST,并计算 AST 之
                 间的相似度)和语义(即使用预训练的编码器,将代码编码为语义向量,并计算语义向量之间的相似度)两个角度,
                 从训练语料库中选出与目标代码段最为相似的两个代码段.最后对输入代码段和检索出的两个相似代码段进
                 行编码,并在解码生成注释时综合利用了这 3 个代码段的信息.
                    Liu 等人 [78] 基于需要生成注释的代码和相关代码的调用依赖关系,提出了一种基于深度学习的注释生成方
                 法.他们从代码中抽取出调用依赖关系,并将其转换成方法名的 token 序列,并通过综合利用代码和调用依赖关
                 系,基于 seq2seq 模型来生成代码注释.Zhou 等人         [79] 提出了 ContextCC 方法,首先使用程序分析方法,通过解析
                 AST 来抽取上下文信息(即方法和相关的依赖关系),接着通过预先定义的模板和规则,从上下文信息中过滤掉
                 无关内容,最后基于 RNN 来生成代码注释.Haque等人             [80] 尝试着利用代码上下文信息来生成注释.他们提出文件
                 上下文(即处在同一个文件内的其他函数)的概念,所提方法在编码器时考虑了 3 类输入(即代码文本、AST 和文件
                 上下文包含的其他函数).实验结果表明,使用文件的上下文信息有助于进一步提升生成的代码注释的质量.
                 4.3   已有工作的对比和评点
                    我们通过表 4 对所有基于深度学习的方法进行全面的对比,包括代码模块粒度、编程语言、方法类型和主
                 要特征.不难看出,基于深度学习的方法是当前该研究领域内最为流行的一类方法.早期的研究一般基于传统的
                 编码器-解码器模型.主要区别是如何对代码进行编码,因为代码与自然语言相比,具有一定的结构性.目前常见
                 的编码方式包括:将源代码直接转化成序列、将源代码建模为 AST、借助 SBT 方法将 AST 转换成序列、直接
                 基于 AST 等方式.其次,研究人员在经典方法的基础上,考虑进一步融合其他学习方法,例如图神经网络、强化学
                 习和对偶学习等.除此之外,除了源代码信息,更多研究人员考虑利用其他信息来提高注释生成的质量,例如考
                 虑 API 序列信息、代码的上下文信息等.由于这类方法主要基于深度学习,因此这类方法的性能同样离不开高
                 质量且规模大的语料库.
                                    Table 4    Comparison of deep learning-based generation methods
                                             表 4   基于深度学习的生成方法的对比
                        相关文献        模块粒度        编程语言          方法类型                 主要特征
                        Iyer 等人 [10]    代码段   C#、SQL 查询    经典编码器-解码器         基于 LSTM 和注意力机制
                      Allamanis 等人 [54]    方法     Java     经典编码器-解码器          基于 CNN 和注意力机制
                       Zheng 等人 [55]    代码段       Java     经典编码器-解码器           提出代码注意力机制
                       Liang 等人 [56]    方法        Java     经典编码器-解码器        基于 Code-RNN 和 Code-GRU
                       Hu 等人 [13,57]    方法        Java     经典编码器-解码器       基于 SBT 方法将 AST 转换成序列
                       Kang 等人 [58]    方法         Java     经典编码器-解码器          考虑了预训练的词嵌入
                      LeClair 等人 [60]    方法       Java     经典编码器-解码器 同时考虑了代码的单词表示和 AST 表示
                       Ahmad 等人 [61]    代码段、方法  Python、Java   经典编码器-解码器          基于 Transformer
   207   208   209   210   211   212   213   214   215   216   217