Page 187 - 《软件学报》2026年第2期
P. 187

666                                                        软件学报  2026  年第  37  卷第  2  期


                 被替换, 而不是像     MLM  那样预测原始     token. Li 等人  [47] 随后提出了一种基于  RTD  的方法, 用于  few-shot 学习, 通
                 过使用模板和标签描述词将输入转化为自然语言提示, 预训练模型预测最少被替换的标签描述词. AraELECTRA                              [48]
                 和  DeBERTaV3 [49] 等其他工作也验证了    RTD  的有效性. Lachaux  等人  [50] 提出了一个新的目标, 称为标识符去混淆
                 (identifier deobfuscation, DOBF), 该方法专注于去混淆源代码中的标识符名称. 与       MLM  不同, 当选择一个标识符
                 时, 该标识符的所有实例都被替换为相同的特殊                token. 这种方法旨在利用编程语言的结构信息, 通过预训练恢复
                 被混淆的源代码. 对比学习        (contrastive learning, CL) 是另一种广泛使用的技术, 它通过训练模型最小化相似正样
                 本之间的距离, 并最大化不同负样本之间的距离. 例如, Jain              等人  [51] 提出了  ContraCode, 利用对比学习聚焦于代码
                 的功能, 而不是其形式. 该模型通过预训练识别功能上相似的程序变体. 然而, 程序的功能不仅依赖于代码序列, 不
                 同的  token  和结构可以实现相同的功能. 为了解决这一问题, Ding            等人  [52] 提出了  BOOST, 通过对比学习使得功能
                 相同的代码在表示空间中更接近. 与这些方法不同, 本文提出了一种在子函数级别进行自监督学习的目标, 旨在增
                 强对函数依赖关系表示的学习.
                  3   问题定义

                    代码生成注释是指生成简洁、易于人类理解的自然语言描述或总结, 概括目标函数中所包含的功能和逻辑.
                 与之前的方法不同, 本文的任务重点关注目标函数中的上下文依赖关系, 以增强代码注释的效果. 具体而言, 设                                 X
                 表示目标函数的源代码, 它由         m 个元素组成, 即    X = [x 1 , x 2 ,..., x m ], 其中  x i (i ∈ [1,m]) 表示源码中的  token,   ˆ X 1 ,..., ˆ X j
                                                                                                       i
                                                                                                  i
                                                                                                i
                 表示  X  中的依赖关系    (即子函数, 下文统称为子函数),        ˆ X i (i ∈ [1, j]) 表示为一个包含   个 l  token  的序列  [ˆx , ˆx ,..., ˆx ].
                                                                                                1  2   l
                 本文的任务是基于输入        X  生成目标序列    Y = [y 1 ,y 2 ,...,y n ], 其中   Y  包含  n 个单词.
                    通常, 条件概率使用由参数         θ  特征化的参数化函数表示:       P(Y|X) = P(Y|X;θ). 在训练过程中, 目的是识别最优
                 的   θ 值, 以最大化训练数据集中     (X,Y) 对的条件概率. 一般而言, 模型旨在根据先前的单词预测注释中的下一个单
                 词, 那么上述的条件概率可以被分解为一系列个别条件概率的乘积:

                                                        n ∏
                                               P(Y|X;θ) =  P(y t |{y 1 ,...,y t−1 },X;θ)              (1)
                                                        i=1
                    最后, 本文使用负对数似然损失作为优化目标:

                                                           T
                                                      1  N ∑∑   (       )
                                                                   i
                                                                      i
                                                                  i
                                                L nll = −    logP y |y ,X ;θ                          (2)
                                                      N           t  <t
                                                        i=1 t=1
                                        i
                                      i
                 其中,   N  是训练数据集中   (X ,Y ) 对的数量,  T  是目标注释的长度.
                  4   方 法
                    本节详细介绍了       DHCS  模型, 该模型采用典型的神经编码器-解码器架构. DHCS               的整体框架如后文图        2  所
                 示. 在此框架中, 设计了一个分层         Transformer 编码器, 以更好地捕捉目标函数和调用的子函数之间的结构化表示,
                 其中子函数编码器用于学习子函数的语义表示, 而目标函数编码器用于捕捉目标函数的上下文语义. 此外, 本文还
                 提出了掩码子函数预测任务, 以增强子函数表示的学习. 最后, 本文使用主题感知复制解码器, 基于学到的上下文
                 语义和子函数的主题分布生成代码注释.
                  4.1   分层编码器
                  4.1.1    子函数编码器
                                                                  ˆ X i (i ∈ [1, j]), 本文首先使用字节对编码  (BPE) 分词
                    子函数编码器接收子函数的源代码作为输入. 给定子函数
                 器  [53] , 根据  Radford  等人  [54] 的方法将   ˆ X i  分词为一系列  token:  [ˆx , ˆx ,..., ˆx ]. 然后, 将该  token  序列传递到嵌入层, 得
                                                                   i
                                                                 i
                                                                        i
                                                                        l
                                                                 1
                                                                   2
                                                                           ˆ H  的语义特征. 具体来说, 如下所示:
                 到嵌入表示    e( ˆ X i ). 最后, 这些嵌入被输入到子函数编码器中, 以编码子函数

                                                    i
                                                           i
                                           e( ˆ X i ) = [e(ˆx ),...,e(ˆx )] = EmbeddingLayer( ˆ X i )  (3)
                                                    1      l
   182   183   184   185   186   187   188   189   190   191   192