Page 209 - 《软件学报》2026年第5期
P. 209
2088 软件学报 2026 年第 37 卷第 5 期
会引入新的错误.
此外, 先前的工作 [5,6] 指出, 将整段代码视为一个整体进行信息表征会掩盖更细致的代码变更块之间的关键细
节. 这种粗粒度的表示方式增加了从其中提取与变更紧密相关特征的难度. 为了克服这一挑战, 特别是在代码更改
涉及多个独立的代码变更块时, 本研究提出了一种新的方法, 即在代码变更块的级别上构建抽象语法树, 保留更详
尽的信息, 以便更准确地理解和分析代码在不同变更块中的变化情况. 通过这种方法, 我们能够捕捉更精细的代码
变更细节, 为后续的错误信息匹配和定位提供强有力的支持.
1.2 基于图的 Transformer
图 Transformer 的整体架构如图 3 所示. 给定初始的邻接矩阵 A, 节点嵌入 X v , 图 Transformer 旨在学习图中代
码节点的嵌入表示. 对于图 G 的邻接矩阵 A ∈ {0,1} N×N , 表示节点和节点之间是否存在有向边.
Linear
Q
Matmul Scale + Softmax
Linear
+ Matmul
K
X d X v
Linear
V v 1
v 2
A
v 3
v 4
v 5
图 3 图 Transformer 的整体架构
本文采用了一种双向信息传播方法, 该方法结合了自底向上和自顶向下的信息传播策略, 旨在全面考虑上下
文信息, 从而显著提升节点 token 表示的质量. 将节点嵌入 X v 与深度编码 X d 作为图 Transformer 的初始输入. 在有
向无环图的结构中, 深度编码包含节点在图中的位置信息, 不仅映射了节点在有向无环图的层级结构位置, 而且为
代码更改的图结构分析和处理奠定了基础. 在本文框架中, 节点深度 v 可以通过以下方式定义:
{
0, if v is a source node
depth(v) = (1)
1+max (u,v)∈E depth(u), otherwise
没有前驱节点的所有节点都是源节点, 源节点的深度为 0. 对于其他节点, 其深度由其所有前驱节点的最大深
度决定. 具体的, 节点的深度是其所有前驱节点 u 的最大值加 1. 根据公式 (1), 有向无环图的深度编码定义如下:
( ) ( )
depth(v) depth(v)
DE (v, 2n) = sin 2n , DE (v, 2n+1) = cos 2n (2)
10000 d 10000 d
其中, d 是节点特征维度, n 是所考虑的维度的索引. 对于有向无环图 G, 定义矩阵 M ∈ R |v|×|v| 来衡量图 G 中节点 v i
和 v j 之间的空间关系. 矩阵 M 可以通过节点之间的连接来得到. 在本文中如果两个节点相连, 定义 M i 是 j v i 和 v j
之间的最短路径的距离, 如果没有, 将其输出设置为特殊的值, 即−1. 由于图 Transformer 需要图结构作为输入, 而
文本本身没有天然的图结构, 因此我们构建了一个虚拟的全连接图, 即每个词节点与其他所有词节点都有连接. 将
词嵌入后的节点特征和虚拟图的边信息作为图 Transformer 模型的输入:
( T )
QK
attention(Q,K,V) = Softmax √ +W m M ij V
d
{ (3)
SPD(v i ,v j ), if v i ← v j
M ij =
−1, otherwise
j
其中, W m 为 M i 矩阵的可学习矩阵, 并在所有的层共享. 通过使用空间关系矩阵 M ij , 单个 Transformer 层中的每个

