提起代码补全,有些人可能会下意识的认为这仅仅是一个普通的语言建模任务,模型只需要根据开发者之前写的代码预测之后的代码即可。因此使用最先进的预训练语言模型,再在代码数据上进行微调说不定是一种好方法。
但是李戈教授表示,这样的想法是远远不够的。预训练语言模型在代码补全任务中效果不佳,主要是因为代码补全任务本身存在诸多不同于自然语言分析任务的挑战。
首先是代码文本中存在的语义抽象性问题。代码的语义(功能语义)与其字面表示之间存在更大的差距。我们无法根据字面确定代码的准确语义。例如,在代码中,只改变一个字符就有可能完全改变整行代码的功能,因此处理代码的语言并准确提取其含义相比自然语言处理任务更棘手。
- f = open('word_ids.txt','r')f = open('word_ids.txt','w')
上图所示,在 Python 代码中,打开某个文件时使用「r」和「w」会实现完全不同的功能。
此外,代码的功能语义难以进行具体的表达和刻画,而且代码功能语义的表达方式多种多样。例如,有多种代码的形式文本用于实现某个功能,不能说某一种代码是对的而另一种是错的。
- list_a = [] for i in items: result = test(i) list_a.append(result) list_a = [test(i) for i in items]
如图所示,实现 list_a 的代码可以是多种多样的,但语言模型会将它们学习为完全不同的表征。
同时,代码文本本身的结构非常复杂。例如,代码的语义与代码结构(如行与行的缩进)之间存在较大的关联性,代码语义依赖于代码结构进行表达。这是预训练语言模型难以表示的特征。
最后,代码具有演化性的特征。代码较自然语言的迭代速度更快,因此预训练语言模型不能够及时捕捉演化特征。
考虑到代码语言中的诸多特性,单纯的预训练语言模型无法得到非常好的效果。
既然单独的语言模型不行,那么 aiXcoder 又结合了哪些技术,它又是靠什么来补全代码的?总体而言,aiXcoder 主要依赖于其特有的对程序代码进行学习的深度神经网络模型,该模型能够对程序的如下几类特征进行分析:
1. 程序的结构语义特征:程序语言是一种结构性很强的语言,程序的结构信息也体现着程序的语义。例如,抽象语法树是对代码进行解析的一种较为通用的结构,它体现了代码的语义特征,aiXcoder 便充分利用了抽象语法树,对程序员已经写下的代码的语义进行解读。
2. 程序元素间的逻辑关系:程序代码的不同元素之间存在着不同的关系,例如程序变量之间的引用关系、类之间的继承关系、方法与参数之间的调用关系等等。程序本身又可以表示为多种图,例如控制流图、数据流图、调用关系图等等。aiXcoder 借助图神经网络能够对程序元素之间的多种关系进行建模,从而能够对程序元素之间的复杂关系进行分析和推理。
- 3. 程序语言序列模型:当然,程序语言也具有与自然语言相似的一面,因此可以利用程序标识符之间的序列关系建立程序语言模型。aiXcoder 也使用了最新的深度学习语言模型对程序中的序列信息进行建模。
在获得程序代码的各种特征之后,就该把这些特征输入深度神经网络进行分析了,但这并不容易,因为在输入神经网络之前需要把这些特征进行向量化表示。在研究过程中,北京大学提出了一系列解决程序语言成分相量化的办法,并且在国际上最早发表了相关的论文,这些都为 aiXcoder 的构造打下了基础。 【编辑推荐】 - 程序员开发工具推荐:Windows上优秀的9个命令行工具
- 让开发人员变平庸的八个习惯,看看你中了几条
- 零代码入门GitHub,图形化交互让你可以轻松存代码
- 阿里巴巴如何管理代码分支?
- Dropbox工程师解释为什么放弃共享代码而使用原生语言
【责任编辑:张燕妮 TEL:(010)68476606】
点赞 0 (编辑:晋中站长网)
【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!
|