【论文精度】PLBART: Unified Pre-training for Program Understanding and Generation

PLBART: Unified Pre-training for Program Understanding and Generation

论文地址:https://arxiv.org/pdf/2103.06333

代码地址:https://github.com/wasiahmad/PLBART

在这里插入图片描述

Abstract

​ 代码摘要和生成支持编程语言(PL)和自然语言(NL)之间的转换,而代码翻译则有助于将旧代码从一种 PL 迁移到另一种 PL。本论文介绍了 PLBART,这是一种序列到序列模型,能够执行广泛的程序和语言理解和生成任务。PLBART 通过去噪自动编码在广泛的 Java 和 Python 函数集合以及相关的 NL 文本上进行了预训练。对七种编程语言的英语代码摘要、代码生成和代码翻译的实验表明,PLBART 优于或与最先进的模型相媲美。此外,对判别任务(例如程序修复、克隆检测和漏洞代码检测)的实验证明了 PLBART 在程序理解方面的有效性。

1. Introduction

​ 论文的目标在于构建一个通用的模型用于不同的PLUG(Program and Language Understanding and Generation)任务。PLUG任务的一个重要方面在于它们需要对程序的语法和语义、以及PL和NL之间的相互依赖有深刻的理解。例如:

在这里插入图片描述

如Figure 1所示,展示了两种PL对相同算法(sorting)的实现,以及对应的NL总结。在这个例子中,自动翻译工具必须理解在Python中的sorted函数与java中的Arrays.sort函数的作用是一样的、Python中的lambda操作与java中的Comparator操作是等价的;同样,一个用于对代码进行总结的工具必须理解Python中的x[0]和java中的Tuple.get(0)都是表示元组列表中的第一个元素。

​ 语言生成任务(例如代码摘要)被建模为seq2seq学习,其中encoder学习对输入代码进行编码、解码器生成目标摘要。尽管现有方法都很有效,但是它们并没有预先训练好的语言生成解码器,因此仍然需要大量的并行数据来训练解码器。为了解决这一问题, Lewis et al. (2020) 提出了去噪序列到序列的预训练,其中Transformer学习重建使用任意噪声函数损坏的原始样本; Lachaux et al. (2020) 研究了使用一个大规模的针对无监督程序翻译的源代码集去噪预训练,并发现这种方法很有用。与其他双模态场景不同,PL和相关联NL文本共享相同的字母表或使用可以帮助学习跨语言语义空间之间的对齐的anchor token(eg. “sort”,“list”,“tuple”)。

​ 本论文介绍了PLBART模型,一个在PL与NL未标记数据上的双向和自回归transformer预训练,学习适应与广泛(broad spectrum)PLUG任务的多语言表示,在代码摘要、生成、翻译、程序修复、克隆检测和漏洞检测等任务上对PLBART进行了评估,实验结果表明PLBART优于CodeBERT和Graph-CodeBERT等主流方法,在程序理解和生成方面具有较好的应用前景。通过深入分析表明,PLBART能够学习程序语法和逻辑数据流,即使在注释数量有限的情况下也能学习到较好的程序语义。

2. PLBART

PLBART使用去噪序列到序列预训练来利用PL和NL的未标记数据,预训练使得PLBART能够对语言语法和语义进行推理,同时学习连贯地(coherently)生成语言。

2.1 Denoising Pre-training

(1)Data & pre-processing:分别在GitHub和Stack Overflow的大量java和Python函数以及自然语言描述上对PLBART进行了预训练;按照Lachaux et al.(2020)的预处理管道提取java和Python函数;收集了Stack Overflow帖子(posts,包括问题和答案,排除代码片段),预训练数据集如Table 1所示:

在这里插入图片描述

使用一个在1/5的预训练数据上学习的句子片段模型(sentencepiece model, Kudo and Richardson,2018)对所有数据进行分词。

汇总来自不同模态的数据的一个关键挑战在于一些模态可能有更多的数据(例如,PL的数据是NL数据的14倍),因此,论文对数据进行**混合和上下采样(mix and up/down sample)**以减轻(allevate)PL的偏置;根据一个概率多项式分布采样用于预训练的实例:在这里插入图片描述
,其中,N是语言总数、ni是语言i中的实例总数、平滑参数α设置为0.3

(2)Architecture: PLBART使用与BART_base相同的架构,它使用seq2seq的Transformer架构,带有6层encoder和6层decoder,模型尺寸为768和12头(约140M参数);唯一的不同点在于,PLBART在编码器和解码器之上添加了一个额外的层归一化层,有助于以FP16的精度稳定训练

(3)Noise function:在去噪自编码(denoising autoencoding) 中,一个模型学习重建一个被噪声函数破坏的输入文本,这需要模型学习语言的语法和语义。本文中,使用了三种噪声策略(noising strategies):token masking、token deletion、token infilling。前两种策略中,采样随机的token并替换为一个mask token或者从输入序列中删除;在token infilling中,一系列文本跨度被采样并被替换为一个单一的mask token,跨度长度由泊松分布(λ=3.5)得到。对每个实例的35%的token进行了掩码。

(4)Input/Output Format:encoder的输入是一个噪声文本序列,decoder的输入是一个带有一个位置偏置的原始文本。一个语言id标记(例如,,)分别被追加(append)和前置(prepend)到encoder和decoder的输入中。输入实例如果超过最大序列长度512将被截断(truncated),具体例子如Table 2 所示。

疑问:这个例子中,表中说的是encoder input和decoder output,不应该是encoder input与decoder input吗?

在这里插入图片描述

(5)Learning:PLBART在N种语言中进行预训练(本文样例中N=3),每种语言Ni有一个无标记实例集Di = {x1, …, xni},每个实例使用噪声函数f进行破坏,训练PLBART从f(x)去预测原始实例x,正式地,PLBART训练为最大化Lθ在这里插入图片描述
,其中,mi是语言i的采样实例数量;P是在标准序列到序列解码之后估计的。

(6)Optimization:在8个Nvidia GeForce RTX 2080 Ti GPUs中训练100K steps,有效批处理大小维持在2080个实例;使用带有线性学习率衰减的Adam(ε = 1e-6, β2 = 0.98) 进行优化;开始训练时dropout设置为0.1,50K steps时将其减到0.05/80K steps时将其减到0(有助于模型更好地拟合数据);总共的训练时间大约276小时(11.5 days)。

2.2 Fine-tuning PLBART

针对两大类下游任务对PLBART进行微调

(1)Sequence Generation:PLBART有一个encoder-decoder架构,其中decoder能够自回归地生成目标序列,因此在序列生成任务(例如代码摘要、代码生成、代码翻译)上可以直接对PLBART进行微调。与去噪预训练不同,源序列在微调期间作为encoder的输入,然后decoder生成目标序列(源序列域目标序列可以是一个代码片段或者文本序列)。Table 3展示了一些PLBART用于不同生成任务的输入输出示例。(PLBART在解码序列中前置一个语言id,可以使得PLBART支持多语言设置,如多语言代码生成)。

在这里插入图片描述

(2)Sequence Classification:输入序列被同时喂给encoder和decoder。对于一个输入对,通过插入一个特殊的token(“”)将它们连接起来,在输入序列尾部添加一个特殊的token;来自最后一个decoder层的最后一个token的表示被喂给一个线性分类器用于预测。

(3)Optimization:微调PLBART,使其在所有下游任务的最大100K步和2500步的warm-up步骤;设置maximum learning rate = 3e-5、batch size = 32、dropout rate = 0.1。基于验证BLEU(生成任务)或准确性(分类任务)选择最终模型。

3. Experiment Setup

重点评估PLBART在源代码和相关自然语言文本中捕获丰富语义的能力。

3.1 Evaluation Tasks

将任务分为四类,数据集如Table 4所示。

在这里插入图片描述

(1)Code Summarization

(2)Code Generation:在Concode数据集上对PLBART进行微调。

(3)Code Translation

(4)Code Classification

3.2 Evalution Metrics

(1)BLEU:计算生成序列和引用集(a collection of references)之间的n-gram overlap。对所有生成任务使用语料库级别的BLUE评分,除了代码摘要任务使用平滑的BLEU-4评分。

(2)CodeBLEU:对生成代码的质量的评估标准。与BLEU不同,CodeBLEU同时基于抽象语法树和数据流结构考虑生成代码的语法和逻辑准确性。

(3)Exact Match(EM):计算生成的序列是否与目标序列完全匹配。

3.3 Baseline Methods

分为两类,将PLBART与其他SOTA模型进行对比。

3.3.1 Training from Scratch

Seq2Seq:带有注意力机制的基于LSTM的seq2seq模型,词汇表使用字节对编码进行构建。

Transformer:是PLBART和其他预训练模型的基础模型,Transformer baseline有跟PLBART相同的参数数量。

3.3.2 Pre-trained Models

PLBART包含一个encoder和一个自回归(autoregressive)decoder,在两类预训练模型中与PLBART进行对比:①encoder-only models (eg. RoBERTa,CodeBERT, GraphCodeBERT)(在特定任务中使用一个随机初始化的decoder进行微调);②decoder-only models(eg. CodeGPT)

RoBERTa, RoBERTa (code):RoBERTa在NL中预训练;RoBERTa(code)在CodeSearchNet的源代码上进行预训练。

CodeBERT:将maksed language modeling(MLM)和replaces token detection(RTD) 目标结合起来预训练一个Transformer encoder。

GraphCodeBERT:通过建模代码token这一件的数据流边来改进CodeBERT

GPT-2, CodeGPT-2, and CodeGPT-adapted:GPT-2是在NL预料上预训练的;CodeGPT-2与CodeGPT-adapted是在CodeSearchNet上预训练的。

4. Results & Analysis

目的在于确定以下问题:

  • PLBART是否从未标记数据中学习强大的程序和语言表示?
  • PLBART是否学习程序特征,例如语法、风格、逻辑数据流?
  • PLBART在注释有限的新的语言中表现如何?

4.1 Code Summarization

在这里插入图片描述

  • 在6中编程语言的测试中,PLBART在其中5种编程语言的性能是最优的,比CodeBERT平均高出了0.49个BLEU score.
  • 与CodeBERT不同,PLBART并没有在Ruby语言上预训练过,但是却取得了最优的性能,这表明PLBART能够更好地学习泛型程序语义。
  • PLBART在PHP语言表现差,潜在的原因是预训练模型的句法和PHP语言句法不匹配;而RoBERTa在PHP的表现比PLBART更优,猜测是因为RoBERTa仅在自然语言上进行预训练,不会收到语法不匹配问题的影响。
  • 总体而言,与Transformer基线相比,PLBART的BLEU-4 score平均提高了2.76,,将这一改进归功于预训练步骤。

4.2 Code Generation

在这里插入图片描述

  • 在BLEU和CodeBLEU指标上PLBART是最优的,在EM指标上CodeBERT-adapted是最优的。这表明PLBART生成的代码再语法和逻辑上比所有的基线都正确得多。

  • 图2展示了PLBART生成的一个代码示例,生成的代码与引用代码语义上是等价的
    在这里插入图片描述

  • 为了研究PLBART是否在预训练或者微调期间学习了代码语义和逻辑流,做了一个消融实验(ablation study),使用训练样本子集(10K, 20K, 50K)去对PLBART进行微调,如Table 6所示。近使用10K 样例时,PLBART在CodeBLEU标准上比所有基线都要优,这表明PLBART在预训练期间学习了程序的语义和数据流信息,在下游任务上有很好的性能。

  • 生成语法和逻辑上正确的代码一直是程序生成中的一共大挑战,论文猜测PLBART的大规模去噪序列到序列的预训练有助于理解程序语法和逻辑流,从而使得PLBART能够生成语法和逻辑上有效的代码。

4.3 Code Translation

在这里插入图片描述

  • 如Table 7所示,PLBART获得SOTA性能。尽管PLBART没有在C#语言上预训练过,但是因为java和C#之间有很强的语法和语义相似性,因此PLBART理解C#语言的语法和语义。

在这里插入图片描述

  • Figure 3展示了PLBART翻译生成的C#代码与引用代码的对比,它们并不完全一致,但是在语义上是等价的。这进一步证明(corroborate)了PLBART的语法理解及其对源代码中数据流的推理(reason)能力。

在这里插入图片描述

  • 在程序修复任务上,输入和输出是同一种语言,但是输入是带有bug的代码,输出是无bug的代码,因此在该任务中EM是关键指标。如Table 8所示,PLBART的性能与GraphCodeBERT相当,后者使用结构感知的预训练来学习程序语法和语义。

4.4 Classification

在这里插入图片描述

  • 如Table 9所示,在克隆检测和缺陷检测任务上,PLBART比CodeBERT性能都要更优。
  • PLBART和CodeBERT在缺陷检测方面都不是最先进的,因为基于图的模型在这一任务中表现最好。

5. Related Work

(1)Pre-training for Language Understanding and Generation:BERT在学习上下文表示中具有很好的性能,但是在生成任务中并不那么有效;GPT使用自回归预训练,在生成任务上表现较好,但是不是双向的(bidirectional);BART是一个使用一个双向的encoder和一个自回归的decoder的去噪自编码器(denoising autoencoder)。与BART类似,PLBART使用去噪预训练去处理生成任务,并联合学习编程语言和自然语言的多语言表示。

(2)Deep Learning in Software Engineering

6. Conclusion

PLBART在各种下游软件工程任务中(包括代码摘要、代码生成、代码翻译)中取得了SOTA性能,同时在程序理解任务中也有效。PLBART通过预训练学习到了摘要的程序特性,例如语义、常规标志符命名、数据流等。

7. 代码理解

(待补充)

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
"YOLO:统一、实时的目标检测"简称YOLO,是一种深度学习算法,用于实时目标检测。它的核心思想是将目标检测问题转化为单个统一的回归问题,使得只需一次前向传播即可直接预测出目标的位置和类别。 相比于传统的目标检测方法,YOLO具有显著的优势。首先,YOLO采用了统一的网络结构,端到端地完成整个目标检测过程。这意味着不需要将图像分割成多个部分进行处理,减少了冗余计算,提高了计算效率。 其次,YOLO实时性能出色。它将目标检测任务与边界框回归深度学习模型相结合,使得可以在一次前向传播中同时预测出多个目标的位置和类别。因此,YOLO在速度上远远超过了传统的基于滑窗的目标检测方法。 此外,YOLO还采用了多尺度的特征图来检测不同大小的目标。通过在不同层级的特征图上进行预测,YOLO可以有效地捕捉目标的多尺度信息,并提高了目标检测的准确性。 然而,YOLO也存在一些局限性。由于采用了统一的网络结构,YOLO对小尺寸的目标检测相对较差。此外,当目标之间存在重叠或者遮挡时,YOLO可能会出现漏检或者虚警的情况。 总而言之,YOLO是一种统一、实时的目标检测算法,具有高效、准确的特点。它在图像处理、智能安防、自动驾驶等领域具有广泛的应用前景。然而,为了提升其性能,在处理小尺寸目标和目标重叠等复杂场景时,仍需要不断的研究和优化。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值