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

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


         不同:  Ruby 语言的语法简洁,  它注重代码的可读性和易于理解,  尽量使用更少的语法结构和标点符号,  使得
         代码看起来更接近自然语言,  因此,  REcomp 极大地拉近了它与自然语言的语义鸿沟;  相比之下,  Java 语言的
         语法更为严格,  需要使用更多的关键字和符号来定义代码结构,  因此在拉近代码和查询之间的语义距离还需
         要更多的结构信息.  根据 Go 和 Python 数据集进一步验证上述猜想,  它们的 MRR 分别增加了 0.4%和 0.6%,  并
         且 Go 和 Python 都注重代码的简洁性和可读性,  相比 Java 其结构更加简单.  它们都采用了清晰简洁的语法和
         规范,  使得代码更易于编写、理解和维护,  因此它们 MRR 的提升都高于语法结构更加复杂的 Java.
                                    表 3   代码克隆检测任务的评价结果  (%)
                                              POJ-104      BigCloneBench
                                     模型
                                              MAP@R   Recall   Precision   F1-score
                                   RoBERTa     76.67   95.1   87.8   91.3
                                  SynCoBERT    88.24   −       −      −
                                   PLBART      86.7   94.8    92.5   93.6
                                   CodeBERT    82.67   94.7   93.4   94.1
                                  REcomp(C)    89.89   94.0   94.0   94.0
                                 GraphCodeBERT   85.16   94.8   95.2   95.0
                                  REcomp(G)    88.63   94.0   94.0   94.0
                                   UniXcoder   90.52   92.9   97.6   95.2
                                  REcomp(U)    91.91   95.0   95.0   95.0
                                表 4   6 种编程语言的代码检索任务的评价结果  (%)
                               模型       Ruby   JavaScript   Go   Python   Java   PHP   平均
                               CNN       27.6   22.4   68.0   24.2   26.3   26.0   32.4
                              BiLSTM     21.3   19.3   68.8   29.0   30.4   33.8   33.8
                             Transformer   27.5   28.7   72.3   39.8   40.4   42.6   41.9
                              RoBERTa    58.7   51.7   85.0   58.7   59.9   56.0   61.7
                            RoBERTa(code)   62.8   56.2   85.9   61.0   62.0   57.9   64.3
                             SynCoBERT   72.2   67.7   91.3   72.4   72.3   67.8   74.0
                              PLBART     67.5   61.6   88.7   66.3   66.3   61.1   68.5
                             CodeBERT    67.9   62.0   88.2   67.2   67.6   62.8   69.3
                             REcomp(C)   71.5   64.6   90.4   68.5   69.8   64.1   71.5
                           GraphCodeBERT   70.3   64.4   89.7   69.2   69.1   64.9   71.3
                             REcomp(G)   75.3   67.5   91.5   71.4   71.8   66.5   74.0
                             UniXcoder   74.0   68.4   91.5   72.0   72.6   67.6   74.4
                             REcomp(U)   76.4   68.9   91.9   72.6   72.8   67.8   75.1

             综上所述,  REcomp 提高了代码表征的准确性,  从而增强了模型在代码理解型任务上的性能.  这有助于减
         少代码调试和优化的需求,  提高了代码的运行效率,  促进了代码的重用和模块化开发.  这样有益于节约能源、
         减少计算机软硬件资源的使用,  并减少对相关电力和碳排放的依赖.
         3.4.2    消融实验
             本小节将验证 3 个问题.
             (1)  PL 型正样本能否让模型学习到具有编程语言特点的特征的语义等价性?
             (2)  NL 型正样本能否弥合自然语言和编程语言的语义鸿沟?
             (3)  PL 与 NL 的组合型是否增强了模型代码表征的能力?
             本文用-w/o 定义了“删除”操作符,  用来检测单个组件的有效性,  则有:
             •  -w/o PL:  表示删除 PL 型正样本,  进行多模态对比学习预训练任务时只使用 NL 型正样本;
             •  -w/o NL:  表示删除 NL 型正样本,  进行多模态对比学习预训练任务时只使用 PL 型正样本;
             •  -w/o MCL:  表示没有经过多模态对比学习预训练任务,  直接用初始化模型对下游任务进行评估.
             (1) NL 型的有效性
             就克隆检测任务而言,  从表 5 观察到:  REcomp(C/G/U)去掉 NL 型,  比 NL+PL 型下降了约 0.14%,  0.4%和
         0.9%,  高出基准方法约 7.1%,  3.1%和 0.54%.  在语义代码检索任务上,  仅用 NL 型作为正样本预训练,  即
         REcomp(C/G/U,  -w/o PL),  在 MRR 上高出其基准分别约 2.1%,  2.6%和 0.9.  REcomp(C/G,  -w/o NL)相比
         REcomp(C/G)下降了 1.8%, 1.4%和 0.7%,  可以得出,  REcomp(C/G/U)是 NL 型敏感的,  即它们的性能会受到具
   28   29   30   31   32   33   34   35   36   37   38