使用深度学习技术增强软件语义可追溯性

I 简介

需求跟踪在软件开发过程中起着至关重要的作用。将需求跟踪定义为“通过持续的细化和迭代,向前和向后描述和跟踪需求生命周期的能力”,可追溯性支持一系列不同的软件工程活动,包括变更影响分析、回归测试选择、成本预测,以及合规性验证。在高可靠性系统中,监管标准,如美国联邦航空管理局(FAA)的 DO178b/c,规定需要在危险、故障、要求、设计、代码和测试用例之间建立和维护跟踪链接,以证明系统使用安全。不幸的是,即使使用工业工具手动创建链接或将其作为开发过程的副产品捕获,跟踪任务也很难执行且容易出错。在实践中,跟踪链接通常是不完整和不准确的,甚至在安全关键系统中也是如此。

为了解决这些问题,研究人员提出并开发了自动创建和维护跟踪链接的解决方案。解决方案包括信息检索方法、机器学习、启发式技术和人工智能群集算法。其他方法,特别是在特征位置领域,需要从运行时执行跟踪获得额外的信息。结果参差不齐,尤其是当应用于工业规模的数据集时,90%以上的可接受召回水平通常只能在极低的精确度水平下实现。

自动化方法的主要原因之一是术语不匹配,这通常存在于相关工件对之间。为了说明这一点,我们从积极的列车控制(PTC)领域的一个例子。PTC 是一种基于通信的列车控制系统,旨在确保列车遵循指令,以防止事故发生。要求“BOS 管理工具集应允许授权管理员查看车载软件的上一次 告版本,包括相关的存储库名称 MD5,以及文件集是首选的还是可接受的。”与设计工件相关联,说明“操作数据面板用于提供有关细分中当前 PTC 操作的信息”。认识和建立这种联系需要对领域概念有非常重要的了解——例如,了解 BOS 管理工具集包含操作数据面板,每个机车包含一个用于 PTC 操作的车载单元,运行数据面板向 BOS 授权管理员显示机车的车载软件版本等信息。向量空间模型(VSM)、潜在语义索引(LSI)和潜在 Direchlet 分配(LDA)等流行的跟踪检索算法很可能会忽略此链接,这些算法都将工件表示为一袋单词,因此会丢失工件的嵌入语义。在不理解概念关联的情况下结合短语的技术也会忽略这一点。事实上,当前大多数技术缺乏推理工件之间语义关联所需的复杂度,因此在术语使用中几乎没有有意义的重叠时,无法建立跟踪链接。

在我们之前的工作中,我们开发了领域上下文化智能可追溯性(DoCIT),作为一种概念验证解决方案,以研究领域知识与跟踪过程的集成。我们证明,对于 PTC 系统域,DoCIT 返回精确的跟踪链接,平均精度(MAP)为 0.822,而使用 VSM 获得的平均精度为 590。然而,为一个领域建立 DoCIT 的成本是不小的,因为它需要仔细地手工制作一个领域本体,并手动定义跟踪链接启发式算法,能够对工件的语义和相关领域知识进行推理。此外,DoCIT 依赖于传统的语法分析器来分析工件以提取有意义的概念。因此,该方法对解析器中的错误、本体中缺少的术语以及缺少或不充分的启发式非常敏感。因此,DoCIT 是有效的,但很脆弱,需要付出巨大的努力才能转移到新的项目领域。

我们提出的方法包括两个主要阶段。首先,我们学习一组单词嵌入领域使用无监督学习方法培训了大量的领域文件。该方法生成高维的词向量,捕获每个词的分布语义和共现统计信息。其次,我们使用域中已验证跟踪链接的现有训练集来训练跟踪 络,以预测两个软件工件之间存在跟踪链接的可能性。在跟踪 络中,我们采用递归神经 络结构来学习工件语义的表示。对于每个工件(即,每个规则、需求或源代码文件等),每个单词被在单词嵌入训练阶段学习的其相关向量表示代替,然后顺序地馈入 RNN。RNN 的最终输出是一个表示工件语义信息的向量。跟踪 络然后比较两个工件的语义向量,并输出它们链接的概率。

我们在 PTC 系统领域的大型工业数据集上评估了我们的方法,以解决两个研究问题:

RQ1:为了生成最精确的跟踪链接,应该如何配置 RNN?

RQ2:与标准基线技术相比,RNN 是否能够显著提高跟踪链路的精度?

II 面向自然语言处理的深度学习

许多现代的深度学习模型和相关的训练方法起源于人工神经 络(ANN)的研究。受神经科学进展的启发,人工神经 络被设计成通过在多层结构中连接大量简单的计算单元来近似人脑的复杂功能。基于人工神经 络的深度学习模型具有更复杂的 络连接,层次更广。从更复杂的结构中获得的一个好处是能够用多层次的抽象来表示数据特征;这通常比更传统的机器学习技术更可取,在这种技术中,需要人类的专业知识来选择数据特征进行训练。反向传播被广泛认为是训练深层神经 络的一种有效方法;它指出了 络应如何调整其内部参数以更好地计算每一层的表示。在介绍我们的方法之前,我们先介绍深度学习技术的基本概念,特别是与自然语言处理任务相关的概念。此外,由于我们的兴趣在于比较评估不同的模型以创建跟踪链接,因此我们对这些不同的技术进行了深入的描述。

A 词嵌入

传统的自然语言处理(NLP)和信息检索技术将唯一的词看作原子符 ,因此不考虑词之间的关联。为了解决这一局限性,单词嵌入学习将语料库中的每个单词表示为一个连续的高维向量,使得相似的单词在向量空间中紧密相连。此外,嵌入的词向量将词之间的句法和语义关系编码为词向量之间的线性关系。学习词向量的使用被认为是最近 NLP 任务深度学习模式成功的主要原因之一。

带负采样的 Skip-gram 和 GloVe 是最流行的单词嵌入模型,因为它们对单词类比任务带来了显著的改进,而不是更传统的方法,如潜在语义分析。利用语料库中单词的共现统计信息,利用未标记的自然语言文本训练单词嵌入模型。Skip-gram 模型扫描整个训练文本的上下文窗口来训练预测模型。假设窗口中的中心词大小为 T,该模型最大化了目标词出现在中心词周围的概率,同时最小化了随机词出现在中心词周围的概率。手套模型使用矩阵分解;但是我们不进一步讨论它,因为它的性能相当于负采样方法的 Skip gram,而它的鲁棒性较差,并且利用了更多的系统资源。

B 神经 络结构

NLP 任务的深度学习通常通过神经 络技术来解决。前馈 络,也称为多层感知器(MLPS),代表了传统的神经 络结构,并为许多其他结构奠定了基础。然而,当 络的宽度和深度增加时,完全连接的 MLP 中的参数数目会变得非常大。为了解决这一局限性,研究人员针对不同类型的实际问题提出了不同的神经 络结构。例如,卷积神经 络(CNN)特别适合于图像识别和视频分析任务。在自然语言处理任务中,递归神经 络(RNN)得到了广泛的应用,并被认为非常适合自然语言处理的独特需求。特别是,RNN 及其变体在许多 NLP 任务中取得了重大突破,包括语言建模、机器翻译和语义蕴涵。在接下来的部分中,我们首先介绍了 RNN 的背景,然后讨论了本研究中评估的几种 RNN 变体。

C、 标准递归神经 络(RNN)

RNN 特别适合处理连续数据,如文本和音频。它们以有向循环连接 络的计算单元,使得在每个时间步骤 t,RNN 中的单元不仅接收当前步骤(即,下一个字嵌入)的输入,而且接收来自上一时间步骤 t-1 的相同单元的隐藏状态。这种反馈机制模拟一个“存储器”,因此 RNN 的输出由其当前和先前的输入决定。此外,由于 RNN 在所有时间步长上使用相同的单位(具有相同的参数),因此它们能够处理任意长度的连续数据。如图 1 所示。在给定的时间步长 t 处,输入向量 xt 及其先前隐藏的输出向量 ht?1,标准 RNN 单元计算其输出为

ht = tanh(W xt + Uht?1 + b) (1)

其中 W、U 和 b 是仿射变换参数,tanh 是双曲正切函数:tanh(z)=(ez?e?z)/(ez+e?z)。

图 1:标准 RNN 模型(左)及其随时间展开的架构(右)。左图中的黑色方块表示一个时间步长延迟

标准 RNN 模型的一个突出缺点是,当序列中存在长相关性时,由于反向传播期间梯度爆炸或消失的现象, 络会退化。这使得标准 RNN 模型难以训练。当梯度的范数大于预设值(即梯度剪裁)时,通过缩小梯度可以有效地解决爆炸梯度问题。为了解决标准 RNN 模型中的消失梯度问题,研究人员提出了几种具有机制的变体来保持长期依赖性;这些变体包括长-短期记忆(LSTM)和门控循环单元(GRU)。

D、 长-短期记忆(LSTM)

LSTM 络在当前单元中包含一个记忆单元向量,以保持长期依赖性。LSTM 公司还引入了一种选通机制来控制何时以及如何向存储单元读写信息。LSTM 中的门通常使用 sigmoid 函数 σ(z)=1/(1+e?z),并使用逐点多复制操作控制信息吞吐量。具体地说,当 sigmoid 函数输出 0 时,门禁止任何信息通过,而当 sigmoid 函数输出为 1 时,允许所有信息通过。每个 LSTM 单元包含一个输入门(it)、一个忘记门(ft)和一个输出门(ot)。每个门的状态由 xt 和 ht?1 决定,以便:

it = σ(Wixt + Uiht?1 + bi)

ft = σ(W f xt + U f ht?1 + bf) (2)

ot = σ(Wo xt + Uoht?1 + bo)

为了更新存储单元中的信息,首先使用 tanh 函数来计算存储候选向量 ∧ct。这个内存候选通过输入门,它控制候选向量中的每个维度应该被“记住”多少。同时,遗忘门控制前一个存储单元状态 ct?1 中的每个维度应该保留多少。然后使用这两部分的总和更新实际的存储单元状态 ct

c?t = tanh(Wc xt + Ucht?1 + bc)

ct = it [1] c?t + ft [1] ct?1 (3)

最后,LSTM 单元使用输出门计算其输出 ht,如下所示:

ht = ot [1] tanh(ct) (4)

图 2(a)说明了典型的 LSTM 单元。LSTM 单元使用保留的存储单元状态和选通机制来“记忆”信息,直到被遗忘门擦除;

因此,LSTM 更有效地处理长期依赖关系。LSTM 被反复应用于解决语义相关任务,并取得了令人信服的效果。这些进展促使我们在跟踪任务中采用 LSTM 作为推理语义。

图 2:LSTM 和 GRU 络的单个单元之间的比较。在(2a)中,i、f 和 o 分别是输入门、遗忘门和输出门;c 是存储单元向量。在(2b)中,r 是复位门,u 是更新门。

E、 门控循环单元(GRU)

最后,最近提出的选通递归单元(GRU)模型也使用选通机制来控制单元内的信息流;但它具有简化的单元结构,并且没有专用的存储单元向量。它只包含一个复位门 rt 和一个更新门 ut:

rt = σ(Wr xt + Urht?1 + br)

ut = σ(Wu xt + Uuht?1 + bu) (5)

在 GRU 络中,先前隐藏的输出 ht?1 通过复位门 rt 并被发送回装置。然后使用选通 ht?1 和装置的电流输入 xt 计算输出候选 h?t,如下所示:

h?t = tanh(Wh xt + Uh(rt [1] ht?1) + bh) (6)

单元 ht 的实际输出是由更新门 ut 控制的先前输出 ht?1 和候选输出 h?t 之间的线性插值。因此,更新门平衡了使用 h?t 和 ht?1 更新的电流输出量。

ht = (1 ? ut) [1] ht?1 + ut [1] h?t (7)

因此,GRU 单元将长期信息直接嵌入到隐藏的输出向量中。图 2 比较了 LSTM 和 GRU 络的单元结构。尽管 GRU 的结构比较简单,但在许多 NLP 任务中,GRU 还是取得了与 LSTM 竞争的结果,因此还没有得出哪个模型更好的决定性结论。在这项工作中,我们比较了 LSTM 和 GRU 的性能,以确定最适合解决跟踪问题的模型。

F、 其他 RNN 变量

除了修改单个 RNN 单元内的结构之外,整个 RNN 络的结构可以改变。例如,多层 RNN 在每个时间步堆叠多个 RNN 单元,目的是从输入序列中提取更多抽象特征。相反,双向 RNN 同时处理前向和后向的序列数据;这使得输出同时受到序列中过去和未来数据的影响。在这项研究中,我们还探讨了使用两层 RNN 和双向 RNN 来生成跟踪链接。

III 追踪 络

跟踪过程包括几个步骤:首先,hu [1] man 分析员对源工件发起跟踪;其次,计算源工件和每个潜在链接的目标工件之间的相似度;第三,返回一个排序的候选链接列表;最后,人类评估这些联系,并接受那些被认为是正确的。对所有源工件重复该过程。我们研究了各种深度学习模型和方法在计算源和目标工件对之间的相似性方面的有效性,目的是生成精确的跟踪链接。这本质上是一个文本比较任务,其中跟踪 络需要利用领域知识来理解两个单独工件的语义,然后评估它们的语义相关性,以便进行跟踪。即使不存在公共词,也需要在相关工件之间建立有效的关联。基于我们对现有技术优缺点的初步分析,我们决定采用 word 嵌入和 RNN 技术来实现这一目标。因此,我们首先需要从一个领域语料库中学习单词嵌入,以便对单词关系进行有效编码,然后在跟踪 络结构中利用这些单词嵌入来提取和比较它们的语义。在本节中,我们将介绍设计和培训这种跟踪 络的方法。

图 3:跟踪 络的体系结构。首先将软件构件映射到嵌入的词向量序列中,经过 RNN 层生成语义向量,然后将语义向量送入语义关系评估层,以预测它们链接的概率。

A、 络体系结构

神经 络结构的设计如图 3 所示。给定源工件 As 和目标工件 At 的文本内容,As 和 At 中的每个单词首先通过单词嵌入层映射到其向量表示。使用第 II-A 节中介绍的 Skip-gram 模型从领域语料库中训练此类映射。然后将源工件 s1、s2、…、sm 中的单词向量依次发送到 RNN 层,并作为表示其语义信息的单个向量 vs 输出。在双向 RNN 的情况下,字向量也以与 sm、sm?1、…、s1 相反的顺序发送。使用 RNN 层以相同的方式生成目标语义向量 vt。最后,在语义关系评价层对这两个向量进行比较。

我们的追踪 络中的语义关系评估层采用了 Tai 等人提出的结构,旨在执行句子对的语义蕴涵分类任务。这部分 络的总体计算可表示为:

这里,[1]是逐点乘法运算符,用于比较每个维度上源向量和目标向量的方向。绝对矢量减法结果 rsub 表示每个维度中两个矢量之间的距离。然后, 络使用一个隐藏的 sigmoid 层来集成 rpmul 和 rsub,并输出一个向量来表示它们的语义相似性。最后,输出 softmax 层使用该结果来产生存在有效跟踪链路的概率;softmax 函数的结果是范围(0,1)内实值的 K 维向量,加起来等于 1(在这种情况下,K=2)

一个具体的跟踪 络建立在这个体系结构之上,并由一组 络设置进一步配置。这些设置指定 RNN 单元的类型(即 GRU 或 LSTM)、RNN 单元中隐藏维度的数量和语义关系评估层,以及其他 RNN 变量,例如 RNN 层的数量和是否使用双向 RNN。为了解决我们的第一个研究问题(RQ1),我们研究了几种不同的配置。我们在第 IV-B 节中描述了如何优化 络设置。跟踪 络是在 Torch 框架上实现的(http://torch.ch),源代码位于https://github.com/jinguo/TraceNN。

B、 追踪 络培训

一个强大的 络只有当它可以使用现有的数据进行适当的训练,并且当它可以归纳为看不见的数据时才有用。为了训练跟踪 络,我们使用正则化的负对数似然作为目标损失函数。这个目标函数通常用于分类预测模型,可以写成

其中,Th 表示需要训练的 络参数,n 是训练数据中的实例总数,席是输入训练实例的输入,Yi 是该示例的实际类别(即链接或非链接);结果,P(y= yx 席,thi)表示 络对当前输入和参数的正确分类的预测。损失函数的第二部分表示防止过拟合的 L2 参数正则化,其中 θ2 是 θ 的欧氏范数,λ 控制正则化的强度。

基于此损失函数,我们使用随机梯度下降法来更新 络参数。根据这种方法,一个典型的训练过程由若干个阶段组成。每个历元对所有训练数据迭代一次以训练 络;因此,整个训练过程多次使用所有训练数据,直到目标损失足够小或不能进一步减少为止。在每个历元中,训练数据被进一步随机划分为若干“小批量”;每个“小批量”包含一个或多个训练数据点。每批处理后,根据损失函数计算参数梯度。然后 络根据这个梯度和一个“学习率”来更新它的参数,这个“学习率”指定参数沿梯度方向移动的速度。在训练过程中,我们采用了自适应学习率程序,根据当前的训练表现调整学习率。为了帮助 络收敛,我们还将每个历元后的学习速率降低到历元 τ,使得历元 k 的学习速率由

式中 0 为初始学习率,α=k/τ。在我们的实验中,τ 设置为 0/100,τ 设置为 500。

基于这些通用方法,跟踪 络训练过程由一组预定义的超参数进一步确定,这些超参数有助于引导学习行为。常用的超参数包括初始学习率、梯度剪辑值、调节强度(λ)、小批量中的数据点数量(即小批量大小)以及训练过程中包含的历元数。第 IV-B 节介绍了选择超参数的技术。

IV 实验设置

在本节中,我们将介绍用于(1)准备数据,(2)系统地调整跟踪 络的配置(即 络设置和超参数),以及(3)将最佳配置的性能与其他流行的跟踪评估方法进行比较的方法。

A、 数据准备

软件项目数据表现出影响神经 络训练的特殊特征。特别是,与工件对的总数相比,对于给定的源和目标工件集,实际跟踪链接的数量通常非常少。在我们的数据集中,在所有 769366 个工件对中,只有 0.18%是有效链接。使用这样一个不平衡的数据集训练神经 络是非常有挑战性的。处理非平衡数据集的一种常见且相对简单的方法是,将少数类(即链接工件)的权重高于多数类(即非链接工件)。然而,在梯度下降法中,较大的损失权重会不恰当地放大少数类的梯度更新,使训练不稳定,导致收敛失败。处理不平衡数据的另一种常见方法是对多数情况进行降采样,以生成一个固定且平衡的训练集。基于最初的实验,我们发现这种方法并没有产生好的结果,因为用于训练 络的非链路的例子倾向于随机排除位于链路和非链路被区分的边界处的伪影对。此外,基于初步实验,我们还排除了上采样方法,因为这大大增加了训练集的大小,过度延长了训练时间。

在进一步实验的基础上,我们采用了一种利用子数据集动态构建平衡训练集的策略。在每个历元中,通过包含原始训练集中的所有有效链接以及从训练集中随机选择相等数量的非链接来构造一个均衡的训练集。非链接的选择在每个时代开始时更新。这种方法确保了随着时间的推移,用于训练的抽样非链接具有代表性,并在每个时期保持了链接和非链接的同等贡献。我们的初步实验结果表明,这种技术是有效的训练我们的跟踪 络。

表一:追踪 络配置搜索空间

B、 模型选择与超参数优化

找到合适的 络设置和一组好的超参数对于将深度学习方法成功应用于实际问题至关重要。然而,考虑到训练所需的运行时间,不同配置的所有可能组合的搜索空间太大,无法提供完全覆盖。因此,我们首先确定了几个可以产生良好性能的配置。这是通过手动观察早期时期训练损失的变化,并遵循中建议的启发式方法来实现的。然后,我们创建了一个 络配置搜索空间,以这些手动识别的配置为中心;我们的搜索空间总结在表一中。我们进行了 格搜索,并使用训练集训练表一中每个配置的所有组合,然后比较它们在开发集上的性能,以找到最佳配置。我们在下面描述我们的搜索空间。

为了学习单词嵌入,我们使用了 Word2vec 工具提供的 Skip-gram 模型。我们使用两种设置来训练单词向量:仅使用 PTC 语料库的 50 维向量和同时使用 PTC 和 Wikipedia dump 的 300 维向量。维度的数量设置不同,因为 PTC 语料库(38771 个标记)包含的标记远远少于 PTC+Wikipedia 转储(8025288 个标记)。向量维数越小,训练速度越快,而向量维数越大,则需要有效地表示后一语料库中所有标记的语义。

为了比较哪种 RNN 变化最适合追踪 络,我们评估了 GRU、LSTM、双向 GRU(bi [1] GRU)、双向 LSTM(bi-LSTM),第 II-C 节中介绍了 1 层和 2 层。每个 RNN 单元中的隐藏维度设置为 30 或 60,而隐藏维度设置为 30 或 60 集成层的尺寸相应地设置为 10 或 20。作为一个基线方法,我们还用一个单词包方法替换了 RNN 层,在这个方法中,工件的语义向量被简单地设置为工件中包含的所有单词向量的平均值(表 I 中的“AveVect”)。我们还总结了表一中跟踪 络的其他超参数的搜索空间。

C、 追踪方法比较

在实际的需求跟踪设置中,跟踪方法返回源工件(服务于用户查询角色)和一组目标工件之间的候选链接列表。一个有效的算法将返回接近列表顶部的所有有效链接。因此,跟踪算法的有效性通常用平均精度(MAP)来衡量。为了计算 MAP,我们首先计算每个查询的平均精度(AP),如下所示:

其中| RetrievedLinks |是检索到的链接数,i 是检索到的候选链接序列中的,relevant(i)是一个二进制函数,如果链接有效则赋值 1,否则赋值 0,Precision(i)是截断紧靠 i 下方的列表后计算的精度。然后,平均精度(MAP)作为平均值计算所有查询的 AP。在典型的信息检索设置中,MAP 是为返回的前 N 个链接计算的;但是,为了便于跟踪,我们在返回跟踪矩阵中指定的所有有效链接时计算 MAP。这意味着我们的 MAP 版本计算的召回率是 100%。

我们仅使用测试数据集计算 MAP,并将我们的跟踪 络的性能与其他流行的跟踪方法,即向量空间模型(VSM)和潜在语义索引(LSI)进行了比较。为了进行公平的比较,我们还使用遗传算法优化了 VSM 和 LSI 方法的配置,以搜索广泛的预处理器和参数配置空间。最后,我们将 VSM 配置为在计算余弦相似性时使用局部逆文档频率(IDF)加权方案。大规模集成电路被缩减到 75%的尺寸。对于 VSM 和 LSI,我们都对文本进行了预处理,去除了非字母数字字符、停止词,并使用 Porter 的词干算法对每个单词进行词干处理。

我们还通过绘制精确性与召回率曲线来评估结果。该图描述了不同相似度或概率值下的召回率和精确度得分。因此,精确召回曲线显示了精确性和召回之间的权衡,并提供了关于每种方法在何处表现最佳的见解——例如,一种技术是在较高或较低的召回水平上提高精度。远离原点的曲线表示性能更好。

V 结论

致谢

声明:本站部分文章及图片源自用户投稿,如本站任何资料有侵权请您尽早请联系jinwei@zod.com.cn进行处理,非常感谢!

上一篇 2021年1月8日
下一篇 2021年1月8日

相关推荐