Title: **
learning to represent programs with graph
**
Authors: Miltiadis Allamanis 、Marc Brockschmidt 、Mahmoud Khademi
Address: Microsoft Research
Publication: ICLR2018
代码:https://github.com/Microsoft/gated-graph-neural-network-samples
数据集: https://aka.ms/iclr18-prog-graphs-dataset
Issues
各种开源社区的源代码可以说是一个大数据–big code。利用现有的机器学习技术来对这些big code进行分析处理,能达到更好的效果。但是首要的问题是如何将这些程序源代码进行表示能够更好地适应各种任务。现在大多数的研究是类比程序语言和自然语言,利用自然语言的方法来进行处理。这些方法不能捕捉到代码中的语义信息(PS:原文这样描述的 does not capitalize on the unique opportunities offered by code’s known sematics(这里应该少个n, semantics)),而且对于长序列依赖,比如相隔较远的变量和函数,这种关系很难被捕捉(long-range dependencies induced by using the same variable or function in distant locations are often not considered)。
解决的办法是将程序用图来表示,通过不同类型的边表示节点之间的不同关系,以此解决长序列依赖问题,同时可以学到程序的语义和语法信息。
Methodology
图神经网络采用GGNN(Gated Graph Neural Network)。一个图用G=(V,ε,X)来表示。
V是所有的节点的集合;ε是所有的有向边类型 ε=(ε1,ε2,…,εk)k表示类型的多少;X是节点的特征,对于每个节点v∈V,其特征用实值向量x(v)来表示。对于节点v,除了有个初始的特征向量x(v),还有状态向量h(v),其维数可以和特征向量一样,也可以用更大的维数(在特征向量后面padding)。
**程序图的表示。**整个图的骨架是抽象语法树,由syntax nodes(描述token的部分)和syntax tokens(实际上token)组成。用Child edge 来连接syntax nodes,用NextToken来连接syntax tokens。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-KyErEcs1-1594777745938)(C:\Users\khy\AppData\Roaming\Typora\typora-user-images\image-20200427161036812.png)]
上图是Assert.NotNull()
的AST表示,其中蓝色框表示syntax node,其中的内容通过编程的语法确定;黑色框表示syntax token,其中的内容就是本身字符串形式。
除了有Chile edge和NextToken来表示一个statement间的关系外,还需要不同语句间的关系和代码块之间的关系。因此还要有捕捉控制流信息和数据流信息的边信息。加入了LastRead 、LastWrite 、ComputedFrom、LastLexicalUse、ReturnsTo、FormalArgName、GuardedBy、GuardedByNegation 等8种类型的边。
LastRead边是指这样的一种关系,同一变量在不同时刻的token之间的关系:给定某个时刻的变量v的token,此时变量v的具体值是源自其它时刻变量v的token。那些变量v的token与此时变量v的token之间就是LastRead关系,由此时变量v指向来源的变量v的token。
LastWrite边也是指这样的一种关系,同一变量在不同时刻的token之间的关系:给定某个时刻的变量v的token,对于在此时变量v的token后面出现的所有变量token,如果这些变量的token,
因为这些边都是有向边,所以将每个边反向,将这些边变成双向边来提高模型的表达能力。(原文是for all types of edges we introduce their respective backwards edges (transposing the adjacency matrix), doubling the number of edges and edge types)
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-4orxsgXv-1594777745940)(C:\Users\khy\AppData\Roaming\Typora\typora-user-images\image-20200427202618246.png)]
上图是 (x1,y2) = Foo(); while(x3 > 0) x4 = x5 + y6
(x1,y2) = Foo();
while(x3>0)
x4 = x5 + y6
这两句代码的其它边关系。红色点边为 LastUse 、绿色虚线为LastWrite、紫色点虚线为 ComputedFrom。
变量类型表示。 作者这里假设是静态类型的编程语言(C/C++/java等,这些语言的变量类型只能是确定的且不能改),并且能够被编译的。对于已知类型的变量,τ(v)表示为其类型。然后将这些类型映射成r(τ),即数值的形式,因为需要输入到神经网络。
**初始化节点的表示。*将将节点的字符串按照两种规则来进行切分。camelCase和Pascal_Case,即根据首字母大写和下划线“_”连接的方式,将一个token分成几个subtoken,然后将这些 subtoken的embedding进行取平均作为整个token的embedding. 最后将之前的变量类型所对应的向量r(v)和token 的embedding连接起来然后通过一个线性layer得到每个节点的初始表示。
对两种任务的描述 VARNAMING 和 VARMISUSE。对VARNAMING,给定一个程序和一个变量v,然后将程序转换成程序图,并将其中有关变量v的所有token用替换。为了预测替换的token的name,首先将节点的初始状态(token name和token type)作为输入,然后经过GGNN 8个时间步,最后将所有用替换的token的embedding取平均作为变量的表示。然后将从图中输出的变量表示,输入到一层的GRU中,然后预测目标变量的name,以一种subtoken序列形式。
对于VARMISUSE
Implementation
对于大图多图的训练通常不好处理,
oken序列形式。
对于VARMISUSE
Implementation
对于大图多图的训练通常不好处理,