代码注释生成:《Deep code comment generationation》论文笔记

原文链接:点此位置
来源:ICPC2018

一、论文背景

软件维护时,代码注释可以帮助开发人员理解程序,并减少阅读和定位源码的时间。但是这些注释在软件项目中通常与源码不匹配、缺失或过时,开发人员必须从源代码中推断出该功能,代码注释自动生成技术应运而生。受CODE-NN的启发,结合深度学习技术的优势,作者提出了一种针对Java语言的代码注释自动生成模型——DeepCom。

两大贡献:

  • 将代码注释生成任务表示为一个机器翻译任务。
  • 自定义了一个基于序列的模型来处理从源代码中提取的结构信息,用于生成Java方法的注释。提出了一种新的AST遍历方法(SBT)和一种更好处理词汇表外的token的方法。

DeepCom优点:

  • 通过学习源代码直接生成注释,而不是从关键字合成注释或搜索类似代码片段的注释。
  • 利用了丰富而明确的代码结构生成注释

二、方法原理

1.整体模型框架

在这里插入图片描述
三个步骤:数据处理、模型训练和在线测试。

训练过程主要面临两个问题

  • 如何表达AST以存储结构信息以及在遍历AST时保持这个表达的明确性
  • 如何处理源码中出现的词汇表没有的token

2.Seq2Seq模型

论文使用Seq2Seq模型学习源码和生成注释,如下图:
在这里插入图片描述

该模型由三个组件组成:编码器、解码器和注意力机制。Seq2Seq模型原理可参考:全面解析RNN,LSTM,Seq2Seq,Attention注意力机制,非常推荐,写的很详细。这里按照论文大概说说:
(1)编码器
论文使用LSTM作为编码器。在每个时间步从输入序列中读取一个token,记为xt,然后利用上一个隐藏状态st-1更新和记录当前的隐藏状态st。编码器从源代码学习潜在特征,最终将特征编码到语义向量c中。

(2)注意力机制
若不加注意力机制,在解码时用的都是固定的语义向量c。引入注意力机制后,固定的中间语义向量c换成了根据当前生成单词而不断变化的ci。计算公式如下:
在这里插入图片描述
即对每个输入单词的隐藏状态sj通过权重αij进行加权求和,αij的值越高,表示第i个输出在第j个输入上分配的注意力越多,在生成第i个输出的时候受第j个输入的影响也就越大。其中
在这里插入图片描述
可以发现权重其实用的就是softmax;eij表示编解码状态的相关性得分,利用输出的第i-1个隐藏状态和编码器的第j个隐藏状态的计算得出。

(3)解码器
解码器也是LSTM实现,不断将前一个时刻的输出yi-1作为后一个时刻的输入,输出的是每个字符的概率值,利用下式计算,可以根据这个概率值进行预测,比如选取概率值最大的字符。
在这里插入图片描述
模型的目标是最小化交叉熵,即最小化下面这个目标函数(N是训练样本的总数,n是每个目标序列的长度。y(i)j是指在第i个样本中的第j个单词。):
在这里插入图片描述

3.AST遍历——SBT

由于源代码的结构问题,很难进行源代码和自然语言之间的翻译,一个简单方法时将代码视为纯文本,显然这样会丢失代码的结构信息。为了同时学习代码的语义和语法信息,论文通过遍历ASTs将其转换为具有特殊格式的序列。由经典遍历方法(如先序和后序遍历)不能通过遍历的结果精确恢复原始的AST(就是给定遍历的结果,可能可以生成不同的树结构,如当二叉树中某个节点仅仅只有一个子节点的时候)。为了解决这个问题,论文提出了一种基于结构的遍历(SBT)方法来遍历AST,具体算法和例子如下:
在这里插入图片描述
以Figure4为例具体说说是怎么遍历的:

  • 从根节点中,首先使用一对方括号来表示树的结构,并将根节点本身放在右括号后面,即(1)1。
  • 遍历根节点的子树,并将子树的所有根节点放入括号中,即(1(2)2(3)3)1。因为1包含两个子树节点2、3。
  • 利用递归遍历每个子树,直到所有节点都被遍历。

在这里插入图片描述
论文还举了一个具体的例子,如下:
在这里插入图片描述
可以发现AST里面的终端节点变量值是用括号括起来的,前面是类型名,如SimpleName(String),为了区分SBT生成序列的括号与AST原本结构内的括号,作者将变量类型和变量值用下划线链接起来,如SimpleName(String)表示为SimpleName_String。非终端节点就用类型表示就可以了。

4.Out-of-vocabulary tokens

在NL中,在数据预处理时通常将词汇量限制在最常见的单词上,词汇表外的单词tokens用未知token(UNK)替换,对于NLP来说这样做十分有效因为UNK非常少。然而对于编程语言,除了固定的运算符和关键字外,用户自定义的标识符占据了大多数代码token,显然不能直接将这些自定义的标识符也视为UNK。
因此,论文提出了一种表示源代码词汇表外token的新方法。DeepCom的词汇包括节点的类型,部分形式为“类型-值”的终端token。论文保留了出现最频繁的30,000个token作为AST序列词汇表。对于词汇表之外的“类型-值”的token,DeepCom使用它们的“类型”术语,而非用UNK标记来它们。这样,词汇表外的token就会用其相关的类型信息而不是毫无意义的单词来表示。


三、实验设置

1.数据集构建

使用Eclipse的JDT编译器将Java方法解析为ASTs,提取相应的Javadoc注释(Java方法的标准注释)。论文舍弃的没有Javadoc注释的方法,对于每个有注释的方法,使用出现在Javadoc描述的第一句话作为注释,因为根据Javadoc指南,第一句话通常描述了Java方法的功能。过滤掉那些注释只有一个单词的方法,以及setter, getter, constructor 和 test等很容易生成注释的方法。最终获得69,708个(Java方法,注释)对,按8:1:1划分训练,验证和测试集。
开源的数据集链接:https://github.com/huxingfree/DeepCom

2.参数设置

  • 模型搭建框架——tensorflow
  • 优化器——SGD
  • 模型——双层LSTM,隐藏状态与词嵌入维度均为512
  • 学习率——0.5,按0.99的衰减速率衰减
  • dropout——0.5
  • minibatch——100
  • epoch——50

3.评价指标

BLEU-4
在这里插入图片描述

四、结果

RQ1: How effective is DeepCom compared with the state-of-the-art baseline?
在这里插入图片描述

RQ2: How effective is DeepCom to source code and comments of varying lengths?
在这里插入图片描述在这里插入图片描述

参考文献

[1]全面解析RNN,LSTM,Seq2Seq,Attention注意力机制:https://wjrsbu.smartapps.cn/zhihu/article?id=135970560&isShared=1&hostname=baiduboxapp&_swebfr=1

  • 3
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Hilbob

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值