Conference: NIPS 2019
Authors: Rahul Gupta, Aditya Kanade, Shirish Shevade
Institution: Indian Institute of Science, Google Brain
dataset and code: https://bitbucket.org/iiscseal/nbl/src/master/
研究动机
代码错误定位任务和目前的研究现状如下:
- 学生在Online Judge (OJ) 平台上提交程序,可以得到即时的反馈。但当学生得到Wrong Answer或其他错误结果的反馈时,在没有其他提示信息的情况下,学生往往较难debug他们的程序。所以作者想做的是学生代码的错误定位。
- 代码错误定位的研究较难,因为缺少错误代码行的groundtruth,并且对精度要求较高。
- 现有的研究存在的问题包括:依赖于启发式的规则;依赖于特定的编程语言;需要执行暴力搜索。
基于此,作者提出NeuralBugLocator,简称NBL。主要从两方面做了创新,一方面是AST的编码方式,该方式可以更有效地对任意形状的AST进行批训练;另一方面是利用prediction attribution技术分析错误代码行的位置。
具体方法
NBL主要包含两个部分,Tree convolutional neural network 和 neural prediction attribution。树卷积神经网络用来学习代码的表示,预测该段代码是否可以通过测试用例,即二分类问题。对于预测为0(不能通过测试用例)的代码段,利用neural prediction attribution技术反推哪行代码使得神经网络预测为0。过程如下图所示:
CNN可以获取到邻居的信息,但是无法获取层次信息。为此,Mou提出tree-based CNN。但是实现困难,并且不支持不同大小程序的批计算。作者提出了一种AST的重新编码方式,编码后,就可以直接使用传统的CNN来学习AST的表示。
AST 转换为矩阵:
- 根据AST进行广度优先遍历,形成一个序列
- 对于序列中每一个非终结节点,用一个列表来表示它,这个列表的第一个元素是该节点,接下来的元素是该节点的直接子节点
- 这样就可以形成一个序列长度不等的2维列表,而使用CNN需要将该数据进行padding,首先是对于每个列表长度的padding,其实是列表个数的padding,保证每个程序形成的矩阵的两个维度都是一样的。所以最终每个AST转换后的矩阵维度都是:|max_subtrees| * |max_nodes|
Tree Convolutional Neural Network:
AST转换为矩阵之后,就可以利用传统的CNN进行卷积操作,得到代码的向量表示了。卷积操作如下图:
Prediciton Attribution:
- 作者使用的Prediction attribution技术是[25]中提出的integrated gradients方法。运用该方法需要一个neutral baseline。
- 对于输入的错误代码,使用与之最相近的一个正确代码作为neutral baseline,然后根据该方法得出每一行语句对于预测出该段代码为错误代码的贡献值。
实验设计
训练数据集:
- 包含29个编程题目
- 共有231个测试用例,平均每题有8个测试用例
评估数据集:
因为评估过程需要代码错误行的groudtruth,本文通过对比错误代码和对应的正确版本代码的区别,自动构建评估数据集。(这里采用的工具是Python’s difflib,可以得出每一行的区别)
论文分析
- prediction attribution依赖于TCNN分类的结果,而文中给出的分类准确率受到数据集构造的影响,并不稳定,大致在72%。这一结果对于后续阶段的predition attribution的影响较大。
- prediction attribution在本文中的应用,选用的baseline是错误代码对应的正确版本,本质上是正确和错误版本的对比。对于没有正确版本的代码貌似无法给出错误定位的信息,也就很难延伸到工业场景。
- 文中仅对预测为0的代码进行prediction attribution的分析,发现哪一行代码对于预测这段代码为错误起到作用。但我不太明白,如果对预测为1的代码也进行prediciton attritbution的分析,应该怎样理解得到的结果呢?
- 文中使用的训练数据集规模小,训练的模型可能会产生过拟合。