近年来,大规模预训练模型在自然语言处理领域取得了显著进展。这些模型通过在大量无标注文本上进行自监督训练,从而学会了有效的上下文表示。自然语言处理领域的成功经验,也推动了多模态预训练模型的发展,例如ViLBERT和VideoBERT。本文介绍了一种名为CodeBERT的新模型,该模型旨在通过学习自然语言和编程语言之间的语义关联,支持多种自然语言与编程语言相关的任务。
CodeBERT采用了Transformer作为基础网络结构。具体来说,它采用了与RoBERTa-base相同的配置,即12层,每层有12个注意力头,每个头的大小为64,隐藏层维度为768,总参数量约为1.25亿。模型的输入由自然语言文本和编程语言代码组成,两部分都使用与RoBERTa-base相同的分词器进行处理。
预训练数据集方面,研究者使用了Husain等人于2019年提供的CodeSearchNet数据集。该数据集包含了210万条自然语言和代码对的数据,以及640万条仅有代码的数据。数据集中涵盖了六种编程语言,具体统计结果见表1。
为了充分利用双模数据和单模数据,研究者提出了一个混合预训练目标:掩码语言模型(MLM)和词替换检测(RTD)。
将自然语言和编程语言的组合文本作为输入,随机选择自然语言或编程语言的部分进行掩码处理,然后用特殊掩码符号替代这些位置。模型的目标是预测出被掩码的原始单词。
首先分别用单模的自然语言和代码数据训练两个生成器,用于生成掩码位置的合理替代词。此外,还有一个判别器负责检测单词是否为原词。该判别器实际上是一个二分类器,如果生成器生成的词正确,则标记为真,否则为假。模型架构如图2所示。
最终的预训练目标为:
预训练完成后,CodeBERT需要在下游任务中进行微调。例如,在自然语言代码检索任务中,模型采用与预训练相同的输入方式。而在代码到文本生成任务中,则使用编码器-解码器框架,并用CodeBERT初始化编码器。
为了验证CodeBERT的有效性,研究者进行了四个不同场景下的实验:自然语言代码检索、自然语言与编程语言探针(NL-PL probing)、代码文档生成和在未经过预训练的编程语言上的泛化性能。
实验使用了Husain等人于2019年发布的CodeSearchNet语料库,其中包括六种编程语言的数据。评估指标为MRR(均值倒数排名),同时计算六种编程语言的宏平均。实验结果表明,CodeBERT在所有编程语言上均表现出色,优于现有模型。
这部分实验旨在探究固定模型参数的情况下,CodeBERT究竟学到了哪些知识。为此,研究者构建了一个新的探针数据集,将其构造成多项选择题的形式。模型在三个不同设置下的表现均优于其他模型。
研究者探讨了在预训练的六种编程语言上,代码到文档生成任务的表现。实验结果表明,CodeBERT在所有编程语言类别中均取得最佳效果。
为了进一步评估模型的泛化能力,研究者在C#编程语言上进行了代码文档生成任务的测试。实验结果显示,相比RoBERTa,CodeBERT表现更优,但略逊于Code2Seq,可能是因为后者更有效地利用了代码中的抽象语法树(AST)信息。
本文提出了一种面向编程语言和自然语言的预训练模型——CodeBERT,并在多个下游任务中展示了其优越性能。此外,研究者还构建了首个自然语言与编程语言探针数据集,以探究预训练模型学到的知识类型。尽管CodeBERT已经取得了很好的成果,但仍有许多方向值得进一步探索,例如引入与生成相关的预训练目标函数,以及考虑编程语言的AST结构信息等。
AI科技联合机械工业出版社华章公司推出15本“新版蜥蜴书”正版旧书赠送活动。活动时间为2020年10月24日至10月31日。参与者需在指定文章的评论区留言,分享自己对本书内容的看法或对机器学习/深度学习的理解。留言点赞最高的前15位读者将获得《机器学习实战:基于Scikit-Learn、Keras和TensorFlow(原书第2版)》一本。活动规则如下:
活动详情及留言入口请参考原文链接。