Page 30 - 《软件学报》2024年第4期
P. 30
1608 软件学报 2024 年第 35 卷第 4 期
第 I 层的 Transformer, 多头注意力机制的输出通过如下方式计算:
N
N
,
H = N {h h 1 N ,...,h n− 1 }, E = n LN (MultiAtt (H n− 1 ) H+ n− 1 ), H = n LN (FFN (E n ) E+ n ) (5)
0
N
其中, MultiAtt 是多头注意力机制, FFN 是前馈神经网络, LN 是正则化操作, 最终的输出 E 由下列公式得到:
Q K T
l−
Q = H W Q , K = H W K , V = H W V , head = softmax i i V
l−
1
1
1
l−
i i i i i i i d k i (6)
N
E = [head 1 ;...;head W N O
]
N
Q
V
,
其中, 前一层的输出 H (l-1) ∈R (n*dh) 被线性映射为〈查询,键,值〉, 即〈Q,K,V〉, dk 是 head 的大小. WW i K ,W ∈
i
i
O
R (dh*dk) , 其初始化 W 1 Q , W 1 K , W 1 V , 是随机初始化的参数. W ∈ R (dh *dk ) 是模型的输出参数.
N
2.3 多模态对比学习
对比学习鼓励原始样本的表示更加接近“正”增强样本的表示, 同时远离“负”样本的表示, 使得模型在不
同数据之间能学习到更加均匀的决策边界点. 最近的几项工作 [42,45] 试图比较相似和不同的源代码, 然而它们
只比较了单个模态的特征, 却忽略了编程语言的多模态特性. 为此, 本文设计了多模态对比学习的预训练目
标来探索不同模态之间交互信息的最大潜力, 鼓励模型学习编程语言不同模态的联系和语义等价性. 对比学
习的关键是构造正负样本, 因此, 本文提出了两种新的数据增强的方法, 分别称作 NL 型和 PL 型, 如图 2(b)
数据增强模块所示.
对于正样本的设计, 本文针对 CodeSearchNet [33] 中双模态(PL-NL)数据进行构造.
(1) NL 型: 为了弥合编程语言与自然语言的语义鸿沟, 本文将文本级的自然语言注释单独视为一个正
*
样本, 将它表示为 code , 如公式(7)所示:
*
code =([CLS]⊕comment⊕[SEP]) (7)
(2) PL 型: 因为功能级的函数名、语义级的代码字符和结构级的 AST 都具有编程语言的特点, 所以为
了学习这 3 个特征的语义等价性, REcomp 交换功能级的函数名 f 和语义级-结构级特征的融合序列
+
ca 在输入序列中的位置, 将此作为一种数据增强的方法, 得到的另一个正样本, 将它表示为 code ,
如公式(8)所示:
+
code =([CLS]⊕ca⊕[SEP]⊕f⊕[SEP]) (8)
为了让模型最大程度地学习编程语言 4 个模态特征的语义等价性, 本文将原始样本、PL 型正样本和 NL
*
*
+
+
型正样本两两组合, 得到(code,code ), (code ,code )和(code ,code)这 3 个组合.
对于负样本的设计, 采用的损失函数是交叉熵损失函数. 对于原始样本 x i , 将原始样本 batch里其余 x j (j≠i)
作为负样本, 简称为 In-batch, 并且将正样本 batch 里不同对 x + j ( j ≠ ) i 也作为负样本, 简称为 cross-batch. 因此,
*
*
以(code,code )为例, 如果一个 batch 里有 N 组(code,code ), 那么对于 1 个 code 就有 2N−2 个负样本, 分别是:
−*
−
N−1个 code 和 N−1个 code . 因此, 对比学习的损失函数 Loss MCL 表示在公式(10), 它的具体工作流程如图 2(c)
多模态对比学习模块所示:
exp( ,vv + )
( ,x
lx i + i ) = − ln i i (9)
exp( ,vv + i ) + 1 ∑ 2N − 2 exp( ,vv i − )
i
i
+
−
其中, v i 是 x i 对应的语义向量, 由公式(7)得到; v 是 x i 正样本的语义向量; v 是 x i 负样本的语义向量:
i
i
( ,x
Loss MCL = 1 ∑ N [ (,lx x i + ) lx+ (, )x + i * i lx i * i + )] (10)
i
+
*
其中, x i 是原始样本, x 是 NL 型的正样本, x 是 PL 型的正样本.
i
i
2.4 下游任务
本文将经过多模态对比学习预训练后的编码器形式化为 Encoder. 为探究模型是否增强了代码表征的能
力, 本文选取了两个典型的理解型下游任务(代码克隆检测和语义代码检索)对模型的有效性进行评估.