文献阅读:Boosting Automated Patch CorrectnessPrediction via Pre-trained Language Model

能否将本文方法运用到其他大模型上提升性能?

摘要

自动程序修复(APR)旨在自动修复软件错误,而无需人工调试,在软件开发和维护中起着至关重要的作用。尽管最近在修复错误的数量方面取得了重大进展,但APR仍然受到长期存在的过拟合问题的挑战(即生成的补丁看似合理,但过拟合)。因此,已经提出了各种技术来解决过拟合问题。其中,利用深度学习方法自动预测补丁正确性,以及最近可用的大规模补丁基准测试正在出现。然而,现有的基于学习的技术主要依赖于手动设计的代码特征,这在实践中可能非常昂贵且难以构建。在本文中,我们提出了APPT,这是一种基于预训练模型的自动补丁正确性评估技术,它将源代码视为一系列令牌,而不需要额外的开销来从不同的角度设计大量特征。特别是,APPT采用预训练模型作为编码器堆栈,然后是LSTM堆栈和深度学习分类器。虽然我们的想法是通用的,可以建立在各种现有的预训练模型上,但我们已经基于BERT模型实现了APPT。我们对1183个Defects4J补丁进行了广泛的实验,实验结果表明,APPT的预测准确率为79.0%,召回率为81.3%,比最先进的CACHE技术高出3.6%和4.8%。我们对49694个真实世界补丁的进一步调查表明,与现有的表示学习技术相比,APPT实现了最佳性能(在评估补丁分类技术的五个常见指标中超过99%)。我们还证明,采用先进的预训练模型可以进一步提供实质性的进步(例如,基于GraphCodeBERT的APPT在精确度和召回率方面分别将基于BERT的APPT提高了3.0%和2.6%),突出了APPT的普遍性。

关键词 自动程序修复、补丁正确性、预训练模型

1 引言

软件错误在现代软件系统中是不可避免的,并导致致命的后果,例如造成数万亿美元的经济损失,影响全球数十亿人[1],[2]。由于现代软件系统的规模和复杂性不断增加,开发人员修复这些错误是非常耗时和劳动密集型的[3]。自动程序修复(APR)旨在在没有人为干预的情况下自动修复暴露的软件错误,在过去几十年中引起了学术界和工业界的广泛关注[4],[5]。尽管有一个新兴的研究领域,但文献[6]、[7]中提出了各种APR技术,并在修复错误的数量方面不断取得有希望的结果。

然而,由于程序规范薄弱,很难对生成的补丁实现高精度[8]。现有的APR技术通常利用开发人员编写的测试用例作为评估所生成补丁正确性的标准。事实上,通过可用测试用例生成的补丁可能无法推广到其他潜在的测试用例,从而导致APR的长期挑战(即过拟合问题)[8]。例如,当在功能中检测到错误时,可以通过删除功能来生成补丁,而可用的测试用例通常无法执行删除的功能[9]。在这种情况下,开发人员需要花费大量时间和精力来过滤过拟合补丁,导致在实践中应用APR技术时调试性能不佳[10],[11]。

因此,已经提出了各种自动补丁正确性评估(APCA)技术来确定生成的补丁是否确实正确[12]。根据提取的特征,传统的APCA技术可分为两类:静态和动态技术[13]。静态技术倾向于根据句法和语义特征分析代码变化模式或代码相似性。例如,Tan等人[14]为有缺陷的程序定义了一组通用的禁止转换(例如,上述功能删除)。相比之下,动态技术通常针对自动测试生成工具(例如Evosuite[15]和Randoop[16])生成的额外测试用例执行合理的补丁。例如,Xiong等人[17]生成新的测试用例,并根据测试用例执行的行为相似性确定补丁的正确性。然而,静态技术可能会遇到预测精度问题,而动态技术生成额外的测试用例并执行所有修补程序则相当耗时[13]。

最近,受发布的大规模补丁基准测试[6]、[7]的启发,提出了一些基于学习的APCA技术,通过嵌入有缺陷和补丁的代码片段来评估补丁的正确性[12]、[18]、[19]。例如,Lin等人[20]利用抽象语法树(AST)路径来表示补丁,并构建深度学习分类器来预测补丁的正确性。同样,He等人[18]在AST级别静态提取代码特征,并训练概率模型来执行补丁预测。然而,尽管预测结果出色,但现有的基于学习的APCA技术主要采用复杂的代码感知特征(例如[20]中的AST路径)或手动设计的代码特征(例如[18]中的202个代码特征),在实践中进行和提取成本很高。

在这项工作中,我们提出了APPT,这是第一种基于预训练模型的自动补丁正确性评估技术,它采用预训练和微调来解决先前工作的上述局限性。我们首先采用大型预训练模型作为编码器堆栈来提取代码表示。然后,我们使用双向LSTM层来捕获有缺陷的代码段和修补的代码段之间的丰富依赖信息。最后,我们构建了一个深度学习分类器来预测补丁是否过拟合。APPT仅将源代码标记视为输入,并使用训练有素的编码器堆栈自动提取代码特征,从而消除了对代码感知特征和手动设计特征的需求。尽管APPT在概念上是通用的,可以建立在各种预训练模型上,但我们已经将APPT实现为基于BERT模型的实用APCA工具。我们在1183个Defects4J补丁上的实验结果表明,APPT将最先进的CACHE技术提高了3.6%的准确率、1.2%的准确度、4.8%的召回率、2.9%的F1评分和3.1%的AUC。我们对来自五个不同补丁基准的49694个真实世界补丁进行了额外调查,结果表明,APPT在准确性、精确度、召回率、F1得分和AUC指标方面超过了99%,优于现有的表示学习技术。我们还采用不同的预训练模型来进一步研究APPT的泛化能力。结果表明,具有先进预训练模型的APPT可以提高预测性能。例如,当配备GraphCodeBERT时,APPT的精确度和召回率可以提高3.0%和2.6%,比最先进的CACHE技术高4.2%和7.2%。

综上所述,我们做出了以下主要贡献:

•新方向。本文为补丁正确性预测开辟了一个新的方向,即通过预训练和微调直接利用大型预训练模型。与现有的基于学习的APCA技术相比,我们的方法不需要任何额外的努力来设计和提取复杂的代码特征。

•新技术。我们提出了APPT,这是一种基于BERT的APCA技术,它利用预训练和分类器来预测补丁的正确性。据我们所知,我们是第一个利用微调预训练模型来评估补丁正确性的人。

•广泛研究。我们进行了各种实证研究,以调查和评估不同斑块基准上的APPT。结果表明,APPT的整体性能明显优于现有的基于学习和传统的APCA技术。

•可用工件。我们发布了实验中使用的相关材料(包括源代码、补丁和结果),用于复制和未来的研究。

2 背景

2.1 APR

APR技术的主要目标是自动识别和修复程序错误。图1展示了典型APR技术的工作流程,通常由三个步骤组成:(1)定位短语使用现成的故障定位技术来识别可疑的代码元素(例如语句或方法)[21],[22];(2) 然后,修复短语根据一组转换规则修改这些元素,以生成各种新的程序变体,也称为候选补丁;(3) 验证短语采用原始测试用例作为oracle来检查候选补丁是否按预期执行。具体来说,通过原始测试用例的候选补丁称为可信补丁。语义上与开发人员补丁等效的合理补丁表示正确补丁;否则,这是一个过度拟合的补丁。

由于实践中程序行为的规范薄弱,确保合理补丁的正确性从根本上来说是具有挑战性的。现有的研究表明,手动识别过拟合补丁是耗时的,可能会损害开发人员的调试性能[10],[23]。因此,已经提出了各种技术来自动验证补丁的正确性。根据是否需要动态执行或机器学习[13],我们将其分为三大类:基于静态的技术、基于动态的技术和基于学习的技术。

•基于静态的APCA技术。这些技术旨在通过静态代码特征(如代码删除程序转换)将正确的补丁优先于过拟合的补丁。

•基于动态的APCA技术。这些技术旨在通过执行基于修复或修补程序生成的额外测试用例来过滤出过拟合的补丁。根据是否需要正确的补丁,这些技术可以进一步分为基于oracle的动态补丁和不基于oracle的静态补丁。

•基于学习的APCA技术。这些技术旨在预测通过机器学习技术增强的合理补丁的正确性。他们通常提取手动设计的代码特征,然后采用分类器进行补丁预测[18]。提出了一些采用代码嵌入技术自动提取代码特征的技术[20],也称为基于表示学习的APCA技术。

最近,越来越多的研究工作试图使用机器学习技术从现有的补丁基准中学习,以预测潜在的补丁正确性,取得了有希望的结果。在这项工作中,我们采用大型预训练模型(即BERT)对合理的补丁进行编码,并训练一个深度学习分类器来预测补丁的正确性。与现有技术相比,我们的论文是第一篇通过预训练和微调预训练模型来预测补丁正确性的工作。

2.2 预训练模型

最近,预训练的语言模型(如BERT)在广泛的自然语言处理(NLP)任务中显著提高了性能,如机器翻译和文本分类[24]-[26]。通常,这些模型经过预训练,通过对大规模未标记数据进行自监督训练来推导通用语言表示,然后通过对有限数据注释进行微调来转移到多个下游任务中。

现有的预训练模型通常采用编码器-解码器架构,其中编码器将输入序列编码为固定长度的向量表示,解码器根据输入表示生成输出序列。

仅使用编码器的模型(例如BERT[24])通常预先训练一个双向transformer,其中每个令牌可以相互关注。仅编码器模型擅长理解任务(例如代码搜索),但它们的双向性对于生成任务需要一个额外的解码器,在生成任务中,这个解码器从头开始初始化,无法从预训练任务中受益。

仅解码器模型(例如GPT[25])是使用单向语言建模进行预训练的,该建模只允许token处理前一个token,并自己预测下一个token。纯解码器模型擅长于代码完成等自回归任务,但单向框架对于理解任务来说不是最优的。

编码器-解码器模型(例如T5[26])通常使用去噪预训练目标,这些目标会破坏源输入并要求解码器恢复它们。与有利于理解和自回归任务的仅编码器和仅解码器模型相比,编码器-解码器模型可以支持代码摘要等生成任务。在这项工作中,我们将补丁正确性评估视为一项二元分类任务,并根据现有工作考虑仅使用编码器的模型来获得代码片段的嵌入[27]。

受NLP中预训练模型成功的启发,最近已经采用了许多尝试,用预训练模型(例如GraphCodeBERT)来增强许多与代码相关的任务(例如代码摘要和代码搜索)[28],[29]。尽管取得了可喜的结果,但很少有工作旨在探索预训练模型在支持补丁正确性评估方面的能力。在这项工作中,BERT被选为利用预训练模型进行自动补丁正确性评估,因为它已被广泛应用于各种与代码相关的任务中,并且对分类任务非常有效[28],[29]。还选择了两种先进的BERT风格模型(即CodeBERT和GraphCodeBERT)来研究APPT的泛化能力。

3 方法

图2显示了我们方法的总体框架。通常,APPT接受一个有缺陷的程序和一个看似合理的补丁,该补丁将可用的测试用例作为输入。APPT提取有缺陷的代码片段及其相应的修补代码片段,并采用四种策略截断代码token。然后,APPT使用预训练的BERT模型来嵌入截断的token。在获得有缺陷和修复的代码片段的表示后,APPT使用四个预定义的函数来集成表示。最后,APPT采用深度学习分类器返回最终结果(即正确或过拟合)。

3.1 代码提取(将缺陷代码和修复代码片段转换成token形式)——对应train.py前4个方法

给定一个有缺陷的程序,现有的APR工具可能会返回一个通过所有可用测试用例的合理补丁p(如果存在)。代码提取阶段旨在将返回的补丁和有缺陷的程序作为输入,并输出相应的有缺陷和已修补的代码token(如图2(a)所示)。

具体来说,我们通过解析补丁文件来获得有缺陷和补丁的代码片段(即Cb和Cp)。首先,我们选择删除和添加的行作为错误行和修补行,分别标记为“+”和“-”。其次,为了保留关于合理补丁的上下文信息,我们在每个代码片段中保留不变的行(即,开头没有“+”和“-”)。最后,有缺陷(或修补)的代码片段由有缺陷(修补)的行和公共上下文部分组成。

我们将有缺陷(或修补)的代码片段视为token序列,并在token代码片段时利用子词标记化方法将标识符进一步分解为子标记,从而解决词汇表外(OOV)问题[30]。在这项工作中,我们保留了原始的标记化词汇表,而不是使用字节对编码(BPE)算法构建新的词汇表,因为我们希望APPT继承自然语言理解能力,并从一个良好的初始点开始学习预测。

在提取出有缺陷(或修复)的代码token后,我们试图将它们作为token嵌入短语的输入。然而,预训练模型通常仅限于特定的输入长度。例如,BERT最多只能接收512个令牌的输入序列。我们进一步截断了标记化后长度大于512的输入。根据现有的工作[31],我们使用不同的方法来截断方法对。

•仅限head:将前512个令牌保留在Cb和Cp中。

•仅尾部:将最后512个令牌保留在Cb和Cp中。

•仅中间:在Cb和Cp中选择中间的512个令牌。

•混合:选择Cb和Cp中的前256个和后256个令牌。

在我们的实验中,我们默认使用head only方法截断代码token。我们还在第5.3.2节中讨论了不同截断方法的影响。最后,基于Cb和Tp提取有缺陷和修补的代码token(即Tb和Tp),以适应BERT的最大长度限制。

3.2 token嵌入(使用BERT将缺陷代码/修复代码token编码成嵌入向量形式)——未找到代码对应部分

token嵌入阶段将有缺陷(或修复)的代码token(即Tb或Tp)作为输入,并将其嵌入到有缺陷(或称修复)的向量(即Eb或Ep)中作为输出(如图2(b)所示)。APPT实现了一个由12层编码器块组成的堆栈,以提取代码段的隐藏状态。每个编码器块由三个组件组成。第一部分是一个多头自注意力层,用于学习输入代码token中的远距离依赖关系。第二部分是一个简单的、位置智能的全连接前馈神经网络,它可以对token嵌入进行线性变换,以获得更好的特征提取。第三部分是围绕每个组件的残差连接,然后进行层归一化,以确保代码token嵌入分布的稳定性。

特别是,自注意力机制通过考虑代码token之间的位置关系来计算每个代码token的表示。自注意力机制主要依赖于三个主要向量,即查询Q、键K和值V,通过将查询和一组键值对映射到输出向量。我们采用缩放的点积自注意力,通过计算所有查询向量Q和键向量K之间的点积来计算每个token的注意力得分。然后使用softmax函数将注意力得分归一化为概率,以获得注意力权重。最后,可以通过在值向量V和注意力权重向量之间取点积来更新值向量V。使用三个矩阵Q、K和V计算自注意力操作,如下所示:

为了捕捉输入代码token更丰富的语义含义,我们进一步使用多头注意力机制来实现自注意,这使得模型能够在不同位置联合处理来自不同代码表示子空间的信息。对于d维Q、K和V,我们将这些向量分成h个头,每个头都有d/h维。在所有的自注意操作之后,每个头部将再次连接起来,以馈入一个全连接的前馈神经网络,该网络包括两个线性变换,中间有一个ReLU激活。多头机构可以用以下方程式概括:

3.3 补丁分类(将2个嵌入向量合并成一个,并使用深度学习分类器进行补丁正确性预测)

在编码器堆栈提取出有缺陷和补丁代码片段的嵌入向量(即Eb和Ep)后,补丁分类阶段首先将这两个向量整合到一个输入向量(即Econ)中,然后采用深度学习分类器自动预测补丁的正确性(如图2(c)所示)。

3.3.1 表达集成

给定两个n维的向量Eb和Ep,分别表示有缺陷和修复的代码片段,我们将这两个向量整合到一个代码更改向量中,用于补丁分类。详细地说,我们利用不同的方法来整合它们,从不同的方面来表征Eb和Ep之间的差异,例如向量级联运算E con、元素加法运算E add、元素减法运算E sub、Hadamard积Epro。我们还试图通过连接上述积分向量E mix来捕捉两个向量之间的交叉特征。选择整合方法是因为它们在之前的研究[12]、[32]中取得了有前景的结果,这些研究如下:

(1) E con是Eb和Ep在2n维向量级上的级联运算(即E con=Eb⊕Ep)。

(2) E add是Eb和Ep在n维元素级上的加法运算(即E add=Eb+Ep)。

(3) E sub是n维元素级上Eb和Ep之间的减法运算(即E sub=Eb−Ep)。

(4) E pro是n维元素水平上Eb和Ep之间的Hadamard积运算(即Esub=Eb⊙Ep)。

(5) E mix是E con、E add、E sub和E pro在矢量级上的串联,具有5n维(即Emix=E con⊕E add⊕E sub⊕E sub)。

3.3.2 LSTM堆栈(将整合后的向量输入到2个双向LSTM网络中)

在提取了已更改代码token的嵌入向量(例如Econ)后,APPT旨在基于深度学习分类器确定给定补丁的正确性。为了提取更多隐藏的代码变化特征,我们进一步将代码变化向量馈送到长短期记忆(LSTM)堆栈中。LSTM堆栈有两个双向LSTM层,其输出是通过一次连接两个方向的隐藏状态而生成的新状态。LSTM是一种专门的循环神经网络(RNN),用于模拟序列的长期依赖性。一个普通的LSTM门单元由一个细胞、一个输入门、一个输出门和一个遗忘门组成。得益于门控机制,LSTM非常适合提取包含token顺序依赖关系的上下文语义特征,并已广泛应用于各种任务,如漏洞检测[33]、故障定位[34]和自动程序修复[35]。

在APPT中,LSTM堆栈通过计算网络门单元激活来计算从输入码变化向量x=(x1,…,xT)(例如E con)到输出向量z=(z1,…,zT)的映射。我们通过利用输入门和遗忘门来控制单元状态的传播,从而实现门控机制。具体而言,当更新单元状态时,输入门决定将当前输入中的哪些新信息包含在单元状态中(即,方程式3),遗忘门决定将哪些信息从单元状态中排除(即,等式4)。基于新的和遗忘的信息,可以更新作为LSTM单元存储器的细胞状态(即方程5)。然后,输出门通过输出门的逐点乘法来确定下一个隐藏状态的值(即方程式6)。最后,当前电池状态的值通过tanh函数(即方程7),通过该函数计算LSTM堆栈的输出(即方程8)。

其中,W项表示权重矩阵(例如,Wix是从输入门到输入的权重矩阵),b项表示偏置向量(例如,bi是输入门偏置向量),而⊙表示向量的逐元素乘法。

3.3.3 分类器(二元分类器,预测生成补丁的正确性)

在计算完所有LSTM迭代后,将更改后的代码token的嵌入向量进一步馈送到设计的深度学习分类器中,以预测补丁的正确性。分类器由两个全连接层和一个二元预测器组成。在APPT中,我们应用标准的softmax函数来获得正确性的概率分布。如果补丁正确的概率大于不正确的概率,则标记为正确;否则,它被认为是过拟合。

特别是,对于补丁p,z表示LSTM堆栈中最后一次迭代的输出,该输出进一步线性转换为实数,如方程9所示,其中W∈R^(d×1),b∈R,n表示类的数量(即正确和过拟合)【也就是有两个类】。然后,我们利用softmax函数将补丁p的输出归一化,如方程10所示,其中s表示模型预测的补丁p的正确或过拟合概率。

3.4 训练

为了训练网络,我们计算损失,根据其预测结果和基准值更新神经权重。我们使用交叉熵损失,它已被广泛应用于一些分类任务和补丁预测研究[20],[36]。特别地,gi∈{0,1}表示第i个补丁是正确的还是过拟合的。交叉熵损失以对数和指数方式将目标gi与预测s进行比较。目标函数在方程11中计算,在训练中不断最小化,以更新我们模型中的参数。

我们采用dropout技术来提高APPT的鲁棒性,并采用Adam方法[37]来优化目标函数。

4 实验

4.1 研究问题

实证研究旨在回答以下研究问题。

RQ1:APPT与现有的基于表示学习的APCA技术相比表现如何?

RQ2:APPT与现有最先进的传统和基于学习的APCA技术相比表现如何?

RQ3:不同的选择在多大程度上影响了APPT的整体有效性?

RQ3.1:token截断选择在多大程度上影响了APPT的整体有效性?

RQ3.2:向量连接选择在多大程度上影响了APPT的整体有效性?

RQ3.3:预训练模型的选择在多大程度上影响了APPT的整体有效性?

RQ1旨在将APPT与16种表示学习技术进行比较,以探索APPT在多大程度上优于这些技术,包括Tian等人[12]的五种表示方法(BERT、code2vec、code2seq、Doc2Vec和CC2Vec)乘以三个分类器(决策树、逻辑回归和朴素贝叶斯),以及Lin等人[20]的最新技术CACHE。

RQ2旨在通过将其与动态和静态技术进行比较来研究APPT的有效性。我们的研究还评估了最新的基于学习的APCA技术ODS。

RQ3侧重于APPT的影响分析,并进一步细化为三个子RQ。RQ3.1详细探讨了四种token截断选择如何影响APPT的有效性。RQ3.2探讨了五种向量级联方法如何影响APPT的有效性。RQ3.3用高级CodeBERT和GraphCodeBERT替换BERT,以研究预训练模型对APPT有效性的影响。

4.2 数据集(小数据集、大数据集)

随着过去几十年APR研究的快速发展,提出了广泛的修复技术[38]-[40],导致许多基准测试中发布了越来越多的补丁[7],[13]。大规模补丁基准测试使基于深度学习的预测技术能够学习正确和过拟合补丁的分布,以进行补丁正确性评估。在这项研究中,我们采用了基于最近研究[12]、[13]、[20]的两个补丁数据集,一个小的包含1183个Defects4J标记补丁,一个大的包含50794个真实世界标记补丁。

在小数据集上,我们主要关注Defects4J[56]发布的补丁,这是APR研究中使用最广泛的基准[7]。我们选择了最近两项大规模研究发布的基准,即Wang等人[13]和Tian等人[12]。具体来说,第一个基准[13]包括Liu等人[7]、Xiong等人[17]和Defects4J开发人员[56]提供的标记补丁。第二个基准[12]包括Liu等人[7]的标记补丁,并考虑了Liu等人[7]中未包含的一些知名APR工具生成的补丁,以更好地探索过拟合问题,即JAID[48]、SketchFix[49]、CapGen[43]、SOFix[53]和SequenceR[55]。为了避免两个基准测试中的数据泄漏问题,还进行了过滤过程以丢弃重复的补丁。特别是,给定一个所有空格都被删除的补丁,将左侧文本信息与其他补丁的文本信息进行比较。如果两个补丁的文本信息相同,则被视为重复,在我们的小数据集中有1183个补丁【数据规模】。这些补丁由22个不同的APR工具生成,可分为四类,即基于启发式、基于约束、基于模板和基于学习的技术。表1列出了这些涵盖的APR工具的详细信息,其中第一列列出了四种修复技术类别,第二列列出了相应的修复技术。

在大数据集上,我们进一步考虑了从其他基准生成的各种补丁,以评估APPT的通用性。最近,现有的研究表明,APR技术在可修复性方面可能会过拟合Defects4J[6],[11]。因此,已经进行了一些其他基准测试来评估APR技术的性能,如Bugs.jar[58]、IntroclassJava[59]、BEARS[60]和QuixBugs[61],为大型数据集提供了大量补丁。在这项工作中,我们考虑了最近一项研究[20]发布的大型补丁数据集,以研究APPT的普遍性。大型补丁数据集包括RepairThemAll框架[6]和ManyStuBs4J[57]提供的标记补丁。特别是,RepairThemAll框架[6]包含使用11个基于Java测试套件的修复工具的64293个补丁和来自五个不同基准的2141个缺陷。然而,存在一个不平衡的数据集问题,因为超过98.6%的生成补丁(63393/64293)实际上被标记为不正确。最近的研究表明,在研究基于深度学习的预测技术时,一个平衡的数据集是必不可少的[12],[18]。为了弥补正确补丁的不足,大型补丁数据集包括ManyStuBs4J[57],它提供了从1000个流行的开源Java项目中挖掘出的简单缺陷修复更改。错误修复更改是对现实世界错误的正确修复尝试,因此在我们的实验中被认为是正确的补丁。最后,通过丢弃重复的补丁并过滤来自小型学生编写的编程作业(例如IntroClassJava)的补丁,从RepairThemAll框架和ManyStuBs4J构建了一个大型的平衡补丁数据集。该数据集涉及在RepairThemAll框架和ManyStuBs4J上生成的所有可用补丁,经过重复数据删除后,共有49694个补丁【数据规模】。

两个数据集的统计数据如表2所示。表2有两个主要行,代表两个数据集,每个数据集有三个子行。第一和第二子行列出了相应数据集中的两个源。第三列列出了我们实验中使用的两个来源的过滤补丁。我们还展示了最后三列中正确、过拟合和总补丁的数量。

0

4.3 基准

文献中提出了各种APCA技术来验证补丁的正确性。根据现有的研究[17]、[20],我们试图选择为Java语言设计的最先进的技术,因为Java是APR社区中最具针对性的语言[7],而现实世界中的错误补丁通常可以在Java语言中找到[12]。我们首先考虑王等人[13]最近的实证研究,以确定现有的APCA技术。然后,我们选择了王等人[13]中未包含的最新高级研究[12]、[20]。

一般来说,根据现有的工作[13]、[20],现有的APCA技术可以根据是否需要执行测试或采用深度学习技术(如第2节所述)分为静态、动态和基于学习的APCA方法。同时,根据是否需要基准补丁,它们可以进一步分为两类(即有或没有oracle)。特别是,与我们提出的方法APPT类似,CHCHE和嵌入学习技术采用表示模型来嵌入更改的代码,并采用深度学习分类器来预测补丁的正确性。这些技术可以进一步被视为表示学习APCA技术。

所选APCA技术的详细信息如表3所示。第一列列出了三个APCA类别。第二列和第三列列出了是否配备了oracle信息。我们还在浅灰色框中列出了表示学习技术(例如APPT)。我们将所选技术总结如下。

4.3.1 基于动态的自动补丁正确性评估技术

基于动态的技术旨在根据原始或生成的测试用例的结果或执行轨迹,将正确补丁与过拟合补丁区分开来。

简单测试生成。由于现有测试用例的充分性不足,过拟合问题在修复过程中很普遍。因此,研究人员使用测试用例生成工具根据修复程序生成额外的测试用例,并检查通过原始测试用例的生成补丁是否可以通过额外的测试用例[23],[66]。在这项工作中,我们采用Evosuite[15]和Randoop[16]作为测试用例生成工具,因为它们在之前的研究中得到了广泛的研究。

DiffTGen。Xin等人[62]通过执行外部测试生成器(即Evosuite)生成的测试用例来识别过拟合补丁。与随机生成测试用例的简单测试生成不同,DiffTGen生成测试用例以揭示修复程序和缺陷程序之间的语法差异。如果修复程序的输出与正确程序的输出不同,则合理的修补程序被视为过拟合。DiffTGen需要一个人工编写的补丁作为参考,并要求为开发人员提供适合人类的测试信息,以便为生成的测试用例提供神谕。

Daikon。Daikon是一种基于oracle信息不变的程序的动态技术。杨等[63]采用程序不变量来探索过拟合和正确补丁之间的差异。如果一个补丁的推断不变量和基准值的不变量相同,则认为它是正确的。如果存在不同的比较,则认为补丁过拟合。

PATCH-SIM。Xiong等人[17]认为,在有缺陷的程序和修补程序上通过测试的执行轨迹可能相似,而在有缺陷程序和修补的程序上测试失败的执行轨迹则可能不同。基于这一概念,它们在没有oracle信息的情况下,基于执行跟踪来近似补丁的正确性。PATCH-SIM采用Randoop生成额外的测试用例来收集动态执行信息。在这项工作中,我们还用Evosuite取代了Randoop,以全面探索测试生成技术(表示为E-PATCH-SIM)的影响。

Opad。Yang等人[67]采用模糊测试来生成新的测试用例,并使用两个测试oracles(crash和memory-safety)来增强补丁的有效性检查。Opad的原始实现不是为Java语言设计的,而是使用美国Fuzz-Lop(AFL)作为模糊技术。在这项工作中,根据最近的研究[13]、[20],我们用Randoop和Evosuite替换AFL,在Java程序上生成新的测试用例,并将其分别表示为R-Opad和E-Opad。

4.3.2 基于静态的自动补丁正确性评估技术

基于静态的技术通常采用静态分析工具来提取一些设计的静态特征,然后根据这些特征检查补丁的正确性。

ssFix。ssFix[64]是一种基于静态的技术,它利用基于token的语法表示来生成具有更高正确概率的补丁。ssFix首先执行语法代码搜索,从与错误上下文语法相关的代码库中查找代码片段,以生成正确的补丁,然后根据修改类型和修改大小对补丁进行优先级排序。

CapGen。Wen等人[43]提出了嵌入AST节点及其周围代码中的上下文信息的三个方面(即谱系上下文、变量上下文和依赖上下文),以优先考虑正确的补丁而不是过拟合的补丁。在这项工作中,根据最近的研究[13]、[20],我们提取了三个上下文信息作为静态特征来研究补丁正确性评估。

反模式。Tan等人[14]定义了一组规则,这些规则基本上捕获了对有缺陷程序的不允许修改,如果补丁落入这些规则中,则属于过拟合。最近的一项研究[13]表明,手动定义的反模式可能会对正确的补丁产生误报,从而在补丁正确性预测中产生破坏性影响。

S3。Le等人[65]假设一个正确的补丁在语法和语义上通常接近有缺陷的代码片段。因此,他们采用六种句法特征(即AST差分、余弦相似性和变量和常量的局部性)和语义特征(即模型计数、输出覆盖率和反模式)来衡量候选补丁和有缺陷的代码片段之间的距离。

4.3.3 基于学习的自动补丁正确性评估技术

基于学习的技术可以基于机器学习技术预测一个合理的补丁是否正确。

ODS。Ye等人[18]首先在抽象语法树级别提取202个代码特征,然后使用监督学习自动学习概率模型。结果表明,ODS可以以更快的速度实现比基于动态的技术PATCH-SIM更好的预测性能。

CACHE。Lin等人[20]提出了一种上下文感知的APCA技术CACHE,该技术同时考虑了更改后的代码段和相关的未更改代码段。CACHE首先将修补的代码片段解析为AST表示,然后利用AST路径技术捕获结构信息。

随机森林。Wang等人[13]研究了采用深度学习模型基于八个静态特征(ssFix的两个、S3的三个和CapGen的三个)预测补丁正确性的有效性。为了整合静态特征,采用了六种广泛使用的分类模型(包括随机森林、决策表、J48、朴素贝叶斯、逻辑回归和SMO)。结果表明,随机森林可以实现更高的准确率和召回率。在这项工作中,在现有工作[20]的基础上,我们还采用随机森林来预测基于集成静态特征的补丁正确性。

嵌入学习。Tian等人[12]提出利用表示学习技术为有缺陷和补丁的代码片段生成嵌入,然后采用监督学习分类来预测补丁的正确性。特别是,评估了九种表示学习APCA技术,涉及三种嵌入技术(即CC2vec、BERT和Doc2Vec)和三种分类器(逻辑回归、决策树和朴素贝叶斯)。

4.4 模型选择(大模型BERT)

据我们所知,APPT是第一种通过微调现有预训练模型来自动预测补丁正确性的技术。在本文中,我们采用BERT作为编码器栈,因为它在之前的工作中具有强大的性能[24]。

具体来说,BERT是在大量文本数据上进行预训练的,具有两个自我监督目标,即掩码语言建模(MLM)和下一句预测(NSP)。MLM旨在让模型通过随机屏蔽每个句子中15%的单词来预测被屏蔽的单词。NSP旨在通过让模型预测给定的句子对是否连续,进一步提高模型理解两句话之间关系的能力。然后,该模型可以进行微调以适应一些特定的下游任务,并在各种自然语言处理任务上取得了显著的最新成果,如问答和语言推理。

存在两种不同规模的模型架构,即BERT base和BERT large[24]。前者有12层和12个注意力头,嵌入大小为768,而后者有双倍层数和16个注意力头。嵌入大小改为1024。在本文中,我们不修改词汇量,而是使用预训练的BERT base作为微调起点,而不是从头开始。

在本文中,APPT在概念和实践上可推广到各种预训练模型。我们还选择CodeBERT和GraphCodeBERT作为编码器堆栈来评估APPT的可扩展性。CodeBERT和GraphCodeBERT与BERT共享相同的模型架构,同时利用成对的自然语言和编程语言对模型进行预训练,以支持与代码相关的任务(如第8.2.2节所述)。

4.5 评估指标

我们通过准确性、精确度、召回率、F1评分和AUC指标来评估各种APCA方法的预测性能,这些指标已被广泛应用于补丁正确性评估研究和其他分类任务[12]、[20]。考虑到真阳性(TP,TP指的是被识别为过拟合的过拟合补丁)、假阳性(FP,FP指的是正确的,被识别为过度拟合的补丁)、伪阴性(FN,FN指的是过拟合补丁被识别为正确)和真阴性(TN,TN指的是识别为正确的正确补丁)的数量,度量定义如下:

准确性:正确报告的补丁(无论补丁是否正确)的比例。准确性衡量APCA技术预测正确的概率。

精度:实际过拟合补丁与报告的过拟合补丁的比例。精度衡量的是当APCA技术预测补丁过拟合时,我们可以信任它的程度。

召回率:报告的过拟合补丁占所有实际过拟合补丁的比例。Recall衡量APCA技术在数据集中找到所有过拟合补丁的能力。

F1分数:精确度和召回率的两倍乘以二者之和。F1分数通过取调和平均值来衡量精确度和召回率之间的权衡。

AUC:整个受试者工作特性曲线下方的整个二维区域。AUC测量分类器将随机选择的过拟合补丁的排名高于随机选择的正确补丁的概率。澳高,APCA技术在预测实际过拟合补丁为过拟合和实际正确补丁为正确方面就越好。

其中M和N表示过拟合和正确补丁的数量,而Poverfitting和Pcorrect表示过拟合与正确补丁的预测概率。

4.6 实现细节

我们所有的方法都是基于PyTorch框架构建的。在我们的工作中,我们使用了BERT的Hugging Face实现版本。考虑到之前的工作建议[26]、[40],我们使用“BERT base uncased”(参见BERT base)作为初始点,因为基本版本在实践中非常轻量级,与大版本相比具有相当的有效性。在“bert-base-uncased”模型中,存在12层transformer块和12个自注意力头。优化器是Adam[37],学习率为5e-5。批大小为16,dropout率为0.5。我们训练了最多50个epoch,由于模型限制,输入的最大长度设置为512。

我们方法的所有训练和评估都是在一台Ubuntu 18.04.3服务器上进行的,该服务器配备了两个Tesla V100-SXM2 GPU。

5 结果和分析

5.1 RQ1:基于表示学习的APCA技术进行比较

5.1.1 实验设计

如第4.3节所述,APPT、CACHE和嵌入学习技术(即表3中浅灰色框内的技术)可归类为表示学习APCA技术。在本节中,我们旨在探讨与这些表示学习技术相比,APPT的性能。特别是,嵌入学习技术[12]主要采用嵌入模型(即BERT、Doc2Vec和CC2Vec)来嵌入有缺陷和补丁的代码片段,然后训练分类模型(即决策树、逻辑回归和朴素贝叶斯)来预测补丁的正确性。在之前的研究[20]之后,我们还在实验中考虑了两个额外的嵌入模型(即code2vec和code2seq)。同时,CACHE也可以被视为一种表示学习技术,它在嵌入代码变化时结合了上下文信息,并训练了一个深度学习分类器来预测补丁的正确性。

在我们的实验中,总共考虑了16种表示学习技术,包括五种嵌入技术乘以三个分类模型【15种】,以及一种上下文感知表示学习技术CACHE。根据之前的研究[12],我们对小型和大型数据集进行了5折交叉验证以进行比较。

5.1.2 结果

表4至表5给出了小型和大型数据集与现有表示学习技术的比较结果。第一列列出了三个分类器,第二列列出了五种嵌入方法。其余列分别列出了准确度、精确度、召回率、F1得分和AUC指标的详细值。我们在表4和表5的底部展示了最新的表示学习工作CACHE和我们的APPT。可以观察到,APPT在每种实验设置下都达到了最佳性能。

在小数据集上,就所有指标而言,APPT比最先进的CACHE技术高出约3.6%、1.2%、4.8%、2.9%和3.1%(即准确率为79.0%对75.4%,精确度为80.7%对79.5%,召回率为81.3%对76.5%,F1评分为80.9%对78.0%,AUC为83.4%对80.3%)。与所有表示学习技术相比,APPT在准确性、精确度、F1分数和AUC指标方面表现最佳。特别是,APPT在准确度和精密度指标上的值分别为79.0%和80.7%,而所有其他技术的最佳值分别为75.4%和79.5%。这表明APPT通常可以实现最准确的预测,并且APPT识别为过拟合的补丁具有很高的过拟合置信度。关于召回率,CC2vec和code2vec的值有时会超过APPT的值,因为它们倾向于将大多数补丁归类为过拟合(例如。,CC2vec使用朴素贝叶斯将1183个补丁中的1051个分类为过拟合,从而实现了94.6%的高召回率)。然而,这些技术实现了相对较低的精度(例如,具有朴素贝叶斯分类器的CC2vec的召回率仅为72.2%)。相反,APPT可以实现超过81%的高召回率,同时保持79.5%的高准确率。

在大数据集上,我们可以发现APPT在五个指标上达到了99%以上,优于所有现有方法。例如,就AUC而言,APPT达到99.9%,比最新技术CACHE获得的第二高值(即98.9%)高1.0%。这表明APPT比CACHE更能区分正确和过拟合的补丁。此外,与CACHE相比,准确性、精确度、召回率和F1得分指标的改进分别达到0.5%、0.3%、0.9%和0.5%。我们还发现,在大数据集上实现的性能通常高于在小数据集上获得的性能。例如,五个指标的平均值从81.06%增加到99.26%,从而提高了22.5%。根据我们对这两个数据集的分析,这种改进的可能原因是大型数据集上的错误通常很简单。我们观察到,大数据集上的所有ManyStuBs4J补丁都是单行操作,而小数据集上补丁通常跨越多行(例如,超过40%的Defects4J开发者补丁是多行补丁[20])。神经网络很容易学习这种简单代码更改的正确性分布。同时,两个数据集之间补丁尺度的差异可能是第二个原因。我们发现大数据集上存在49694个补丁,是小数据集的42倍。训练数据量通常是决定神经网络性能的最主要因素[68]。更多可用的补丁有利于神经网络更好地学习各种代码变化。

RQ1的答案:总体而言,我们对表示学习技术的分析表明:(1)在所有指标和数据集下,APPT的表现都优于最先进的表示学习技术CACHE。(2) 在小数据集上,APPT的准确率达到79.0%,AUC达到83.4%,分别比CACHE高出3.6%和3.1%。(3) 在大型数据集上,APPT在所有指标上都超过了99%,但现有的表示学习技术都没有达到这一点。

5.2 RQ2:传统的和基于学习的APCA技术进行比较

5.2.1 实验设计

在本节中,我们的目的是进一步比较所提出的方法APPT与现有的APCA技术。我们选择第4.3节中提到的其余技术(RQ1中讨论的表示学习技术除外)。实验中总共考虑了14种APCA技术,包括四种静态技术(反模式、ssFix、CapGen和S3)、八种动态技术(Evosuite、Randoop、DiffTGen、Daikon、R-Opad、E-Opad、PATCH-SIM和EPATCH-SIM)和两种学习技术(随机森林和ODS)。

由于运行所有技术(特别是动态和学习技术)都很耗时,在现有工作[20]之后,我们重用了最近工作[13]、[18]、[20]中发布的结果。我们从Lin等人[20]那里收集了所有选定APCA技术的详细结果,这些结果是基于902个补丁(即表2中的Wang等人[13])和10折交叉验证得出的。为了与所有最先进的技术进行公平的比较,我们在相同的实验环境中进行了实验。

5.2.2 结果

实验结果列于表6中。前两列列出了所选的技术及其相应的类别。其余列列出了准确度、精确度、召回率和F1分数指标的详细值。

与传统的基于动态和基于静态的APCA技术相比,我们可以发现APPT在准确性、召回率和F1得分方面分别达到了90.4%、96.0%和93.6%。具体来说,APPT在三个指标上取得了最佳的整体性能,之前的技术都没有超过90%。至于精度,APPT报告的补丁中有91%以上确实是过拟合补丁,这比所有基于静态的技术和三种基于动态的技术(即Daikon、PATCHSIM和e-PATCH-SIM)都要好。尽管一些动态测试用例具有更高的精度值,但生成额外的测试用例和收集运行时信息很耗时。更重要的是,这些技术的召回率通常较低(例如,R-Opad的召回率为10.3%),或者需要基准预言(例如,Evosuite和Randoop技术),这限制了这些技术在实践中的应用。

与基于学习的技术相比,我们发现APPT在所有四个指标上仍然比最先进的技术ODS表现更好(准确率分别为90.4%和88.9%,精确度分别为91.5%和90.4%,召回率分别为96.0%和94.8%,F1分数分别为93.6%和92.5%)。总体而言,对随机森林和ODS的改善达到4.5%~17.9%和1.1%~1.5%。考虑到ODS在AST级别提取数百个手动设计的代码特征的成本很高,我们的方法——简单地采用预训练的模型来编码一系列token——甚至更有前景。我们还强调了将代码感知功能(例如代码编辑和AST表示)与预训练模型集成以进行补丁正确性评估的方向。

对RQ2的回答:总体而言,我们的比较结果表明,(1)与现有的基于静态的技术相比,APPT可以实现显著的性能,召回率高达96.0%。(2) APPT的精度比最先进的基于动态的技术PATCH-SIM高8.5%。(3) 与现有的基于学习的技术相比,APPT可以在所有指标中实现最佳性能。

5.3 RQ3:影响分析

5.3.1 实验设计

为了进一步探索不同的微调选择如何影响预训练模型的预测性能,

我们首先考虑并用其他截断方法(如混合、仅中间和仅尾部标记截断)替换仅头部标记截断。

然后,我们采用不同的方法来合并有缺陷的方法向量和修复的方法向量,如连接、加法、减法和乘积运算。我们还将上述合并向量混合作为一种额外的连接方法。最近,在BERT模型架构之后,研究人员使用一些与代码相关的预训练任务来捕捉自然语言和编程语言之间的语义联系,从而进一步使这些预训练模型适应编程语言。因此,我们用两个预先用编程语言训练的高级模型来代替BERT,即CodeBERT[28]和GraphCodeBERT[29]。

5.3.2 RQ3.1 结果:token截断选择的影响

表7显示了不同截断选择下的预测结果。第一列列出了两个数据集。第二列列出了四种截断选项,即仅限头部、仅限中部、仅限尾部和混合。其余列列出了准确度、精确度、召回率和F1score以及AUC指标的详细值。

在小数据集上,我们可以发现,仅头部方法在准确性(79.72%)、精确度(80.84%)、召回率(80.84%)和F1得分(81.76%)方面达到了最佳性能,而混合方法达到了最佳AUC得分(83.43%)。考虑到有缺陷和修补方法中的中间tokens,仅中间方法在所有指标上都取得了第三好的性能,其次是仅尾部方法。在大型数据集上可以观察到类似的性能。例如,仅头部和混合方法在所有指标中都具有最佳性能,而仅中间和仅尾部的方法如下。结果表明,仅头部提取开始代码标记的方法在区分预训练模型的有缺陷和修补的代码片段方面是有效的。

5.3.3 RQ3.2 结果:向量级联选择的影响

表8显示了不同连接选择下的预测结果。第一列列出了两个数据集。第二列列出了五种连接选项,即concat、加法、减法、乘积和混合。其余列列出了准确度、精确度、召回率和F1分数以及AUC指标的详细值。

在小数据集上,虽然概念上很简单,但APPT concat在准确性、精确度、召回率、F1得分和AUC指标方面可以获得79.04%、80.67%、81.34%、80.92%和83.43%,其中四种是所有研究的级联方法中最高的???。APPT product的召回率最高(96.32%),而在其他四个指标上,它的表现比APPT concat差15.77%、18.30%、6.11%和16.97%。APPT addition和APPT subtraction对有缺陷和修补的向量执行加法和减法运算,并且对所有指标都具有相似的性能。同时,应用这些不同的比较函数来表示变化的嵌入向量的混合方法APPT mix可以获得比APPT concat更好的结果,这也与现有的研究结果一致[12],[32]。这些结果表明,通过整合不同的级联方式,预训练模型可以更好地捕获代码变化信息。在大数据集上,APPT concat在准确性、F1得分和AUC指标方面表现最佳,而APPT subtraction和APPT mix分别在精确度和召回率方面表现最佳。性能差异相似,因为这些方法具有相对较高的度量值。例如,APPT concat和APPT mix的所有度量值都高于99%。

5.3.4 RQ3.3结果:预训练模型选择的影响

表9展示了三个预训练模型的预测性能。第一列列出了两个数据集。第二列列出了三个模型,即BERT、CodeBERT和GraphCodeBERT。其余列列出了准确度、精密度、召回率和F1-score以及AUC指标的详细值。

一般来说,所有采用的模型在所有指标上都比最先进的CACHE技术具有更高的性能。例如,在小数据集上,BERT、CodeBERT和GraphCodeBERT的F1得分分别达到80.9%、83.3%和83.5%,分别比CACHE高2.9%、5.3%和5.5%。在大型数据集上也可以观察到类似的改进。这表明模型选择可能不会对性能产生显著影响,经过预训练的模型可以始终如一地达到最先进的性能。

具体来说,为了比较不同预训练模型的性能,我们可以观察到CodeBERT和GraphCodeBert在小数据集上的所有指标都达到了更好的值。这种卓越的性能也适用于大型数据集,其中CodeBERT和GraphCodeBert在指标上具有更好或更具竞争力的性能(例如AUC)。一种可能的解释是,BERT是为自然语言处理任务设计的,而CodeBERT和GraphCodeBERT将源代码视为一系列token或图形表示,然后对源代码进行预训练模型,以支持与代码相关的任务。这表明,尽管NLP中的预训练模型在评估补丁正确性方面可以达到最先进的性能,但针对源代码采用预训练模型可以进一步促进改进。

RQ3的答案:不同选择下的性能表明:(1)对于预训练模型,开始代码token可以很好地表示有缺陷和修复的代码片段;(2) bug和补丁向量的连接比其他方法更能区分更改的代码片段,而不同连接方式的集成可以达到最佳效果。(3) 先进的预训练模型可以提供稳定甚至更好的性能。

6 讨论

6.1 有效性威胁

为了便于复制和验证我们的实验,我们提供了相关材料(包括源代码、训练模型和补丁数据)。尽管如此,我们的研究仍面临一些有效性威胁,如下所述。

对有效性的第一个威胁在于补丁基准。我们专注于具有可再现真实故障的Defects4J数据库,并收集了现有APR工具生成的1183个补丁。然而,补丁基准测试可能不会考虑所有可用的APR工具。为了解决这个问题,根据最新的工作[20],我们纳入了涵盖四类的22个APR工具。值得注意的是,尽管基于学习的类别只包含SequenceR,但它包含73个补丁,这是单个APR工具的最大数量[20]。我们还通过使用多种评估指标来全面评估APCA技术,从而减轻潜在的偏差。此外,我们采用另一个包含49694个真实世界补丁的大型基准来评估所研究技术的泛化能力。总体而言,据我们所知,所使用的补丁基准是补丁正确性评估文献中探索的最大集合。

有效性的第二个威胁是APPT的性能可能无法推广到其他预训练模型。我们在实验中选择BERT,是因为它在最近的代码相关工作中具有强大的性能。然而,尚不清楚在使用其他预训练模型时,我们实验中的结论(在第5节中讨论)是否可以保持不变。我们通过使用CodeBERT和GraphCodeBERT来演示APPT在不同预训练模型下的性能,从而减轻了潜在的威胁。所研究的预训练模型包括与代码相关的模型(如CodeBERT)和特定于自然语言的模型(例如BERT)。我们还依靠两个不同的补丁基准来确保实验结论的普遍性。

对有效性的最后一个威胁是基线的实施。在我们的工作中,我们将APPT与不同类别的各种APCA技术进行了比较。实施这些基线可能会对内部有效性构成潜在威胁。为了减轻这种威胁,在最近的工作[20]之后,我们在相同的设置下进行了实验,并重用了原始工作[12]、[13]、[20]中发布的结果。此外,我们仔细检查重复使用的结果,并公开发布所有材料以供进一步验证。

6.2 与BATS比较

在我们的工作中,继最近的一些APCA工作[12]、[13]之后,我们在实验中比较了30种不同类别的相关APCA技术(即16种基于表征学习的技术、9种基于动态的技术、4种基于静态的技术和2种基于学习的技术)(在第5节中讨论)。据我们所知,所选基线是文献中补丁正确性预测的最大集合。然而,可能存在其他可能使用的技术。例如,最近的BATS[19]根据失败测试用例的相似性预测补丁的正确性,这可以补充最先进的APCA技术。我们在实验中不包括BATS(在第5节中讨论),因为它需要历史测试用例作为搜索类似用例的搜索空间,而我们的数据集中没有类似用例。

然后,我们通过评估BATS中提供的数据集的APPT来进行额外的评估。然而,BATS未能评估一些合理的补丁,因为它只考虑了相似性高于阈值的历史测试用例。例如,阈值为0.8的BATS只能预测8.9%(114/1278)的合理补丁。因此,我们将APPT与阈值为0.0的BATS进行比较,BATS可以对所有补丁进行预测。我们还将APPT与阈值为0.8的BATS进行了比较,因为它在所有阈值中实现了最佳的召回率、F1得分和AUC表现。结果如表10所示。第一列列出了APPT和BATS(阈值分别为0.0和0.8)。第二列列出了预测的补丁数量。每个单元格表示为x(y),其中x是APPT和BATS预测的补丁数量,y是数据集中的补丁总数。其余列列出了指标下的详细性能。我们可以发现,与BATS(阈值设置为0.0)相比,APPT达到了83.39%~85.05%,将指标提高了21.56%~34.58%。当BATS的阈值设置为0.8时,APPT仍然可以将指标平均提高12.40%,同时预测91.1%更合理的补丁。总体而言,结果表明,在预测补丁数量和预测指标方面,APPT的表现优于BATS。

7 含义和指导原则

根据我们实验中的观察结果,我们可以总结出以下基本的实用指南,用于未来的补丁正确性评估研究。

简单的功能可以工作。我们的研究表明,考虑到复杂的代码感知特征(如抽象语法树),将源代码表示为一系列token的APPT的性能甚至优于现有的学习技术(如CACHE)。此外,在这项工作中,token序列已经可以超越手动设计的静态特征(如行号)和耗时的动态特征(如代码覆盖率)。这些观察表明,不应忽视代码序列等简单特征,未来需要进行系统研究,探讨不同代码表示的影响。事实上,应该考虑它们,甚至将其与不同的特征(如数据流图)集成,以设计更先进的补丁正确性评估技术。【未来研究点:使用不同的代码表示技术+数据流图等来提高补丁验证的性能】

训练数据集的质量很重要。我们可以发现,APPT在表6中达到了91.5%的精度,而在表4中精度降低了10.8%。Lin等人[20]也观察到了类似的表现。结果表明,更多的训练数据并不总是能带来更好的补丁正确性评估性能。自动选择代表整个补丁基准的信息量最大的训练集以优化预测精度至关重要。例如,探索补丁数量如何在修复模板中分布,以及如何为每个修复模板选择平衡的补丁,这很有趣。未来还可以开展工作,研究针对预测中的特定bug基准甚至预测中的具体bug类型的训练数据选择方法。【未来研究点:根据特定的缺陷选择特定的训练数据方法】

基于预训练模型的APCA技术需要更多的关注。我们的结果表明,基于BERT的APPT的性能甚至优于最先进的APCA技术。此外,基于CodeBERT和基于GraphCodeBERT的APPT可以进一步提高预测效果。这种观察促使未来的研究人员通过采用不同的预训练模型来研究更先进的APCA技术。例如,通过设计与修复相关的预训练任务来提出特定领域的预训练模型是很有趣的。同时,建议进行彻底的评估,以探索不同的特征(如错误类型和修复模板)如何影响预训练模型在补丁正确性预测中的性能。【未来研究点:使用不同的预训练模型/研究影响预训练模型性能的因素有哪些】

8 相关工作

在本文中,我们采用预训练的语言模型来预测现成的自动化程序修复工具生成的补丁正确性。我们的工作涉及自动化程序修复、补丁正确性评估和预训练模型。我们在第4.3节中介绍了关于补丁正确性评估的现有工作。因此,在本节中,我们将重点讨论自动程序修复技术(第8.1节)和预训练模型(第8.2节)的现有工作。

8.1 APR

在过去的十年中,研究人员提出了各种技术来基于不同的假设生成补丁[1],[69]。根据最近的工作[2]、[7]、[11],我们将它们分为四大类:基于启发式的[38]、[41]、[70]、基于约束的[44]、[45]、[71]、基于模板的[5]、[51]、[52]和基于学习的修复技术[35]、[39]、[40]、[72]。

基于启发式的修复技术。这些技术通常使用启发式算法,通过迭代探索句法程序修改的搜索空间来找到有效的补丁[38]、[41]、[70]。其中,早期提出的GenProg[70]被认为是该领域的一项开创性工作,它使用遗传编程来寻找正确的修复方法。GenProg将候选修复表示为对源代码的编辑序列,并通过测试用例的执行结果对其进行评估。通过更多测试用例的候选对象被认为具有更高的适应度,并被迭代应用于基于变异和交叉操作生成新的候选对象。最近的SimFix技术[42]利用不同项目中现有补丁的代码更改操作和有缺陷项目中的类似代码片段来构建两个搜索空间。然后,上述两个搜索空间的交集进一步用于使用基本启发式方法搜索最终补丁。

基于约束的修复技术。这些技术主要侧重于修复条件语句,它可以修复现有APR方法修复的一半以上的错误[44],[45],[47]。详细地说,这些技术将补丁生成转化为约束求解问题,并使用求解器获得可行的解决方案。例如,Nopol[45]在通过天使修复定位和收集程序的测试执行跟踪来识别补丁的潜在位置后,依靠SMT求解器来解决条件合成问题。其中,ACS[46]改进条件合成成分的排名被认为是最先进的基于约束的修复技术之一[7]。

基于模板的修复技术。这些技术通过设计预定义的修复模板来生成补丁,以使用检索到的供体代码修改有缺陷的代码片段[5]、[51]、[52]。例如,Liu等人[5]通过一项系统研究重新审视了修复模板的修复性能,该研究评估了文献中总结的各种修复模板的有效性。其中,最近的PraPR技术[73]能够分别为148个和43个真实错误生成合理和正确的补丁,这是Defects4J发布时报告修复的最大数量的缺陷。

基于学习的修复技术。这些技术试图修复机器学习技术增强的bug[30],[35],[39],[74]-[76],最近越来越受到关注。例如,Tufano等人[75]广泛评估了神经机器翻译技术在已经发布的技术中从缺陷修复提交生成补丁的能力。Li等人[35]采用基于树的RNN编码器-解码器模型(即DLFix)来学习代码上下文和之前错误修复的转换。Lutellier等人[39]提出了一种新的上下文感知NMT架构(即CoCoNut),它分别表示有错误的源代码及其周围的上下文,以自动修复多种编程语言中的错误。

在我们的实验中,我们从四个类别中选择了22个具有代表性的APR工具(例如SimFix、ACS和SEQUENCER),代表了相应类别中的最先进技术。然后,我们在这些APR技术生成的合理补丁(即通过原始测试用例)上评估APPT。

8.2 预训练模型

我们的方法受到预训练模型在NLP和代码相关任务中的应用的启发。在本节中,我们首先介绍了NLP(第8.2.1节)和SE(第8.2.2节)中关于预训练模型的现有研究。然后,我们讨论了预训练模型在SE中与代码相关的一些任务中的应用(第8.2.3节)。

8.2.1 在自然语言处理中的预训练模型

最近的工作表明,通过在大型文本语料库上进行预训练,然后对特定任务进行微调,许多NLP任务和基准测试都取得了实质性的进展。例如,Devlin等人[24]提出了一种新的语言表示模型BERT,通过在所有层中对左右上下文进行联合调节,从未标记的文本中预训练深度双向表示。为了探索NLP迁移学习技术的前景,Raffel等人[26]通过引入一个统一的框架,将所有基于文本的语言问题转换为文本到文本格式,提出了一种文本到文本的迁移transformer T5。Brown等人[25]提出了一种自回归语言模型GPT-3,该模型没有任何梯度更新或微调,仅通过与模型的文本交互指定任务和少样本演示。

在这项工作中,我们选择BERT将给定的可信补丁编码为固定长度的表示向量作为深度学习分类器的输入,因为BERT在之前的工作中具有强大的性能[77]。

8.2.2 在软件工程中的预训练模型

受预训练模型在NLP中的应用的启发,许多研究人员将预训练模型应用于与代码相关的任务。SE研究人员通常采用NLP中的现有架构,并设计一些代码感知的预训练任务(例如,代码AST预测和双峰双生成)来学习源代码的表示,而不是设计新的网络架构。然后,预训练模型进一步微调到一些与代码相关的多样化任务,如代码-代码(克隆检测、缺陷检测、完形填空测试、代码完成、代码细化和代码到代码翻译)、文本代码(自然语言代码搜索、文本到代码生成)和代码文本(代码摘要)场景。

例如,Feng等人[28]通过掩码语言建模和替换标记检测,提出了一种用于自然语言和编程语言的双峰预训练模型(CodeBERT),以支持代码搜索和代码文档生成任务。Guo等人[29]提出了第一个预训练模型(GraphCodeBERT),该模型利用代码结构来学习代码表示,以提高代码理解任务(即代码搜索、克隆检测、代码翻译和代码细化)。Guo等人[27]提出了UniXcoder,这是一种用于编程语言的统一跨模态预训练模型。UniXcoder利用带有前缀适配器的掩码注意力矩阵来控制模型的行为,并利用AST和代码注释等跨模态内容来增强代码表示。与大多数从头开始预训练大规模模型的研究相比,我们试图在现有的预训练语言模型微调范式的基础上提高补丁正确性评估。

在这项工作中,为了进一步探索APPT的泛化能力,我们选择了其他类似BERT的模型(即CodeBERT和GraphCodeBERT)作为编码器堆栈,因为它们在代码相关任务中具有强大的性能。

8.2.3 在软件工程中预训练模型的应用

除了上述典型的代码相关任务(例如,自动修复错误、注入代码突变体、在测试中生成断言和[78]中的代码摘要)外,研究人员还将预训练模型应用于SE中的一些其他领域(例如,代码完成和程序修复)。

例如,Cinisell等人[77]评估了BERT模型在不同粒度级别(包括单个令牌、一个或多个完整语句)的代码完成任务中的性能。结果表明,该模型取得了优于最先进的n-gram模型的有前景的结果,并且当使用代码抽象时,该模型在某些特定数据集(例如Android)上学习效果更好。Ciborowska等人[79]将BERT应用于错误定位问题,以提高检索质量,特别是在简单的文本相似性不足的错误报告中。最近,Salza等人[80]研究了如何通过预训练和微调基于自然语言和源代码组合的BERT模型,将迁移学习应用于代码搜索。Mashhadi等人。[81]通过在ManyStuBs4J基准上微调CodeBERT,提出了一种新的基于预训练模型的APR技术,并发现该方法为不同类型的错误生成修复代码,与最先进的APR方法相比,其有效性和功效相当。

尽管存在一些受益于预训练模型的SE任务(例如代码审查和错误定位),但在这项工作中,我们首次应用预训练模型来预测自动程序修复中生成的补丁的正确性。

9 结论

在这项工作中,我们提出了APPT,这是一种基于预训练模型和分类器的新型自动补丁正确性预测技术。我们首先采用现成的预训练模型作为编码器堆栈和LSTM堆栈,以增强有缺陷和修补代码片段之间的依赖关系。然后,我们通过两个全连接层和一个标准的softmax函数来构建一个深度学习分类器,以预测补丁是否过拟合。

我们在两个补丁数据集上进行了实验,结果表明APPT明显优于最先进的基于学习的和传统的APCA技术。我们进一步证明了APPT可以推广到各种预训练模型。基于这些观察,提供了一些关于改进现有基于学习的技术(例如,使用简单特征和预训练模型)的启示和指导方针。我们强调了应用预训练模型自动预测补丁正确性的方向。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值