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

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


         2.4.1    代码克隆检测
             代码克隆检测是一个通过测量两个源代码之间的相似性来识别代码克隆问题是否存在的任务,  这个问题
         形式化定义为:  给定一个源代码 c 1 和一个待检测的代码 c 2 ,  根据 c 1 和 c 2 的相似性分数,  返回 0/1 标签,  标签 0
         表示 c 2 不是 c 1 的克隆体,  标签 1 则表示 c 2 是 c 1 的克隆体.  本文选择余弦相似性(记作 cosSim)作为相似性分数
         的计算函数,  来对它们进行相似度分数计算,  计算表示如公式(11):
                                                     ( ), score =
                                        ( ), e =
                              e =  Encoder c   Encoder c       cosSim (e  ,e  )               (11)
                               1 c       1  2 c        2              1 c  2 c
         2.4.2    语义代码检索
             语义代码检索是一个根据用户的查询意图,  从代码语料库中匹配最具相关性的源代码的任务.  这个问题
         形式化定义为:  给定一个自然语言形式的查询语句 n,  与代码语料库 U C ={c 1 ,c 2 ,c 3 ,…,c i ,…,c I }中的代码 c i ∈U C
         进行相似度分数计算(I 表示 U C 中代码的总数量),  并且从 U C 中返回具有最高分数的源代码 ˆ c ,  计算表示如公
                                                                                   τ
         式(12):
                                       ( ), e =
                                                    ( ),
                             e =  Encoder c   Encoder n  ˆ c =  argmaxcosSim (e e            (12)
                                                                        , )
                              i c       i  n            τ              i c  n
                                                             i c
         3    实   验
         3.1   数据集
                                                                    [2]
             REcomp 使用的是一个代码智能领域的公开基准数据集 CodeXGLUE .  本文选取代码克隆检测任务的两
         个数据集——BigCloneBench    [34] 和 POJ-104 [35] 以及代码检索任务的 CodeSearchNet [33] 数据集.
             BigCloneBench 是一种广泛被使用的大型代码克隆基准,  包含约 6 000 000 真的克隆对和 260 000 个假的
         克隆对,  这些克隆对来自 10 个不同功能的克隆对语料库.  它们                [34] 通过对没有任何标记的真假克隆对的源代码
         进行过滤,  最后将数据集划分成 901 208 / 415 415 / 415 416 个示例,  分别用于训练、验证和测试;
             POJ-104 数据集来自一个教学的开放编程平台,  它包含 104 个问题,  每个问题包含 500 个学生编写的
         C/C++程序.  它被划分成 32 000 / 8 000 / 12 000 条数据,  分别用于训练、验证和测试;
             CodeSearchNet 中每个示例都包含一个与文档配对的函数,  它们              [33] 选取文档的第 1 段作为代码功能描述
         的注释,  通过删除满足一定条件的示例来对其进行数据过滤,  进而提高数据集的质量.  上述数据过滤的条件
         分别是:  去除源代码存在编译错误且无法解析成为抽象语法树的示例;  去除源代码的文档(即自然语言注释)
         字符数量小于 3 或者大于 256 的示例;  去除源代码的文档中含有特殊表示和一些与功能无关的内容,  如指向
         外部资 源的 链接或 者 HTML 标签 等示例 ;  去 除源 代 码的文 档里 含有非 英文 字符的 示例 .  过滤 后 的
         CodeSearchNet 数据集统计信息见表 2.
                                 表 2   代码检索任务中 CodeSearchNet 的数据统计
                            编程语言     Ruby   Java   JavaScript   PHP   Python   Go
                             训练集    24 927   164 923   58 025   241 241   251 251   167 288
                             验证集     1 400   5 183   3 885   12 982   13 914   317 325
                             测试集     1 261   10 955   3 291   14 014   14 918   8 122

         3.2   预训练设置
             为了公平比较,  本文同样在 CodeSearchNet        [33] 数据集上预训练 REcomp.  REcomp(C/G/U)表示分别以
         CodeBERT,  GraphCodeBERT,  UniXcoder 初始化的 REcomp,  他们的训练集大小分别为 48/60/64,  学习率为
         1e−5,  优化器采用 AdmW,  原始样本和 PL 型正样本输入大小为 300,  NL 型正样本的输入大小为 64.  然后,  用
         1 个 NVIDIA Tesla A100(大小为 40 GB)分别训练 28k, 22k 和 21k 训练步.
   26   27   28   29   30   31   32   33   34   35   36