一种残膜回收机防缠绕挑膜装置的制 一种秧草收获机用电力驱动行走机构

一种基于细粒度共注意机制的语义代码搜索方法与流程

2022-03-26 16:17:19 来源:中国专利 TAG:


1.本发明涉及语义代码搜索领域,特别涉及一种基于细粒度共注意机制的语义代码搜索方法。


背景技术:

2.现有为了提高软件开发效率,开发人员经常通过利用代码搜索模型,从大型软件存储库(例如,github)中的代码库中搜索和重用现有的源代码片段。一般来说,代码搜索模型旨在找到其编程语义与在自然语言查询中表达的开发人员的意图相匹配的代码片段。
3.早期的模型利用信息检索(ir)技术来完成代码搜索任务。sourcerer是一个具有代表性的模型。它将代码片段视为纯文本,并使用文本搜索引擎lucene为它们构建索引,最后,通过匹配查询和索引代码片段之间的关键字来执行代码搜索。然而,简单的关键字匹配很难弥合查询和代码片段之间的语义差距。为了解决这个问题,lv等人提出了模型codehow,它利用与编程上下文更相关的api来扩展查询,并利用扩展布尔模型来提升关键字匹配的性能。
4.近年来,研究人员已经证明,与传统的基于ir的模型相比,深度学习(dl)技术是一种更好的代码搜索选择。原因是基于dl的模型可以通过将代码片段和相关的自然语言描述嵌入到一个共享的向量空间中来直接学习它们之间的语义关系。这些模型可以通过自然语言中的代码片段和相应的注释进行训练。这样,可以通过在查询向量与代码库中计算向量之间的余弦相似性来搜索与查询相关的代码段。
5.deepcs是一个具有代表性的基于dl的模型,它通过三个特征(即方法名、api序列和令牌)来表示代码片段,并采用长短期记忆模型(lstm)和多层感知机(mlp)来嵌入查询和代码片段。最近,研究人员提出了一些模型来解决deepcs的缺点。unif是一个更简单的模型,它用浅层神经网络模型fasttext取代了复杂的嵌入(即lstm和mlp),并通过注意力机制提高了性能。同时,一些研究人员观察到deepcs在许多情况下无法工作,因为它忽略了查询和代码片段之间复杂的语义相关性。为了解决这一挑战,他们提出了两种改进的模型carlcs-cnn和tabcs。carlcs-cnn通过使用卷积神经网络(cnn)进行嵌入,并利用共注意机制]来学习语义相关性。tabcs是目前很先进的模型。这是一个基于注意力的两阶段代码搜索模型,它使用抽象语法树(ast)扩展了carlcs-cnn,以更好地表示代码语义。实验结果表明,tabcs显著优于deepcs、unif和carlcs-cnn。
6.然而,tabcs仍然有两个局限性:语义丢失和语义混淆。tabcs将代码的结构信息分解为抽象语法树(ast)的令牌级单词,丢失了编程语句中单词之间的顺序语义,并在融合所有代码特征后构建代码和查询的语义相关性,这可能会混淆单个代码特征与查询之间的相关性。


技术实现要素:

7.针对现有技术存在的上述问题,本发明要解决的技术问题是:在搜索过程中容易
丢失编程语句中单词之间的顺序语义,同时代码与查询之间的语义相关性容易出现混淆,导致代码的查询结果不够准确。
8.为解决上述技术问题,本发明采用如下技术方案:一种基于细粒度共注意机制的语义代码搜索方法,包括如下步骤:
9.s1:构建代码搜索模型,该代码搜索模型由五部分堆叠而成:该五部分分别是数据预处理模块、特征表示网络模块、细粒度共注意力网络模块、语义特征融合网络模块和余弦相似度计算模块;
10.s2:选取公开java数据集,该数据集包括若干个代码查询对,每个代码查询对包括一个java代码片段和相应的自然语言查询令牌;
11.s3:数据预处理模块采用现有特征提取方法将数据集中所有的代码片段和查询令牌分别进行处理得到代码特征和查询特征,其中代码特征包括:方法名特征、api序列特征、代码令牌特征和语句树序列特征;
12.s4:特征表示网络模块将方法名特征、api序列特征、代码令牌特征和语句树序列特征分别经过wordembedding词嵌入技术处理后对应的得到方法名特征嵌入矩阵methodname、api序列特征嵌入矩阵api、代码令牌特征嵌入矩阵token和语句树序列特征嵌入矩阵statementtree;
13.方法名特征嵌入矩阵:methodname=(m1,m2,mi,...,m
p
),其中,mi表示方法名中第i个词向量;
14.api序列特征嵌入矩阵:api=(a1,a2,ai,...,aq),ai表示api序列中第i个api词向量;
15.代码令牌特征嵌入矩阵:token=(t1,t2,ti,...,tn),ti表示代码令牌中第i个代码词向量;
16.语句树序列特征嵌入矩阵:statementtree=(statree1,statree2,statreei,...,statrees),statreei表示第i个语句树向量;
17.将方法名特征嵌入矩阵methodname、api序列特征嵌入矩阵api、代码令牌特征嵌入矩阵token和语句树序列特征嵌入矩阵statementtree输入到注意力网络中,得到对应的特征矩阵,用m表示方法名特征矩阵、a表示api特征矩阵、t表示代码令牌特征矩阵、statree表示语句树序列特征矩阵和q表示查询特征矩阵,q={q1,q2,qi,...,qo},qi表示查询中第i个查询词向量;
18.s5:细粒度共注意力网络模块将构成代码特征矩阵的m、a、t、statree分别和查询特征矩阵q通过细粒度共注意机制进行对齐;
19.s6:语义特征融合网络模块计算代码向量vc和查询向量vq;
20.s7:余弦相似度计算模块计算代码向量vc和查询向量vq的余弦相似度,表达式如下:
[0021][0022]
其中,sim表示代码向量和查询向量之间的余弦相似度;
[0023]
s8:对代码搜索模型进行训练,具体步骤如下:
[0024]
s81:采用s2获得的数据集构建训练样本集,训练样本集中每个训练样本为一个实
例三元组《c、q

、q-》,其中,《c,q

》是代码查询对,q-表示除《c,q

》代码查询对以外的其他的代码查询对中的一个查询语句;
[0025]
s82:采用s2-s6的方法将代码c表示成代码向量vc,将代码c的查询q

和查询q-分别表示成查询向量和
[0026]
通过步骤s7的方法计算向量间的余弦相似度和
[0027]
s83:预设边缘约束参数β,将训练样本中代码的余弦相似度和作为输入,通过损失函数计算l(θ),并采用梯度下降法反向更新代码搜索模型进中的所有参数,损失函数计算如下:
[0028][0029]
其中θ表示模型中所有的参数,g表示训练样本集;
[0030]
s84:当训练达到最大迭代次数时停止训练,并将当前代码搜索模型作为最优搜索模型,否则返回s82;
[0031]
s80:对于一个待查询代码,将其输入最优搜索模型,同时在最优搜索模型中预设查询输出结果个数为n,最优搜索模型计算待查询代码与代码库中的各个代码向量计算余弦相似度,将余弦相似度自大到小排序,输出前n个余弦相似度对应的代码,该n个代码即为待查询代码的的查询结果。
[0032]
作为改进,所述s3中语句树序列特征的提取步骤如下:
[0033]
s31:将代码片段中的语句按行标记为s1,s2,s3,

sn;
[0034]
s32:根据代码片段构建相对应的ast结构,并将该ast结构分解为n个部分,每个部分对应每行代码语句;
[0035]
s33:利用深度优先遍历算法遍历每个语句树,从而将每个语句树表示成序列形式得到n个语句树序列subtreei,其中i=1,2,

,n;
[0036]
s34:将n个语句树序列subtreei拼接成一个序列,得到语句树序列特征statementtree;
[0037]
作为改进,所述s4中计算方法名特征矩阵、api特征矩阵、代码令牌特征矩阵、语句树序列特征矩阵和查询特征矩阵的步骤如下:
[0038]
s41:计算methodname中每个方法名词嵌入的注意力权重α
mi
,mi表示methodname中第i个词向量,计算表达式如下:
[0039]
α
mi
=softmax(tanh(wmi b))
ꢀꢀ
(1);
[0040]
其中,w为可训练参数矩阵,b为可训练偏差。
[0041]
s42:对方法名词向量进行注意力加权处理,并通过连接算子将多个词向量拼接成最终的方法名特征矩阵,计算表达式如下:
[0042][0043]
其中m∈r
k*p
为方法名特征矩阵,k为词嵌入向量的维度,p为方法名中单词的个数;
[0044]
s43:s41-s42中的方法,计算得到api特征矩阵a,代码令牌特征矩阵t,语句树序列特征矩阵statree和查询特征矩阵q。
[0045]
作为改进,所述s5中将m、a、t、statree分和查询特征矩阵q进行对齐的具体步骤如
下:
[0046]
s51:计算方法名特征嵌入矩阵与查询特征嵌入矩阵之间相互关联的方法名关联矩阵,具体表达式如下:
[0047]
b=tanh(m
t
uq)
ꢀꢀ
(3);
[0048]
其中,m
t
表示方法名特征嵌入矩阵的转置矩阵,b∈r
p*o
表示方法名关联矩阵,其中p为方法名单词个数,o为查询单词个数;u∈r
k*k
表示可训练的参数矩阵;q表示查询特征嵌入矩阵;
[0049]
s52:通过卷积神经网络沿着方法名关联矩阵b的行方向提取方法名特征嵌入矩阵与查询特征嵌入矩阵相关的方法名语义特征矩阵bm,通过卷积神经网络沿着方法名关联矩阵b的列方向提取查询特征嵌入矩阵与方法名特征嵌入矩阵相关的查询语义特征矩阵bq;
[0050]
s53:定义:vm表示为方法名特征嵌入矩阵与查询特征嵌入矩阵相关的方法名语义特征向量,v
qm
表示为查询特征嵌入矩阵与方法名特征嵌入矩阵相关的查询语义特征向量,计算方法名语义特征向量vm和相对应的查询语义特征向量v
qm

[0051]
s54:使用相同方法计算api序列语义特征向量va和相应的查询语义特征向量v
qa
,代码令牌语义特征向量v
t
和相应的查询语义特征向量v
qt
,语句树序列语义特征向量v
statree
和相应的查询语义特征向量v
qstatree
,得到代码语义向量code={vm、va、v
t
、v
statree
}和查询语义特征向量query={v
qm
、v
qa
、v
qt
、v
qstatree
}。
[0052]
作为改进,所述s52中所使用的神经网络为cnn,具体计算步骤如下:
[0053][0054][0055][0056][0057]
其中,w∈r
k*h
表示滤波器,b
i,j
表示语义关联矩阵b中的元素,fc表示完全连接的层,ave-pooling表示平均池策略;
[0058]
作为改进,所述s53中计算方法名语义特征向量vm和相对应的查询语义特征向量v
qm
的具体步骤如下:
[0059]
s531:计算vm的注意力权重am∈r
p
和v
qm
的注意力权重aq∈ro,计算表达式如下:
[0060][0061][0062][0063][0064]
其中,是am的第i个元素,是aq的第i个元素,表示方法名语义特征矩阵中的第j个元素,表示查询语义特征矩阵的第i个元素;
[0065]
s532:通过对方法名特征嵌入矩阵和对应的注意力权重进行点积运算,得到vm和vqm
,计算表达式如下:
[0066]vm
=m
·am
ꢀꢀ
(8);
[0067]vqm
=q
·aq
ꢀꢀ
(9);
[0068]
其中,am表示vm的权重,aq表示v
qm
的权重;m表示方法名特征嵌入;q表示查询特征嵌入。
[0069]
作为改进,所述s6中计算代码向量vc和查询向量vq,具体步骤如下:
[0070]
s61:计算代码向量权重α
vc
和查询向量权重α
vq
,具体计算表达式如下:
[0071]
α
vc
=softmax(tanh(wvc b))
ꢀꢀ
(10);
[0072]
α
vq
=softmax(tanh(wvq b))
ꢀꢀ
(11);
[0073]
其中,w为可训练参数矩阵,b为可训练偏差,vc∈code,vq∈query;
[0074]
s62:根据权重将语义特征进行融合,计算代码向量vc和查询向量vq,具体计算表达式如下:
[0075][0076][0077]
其中,vc表示代码语义向量中的元素,vq表示查询语义向量中的元素。
[0078]
作为改进,所述s83中损失函数的具体表达式如下:
[0079][0080]
其中,θ表示搜索模型中的所有参数,sim表示代码向量和查询向量之间的余弦相似性,β为边缘约束参数。
[0081]
作为改进,所述s83中损失函数中的边缘约束函数β设置为值0.05。
[0082]
相对于现有技术,本发明至少具有如下优点:
[0083]
1.本发明方法(命名为fcarcs),该方法通过一种细粒度的共注意机制捕获不同代码语句单词之间的顺序语义,分别区分查询和每个代码特征之间的相关表示,并通过考虑每个相关表示的贡献来增强表示融合。
[0084]
2.提取结构信息。根据代码的语句顺序提取抽象语法树的结构特征,并将这种语句级的结构特征和代码文本特征相结合,共同表征代码向量,从而更精准的表达代码语义。
[0085]
3.搜索效率更高。实验在一个大规模的数据集上进行了一个代码搜索实验,fcarcs模型显著优于三种最先进的模型(deepcs、unif和tabcs)。
[0086]
4.应用范围更广。对50个真实世界的查询进行了用户研究,发现fcarcs可以实质上搜索比deepcs、unif和tabcs更相关的代码片段。
附图说明
[0087]
图1表示本发明代码搜索模型的概览图。
[0088]
图2表示本发明中细粒度共注意机制的工作流程。
[0089]
图3表示本发明的对比方法tabcs检索“how to read text file line by line”的第一个结果。
[0090]
图4表示本发明的方法fcarcs检索“how to read text file line by line”的第一个结果。
具体实施方式
[0091]
下面对本发明作进一步详细说明。
[0092]
参见图1,展示了fcarcs的整体框架,它通过三个阶段实现了代码搜索:特征表示、细粒度共注意网络和语义特征融合。第一阶段将代码特征嵌入矩阵(即方法名、api序列、令牌和语句树序列)和查询特征嵌入矩阵(即令牌序列)输入到一个注意力机制中,以获得代码/查询特征矩阵。然后,第二阶段将特征矩阵分别输入四种细粒度的共注意机制中,得到每个代码特征与查询之间的细粒度相关性,以增强代码/查询特征向量。在第三阶段,相互依赖的特征向量分别融合成最终的代码/查询向量。最后,fcarcs计算了两个代表性向量之间的余弦相似性。
[0093]
本发明引入了一个语句级的代码结构特征,命名为语句树序列,这是一个更好的代码表示输入。该特征根据代码语句从ast中提取子树,并通过深度优先遍历将它们解析成许多序列。每个序列都被视为一个整体,以保存不同代码语句中的单词之间的顺序语义。
[0094]
本发明没有对融合的代码特征执行一个共注意过程,而是构建了一种新的细粒度共注意机制,分别学习查询和每个代码特征之间的相互依赖表示。一般来说,该机制利用行/列级cnn,使模型能够关注代码特征和查询之间强相关的局部信息。此外,本发明通过为具有更高相关性的向量表示分配更大的权重来执行最后的特征向量融合。
[0095]
一种基于细粒度共注意机制的语义代码搜索方法,包括如下步骤:
[0096]
s1:构建代码搜索模型,该代码搜索模型由五部分堆叠而成:该五部分分别是数据预处理模块、特征表示网络模块、细粒度共注意力网络模块、语义特征融合网络模块和余弦相似度计算模块。
[0097]
s2:选取公开java数据集,该数据集包括若干个代码查询对,每个代码查询对包括一个java代码片段和相应的自然语言查询令牌。
[0098]
s3:数据预处理模块采用现有特征提取方法将数据集中所有的代码片段和查询令牌分别进行处理得到代码特征和查询特征,其中代码特征包括:方法名特征、api序列特征、代码令牌特征和语句树序列特征。通过使用现有技术eclipsejdt编译器解析代码的抽象语法树(即ast),根据ast得到代码对应的方法名特征和api序列特征。根据代码语句顺序将ast分解为多个子语法结构树,每个子树对应一行代码语句,通过深度优先遍历这些子树提取语句树序列特征;将代码片段通过空格将其中的单词分开,并根据驼峰命名法对每个单词进行分词得到代码令牌特征。
[0099]
s4:特征表示网络模块将方法名特征、api序列特征、代码令牌特征和语句树序列特征分别经过wordembedding词嵌入技术处理后对应的得到方法名特征嵌入矩阵methodname、api序列特征嵌入矩阵api、代码令牌特征嵌入矩阵token和语句树序列特征嵌入矩阵statementtree。
[0100]
方法名特征嵌入矩阵:methodname=(m1,m2,mi,...,m
p
),其中,mi表示方法名中第i个词向量。
[0101]
api序列特征嵌入矩阵:api=(a1,a2,ai,...,aq),ai表示api序列中第i个api词向量。
[0102]
代码令牌特征嵌入矩阵:token=(t1,t2,ti,...,tn),ti表示代码令牌中第i个代码词向量。
[0103]
语句树序列特征嵌入矩阵:statementtree=(statree1,statree2,statreei,...,statrees),statreei表示第i个语句树向量。wordembedding为现有词嵌入技术。
[0104]
将方法名特征嵌入矩阵methodname、api序列特征嵌入矩阵api、代码令牌特征嵌入矩阵token和语句树序列特征嵌入矩阵statementtree输入到注意力网络中,计算每个特征序列中单词的重要性程度,从而捕获序列中的关键语义信息,最终得到对应的特征矩阵,用m表示方法名特征矩阵、a表示api特征矩阵、t表示代码令牌特征矩阵、statree表示语句树序列特征矩阵和q表示查询特征矩阵,q={q1,q2,qi,...,qo},qi表示查询中第i个查询词向量。
[0105]
s5:细粒度共注意力网络模块将构成代码特征矩阵的m、a、t、statree分别和查询特征矩阵q通过细粒度共注意机制进行对齐。这种机制背后的关键思想是探索每个代码特征和查询之间更细粒度的语义相关性,并分别丰富它们的表示。这样,该模型清晰地识别了不同代码特征和查询之间的语义,避免了特征融合造成的语义混淆。
[0106]
s6:语义特征融合网络模块计算代码向量vc和查询向量vq。
[0107]
s7:余弦相似度计算模块计算代码向量vc和查询向量vq的余弦相似度,表达式如下:
[0108][0109]
其中,sim表示代码向量和查询向量之间的余弦相似度。
[0110]
s8:对代码搜索模型进行训练,具体步骤如下:
[0111]
s81:采用s2获得的数据集构建训练样本集,训练样本集中每个训练样本为一个实例三元组《c、q

、q-》,其中,《c,q

》是代码查询对,即查询q

是代码c对应的查询语句。q-表示除《c,q

》代码查询对以外的其他的代码查询对中的一个查询语句。即与代码c的不相关查询。
[0112]
s82:采用s2-s6的方法将代码c表示成代码向量vc,将代码c的查询q

和查询q-分别表示成查询向量和
[0113]
通过步骤s7的方法计算向量间的余弦相似度和
[0114]
s83:预设边缘约束参数β,将训练样本中代码的余弦相似度和作为输入,通过损失函数计算l(θ),并采用梯度下降法反向更新代码搜索模型进中的所有参数,损失函数计算如下:
[0115][0116]
其中θ表示模型中所有的参数,g表示训练样本集。
[0117]
s84:当训练达到最大迭代次数时停止训练,并将当前代码搜索模型作为最优搜索模型,否则返回s82。
[0118]
s80:对于一个待查询代码,将其输入最优搜索模型,同时在最优搜索模型中预设查询输出结果个数为n,最优搜索模型计算待查询代码与代码库中的各个代码向量计算余弦相似度,将余弦相似度自大到小排序,输出前n个余弦相似度对应的代码,该n个代码即为待查询代码的的查询结果。
[0119]
具体的,所述s3中语句树序列特征的提取步骤如下:
[0120]
s31:将代码片段中的语句按行标记为s1,s2,s3,

sn;
[0121]
s32:根据代码片段构建相对应的ast结构,并将该ast结构分解为n个部分(即n个语句树),每个部分对应每行代码语句。
[0122]
s33:利用深度优先遍历算法遍历每个语句树,从而将每个语句树表示成序列形式得到n个语句树序列subtreei,其中i=1,2,

,n。
[0123]
s34:将n个语句树序列subtreei拼接成一个序列,得到语句树序列特征statementtree。
[0124]
根据代码片段构建对应的ast,并根据每行代码语句提取ast中相应的部分。如摘要附图,代码的“s1”表示为以“methoddeclaration”作为根节点的语句树。示例代码有四行语句,因此能提取四个语句树,然后利用深度优先遍历将每个语句树表示成序列形式(即图2中s1-》subtree1的过程),将这四个语句树序列拼接成一个序列,即“statree:[subtree1][subtree2][subtree3][subtree4]”,并作为包含四个单词的序列处理,用于后续的单词嵌入(即每个语句树序列被视为一个整体进行嵌入)。
[0125]
代码的基本组成元素是代码语句,所以我们将ast按照代码语句分割成n个子结构(即语句树),每个子结构对应一行代码语句,然后通过树遍历算法获取每个子结构的序列表示,最后按照代码语句顺序将n个子结构序列拼接起来作为一个特征,这种处理方式能够保证语句结构的完整性和顺序性,从而更好的表征代码结构。
[0126]
具体的,所述s4中计算方法名特征矩阵、api特征矩阵、代码令牌特征矩阵、语句树序列特征矩阵和查询特征矩阵的步骤如下:
[0127]
s41:计算methodname中每个方法名词嵌入的注意力权重α
mi
,mi表示methodname中第i个词向量,计算表达式如下:
[0128]
α
mi
=softmax(tanh(wmi b))
ꢀꢀ
(1);
[0129]
其中,w为可训练参数矩阵,b为可训练偏差。
[0130]
s42:对方法名词向量进行注意力加权处理,并通过连接算子将多个词向量拼接成最终的方法名特征矩阵,计算表达式如下:
[0131][0132]
其中m∈r
k*p
为方法名特征矩阵,k为词嵌入向量的维度,p为方法名中单词的个数。
[0133]
s43:s41-s42中的方法,计算得到api特征矩阵a,代码令牌特征矩阵t,语句树序列特征矩阵statree和查询特征矩阵q。
[0134]
具体的,所述s5中将m、a、t、statree分和查询特征矩阵q进行对齐的具体步骤如下:
[0135]
s51:计算方法名特征嵌入矩阵与查询特征嵌入矩阵之间相互关联的方法名关联矩阵,具体表达式如下:
[0136]
b=tanh(m
t
uq)
ꢀꢀ
(3);
[0137]
其中,m
t
表示方法名特征嵌入矩阵的转置矩阵,b∈r
p*o
表示方法名关联矩阵,其中p为方法名单词个数,o为查询单词个数;u∈r
k*k
表示可训练的参数矩阵;q表示查询特征嵌入矩阵;计算语义关联可以用于丰富代码特征和查询特征的表示,语义关联矩阵b表示每种代码特征中的单词与查询中的单词之间的相关性,同时使用tanh激活函数将矩阵中每个元素的值限制在-1和1之间。单词之间的相关性反映在矩阵b中的每个元素b
i,j
上,它表示第i
个代码词与第j个查询词之间的相关性。
[0138]
s52:通过卷积神经网络沿着方法名关联矩阵b的行方向提取方法名特征嵌入矩阵与查询特征嵌入矩阵相关的方法名语义特征矩阵bm,通过卷积神经网络沿着方法名关联矩阵b的列方向提取查询特征嵌入矩阵与方法名特征嵌入矩阵相关的查询语义特征矩阵bq。
[0139]
s53:定义:vm表示为方法名特征嵌入矩阵与查询特征嵌入矩阵相关的方法名语义特征向量,v
qm
表示为查询特征嵌入矩阵与方法名特征嵌入矩阵相关的查询语义特征向量,计算方法名语义特征向量vm和相对应的查询语义特征向量v
qm

[0140]
s54:使用相同方法计算api序列语义特征向量va和相应的查询语义特征向量v
qa
,代码令牌语义特征向量v
t
和相应的查询语义特征向量v
qt
,语句树序列语义特征向量v
statree
和相应的查询语义特征向量v
qstatree
,得到代码语义向量code={vm、va、v
t
、v
statree
}和查询语义特征向量query={v
qm
、v
qa
、v
qt
、v
qstatree
}。
[0141]
具体的,所述s52中所使用的神经网络为cnn,具体计算步骤如下:
[0142][0143][0144][0145][0146]
其中,w∈r
k*h
表示滤波器,b
i,j
表示语义关联矩阵b中的元素,fc表示完全连接的层,ave-pooling表示平均池策略。
[0147]
卷积神经网络cnn可以感知矩阵的局部信息,并且很擅长提取抽象特征,此处滤波器窗口大小h可设置为2;fc可以聚合通过卷积网络计算得到局部信息和由于最大池策略可能忽略了一些重要的特征,所以采用平均池策略,在整个连接层聚合信息后,使用ave-pooling来提取更多的信息。
[0148]
具体的,所述s53中计算方法名语义特征向量vm和相对应的查询语义特征向量v
qm
的具体步骤如下:
[0149]
s531:计算vm的注意力权重am∈r
p
和v
qm
的注意力权重aq∈ro,计算表达式如下:
[0150][0151][0152][0153][0154]
其中,是am的第i个元素,是aq的第i个元素,表示方法名语义特征矩阵中的第j个元素,表示查询语义特征矩阵的第i个元素。
[0155]
s532:通过对方法名特征嵌入矩阵和对应的注意力权重进行点积运算,得到vm和v
qm
,计算表达式如下:
[0156]vm
=m
·am
ꢀꢀ
(8);
[0157]vqm
=q
·aq
ꢀꢀ
(9);
[0158]
其中,am表示vm的权重,aq表示v
qm
的权重;m表示方法名特征嵌入;q表示查询特征嵌入。
[0159]
具体的,所述s6中计算代码向量vc和查询向量vq,具体步骤如下:
[0160]
s61:计算代码向量权重α
vc
和查询向量权重α
vq
,具体计算表达式如下:
[0161]
α
vc
=softmax(tanh(wvc b))
ꢀꢀ
(10);
[0162]
α
vq
=softmax(tanh(wvq b))
ꢀꢀ
(11);
[0163]
其中,w为可训练参数矩阵,b为可训练偏差,vc∈code,vq∈query。
[0164]
s62:根据权重将语义特征进行融合,计算代码向量vc和查询向量vq,具体计算表达式如下:
[0165][0166][0167]
其中,vc表示代码语义向量中的元素,vq表示查询语义向量中的元素。
[0168]
具体的,所述s83中损失函数的具体表达式如下:
[0169][0170]
其中,θ表示搜索模型中的所有参数,sim表示代码向量和查询向量之间的余弦相似性,β为边缘约束参数。引入边缘约束参数β,是为了确保代码向量与正确查询向量之间的距离,至少比代码向量与错误查询向量之间的距离更接近β,这样可以得到更加准确的搜索模型参数。具体的,损失函数中的边缘约束函数β设置为值0.05。使用adam算法来最小化损失函数。在训练过程中,损失函数通过adam实现梯度下降,迭代更新模型参数。
[0171]
实验设置
[0172]
a、数据集
[0173]
为了评估该模型的有效性,本实验在hu等人收集的现有大规模java数据集上进行了实验。该数据集包含475k个用于训练的代码查询对和10k个用于测试的代码查询对。该数据集的内容是从github 2015年至2016年上创建的java存储库中提取的,提取的每个项目至少有10颗星。此外还进行了一项用户研究,以测试本发明模型在gu等人从stack overflow中收集的50个真实查询上的性能。
[0174]
b、基线模型
[0175]
deepcs模型。gu等人提出了一个基于dl的代码搜索模型,它使用lstm和mlp将代码片段和查询嵌入到一个共享的向量空间中,并计算向量之间的相似性。
[0176]
unif模型。cambronero等人提出的一个更简单的代码搜索模型。它使用了一个基于fasttext的神经网络,并执行了一种针对代码表示的注意力机制,同时用余弦距离作为相似度度量。
[0177]
tabcs模型。yang等人提出了一种基于两阶段注意力机制的最新模型。第一阶段利用注意力机制从代码和查询中提取语义,并考虑到它们的语义差距;第二阶段利用共同注意机制来捕获它们的语义相关性,并学习更好的代码/查询表示。
[0178]
c、评价指标
[0179]
通过使用两个广泛使用的指标来评估所提出的模型的有效性:平均倒数排名(mrr)和前k个结果的成功率(sr@k)。
[0180]
mrr是所有查询的倒数秩的平均值,计算方法如下:
[0181][0182]
其中frankq为第q个查询的第一个正确结果的排名位置,|q|为q中的查询数。由于开发人员更喜欢检查列表中的前几个代码片段来找到预期的代码方法,所以本发明延续gu等人的做法,在排名前10的列表上计算mrr。
[0183]
sr@k是相关代码可以在排名前k的结果中找到的查询比例,跟随gu等人,分别用k在1、5、10处评估sr。
[0184][0185]
如果在前k个结果中可以找到第q个查询对应的代码,则δ返回1,否则返回0。
[0186]
实验数据
[0187]
本发明将fcarcs模型与最先进的deepcs、unif和tabcs模型进行了比较。表1给出了fcarcs在hu等人的的数据集上与三种基线模型进行比较的实验结果。结果表明,fcarcs的mrr为0.595,sr/1/5/10为0.610/0.758/0.817。本发明提出的fcarcs在mrr方面比deepcs、unif和tabcs多出110.99%、13.33%和9.38%;在sr/1/5/10方面比deepcs、unif和tabcs多出119.42%/74.65%/58.33%、15.31%/11.14%/5.83%和10.91%/5.42%/3.16%。
[0188]
其中,deepcs模型:gu等人提出了一个基于dl的代码搜索模型,它使用lstm和mlp将代码片段和查询嵌入到一个共享的向量空间中,并计算向量之间的相似性。
[0189]
unif模型:cambronero等人提出的一个更简单的代码搜索模型。它使用了一个基于fasttext的神经网络,并执行了一种针对代码表示的注意力机制,同时用余弦距离作为相似度度量。
[0190]
tabcs模型:yang等人提出了一种基于两阶段注意力机制的最新模型。第一阶段利用注意力机制从代码和查询中提取语义,并考虑到它们的语义差距;第二阶段利用共同注意机制来捕获它们的语义相关性,并学习更好的代码/查询表示。
[0191]
fcarcs模型是本发明提出的模型。
[0192]
sr@1,sr@5,sr@10表示:相关代码可以在排名前1、5、10的结果中找到的查询比例。
[0193]
mrr表示所有查询的倒数秩的平均值。
[0194]
表1.在sr@1/5/10和mrr指标上,deepcs、unif、tabcs和fcarcs的性能比较
[0195]
模型sr@1sr@5sr@10mrrdeepcs0.2780.4340.5160.282unif0.5290.6820.7720.525tabcs0.5500.7190.7920.544fcarcs0.6100.7580.8170.595
[0196]
结论:所提出的模型fcarcs模型在代码搜索方面显著优于最先进的基线deepcs、unif和tabcs。
[0197]
为了研究代码的四个特征(方法名、令牌、api序列和语句树序列)的相对重要性,本发明一次从fcarcs中删除一个特征。在表2中,fcarcs中的m、a、t和st表示方法名、api序列、令牌序列和语句树序列。对于tabcs-statree模型,是用本发明提取的语句树序列替换了原始模型tabcs中使用的代码结构序列而构建的对比模型。而unif-statree表示本发明将语句树序列作为代码结构特征添加到模型的unif输入中构建的对比模型。
[0198]
从表2可以看出,tabcs-statree的sr@1/5/10和mrr对比tabcs分别提高了6.36%/4.17%/2.90%和5.33%。unif-statree的sr@1/5/10和mrr对比unif分别提高了6.24%/5.72%/2.07%和4.57%。fcarcs在mrr方面分别比tabcs-statree和unif-statree高出3.84%和8.38%。对于fcarcs,通过删除方法名、api序列、令牌序列和语句树序列,mrr分别降低了2.19%/1.18%/7.90%/2.35%。
[0199]
fcarcs(a t st)表示本发明提出的模型在输入代码特征时删去方法名特征。
[0200]
fcarcs(m t st)表示本发明提出的模型在输入代码特征时删去api序列特征。
[0201]
fcarcs(m a st)表示本发明提出的模型在输入代码特征时删去代码令牌特征。
[0202]
fcarcs(m a t)表示本发明提出的模型在输入代码特征时删去语句树序列特征。
[0203]
fcarcs(m a t st)表示本发明提出的模型在输入代码特征使用全部特征。
[0204]
表2.五种不同的特征设置在sr@1/5/10和mrr方面的有效性比较
[0205]
模型sr@1sr@5sr@10mrrunif0.5290.6820.7720.525unif-statree0.5620.7210.7880.549tabcs0.5500.7190.7920.544tabcs-statree0.5850.7490.8150.573fcarcs(a t st)0.5980.7470.8050.582fcarcs(m t st)0.6060.7490.8140.588fcarcs(m a st)0.5630.7190.7840.548fcarcs(m a t)0.5970.7500.5120.581fcarcs(m a t st)0.6100.7580.8170.595
[0206]
结果表明,这四种代码特征都可以提高fcarcs的性能。此外,本发明可以观察到,语句树序列可以提高unif、tabcs和fcarcs的性能。结果表明,将四种代码特征一起作为模型输入可以获得最佳的性能,而代码令牌对fcarcs模型的有效性影响最大。
[0207]
结论:所提出的结构特征对代码搜索是必要的、有用的。同时,这四种代码特征都有助于fcarcs的有效性。
[0208]
表3显示了以下使用相同特征的变体模型的有效性比较:tabcs-statree是共同注意机制的代表;fcarcs-no表示本发明模型的一个变体,其在注意力机制后直接连接所有代码特征,以获得代码矩阵,然后平均池化层处理代码/查询矩阵分别得到代码/查询向量;fcarcs-fusion表示本发明模型的一个变体,其在融合所有代码特征矩阵后使用细粒度共注意机制直接获得代码/查询向量;fcarcs是本发明提出的模型。
[0209]
模型tabcs-statree和fcarcs-fusion的核心思想是首先融合所有代码特征嵌入,然后与查询计算共注意表示。然而,如表3所示,mrr和sr在fcarcs-no方面优于tabcs-statree和fcarcs-fusion。这一结果表明,融合特征后的代码和查询的共注意表示可能会
混淆单个代码特征与查询之间的语义相关性,从而影响代码和查询的匹配。
[0210]
此外,fcarcs在mrr方面比tabcs-statree、fcarcs-no和fcarcs-fusion高3.84%、2.41%和3.30%。这一结果表明,捕获代码特征和查询之间的语义相关性来丰富各自的向量表示可以提高模型性能,而细粒度的共注意机制有助于fcarcs的有效性。
[0211]
表3.三种不同的共同注意力设置在sr@1/5/10和mrr方面的有效性比较
[0212]
模型sr@1sr@5sr@10mrrtabcs-statree0.5850.7490.8150.573fcarcs-no0.5940.7450.8110.581fcarcs-fusion0.5940.7390.7990.576fcarcs0.6100.7580.8170.595
[0213]
结论:与其他具有代表性的共注意设置相比,所提出的细粒度共注意机制是代码搜索的最佳设置。
[0214]
对于语句树序列,嵌入序列的方法也很不同。除了语句级的嵌入粒度外,本发明还考虑了另外两个粒度:令牌级和序列级。令牌级将序列中的每个令牌视为一个单词,而序列级别将整个序列视为一个单词。本发明分别比较了tabcs和fcarcs上的令牌级粒度、语句级粒度和序列级粒度。
[0215]
从表4中可以观察到,语句级粒度是在tabcs和fcarcs上嵌入语句树序列的最佳选择。对于这两个模型,语句级粒度显示出更好的性能,mrr分别为0.573和0.595,分别优于令牌级和序列级。结果表明,语句级表示是令牌级和序列级表示之间很好的权衡。
[0216]
token-level表示语句树序列中的每个令牌都被视为一个单词。
[0217]
statement-level表示与每行代码语句对应的语句树序列子部分被视为一个单词。
[0218]
sequence-level表示整个语句树结构序列被视为一个词。
[0219]
表4.不同的结构特征的词嵌入粒度在sr@1/5/10和mrr方面的有效性比较
[0220]
模型(tabcs)sr@1sr@5sr@10mrrtoken-level0.5840.7460.8150.568statement-level0.5850.7490.8150.573sequence-level0.5770.7410.8130.566模型(fcarcs)sr@1sr@5sr@10mrrtoken-level0.5920.7460.8060.579statement-level0.6100.7580.8170.595sequence-level0.6010.7520.8140.585
[0221]
结论:语句级粒度是在特征表示中嵌入结构序列以实现代码搜索的最佳选择。
[0222]
表5显示了fcarcs和对比基线模型对50个真实查询的用户研究。“question id”显示查询来自的stack overflow中问题的原始id,“query”表示问题中用户输入的查询语句。最后四列显示了每个模型的frank结果,这是指模型返回第一个相关代码结果的排名位置。符号“nf”表示在前k结果(k=10)中没有找到相关结果,本发明保守地将符号为“nf”的查询的frank视为11。本发明观察到fcarcs获得了更相关的结果,平均frank(即average frank)为5.12,比deepcs(8.12)、unif(6.70)和tabcs(6.84)的平均frank分别降低了36.9%、
23.6%和25.1%。结果表明,fcarcs通常返回的代码比deepcs、unif和tabcs更相关。
[0223]
此外,为了分析fcarcs和这些基线之间的统计学差异,本发明在5%的显著性水平上对frank应用wilcoxon符号检验。p值小于0.01,说明fcarcs对这些基线的改善有显著的统计学意义。
[0224]
表5.基准测试查询和评估结果
[0225]
(nf:未在top10中返回结果d:deepcs u:unif t:tabcs f:fcarcs)
[0226][0227]
结论:对于目前公开的查询方法中,fcarcs在统计意义上大大优于目前最先进的模型。
[0228]
上述实验说明,虽然tabcs在代码表示中同时考虑了文本和结构特征,但它将一组令牌级ast的单词作为代码结构,可能会导致语义丢失。对于fcarcs,它将结构语义分解为一组与代码语句对应的语句级子树,并将其转换为序列,允许模型在捕获结构语义的同时保留代码语句中单词之间的顺序语义。表2的结果证明,语句级结构可以显著提高tabcs和fcarcs的性能。
[0229]
此外,fcarcs分别通过细粒度的共注意机制来学习查询和每个代码特征之间的语义相关性,这比tabcs中对融合所有特征的代码执行一个共注意过程更有利于学习相互依赖的代码/查询表示。图3和图4显示了tabcs和本发明提出的fcarcs关于查询“how to read text file line by line”的第一个结果。从图3中可以观察到tabcs返回了一个不相关的代码,尽管方法名和api包含查询关键字(例如,“read”和“line”)。因为tabcs融合了所有的代码特征来计算与查询的共注意表示,其中许多不相关的代码字(例如,“inputstreamreader”、“getlinenumber”)会混淆代码和查询之间的语义相关性。相比之下,fcarcs可以检索图4中预期的代码片段,其中代码涉及许多与查询相关的关键字,如“readlines”、“filename”、“reader”、“readline”等。一个重要的原因是fcarcs通过一种细粒度的共注意机制分别获得每个代码特征和查询之间的相关性。通过这种方式,fcarcs清楚地捕获了代码和查询之间相互依赖的语义,并减轻了语义混淆。
[0230]
本发明提出了一种用于语义代码搜索的细粒度共注意表示学习模型fcarcs,它不仅能提取代码文本特征,而且还通过引入语句级代码结构来提取结构信息。fcarcs不是学习孤立的表示,而是构建了一个细粒度的共注意机制来学习每个代码特征和查询的语义相关性,这可以直接增强它们各自的表示。基于这些语义特征表示,fcarcs可以更好地学习相互依赖的代码/查询向量。对最新开源数据集的评估显示,就mrr而言,fcarcs比最先进的模型(即deepcs、unif和tabcs)分别好了110.99%、13.33%和9.38%。此外,通过对50个真实世界的查询进行了用户研究,结果显示fcarcs显著将deepcs、unif和tabcs的平均frank分别降低了36.9%、23.6%和25.1%。因此,fcarcs使用的语句级结构和细粒度共同注意机制是非常有助于搜索符合开发人员意图的代码片段。
[0231]
最后说明的是,以上实施例仅用以说明本发明的技术方案而非限制,尽管参照较佳实施例对本发明进行了详细说明,本领域的普通技术人员应当理解,可以对本发明的技术方案进行修改或者等同替换,而不脱离本发明技术方案的宗旨和范围,其均应涵盖在本发明的权利要求范围当中。
再多了解一些

本文用于企业家、创业者技术爱好者查询,结果仅供参考。

发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表

相关文献