code embedding研究系列三-CC2Vec

论文概述

这篇文章主要做的是将源代码补丁(补丁:用来修复bug,更新API功能…),补丁通常包括2个部分:

  • 日志信息:描述更新代码(code changes)的含义(semantics)
  • 更新代码(code change):表示增加或删除的代码行(原文:The code change indicates thelines of code to remove or add across one or multiple files)

作者将这种代码向量化的方式应用在3个任务上:

  • 日志信息生成(log message generation):根据更新的代码(code changes)进行日志信息生成,这样开发者就不必自己写文档 ,并且日志信息对软件更新过程的理解也是有重要的帮助。因此,这样任务志在根据修改的代码来生成简短的日志信息

  • Bug修复补丁识别(Bug Fixing Patch Identification):为了应付新的需求,应用软件通常会不断更新,这也会招致新的bug的出现。当支持遗留代码库时,可能需要将错误修复向后移植到项目的旧版本。例如,Linux内核开发人员定期将最新版本的错误修复向后移植到仍受支持的旧版本。但是,旧版本的维护者可能会忽略最新版本中的相关补丁。所以,自动区分一个补丁是不是bug修复补丁十分重要(可能是增加新功能的补丁)这项任务是一个二分类任务,输入更新代码(code change)和日志信息(log message),输出此次更新是否是为了修复bug。

  • 实时缺陷预测(Just-in-Time Defect Prediction):这也是一项二分类任务,输入包含更新代码(code change)和日志信息(log message)的更新包(patch),输出该patch是否包含其它缺陷(defect)。

CC2Vec架构

架构图如下所示:
在这里插入图片描述
整体架构包括如下部分:

  • Preprocessing:这部分的输入是一个补丁的更新代码集合(code changes),输出一个list,list中每一个元素对应一个文件的增加或删除的代码(Outputs a list offiles. Each file includes a set of removed code lines and addedcode lines.)。

  • Input layer:将预处理部分输出的list当作输入,将list中每一个元素(file)编码成一个3维向量输出,那么整层的输出是一个list,每个元素是一个3维向量。

  • Feature extraction layers:该层用HAN模型(Hierarchical attention network)对list中每一个file的3维向量提取embedding vector。然后将list中的每一个embedding vector进行concatenated。得到code change vector。

  • Feature fusion layers and word prediction layer:将code change vector映射为从日志信息第一行中提取出来的word vector。

整个过程就是一个预训练过程,学习的是一个函数 f : P → Y f: P \rightarrow Y f:PY
其中, y i ∈ Y y_i \in Y yiY 表示日志信息集合 Y Y Y中第 i i i 个patch的日志信息。 p i ∈ P p_i \in P piP 表示补丁集合 P P P i i i 个补丁。

Preprocessing

给定修补程序的代码更改包括对一个或多个文件所做的更改。每个更改的文件都包含一组删除的代码和添加的代码。我们通过以下步骤处理每个补丁的代码更改:

  • Split the code change based on the affected files:首先将每个更改文件的代码更改信息分离到一个单独的代码文档中(即File1、File2等)。

  • Tokenize the removed code and added code lines:使用NLP的NLTK库,将其删除的代码行或添加的代码行解析为单词序列(token sequence)。我们忽略更改文件中的空行。

  • Construct a code vocabulary:基于训练集,我们建立了一个词汇库 V c V_c Vc。此词汇表包含出现在修补程序集合的代码更改中的代码token。

Input Layer

一个补丁的code changes可能包括对多个文件的更改;对每个文件的更改可能包含对不同hunks的更改;每个hunks包含删除和/或添加的代码行的列表。

为了保留这些结构信息,在每个更改的文件中,我们将删除(添加)的代码表示为一个三维矩阵 B ∈ R H × L × W B \in R^{H \times L \times W} BRH×L×W

其中, H H H 是每个file中hunks的数量, L L L 是每个hunk中的删除(添加)代码行的数量,而 W W W 是受影响文件中每个删除(添加)代码行中的token数量。

分别用3维矩阵 B r B_r Br B a B_a Ba 来表示移除代码和增加代码。

每个patch的修改文件数量可能不同,每个文件的hunks数量也可能不同,每个hunk中代码行数也可能不同,每个行的token数量也可能不同,因此需要padding和truncate操作。

那该部分的输出就是一个list,每个元素包含 B r B_r Br B a B_a Ba 2个矩阵。

Feature Extraction Layers

特征提取层的任务是给定一个file的 B r B_r Br B a B_a Ba 2个矩阵,来生成该file的code change vector。之后,一个patch(补丁)中的所有涉及到的file的code change vector进行 concatenated,生成该patch的code change vector。

架构图如下所示:
在这里插入图片描述
输入的 B r B_r Br B a B_a Ba 均为 H × L × W H \times L \times W H×L×W 矩阵。

模型可分成2部分:

Hierarchical Attention Network.

该层次attention模型总共分为3层

  • word sequence encoder + word-level attention layer
  • line encoder + line-level attention layer
  • hunk sequence encoder + hunk attention layer

架构图如下:
在这里插入图片描述模型首先还包括了一个embedding层,为 ∣ V ∣ × d |V| \times d V×d矩阵, ∣ V ∣ |V| V为词表大小,d为嵌入维度,嵌入过后 H × L × W H \times L \times W H×L×W 的矩阵就变成了 H × L × W × d H \times L \times W \times d H×L×W×d 矩阵

模型具体运算过程就不说了,其中用到了GRU。最终分别对 B r B_r Br B a B_a Ba 生成 e r e_r er e a e_a ea 向量。表示删除和新增代码的embedding向量。其中 e r , e a ∈ R n e_r, e_a \in R^n er,eaRn

Comparison Layers

比较层的目的是是构建vector,以捕获给定补丁(patch)中受影响文件的删除代码和添加代码之间的差异。也就是给定一个file的 e r e_r er e a e_a ea 向量,生成删除代码和添加代码之间差异的向量 e f e_f ef 作为该file的code change的最终向量表示, e f ∈ R n e_f \in R^n efRn

文中也列举了几种比较方法
在这里插入图片描述

  • Neural Tensor Network
    e N T = R e L U ( e r T ⋅ T [ 1 , . . . n ] ⋅ e a + b N T ) e_{NT} = ReLU(e_r^T \cdot T^{[1,...n]} \cdot e_a + b_{NT}) eNT=ReLU(erTT[1,...n]ea+bNT) T i ∈ R n × n T_i \in R^{n \times n} TiRn×n

  • Neural Network
    e N N = R e L U ( W ⋅ [ e a ⊕ e r ] ) e_{NN} = ReLU(W \cdot [e_a \oplus e_r]) eNN=ReLU(W[eaer]) W ∈ R n × 2 n W \in R^{n \times 2n} WRn×2n
    ⊕ \oplus 表示concatenated操作。

  • Similarity
    e s i m = E U C ( e r , e a ) ⊕ C O S ( e r , e a ) e_{sim} = EUC(e_r, e_a) \oplus COS(e_r, e_a) esim=EUC(er,ea)COS(er,ea)
    E U C ( e r , e a ) = ∣ ∣ e r − e a ∣ ∣ 2 EUC(e_r, e_a) = || e_r - e_a ||^2 EUC(er,ea)=erea2
    C O S ( e r , e a ) = e r e a ∣ ∣ e r ∣ ∣ ∣ ∣ e a ∣ ∣ COS(e_r, e_a) = \frac{e_r e_a}{|| e_r || || e_a ||} COS(er,ea)=ereaerea

  • Element-wise subtraction
    e s u b = e r − e a e_{sub} = e_r - e_a esub=erea

  • Element-wise multiplication
    e m u l = e r ⊙ e a e_{mul} = e_r \odot e_a emul=erea
    ⊙ \odot 是按位乘法

最终Comparison Layers输出的向量 e f i = e N T ⊕ e N N ⊕ e s i m ⊕ e s u b ⊕ e m u l e_{f_i} = e_{NT} \oplus e_{NN} \oplus e_{sim} \oplus e_{sub} \oplus e_{mul} efi=eNTeNNesimesubemul

f i f_i fi表示该patch中的第 i i i 个file。

Feature Fusion and Word Prediction Layers

架构图如下:
在这里插入图片描述该patch最终向量表示为 e p = e f 1 ⊕ e f 2 ⊕ . . . ⊕ e f F e_p = e_{f_1} \oplus e_{f_2} \oplus ... \oplus e_{f_F} ep=ef1ef2...efF

hidden layer和 word prediction layer分别用矩阵 w h 和 w o w_h和w_o whwo表示,该层的运算如下:
h = δ ( w h ⋅ e p + b h ) h = \delta(w_h \cdot e_p + b_h) h=δ(whep+bh)
o = − h ⋅ w o o = -h \cdot w_o o=hwo
o ∈ R ∣ V m ∣ × 1 o \in R^{|V_m| \times 1} oRVm×1
∣ V m ∣ |V_m| Vm 表示日志序列词表大小

p ( o i ∣ p ) = s i g m o i d ( o i ) p(o_i| p) = sigmoid(o_i) p(oip)=sigmoid(oi)
o i ∈ o o_i \in o oio 表示日志序列词表第 i i i个词。

预训练设置

采用最小化以下目标函数进行训练:
O = ∑ y i ∈ y ( y i × − l o g ( p ( o i ∣ p ) ) + ( 1 − y i ) × − l o g ( 1 − p ( o i ∣ p ) ) ) + λ 2 ∣ ∣ θ ∣ ∣ 2 O = \sum_{y_i \in y} (y_i \times -log(p(o_i | p)) + (1 - y_i) \times -log(1 - p(o_i | p))) + \frac{\lambda}{2}||\theta||^2 O=yiy(yi×log(p(oip))+(1yi)×log(1p(oip)))+2λθ2

y i ∈ 0 , 1 y_i \in {0, 1} yi0,1表示日志词表第 i i i个词 o i o_i oi是否出现在补丁p的日志序列中, θ \theta θ表示模型的所有参数

在其它任务上的实验

日志信息生成(log message generation)

任务目标是给定一个patch的code changes,来生成日志信息。实验证明该模型的BLEU-4分数高于state-of-art

Bug修复补丁识别(Bug Fixing Patch Identification)

给定一个patch的code changes和日志信息,输出该patch是否是用来修复bug。
state-of-art-approach:PatchNet

方法如下:

  • 用CC2Vec提取code changes的vector
  • 用PatchNet提取log messages和code changes的vector。
  • 将上述向量concatenated
  • 用PatchNet进行分类。

实验结果:
在这里插入图片描述

实时缺陷预测(Just-in-Time Defect Prediction)

给定一个patch的code change和 log message。判断该patch是否包含缺陷。
state-of-art-approach:DeepJIT

方法如下:

  • 用CC2Vec提取code changes的vector
  • 用DeepJIT提取log messages和code changes的vector。
  • 将上述向量concatenated
  • 用DeepJIT进行分类。

实验结果:
在这里插入图片描述

总结

作者提出了一种将code change(修改部分的代码)进行向量化的方法(CC2Vec),并分别在3个任务(相关文档生成,Bug修复补丁识别,补丁缺陷预测)进行了测试,和state-of-art方法进行整合,效果要好于state-of-art方法。

相关代码已开源:CC2Vec

参考文献

Hoang, T. , Kang, H. , Lo, D. , & Lawall, J. L. . (2020). CC2Vec: distributed representations of code changes.

  • 2
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值