Page 295 - 《软件学报》2024年第6期
P. 295
周光有 等: 基于关系图卷积网络的代码搜索方法 2871
相似度分数 score(q, p) ∈ R . 其中 a i 是一个权重参数.
2 ∑
score(q, p) = F (sim 1 , sim 2 ) = a i · sim i (14)
i=1
在搜索过程中, 代码库的所有代码片段图嵌入已经离线完成. 对于一个文本图 G q , 可以与代码库中的所有候
选代码图 G p 并行计算, 并快速得到每对文本和代码最终的相似度得分 score(q, p) . 相似度得分高的候选代码片段
会被返回, 整个搜索过程是快速高效的. 模型在大型的文本代码配对的语料库上以端到端的方式进行训练的. 具体
−
来说, 训练语料库 T 中的每一个训练样本都是一个三元组 < q, p, p > . 对于每个文本查询 q 和对应的代码片段 p ,
− −
随机从语料库中选中一个负样本代码片段 p . 模型的目标是预测得到 score(q, p) 的分数比 score(q, p ) 的分数高.
本文使用 margin 损失函数进行模型优化.
∑
−
L(θ) = max(0,δ− score(q, p)+ score(q, p )) (15)
<q,p,p − >∈T
δ
其中, θ 代表要训练的所有模型参数, 代表损失函数的边际值. 排名损失会促使文本查询和相关的正样本代码片
段的相似度得分上升, 而文本查询和负样本代码片段的相似度得分下降.
216 259
3 实验部分
3.1 数据集处理
本文在两个公开的代码搜索数据集上评估提出的 GraphCS 模型: FB-Java 数据集和 CSN-Python 数据集. FB-
Java 数据集是 Fackbook 团队 [22] 发布的可用于代码搜索任务的 Android 项目代码数据集. GitHub 团队于 2019 年
提出了评测代码搜索任务的基准数据集 CodeSearchNet Corpus [23] , 这个庞大的数据集包含 6 种编程语言的海量代
码文本对, 本文使用其中的 Python 数据集模块 CSN-Python. 要说明的是, 我们的数据集处理流程和图构建模块沿
用 Ling 等人 [24] 的方法和数据.
为了使数据集更好地评估代码搜索任务, 需要对数据集的每个函数或方法做一些必要的处理和移除工作. 首
先剔除没有文档描述和注释信息的代码片段, 这样的代码片段不适合用来训练模型. 代码行数少于 3 行或注释信
息少于 3 个单词的代码片段也移除, 不便于图的构建. 对于有方法重载或覆盖的片段和有重复信息的代码片段, 只
保留一种代码方法.
对于文本图构建模块, 可以应用 Stanford CoreNLP 工具包 [25] 生成注释文本的选区树, 并将选区树中的终端节
点链接起来. 对于代码图构建模块, 基于文献 [26,27] 的开源代码构建增强表示的抽象语法树. 并且在图构建阶段,
有必要限制文本图和代码图的节点最大数为 300, 过于庞大的图对实验设备要求更高, 所以舍弃节点数大于 300
的文本代码对. 最后从 FB-Java 数据集中, 得到了 226 259 对 Java 代码图和文本图, 从 CSN-Python 数据集中, 得到了
330 404 对 Python 代码图和文本图. 然后, 将数据集分为训练集/验证集/测试集, 统计结果如表 2 所示.
表 2 数据集划分
数据集 训练集 验证集 测试集
FB-Java 9 000 1 000
CSN-Python 312 189 17 215 1 000
3.2 模型参数设置
在图嵌入模块设置关系图卷积网络的层数是 1, 输入的节点维度为 300, 输出的节点维度为 100. 值得注意的
是, 本文的模型是基于 siamese 网络 [28] 进行训练的, 也就是说用于学习文本图和代码图表示的 RGCN 网络共享参
数. 这样不仅可以减少模型过拟合的可能, 还能使节点规模大小不同但结构语义相似的文本图和代码图经过关系
图卷积网络后更加接近.
文本图和代码图中每个节点都包含一个单词, 采用词嵌入工具 GloVe [29] 得到初始化的单词嵌入向量, 每个单