Page 27 - 《软件学报》2024年第4期
P. 27
杨宏宇 等: 基于多模态对比学习的代码表征增强预训练方法 1605
构级特征 AST, 提出了一种简单的基于结构的 AST 遍历算法, 并将其序列化结果作为代码的特征, 这个特征
被编码为 Transformer [23] 的输入序列, 在代码摘要任务中表现良好. 后来, MMAN [14] 为进一步充分挖掘结构信
息, 将结构级的 AST, CFG 和语义级的代码字符结合. DeGraphCS [15] 提出在编译后, 构造一个基于变量的流图,
以进一步提高代码语义表示的准确性, 并提出一种优化算法来去除变量流图中的冗余信息.
1.3 对比学习
传统的监督学习方法很大程度上依赖于大量的标注数据, 而标注数据往往需要领域的专家, 代价昂贵.
因此, 近年来, 无需外部监督信息的自监督学习方受到了研究者们的极大关注. 对比学习就是一种有效的自
监督学习方法, 它通过最小化相似样本的语义向量的空间距离, 同时最大化不同样本之间的距离, 目的是帮
助相近样本彼此更接近而不同样本彼此远离 [39] . 它可以使模型学到样本的重要且具有区分度的内在隐藏特
征, 进而将其应用于下游任务, 在计算机视觉和自然语言处理等领域得到了广泛研究, 如 SimCSE [40] 是一个基
于对比学习的方法来表示句子的通用嵌入的框架. 近年来, 有研究将对比学习应用到各种软件工程任务中,例
如: Coder [41] 是一种用于代码-代码检索、文本-代码检索和代码-文本摘要生成的对比学习方法; VarCLR [42] 是基
于不同的下游任务的对比学习模型, 旨在学习变量名称的语义表示. 最近, cpt-code [43] 也证实了对比学习预训
练可以得到代码更加丰富的语义表征. 在代码智能领域中, 设计源代码的数据增强方法成为应用对比学习的
关键. ContraCode [44] 通过源代码编译器在 JavaScript 上生成变体, 并进一步组合这些生成的变体作为数据增强
的一种方法. MuCoS [45] 应用一个名叫 JavaTransformer [46] 的工具包, 里面包含 9 种对 Java 源代码进行数据增强
的方法.
2 REcomp
本节将介绍 REcomp, 如图 2 所示.
多模态特征 多模态
源代码 数据增强(b) 编码器(b)
提取(a) 对比学习(c)
代码编码器 代码编码器 文本编码器 代码编码器
代码向量 代码向量 文本向量 代码向量
余弦相似性 余弦相似性
相似度计算 相似度计算
代码克隆检测 语义代码检索
comment tokens_ast function_name
源代码
1 def sum ( x , y ) : 文本级特征 词汇级-结构级特征 功能级特征
2 # Return the sum of two numbers 多模态 # Return the sum module function def sum parameters ( x , y ) : block Sum
3 result = x + y 特征提取 of two numbers expression_statement assignment result = binary_operator x + y
4 return result return_statement return result
(a) 多模态特征提取模块
多模态对比学习损失
layer1 layer2 layer3 …… layer11 layer12 TransF
TransF
TransF
TransF TransF TransF TransF TransF 原始样例 损失平均层
PL型样例 Loss1 Loss2 Loss3
TransF NL型样例 TransF 对比 对比 对比
TransF
TransF TransF TransF TransF TransF 学习 学习 学习
原始样例 PL型样例 NL型样例 + + ∗ ∗
[CLS] tokens_ast
[CLS] function_name [CLS]comment TransF
[SEP] tokens_ast [SEP] [SEP] [SEP] + ∗
function_name[SEP] Transformer模块
原始 PL型 NL型
(b) 数据增强模块和编码器模块 (c) 多模态对比学习模块
图 2 基于多模态对比学习的代码表征增强模型的框架图