基于多维度匹配的代码搜索方法

文档序号:29250025发布日期:2022-03-16 01:16阅读:237来源:国知局
基于多维度匹配的代码搜索方法

1.本发明涉及代码搜索技术领域,具体地说,涉及一种基于多维度匹配的代码搜索方法。


背景技术:

2.代码搜索技术可从开源代码中根据自然语言描述找到对应的代码片段,以此提高开发人员的编码效率。目前大量研究通过深度学习方法将自然语言和代码段嵌入到高维空间,学习二者之间的深层次映射关系,从而提升代码搜索任务的准确率。然而,由于代码与传统自然语言之间存在语法差异,导致现有深度学习模型无法准确理解代码段的结构及语义特征,同时,由于模型本身需要输入更多的异构样本信息,使得模型结构的冗余程度大幅增加。


技术实现要素:

3.本发明的内容是提供一种基于多维度匹配的代码搜索方法,其能够克服现有技术的某种或某些缺陷。
4.根据本发明的基于多维度匹配的代码搜索方法,其包括以下步骤:
5.一、从开源代码库中提取大量《code,decsting》对作为训练数据,然后用训练数据训练模型tsmcs;
6.二、输入一段自然语言描述,训练好的模型便将最接近的代码片段搜索出来;
7.模型tsmcs通过引入语义级别与结构级别匹配模块对代码和描述进行语义提取和匹配,包括:
8.词嵌入层:采用无监督学习的fasttext模型,使用了n-gram、子词正则化特征增强方法;
9.图嵌入层:使用deepwalk,deepwalk分为随机游走和生成表示向量两个部分;
10.代码语义表示图csrg:基于抽象语法树,对节点进行聚合,并融入数据流特征;
11.语义提取层:使用lstm或者transformer来进行描述的语义特征的提取;
12.图特征提取层:使用图注意力网络gat去提取代码的csrg特征;
13.cress block:一种基于残差和交互的匹配模块,用于找到代码段和描述的匹配关系;通过级联残差信息和注意力机制增强词句的描述能力,从而保留更多的代码和描述的文本特征;
14.融合注意力层:用于将对应向量融合为一个向量;
15.损失函数。
16.作为优选,词嵌入层中,code和docstring分别经过token处理后送入词嵌入模型进行词向量的训练。
17.作为优选,deepwalk方法为:利用随机游走算法从图中提取一些顶点序列;然后借助自然语言处理的思路,将生成的定点序列看作由单词组成的句子,所有的序列可以看作
一个大的语料库,最有利用自然语言处理工具word2vec将每一个顶点表示为一个维度为d的向量。
18.作为优选,代码语义表示图生成过程为:首先我们通过第三方工具生成代码段的ast和dfg,对于ast,本文对其节点进行融合,相同的节点仅出现一次,其次,将dfg中的节点在融合后的ast中进行定位,将dfg的边特征加入到ast中,最后,将这两种边赋予不同的权值,即得到了代码语义表视图。
19.作为优选,图特征提取层中,使用gat去提取代码的csrg特征的方法为:
20.假设graph包含n个节点,每个节点的特征向量为hi,维度是f,表示为:h={h1,h2,...,hn},hi∈rf,对节点特征向量h进行线性变换,可以得到新的特征向量h'i,维度是f

,如下所示,w为线性变换的矩阵:
21.h'i=whi,w∈rf×f;
22.h'={h'1,h'1,

,h'1},h'i∈
rf
';
23.节点j是节点i的邻居,则可以使用attention机制计算节点j对于节点i的重要性,即attentionscore:
24.e
ij
=attention(whi,whj);
[0025][0026]
gat具体的attention做法如下,把节点i,j的特征向量h'i,h'j拼接在一起,然后和一个2f

维的向量a计算内积;激活函数采用leakyrelu,公式如下:
[0027][0028]
||表示拼接操作;经过attention之后节点i的特征向量如下:
[0029][0030]
作为优选,cress block匹配方法为:
[0031]
对于一个长度为l的序列,我们将第n个block的输入输出分别表示为:和第n个block的输入为第一次的输入和前两个block的输出的串联:
[0032][0033]
其中[;]表示串联操作;
[0034]
cross layer使用注意力机制,进行简单的镜像操作,输出两个序列的相似度得分;对于两个匹配序列a和b,长度分别为la和lb,可以表示为a=(a1,a2,...,a
la
),b=(b1,b2,...,b
lb
),对于ai和bj的相似度得分e
ij
为:
[0035]eij
=f(ai)
t
f(bj);
[0036]
f为恒等函数或者单层前馈神经网络,可以被视为一个超参数,则经过cross layer的序列ai,bj为:
[0037][0038][0039]
将三个角度的特征向量进行融合计算,输入序列a的输出:
[0040][0041][0042][0043][0044]
g,g1,g2,g3为参数独立的单层前馈神经网络,其中
·
表示element-wise乘法,经过fusionlayer的融合,输出中已经包含了各种特征。
[0045]
作为优选,融合注意力层中,对每个单词计算对应的注意力分值,并通过加权方式得到最终向量:
[0046][0047]
其中αi表示编码器隐藏状态hi对应的注意力得分。
[0048]
作为优选,损失函数为:
[0049][0050]
其中θ表示模型参数,表示训练数据集,β是一个超参数,sim表示两个向量之间的相似度得分,xd
+
d-分别表示代码片段x,与代码片段对应的描述语句d
+
,与代码片段不对应的描述语句d-经过模型嵌入之后维度相同的向量。
[0051]
本发明提出一种基于文本语义和结构注意力匹配的代码搜索模型tsmcs(code search based on text semantics and structuralattention matching),通过引入语义级别与结构级别匹配模块,模型可更有效地提取和融合多个维度下的代码特征。在文本语义级别匹配模块中,本发明设计了一种基于残差交互的匹配模块,通过级联残差信息和注意力机制增强词句的描述能力,从而保留了更多的代码和描述的文本特征,同时引入权值共享机制,在语义级别进行代码和描述的匹配,该模块的引入最大可提高26.07%mrr值;在结构级别匹配模块中,本发明设计了csrg(code semantic representation graph)的全新代码表示结构,使其在保留抽象语法树结构和复杂度的同时,对节点信息进行聚合,并融入
了代码的数据流特征,提高了信息密度;在相似度计算模块,设置融合注意力机层,由于不同特征对搜索结果的贡献度不同,tsmcs在计算最终的相似度之前对不同模块的输出进行加权得到最终代码-描述向量及贡献度排序,相较传统的余弦相似度排序效果更优。
附图说明
[0052]
图1为实施例1中基于多维度匹配的代码搜索方法的流程图。
具体实施方式
[0053]
为进一步了解本发明的内容,结合附图和实施例对本发明作详细描述。应当理解的是,实施例仅仅是对本发明进行解释而并非限定。
[0054]
实施例1
[0055]
如图1所示,本实施例提供了基于多维度匹配的代码搜索方法,其包括以下步骤:
[0056]
一、从开源代码库中提取大量《code,decsting》对作为训练数据,然后用训练数据训练模型tsmcs;
[0057]
二、输入一段自然语言描述,训练好的模型便将最接近的代码片段搜索出来;
[0058]
模型tsmcs通过引入语义级别与结构级别匹配模块对代码和描述进行语义提取和匹配,包括:
[0059]
词嵌入层:采用无监督学习的fasttext模型,使用了n-gram、子词正则化特征增强方法;code和docstring分别经过token处理后送入词嵌入模型进行词向量的训练。
[0060]
图嵌入层:使用deepwalk,deepwalk分为随机游走和生成表示向量两个部分;deepwalk方法为:利用随机游走算法从图中提取一些顶点序列;然后借助自然语言处理的思路,将生成的定点序列看作由单词组成的句子,所有的序列可以看作一个大的语料库,最有利用自然语言处理工具word2vec将每一个顶点表示为一个维度为d的向量。
[0061]
代码语义表示图csrg:基于抽象语法树,对节点进行聚合,并融入数据流特征;代码语义表示图生成过程为:首先我们通过第三方工具生成代码段的ast和dfg,对于ast,本文对其节点进行融合,相同的节点仅出现一次,其次,将dfg中的节点在融合后的ast中进行定位,将dfg的变特征加入到ast中,最后,将这两种边赋予不同的权值,即得到了代码语义表视图。
[0062]
语义提取层:使用lstm或者transformer来进行描述的语义特征的提取;
[0063]
图特征提取层:使用图注意力网络gat去提取代码的csrg特征;
[0064]
使用gat去提取代码的csrg特征的方法为:
[0065]
假设graph包含n个节点,每个节点的特征向量为hi,维度是f,表示为:h={h1,h2,...,hn},hi∈rf,对节点特征向量h进行线性变换,可以得到新的特征向量h'i,维度是f

,如下所示,w为线性变换的矩阵:
[0066]
h'i=whi,w∈r
f'
×f;
[0067]
h'={h'1,h'1,

,h'1},h
'
i∈r
f'

[0068]
节点j是节点i的邻居,则可以使用attention机制计算节点j对于节点i的重要性,即attentionscore:
[0069]eij
=attention(whi,whj);
[0070][0071]
gat具体的attention做法如下,把节点i,j的特征向量h'i,h'j拼接在一起,然后和一个2f

维的向量a计算内积;激活函数采用leakyrelu,公式如下:
[0072][0073]
||表示拼接操作;经过attention之后节点i的特征向量如下:
[0074][0075]
cress block:一种基于残差和交互的匹配模块,用于找到代码段和描述的匹配关系;通过级联残差信息和注意力机制增强词句的描述能力,从而保留更多的代码和描述的文本特征;
[0076]
cress block匹配方法为:
[0077]
对于一个长度为l的序列,我们将第n个block的输入输出分别表示为:和第n个block的输入为第一次的输入和前两个block的输出的串联:
[0078][0079]
其中[;]表示串联操作;
[0080]
cross layer使用注意力机制,进行简单的镜像操作,输出两个序列的相似度得分;对于两个匹配序列a和b,长度分别为la和lb,可以表示为a=(a1,a2,...,a
la
),b=(b1,b2,...,b
lb
),对于ai和bj的相似度得分e
ij
为:
[0081]eij
=f(ai)
t
f(bj);
[0082]
f为恒等函数或者单层前馈神经网络,可以被视为一个超参数,则经过cross layer的序列ai,bj为:
[0083][0084][0085]
将三个角度的特征向量进行融合计算,输入序列a的输出:
[0086]
[0087][0088][0089][0090]
g,g1,g2,g3为参数独立的单层前馈神经网络,其中
·
表示element-wise乘法,经过fusionlayer的融合,输出中已经包含了各种特征。
[0091]
融合注意力层:用于将对应向量融合为一个向量;
[0092]
对于代码会生成三个向量,分别是doctokenslstm、doctokensre2和asggat,对于其对应的描述会生成两个向量,分别是doctokenslstm和doctokensre2,需要将这些对应向量融合为一个向量,这里我们使用注意力机制。在文本序列模型中每个单词对最终的匹配结果的重要程度是不同的,所以需要对每个单词计算对应的注意力分值,并通过加权方式得到最终向量:所以需要对每个单词计算对应的注意力分值,并通过加权方式得到最终向量:
[0093][0094]
其中αi表示编码器隐藏状态hi对应的注意力得分。
[0095]
损失函数为:
[0096][0097]
其中θ表示模型参数,表示训练数据集,β是一个超参数,sim表示两个向量之间的相似度得分,xd
+
d-分别表示代码片段x,与代码片段对应的描述语句d
+
,与代码片段不对应的描述语句d-经过模型嵌入之后维度相同的向量。
[0098]
代码搜索
[0099]
给定一个待搜索的代码段集合χ,对于一个输入的查询q,我们需要对数据库中所有的代码段进行相似性排序,选出与查询q最接近的k个代码片段的集合x1,x2,...,xk。对于输入的查询q,将其输入到训练好的模型中,计算得到q,然后对代码片段集合中的每个代码段x,经过模型计算得到x,然后通过以下的余弦相似度计算相似性:
[0100][0101]
其中x和q分别表示代码段和查询语句的向量,相似度数值越大,则说明对应代码段和查询语句的相关性越高。
[0102]
实验
[0103]
数据集
[0104]
我们在两个公开的数据集上对模型进行训练和评估,一个是由发布的java数据集,另一个是python的数据集。两个数据集的统计数据如表1所示。
[0105]
表1数据集
[0106]
datasetjavapythontrain6970855538test871418502avg.tokensincomment17.79.49avg.tokensincode98.835.6
[0107]
对于java数据集,其中包含的代码片段(java方法)是从github上收集的2015到2016年的java项目中的,其中每个代码片段包含一段对应的自然语言描述,我们按照hu et al.的使用方法将每个处理为《method;comment》的形式。python数据集是barone et al.整理的,其中包含110k个平行语料和超过160k个仅代码数据,平行语料库被用于代码搜索和代码摘要任务,我们遵循wan et al.的方法去处理这个数据集,将其分成3:1的训练集和测试集。
[0108]
评价指标
[0109]
mrr(mean reciprocal rank)
[0110]
这是一个常用来衡量搜索算法效果的指标,目前被广泛用在允许返回多个结果的问题,或者目前还比较难以解决的问题中(由于如果只返回top1的结果,准确率或召回率会很差,所以在技术不成熟的情况下,先返回多个结果)。在这类问题中,系统会对每一个返回的结果给一个置信度(打分),然后根据置信度排序,将得分高的结果排在前面返回。对于查询集合q,返回的结果集合为q,正确结果出现的位置为f rank,得分为f rank的倒数,则mrr为:
[0111][0112]
mrr值越高,说明代码搜索模型的表现越好。
[0113]
successrate@k(success percentage at k)
[0114]
此指标衡量在前k个结果中可能存在一个或者多个正确结果的百分比,计算方法如下:
[0115][0116]
δ为一个函数,输入为真时输出1,否则输出0。一个好的代码搜索引擎应该将正确结果放在返回值尽可能靠前的位置,这样可以方便使用人员更快速的找到自己需要的结果,同样的,r@k值越高,表明代码搜索模型的表现越好。
[0117]
normalizeddiscounted cumulative gain(ndcg)
[0118]
归一化折损累计增益,用作排序结果的评价指标,评价排序的准确性。推荐系统通常为某用户返回一个item列表,假设列表长度为k,这时可以用ndcg@k评价该排序列表与用户真实交互列表的差距。
[0119][0120]
r(i)为第i个结果的得分,在代码搜索任务中,只有正确与否,对应的得分为1和0.在实验中,取ndcg@50作为评价指标。
[0121]
实现细节
[0122]
分词
[0123]
描述作为自然语言,我们按照单词的间隔去分词就已经足够,但是对于程序语言来说,存在着例如驼峰命名法、大量的符号语言等元素。对于驼峰命名法,例如“getfilename”,我们可以将其分词为”get”、”file”和”name”这三个词。对于程序语言中存在的大量的符号,在一些论文中会将所有的符号去掉,只留下单词,但笔者认为,代码中的符号也蕴含着大量的语义信息,所以在本文中,我们保留了代码语法中存在的符号。
[0124]
代码语义表示图csrg提取与生成
[0125]
代码的中间表示结构像ast、cfg、dfg等可以更好的体现代码的语义特征,然而分别处理这些树结构,模型复杂度的增加和模型效果的提升不成正比。如何更好的融合这些代码属性图?我们在抽象语法树的基础上提出了代码语义表示图。首先,我们借助开源工具生成抽象语法树,然后我们首先对抽象语法树进行节点融合,这里我们采取了一种非常简单的办法,就是将一段代码的抽象语法树中的相同节点就行融合,只保留一个,将原来节点的各条边汇聚到一个节点,此时,这个处理过的图中已经天然的蕴含着一部分的数据流信息。接下来,我们借助编译器提取代码的静态单赋值表示ssa,这个中间表示中包含着数据流信息,我们将ssa的信息加入到代码语义图中,此时的图已经比较完整。
[0126]
为了区别代码语义图中的两种边信息,我们将ast生成的边的权值设置为0.6,将ssa生成的边的权重置为0.4。
[0127]
实验结果分析
[0128]
与baseline对比实验
[0129]
我们选择了以下的几个模型和我们的模型进行对比:
[0130]
1.codehow:是前几年提出的sota的代码搜索引擎。它是以信息检索为基础的代码搜索工具,包含扩展的布尔值模型和api匹配。
[0131]
2.deepcs:是基于神经网络的一个sota的代码检索的方法。通过将源代码和描述嵌入到同一个向量空间来进行代码-描述的匹配搜索。
[0132]
3.carlcs:一个使用cnn进行特征提取的代码搜索模型,同时使用了关联矩阵进行参数共享,取得了良好的效果。
[0133]
4.mpcat:一个使用了层次遍历法(sbt)去编码代码抽象语法树和融合了文本匹配模型bimpm模型的代码搜索模型。
[0134]
我们在相同的数据集上训练和测试了code-how,deepcs,carlcs,mpcat以及我们的模型mdmcs,实验数据如表2和表3所示,从数据上看,我们的模型要优于3个基于深度学习的模型(deepcs,carlcs,mpcat)和一个基于信息检索的模型codehow。
[0135]
对于java数据集,结果在表3,我们的模型的mrr值达到0.540,在r@/1/5/10达到了0.299/0.591/0.675,mdmcs在mrr分别超过了codehow,deepcs,carlcs,mpcat 106.46%,
81.01%,8.65%,5455%在r@/1/5/10超过了baseline 44.13%/40.08%/4.59%/35.01%,49.78%/34.30%/7.59%/29.19%和49.78%/34.30%/7.59%/29.19%。
[0136]
实验结果表明。我们的模型的表现要好于以上的baseline模型。
[0137]
表2 python数据集
[0138]
modelr@1r@5r@10mrrndcg@50codehow11111deepcs11111carlcs11111mpcat11111mdmcs11111
[0139]
表3 java数据集
[0140]
modelr@1r@5r@10mrrcodehow0.20710.39470.48200.2359deepcs0.2131050.44021110.535570.2514carlcs0.28540.54950.61100.3387mpcat0.22110.45760.59140.2936mdmcs0.29850.59120.67540.4445
[0141]
模型有效性分析
[0142]
我们基于模型做了一些消融实验,来验证各个模块对实验结果的影响。表4展示了各个模块对实验结果的影响,从实验数据中我们可以看出,语义级别的匹配模块和结构级别的匹配模块对实验结果都有正面的影响,将各个级别的匹配模块融合之后,模型的表现要好于单独使用这些模块,这也说明在不同级别的匹配层之间的互补作用大于它们之间的冲突。通过加入和去掉attention层,实验结果也证明了融合注意力层对模型效果的正面贡献。
[0143]
表4消融实验
[0144][0145][0146]
在本实施例中,我们提出了一个基于语义和结构双级别匹配的代码搜索模型tsmcs,模型不仅从语义级别考虑代码和描述的匹配关系,也在代码ast基础上提出了csrg在结构上去进行代码和描述的匹配,同时加入注意力机制去平衡各个级别的匹配结果,实验证明我们的模型是有效的并且达到了sota的效果,超过了现有的代码搜索模型。
[0147]
以上示意性的对本发明及其实施方式进行了描述,该描述没有限制性,附图中所示的也只是本发明的实施方式之一,实际的结构并不局限于此。所以,如果本领域的普通技术人员受其启示,在不脱离本发明创造宗旨的情况下,不经创造性的设计出与该技术方案相似的结构方式及实施例,均应属于本发明的保护范围。
当前第1页1 2 
网友询问留言 已有0条留言
  • 还没有人留言评论。精彩留言会获得点赞!
1