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.  为探究模型是否增强了代码表征的能
         力,  本文选取了两个典型的理解型下游任务(代码克隆检测和语义代码检索)对模型的有效性进行评估.
   25   26   27   28   29   30   31   32   33   34   35