本发明涉及一种代码分类的方法,特别是一种基于神经网络语言模型的代码分类方法,可以对代码按照功能进行分类。
背景技术:
hindle等人利用统计学的方法将编程语言与自然语言进行了比较,发现它们有非常相似的统计学特性。这些特性对于人类来说非常难以捕捉,但是他们证明了可以将基于学习的方法应用在代码分析领域。基于机器学习的代码分析方法已经被研究了很长一段时间,在解决代码错误检测、代码重复性分析等问题时,依赖了大量的人工特征。对于一个具体的问题,这些特征需要大量的有标签的数据。而且该方法对于数据的表示是一种onehot的表示,即使用n维向量来对字典中的n个词进行编码。这样,在数据量增大的情况下会带来维度灾难的问题。经过研究表明,人工特征的效果可能要比自动学习的特征的效果还要差。例如在自然语言处理(naturallanguageprocessing,nlp)中,自动学习到的词的分类要比著名的词典wordnet还要准确。
技术实现要素:
基于以上技术问题,本发明提供了一种基于神经网络语言模型的代码分类方法,旨在解决代码分类时因符号表示方法造成维度灾难的技术问题。
本发明采用的技术方案如下:
一种基于神经网络语言模型的代码分类方法,包括以下步骤:
步骤1:将代码转换为ast树;
步骤2:初始化ast树结点ci的向量vec(ci),所述结点ci中非叶子结点pk的向量为vec(pk)1,所述非叶子结点pk的孩子结点tx的向量为vec(tx),其中vec(pk)1∈vec(ci),vec(tx)∈vec(ci),其中i表示结点的序号,k表示非叶子节点的序号,x表示孩子结点的序号;
步骤3:利用所述孩子结点tx的向量vec(tx),得到所述非叶子结点pk的重构向量vec(pk)2;
步骤4:利用ast_node2vec模型对所述结点向量vec(ci)进行学习,若不满足循环条件,更新结点向量vec(ci),跳转到步骤3;若满足循环条件,则输出更新了结点向量vec(ci)的ast树和更新后的非叶子结点pk的重构向量vec(pk)2;
步骤5:将更新了结点向量vec(ci)的ast树和更新后的非叶子结点pk的重构向量vec(pk)2作为基于树的卷积神经网络的输入,利用基于树的卷积神经网络完成对代码的分类。
进一步的,所述步骤2中,ast树的结点向量vec(ci)的初始化的方法为给所述ast树中的结点分别分配一个随机值向量。
进一步的,所述步骤3中,非叶子结点pk的重构向量vec(pk)2的计算步骤如下:
其中,n表示结点的个数,b表示大小为
进一步的,利用ast_node2vec模型对所述结点向量vec(ci)进行学习的步骤如下:
s401:计算非叶子结点pk的向量vec(pk)1和重构向量vec(pk)2之间的差异值,计算公式如下为:
s402:对ast树中的结点进行负采样,得到y个训练样例和y个由训练样例产生的负样例,训练样例与负样例的损失函数的计算公式如下:
其中,d(y)表示第y个训练样例的差异值,
s403:对ast_node2vec模型的参数进行正则化,得到的目标函数公式如下:
其中,m表示矩阵wl和wr中元素的个数且
s404:对所述目标函数使用随机梯度下降算法,使模型的参数得到调整,其中参数的更新公式如下:
其中,vec(ci)j表示结点向量vec(ci)中的元素,
进一步的,利用所述基于树的卷积神经网络完成对代码的分类的具体步骤如下:
s501:将非将更新了结点向量vec(ci)的ast树和更新后的非叶子结点pk的重构向量vec(pk)2作为基于树的卷积神经网络中编码层的输入,利用所述非叶子结点pk的向量vec(pk)1和重构向量vec(pk)2计算非叶子结点pk的线性组合向量vec(pk),计算公式如下:
vec(ek)=wcomb1·vec(pk)1+wcomb2·vec(pk)2(10),
其中,wcomb1表示非叶子结点pk的向量vec(pk)1的权重,wcomb2表示重构向量vec(pk)2的权重;
s502:将所述非叶子结点pk的向量vec(pk)1替换为所述线性组合向量vec(pk),其余叶子结点的向量不变,得到更新后的ast树;
s503:利用卷积层对更新后的ast树进行处理,即使特征探测器在ast树进行滑动,得到特征探测器输出h,计算公式如下:
其中,
s504:将卷积层输出的ast树输入到池化层进行处理;
s505:将池化层处理后的ast树输入到隐藏层进行处理;
s506:将隐藏层处理后的结果输入到输出层中,输出分类的结果。
综上所述,由于采用了上述技术方案,本发明的有益效果是:
基于神经网络语言模型,可利用分布式的表示方法表示ast树中结点的符号,能够有效的避免维度灾难的问题,特别是在处理大规模数据问题时;利用该分类方法能显示出语义上的相似性,充分利用了编程语言中丰富的结构化信息;利用抽象语法树来表示代码,不依赖于源语言的语法,对于所有编程语言来说具有通用性;利用无监督学习方式学习到结点的向量表示,有效地避免了使用深度神经网络时所遇到的梯度弥散问题;将代码进行分类,使相同功能的代码得到重复利用,提升软件的开发效率。
附图说明
图1是本发明的流程图;
图2是本发明的示意图。
具体实施方式
本说明书中公开的所有特征,除了互相排斥的特征和/或步骤以外,均可以以任何方式组合。
下面结合附图对本发明作详细说明。
一种基于神经网络语言模型的代码分类方法,包括以下步骤:
步骤1:利用工具pycparser将代码转换为ast树(抽象语法树)。
步骤2:初始化ast树结点ci的向量vec(ci),即给所述ast树中的结点分别分配一个随机值向量;所述结点ci中非叶子结点pk的向量为vec(pk)1,所述非叶子结点pk的孩子结点tx的向量为vec(tx),其中vec(pk)1∈vec(ci),vec(tx)∈vec(ci),其中i表示结点的序号,k表示非叶子节点的序号,x表示孩子结点的序号。
步骤3:为了使ast树中相似的结点间有着相近的向量表示,ast树中一个非叶子结点pk的向量表示可以由其孩子子结点的向量表示通过一个单层的神经网络得到;即利用孩子结点tx的向量vec(tx),得到所述非叶子结点pk的重构向量vec(pk)2的计算步骤如下:
其中,n表示结点的个数,b表示大小为
步骤4:利用ast_node2vec模型对所述结点向量vec(ci)进行学习,若不满足循环条件,更新结点向量vec(ci),跳转到步骤3;若满足循环条件,则输出更新了结点向量vec(ci)的ast树和更新后的非叶子结点pk的重构向量vec(pk)2,循环条件可设置为循环次数;
进行学习的步骤如下:
s401:计算非叶子结点pk的向量vec(pk)1和重构向量vec(pk)2之间的差异值,计算公式如下为:
s402:对ast树中的结点进行负采样,得到y个训练样例和y个由训练样例产生的负样例,训练样例与负样例的损失函数的计算公式如下:
其中,d(y)表示第y个训练样例的差异值,
s403:对ast_node2vec模型的参数进行正则化,得到的目标函数公式如下:
其中,m表示矩阵wl和wr中元素的个数且
s404:对所述目标函数使用随机梯度下降算法,使模型的参数得到调整,其中参数的更新公式如下:
其中,vec(ci)j表示结点向量vec(ci)中的元素,
步骤5:将更新了结点向量vec(ci)的ast树和更新后的非叶子结点pk的重构向量vec(pk)2作为基于树的卷积神经网络(tcnn)的输入,利用基于树的所述卷积神经网络完成对代码的分类,具体步骤如下:
s501:将非将更新了结点向量vec(ci)的ast树和更新后的非叶子结点pk的重构向量vec(pk)2作为基于树的卷积神经网络中编码层的输入,利用所述非叶子结点pk的向量vec(pk)1和重构向量vec(pk)2计算非叶子结点pk的线性组合向量vec(pk),计算公式如下:
vec(pk)=wcomb1·vec(pk)1+wcomb2·vec(pk)2(25),
其中,wcomb1表示非叶子结点pk的向量vec(pk)1的权重,wcomb2表示重构向量vec(pk)2的权重;
s502:将所述非叶子结点pk的向量vec(pk)1替换为所述线性组合向量vec(pk),其余叶子结点的向量不变,得到更新后的ast树;
s503:利用卷积层对更新后的ast树进行处理,即使特征探测器在ast树进行滑动,得到特征探测器输出h,计算公式如下:
其中,
s504:将卷积层输出的ast树输入到池化层进行处理,将结点ci的多维向量转化为一维向量,选取所述一维向量中的最大值,输出所述最大值;
s505:将池化层处理后的ast树输入到隐藏层进行处理,即将ast树中的结点ci与隐藏层中的每一个神经元进行连接;
s506:将隐藏层处理后的结果输入到输出层中,输出层采用的函为数softmax,输出分类的结果。
如上所述即为本发明的实施例。本发明不局限于上述实施方式,任何人应该得知在本发明的启示下做出的结构变化,凡是与本发明具有相同或相近的技术方案,均落入本发明的保护范围之内。