CodeBERT是一个针对PL与NL的双模态的预训练模型,CodeBERT基于Transformer,通过混合目标方法训练,预训练任务是替换词语检测(replaced token detection, RTD),即检测生成器中可行的替代样本。这个方法使模型既可以运用双模态数据(bimodal data,即NL-PL对)又可以运用单模态数据(unimodal data,即单纯的NL或PL)。双模态数据为模型训练提供输入的tokens,单模态数据便于生成器学习。CodeBERT在通过自然语言搜索代码任务和代码文档化任务中都取得了好结果。
光看摘要真的不知道是在干啥,接着往下看好了。
ELMo/GPT/BERT/XLNet/RoBERTa等一众预训练模型大幅提升了NLP任务完成水平。这些预训练模型通过MLM等自监督学习手段学习。预训练模型在NLP领域的成功也催生了别的领域内的预训练模型。
本论文介绍了CodeBERT的工作。CodeBERT是一个针对PL与NL的双模态预训练模型,CodeBERT能够抓住NL和PL的语义学联系,并生成可以用来完成各种关于NL-PL理解任务的向量表示。CodeBERT由多层Transformer构成。为了充分利用双模态和单模态数据,使用一个混合目标函数来训练。混合目标包含MLM和RTD(即首先使用一个生成器预测句中被mask掉的token,接下来使用预测的token替代句中的[MASK]
标记,然后使用一个判别器区分句中的每个token是原始的还是替换后的)。单模态数据可以为替换词语检测训练更好的生成器,训练得越好就可以生成更好的替代词汇。代码包含GitHub代码仓库中的六种语言,不显式标注语言类型。
这一段讲的就稍微能理解一些了。
首先是又介绍了一遍预训练模型(感觉已经介绍了三遍了)。
然后是讲了一下自己的模型与之前模型的不同。首先是既用了双模态数据又用了单模态数据,第二是与一个同时期的工作(Kanade et al., 2019)相对比有三点不同:①不止用了单纯的代码,还用了NL-PL结合的代码;②不止用了Python代码,一共用了六种不同语言的代码。③CodeBERT创新了训练方式,采用替换词语检测任务训练。
本段正式介绍模型。
采用与RoBERTa相同的模型架构,即多层双向Transformer。
在预训练阶段,将句子表示如下:
结合上次看的code2seq这个地方应该可以优化代码段的输入,用抽象语法树来表示代码段。
输出包括包含NL和PL在内每个token的向量表示。
还就那个双模态数据(NL-PL对)和单模态数据(单独的NL和PL),在论文里提过无数次了。
论文中此处提到了数据的来源及选取标准。
训练CodeBERT用到的两个任务:MLM和RTD。其中MLM用双模态数据,RTD用单模态数据。
输入:
目标:预测覆盖住的token是什么。
输入:
目标:确定句子中的词语是不是原本的那一个。
备注:生成器的训练方式在这篇论文中并没有被特别强调。论文中就是用的简单的n-gram模型。用n-gram也能练双模态的生成器。当然也可以不用n-gram用Transformer,论文中并没有涉及这部分工作了。
上面这两个任务的损失函数都是交叉熵损失函数。
以自然语言代码搜索为例,那就是先把自然语言过CodeBERT,然后把生成的向量过encoder-decoder架构。详情见下面实验部分。
输入为一段自然语言,输出为一堆代码段中最符合语义的那段代码段。这应该是一个选择任务而非生成任务。
本小节实验主要为了从一个小细节上去探究CodeBERT到底学了什么。因为预训练模型在fine-tuning上表现出色有可能是fine-tuning得好,并不一定就是这个预训练模型训得好,所以要设计任务看预训练模型本身是否学到了东西。
probing的目的是为了弄清楚在预训练模型的每一层中模型究竟学了什么。一般做法是设计一些简单的分类任务(一种任务包含一种特定的语言学信息),将 BERT 每一层的输出作为 embedding,在得到 embedding 后通过简单的分类器(例如一层的 FFN,为了不过多干扰模型本身的能力),来验证模型的不同层在不同 probing task 上的能力。
在本实验中,设定的NL-PL probing的目标是在一些干扰选项之间选择正确的masked token。一般而言,有两种干扰方式:其一是整个词汇表都用来生成干扰选项,第二种是根据专家的专业知识选取特定的一些干扰选项。此处选择第二种干扰方式。整个NL-PL probing其实就像是让电脑做完形填空。如果要看在NL上的表现,那就给完整的代码和遮盖过的文档(此处遮盖的词统一为最大(max/maximize)、最小(min/minimize)、小于(less)、大于(greater)),然后让电脑填空,看是否能填对。如果要看在PL上的表现也是一样,不过文中PL给了两种验证方式,一种是
代码文档生成任务的挑战在于训练CodeBERT时并没有做生成方面的任务,但最后结果居然是SOTA。
(讲真这个听起来就很nb)
这个的结果是比RoBERTa好但比code2seq差,也算是个好结果了。
本文提出了第一个同时针对NL和PL的大型双模态预训练模型CodeBert,在双模态和单模态数据上训练CodeBert,并在两个NL-PL下游任务中进行fine-tuning取得了SOTA的结果,接下来的工作目标有:①使用更好的神经网络架构;②在预训练时增加生成任务;③将AST等结构融入特征提取的过程中;④尝试更多的下游任务。