Page 29 - 《软件学报》2024年第4期
P. 29

杨宏宇  等:  基于多模态对比学习的代码表征增强预训练方法                                                   1607


             5.        _SemanticsStructureFusion(Code,the root of the AST parsed by Code)
             6.      Return TokensAST
             7.   Function _SemanticsStructureFusion(Code,root)
             8.   TokensAST←∅
             9.     If root.Children=∅ then Return
             10.    For child in root.children
             11.       If child.type=“identifier” and child.children≠∅ then
             12.     tokens←AlignNodeToTokens(child is one leaf node N leaf  of the AST,Code)
             13.        add the tokens to the TokensAST
             14.     Else
             15.     ast←child.type and add the ast to the TokensAST
             16.     _SemanticsStructureFusion(Code,child)
             17.    Return TokensAST
             18.   Function AlignNodeToTokens(N leaf ,Code)
             19.   start←N leaf .start_node,end←N leaf .end_node
             20.   tokens←∅ and tokens⊂Code
             21.    If start[0]=end[0] then tokens←Code[start[0]][start[1]:end[1]]
             22.    Else
             23.      tokens←Code[start[0]][start[1]:]
             24.        For i in [start[0]+1,…,end[0]]
             25.       concatenate Code[i] to tokens
             26.      concatenate Code[end[0]][:end[1]] to tokens
             27.    Return tokens
             注意:  AlignNodeToTokens 函数(第 18−27 行)中,  根据 N leaf 的 start_node 和 end_node 属性值,在源代码中有
         唯一确定的 tokens⊂S 与 N leaf 对齐.  并且 start_node 是一个元组,  表示为(行号,序号).  例如图 3 所示:  源代码中
         的字符“sum”位于第 1 行,  包含第 5 个字符到第 7 个字符,  因此它的 start_node 值为(0,4);  同理,它的 end_point
         的值为(0,6).
             Code  S 的函数名和自然语言注释形式化为 f 和 n,  其中,  J 和 L 是 f 和 n 应用 RoBERTa         [25] 分词器划分的
         长度:
                                                                        i
                                                             j
                             ca =  ( , ,..., ,...,t t 2  c 1  t |N nonleaf  | ,...,c |N leaf  | ), t =  ( t N nonleaf  ), c =  (N leaf  )    (1)
                                                                   i
                                                        j
                                  1
                              f=(f 1 ,f 2 ,…,f j ,…,f J ), 1≤j≤J, n=(n 1 ,n 2 ,…,n l …,n L ), 1≤l≤L   (2)
             将公式(1)的 ca 和公式(2)的 f 进行拼接,  且使用特殊符号[CLS]表示是一个位于段序列最前端的特殊开始
         字符, [SEP]是分隔不同模态数据的特殊字符,  源代码的输入 code 表示如下:
                                      code=([CLS]⊕f⊕[SEP]⊕ca⊕[SEP])                           (3)
         2.2   编码器
                                                                           [3]
             REcomp 分别以 CodeBERT,  GraphCodeBERT 和 UniXcoder 为初始化模型 ,  其编码向量函数表示为
         Embedding(⋅),  结合多模态输入 code,  如公式(3)所示,  其中间表示 e code 表示在公式(4):
                                           e code =Embedding(code)                            (4)
             如图 2(b)编码器模块所示: REcomp 由 N(N=12)层 Transformer    [23] 组成,  由中间形式 e 作为模型输入生成每
                        N
         一层的隐藏状态 H ,  每一层 Transformer 都含有一个架构相同的转换器,  该转换器使用多头注意力机制(multi-
                                                                                       0
         headedself-attention),  通过一个前馈神经网络(FeedForwardLayer)覆盖上一层的输出,  初始化时 H =e code ,  对于
   24   25   26   27   28   29   30   31   32   33   34