譚丁武,張坤芳,劉 燕,鄭一基,魯鳴鳴
中南大學(xué) 信息科學(xué)與工程學(xué)院,長沙410083
隨著開源代碼倉庫的涌現(xiàn)和機(jī)器學(xué)習(xí)技術(shù)的發(fā)展,源代碼數(shù)據(jù)挖掘受到了廣泛的關(guān)注[1]。在源代碼挖掘領(lǐng)域,如何學(xué)習(xí)代碼中的語義嵌入表達(dá)尤為重要。通過機(jī)器學(xué)習(xí)得到的代碼嵌入表達(dá)不僅能輔助人工理解代碼[2],還能促進(jìn)計(jì)算機(jī)自動編碼的研究[3]。
早期的源代碼數(shù)據(jù)挖掘工作受到自然語言處理(NLP)的啟發(fā),研究者們傾向于將源代碼看作文本序列,進(jìn)而將自然語言處理系列模型應(yīng)用到源代碼各種相關(guān)任務(wù)上[4-8]。然而,源代碼和自然語言不同。一方面,自然語言天然地?fù)碛袛?shù)目相對固定的詞庫,而在源代碼中,類名、變量名和函數(shù)名都沒有限制;另一方面,自然語言對于語法結(jié)構(gòu)要求松散,而源代碼往往具有較為嚴(yán)格的語法規(guī)范。
為了解決上述問題,部分工作[9-13]提出采用抽象語法樹(Abstract Syntax Tree,AST)刻畫源代碼的語法結(jié)構(gòu)信息。AST是在程序設(shè)計(jì)語言語法規(guī)則的指導(dǎo)下,對源代碼進(jìn)行文法解析而產(chǎn)生的中間表達(dá)形式。AST 用于描述源代碼中各種語法成分組成,其通常將相應(yīng)程序設(shè)計(jì)語言解析成樹狀結(jié)構(gòu)的抽象語法樹。
雖然基于抽象語法樹的技術(shù)充分利用了源代碼中靜態(tài)語法結(jié)構(gòu)信息,但這些方法卻忽略了動態(tài)運(yùn)行時(shí)數(shù)據(jù)信息(語義信息),例如數(shù)據(jù)流信息、控制流信息等。因此,本文提出一種用于構(gòu)建包含動態(tài)數(shù)據(jù)信息和靜態(tài)語法結(jié)構(gòu)信息的程序代碼表示圖(EAST)的方法。并且結(jié)合EAST圖的數(shù)據(jù)特點(diǎn),本文進(jìn)而提出基于注意力機(jī)制的門控圖神經(jīng)網(wǎng)絡(luò)(Gated Graph Attention Neural Network,GGANN)用于學(xué)習(xí)EAST圖的嵌入表達(dá),以完成程序分類任務(wù)。GGANN 模型考慮到節(jié)點(diǎn)在圖中拓?fù)浣Y(jié)構(gòu)性質(zhì)的差異性,從而摒棄了原始模型中對鄰域信息的簡單累加操作。GGANN中,注意力機(jī)制構(gòu)建的注意力層實(shí)現(xiàn)了帶權(quán)重的鄰域信息匯集。而且,以注意力機(jī)制為注意力層的方法,有效地解決了領(lǐng)域節(jié)點(diǎn)數(shù)目動態(tài)變化的問題。
早期的源代碼挖掘領(lǐng)域,大部分存在的工作都依賴于自然語言相關(guān)技術(shù),從而傾向于將源代碼解析成關(guān)鍵字序列[4-5,14-15]或者API序列[6-7]。這些工作涉及的任務(wù)主要分為以下幾種:序列預(yù)測、代碼與自然語言互譯、代碼補(bǔ)全以及變量名預(yù)測。文獻(xiàn)[5]驗(yàn)證了源代碼具備與自然語言一樣具有統(tǒng)計(jì)特性,因此,他們使用N 元統(tǒng)計(jì)模型(N-Gram)為源代碼建模,之后又證明了他們的模型能夠提高Eclipse 自動補(bǔ)全代碼的能力。Bhoopchand等[16]使用端到端的指針網(wǎng)絡(luò)(Pointer Network)實(shí)現(xiàn)自動IDE代碼補(bǔ)全。Gu等[6]則采用編碼器-解碼器模型學(xué)習(xí)API使用序列和自然語言描述之間的映射關(guān)系。
為了刻畫源代碼中的靜態(tài)語法結(jié)構(gòu)信息,Mou等[11-13]設(shè)計(jì)出一種基于樹的卷積神經(jīng)網(wǎng)絡(luò)模型(Tree Based Convolution Neural Network,TBCNN)。TBCNN 模型直接在AST 上做卷積處理,從而將AST 映射成蘊(yùn)含語法結(jié)構(gòu)信息的嵌入向量。文獻(xiàn)[9]則進(jìn)一步利用TBCNN模型實(shí)現(xiàn)了Java程序語言和C++程序語言之間的代碼轉(zhuǎn)換。
與自然語言不盡相同,程序語言有一個(gè)很突出的特點(diǎn)就是可運(yùn)行性。因此,僅僅考慮靜態(tài)的語法信息遠(yuǎn)遠(yuǎn)不夠,而如何融入“運(yùn)行”時(shí)的程序語義信息顯得尤其重要和棘手。Allamanis 等[17]提出直接將“運(yùn)行”時(shí)信息融入抽象語法樹,但是擴(kuò)展后的抽象語法樹不再是嚴(yán)格意義上的樹形結(jié)構(gòu)。這時(shí)的抽象語法樹不再是完全地自頂向下的結(jié)構(gòu),甚至可能產(chǎn)生環(huán)。顯然,原有的基于樹的卷積神經(jīng)網(wǎng)絡(luò)模型已經(jīng)不能處理這樣的抽象語法樹。隨著圖神經(jīng)網(wǎng)絡(luò)(GNN)[18-19]在不同領(lǐng)域展現(xiàn)出的強(qiáng)大學(xué)習(xí)能力,源代碼領(lǐng)域研究者們深受啟發(fā)。他們認(rèn)為樹是弱化的圖,因此使用圖神經(jīng)網(wǎng)絡(luò)學(xué)習(xí)當(dāng)前擴(kuò)展后的抽象語法樹恰恰解決了之前模型不適用的問題。Li等[20]的核心思想就是利用GNN 模型為源代碼建模,以此獲得源代碼分布式向量表達(dá)。
基于上述相關(guān)研究,本文提出一種基于門控圖神經(jīng)網(wǎng)絡(luò)與注意力機(jī)制的程序分類方法。該方法針對在線判題(OJ)系統(tǒng)收集的C++源代碼建立深度學(xué)習(xí)模型,以提取程序代碼的分布式代碼表征,進(jìn)而完成程序分類。
本文提出的基于門控圖神經(jīng)網(wǎng)絡(luò)與注意力機(jī)制的代碼表征學(xué)習(xí)方法主要包括三個(gè)步驟,如圖1所示。
(1)分別構(gòu)建程序算法的抽象語法樹(AST)、數(shù)據(jù)流圖(DFG)以及函數(shù)調(diào)用圖(FCG)。
(2)融合程序算法圖EAST(Extended Abstract Syntax Tree)。
(3)將GGANN 模型應(yīng)用于學(xué)習(xí)EAST 圖的拓?fù)浣Y(jié)構(gòu),以得到節(jié)點(diǎn)向量表達(dá)和EAST 圖向量表達(dá),最后使用上述向量表達(dá)分別完成節(jié)點(diǎn)分類任務(wù)和程序分類任務(wù)。
圖1 模型架構(gòu)
如圖1 所示,構(gòu)建程序算法圖EAST 實(shí)際上包括兩個(gè)主要的步驟:(1)分別構(gòu)建抽象語法樹AST(Abstract Syntax Tree)、函數(shù)調(diào)用圖FCG(Function Call Graph)和數(shù)據(jù)流圖DFG(Data Flow Graph);(2)融合AST、DFG、FCG 得到程序算法圖EAST(Extended Abstract Syntax Tree)。
抽象語法樹:AST[21]是對源代碼進(jìn)行語法分析和語義分析的中間表示形式,它是通過代碼使用無關(guān)上下文規(guī)則(https://en.wikipedia.org/wiki/Context-free_grammar)解析后得到的用于描述代碼語法規(guī)則和執(zhí)行順序的樹形結(jié)構(gòu)數(shù)據(jù)。在AST 中,葉子節(jié)點(diǎn)代表源代碼中的標(biāo)志符,而非葉子節(jié)點(diǎn)則代表語法結(jié)構(gòu)體。作為源代碼的解析樹,AST基本上覆蓋了以下語法結(jié)構(gòu)體:(1)選擇結(jié)構(gòu)體。例如,IF、SWITCH等。(2)循環(huán)結(jié)構(gòu)體。例如,WHILE、FOR 等。(3)序列結(jié)構(gòu)體。例如,表達(dá)式、賦值語句等。因此,AST 作為源代碼的中間表示形式,能夠有效地保留與程序語言相關(guān)的語法上下文信息。
函數(shù)調(diào)用圖:FCG[22]用于刻畫源代碼中與控制流相關(guān)的信息。函數(shù)調(diào)用圖中的每個(gè)節(jié)點(diǎn)代表一個(gè)函數(shù),而其中的邊表示函數(shù)之間的調(diào)用關(guān)系。如圖2 是示例代碼,圖3(a)是圖2 代碼的函數(shù)調(diào)用圖,其中每個(gè)節(jié)點(diǎn)表示一個(gè)函數(shù)。
圖2 示例代碼
數(shù)據(jù)流圖:DFG[23]顯式地蘊(yùn)含了源代碼中數(shù)據(jù)轉(zhuǎn)移和數(shù)據(jù)處理兩個(gè)方面的數(shù)據(jù)邏輯。DFG 中的節(jié)點(diǎn)表示實(shí)體,例如,變量聲明、操作數(shù)、操作符、結(jié)構(gòu)體等等,而其中的邊代表這些實(shí)體之間存在的數(shù)據(jù)關(guān)系。DFG 能夠描述源代碼的數(shù)據(jù)邏輯和程序功能,被用于分析程序動態(tài)的運(yùn)行時(shí)數(shù)據(jù)流信息。如圖3(b)所示,是圖2(a)所示的代碼片段的數(shù)據(jù)流圖。在數(shù)據(jù)流圖中,參考動態(tài)分析程序相關(guān)方法,挖掘出5 種常見的數(shù)據(jù)流關(guān)系,并且使用不同顏色的邊在圖3(b)中標(biāo)注出來:(1)(藍(lán)色)同一個(gè)變量在不同時(shí)刻的數(shù)據(jù)轉(zhuǎn)移關(guān)系。(2)(紫色)不同變量的數(shù)據(jù)傳遞關(guān)系。(3)(橙色)形參/實(shí)參數(shù)據(jù)傳遞關(guān)系。(4)(紅色)函數(shù)聲明/函數(shù)體返回值的賦值關(guān)系。(5)(綠色)操作符號/操作數(shù)之間的雙向運(yùn)算關(guān)系。
程序算法圖EAST:通過比較AST、FCG 和DFG 的特性,很顯然每種不同形式的中間表達(dá)形式都僅僅從某一個(gè)角度上刻畫程序源代碼。AST 僅蘊(yùn)含語法結(jié)構(gòu)相關(guān)的靜態(tài)信息,而后二者分別用于描述與控制流與數(shù)據(jù)流相關(guān)的運(yùn)行時(shí)動態(tài)信息。特別地,后兩者參考的角度不相同。FCG 從函數(shù)粗顆粒度的角度出發(fā),而DFG 從細(xì)顆粒度的變量、運(yùn)算符、運(yùn)算數(shù)等標(biāo)志符出發(fā)。源代碼作為可運(yùn)行的特殊文本,靜態(tài)語法信息和動態(tài)運(yùn)行信息都很重要。因此,將AST、FCG和DFG中攜帶的代碼信息進(jìn)行融合有助于減少由源代碼向中間表達(dá)轉(zhuǎn)化產(chǎn)生的信息損失。
如圖3(c)所示是圖2(a)所示代碼的EAST,EAST以AST為骨架,保持AST原有的節(jié)點(diǎn)不變,僅僅通過增加額外的邊以融入數(shù)據(jù)流信息和函數(shù)調(diào)用信息。
圖3 EAST示例
本文用到的圖模型涉及有向圖G=(V,E),其中V代表大小為|V|的節(jié)點(diǎn)集,E 代表大小為|E|的有向邊集合。V 中的節(jié)點(diǎn)使用節(jié)點(diǎn)編號i 表示,E 中的有向邊使用eij表示,eij代表由節(jié)點(diǎn)i 指向節(jié)點(diǎn)j 的邊。對于圖中不同類型的邊,使用邊類型集合表示。圖G 中節(jié)點(diǎn)之間的連接關(guān)系使用連接矩陣A 表示。A 的維度有兩種設(shè)計(jì)方案:(1)。圖中有向邊eij看成是兩條不同類型的出入邊。一條是節(jié)點(diǎn)i 的出邊,另一條是節(jié)點(diǎn)j 的入邊。(2)。方案二僅將有向邊eij看作節(jié)點(diǎn)j 的入邊。而本文中的連接矩陣示例參照第二種方案。
A 中第i 行第j 列的元素Aij是一個(gè)d×d 的矩陣(d 代表節(jié)點(diǎn)狀態(tài)向量維度)。Aij又稱為邊eij上的傳播矩陣,表示節(jié)點(diǎn)i 到節(jié)點(diǎn)j 的信息傳播規(guī)則。例如,圖4(c)顯示了圖3(b)所示的數(shù)據(jù)流圖所對應(yīng)的連接矩陣,其中兩個(gè)紅色矩形框出的矩陣分別是e3y和eyz所對應(yīng)的傳播矩陣。
圖4 連接矩陣和傳播矩陣示例
在圖2(a)所示的賦值語句中,關(guān)心的是數(shù)字3是否能夠傳遞到變量z,如圖4(b)所示。為此,可將節(jié)點(diǎn)3和z 分別看成源節(jié)點(diǎn)和目標(biāo)節(jié)點(diǎn),并分別初始化其特征向量為和(兩維向量第一維為1,表示3 可達(dá)該節(jié)點(diǎn)),而節(jié)點(diǎn)y 的特征向量表示初始化為
傳播矩陣Aij決定了節(jié)點(diǎn)i 的各個(gè)維度信息如何傳播給節(jié)點(diǎn)j 的各個(gè)維度,“0”代表不傳播,“1”代表完全傳播。例如,圖4(c)的A3y表示節(jié)點(diǎn)3 只將其第一維度的信息傳遞給節(jié)點(diǎn)y 的第一維度,這樣,向量h3與A3y相乘的結(jié)果仍然為hy=[1,0],表示數(shù)據(jù)仍然未能傳遞到目標(biāo)節(jié)點(diǎn)z。然而,圖4(c)中的Ayz表示節(jié)點(diǎn)y 的第一維的信息要傳遞給節(jié)點(diǎn)z 的第一維,因此,向量hy與Ayz相乘的結(jié)果為hz=[1,0],表示數(shù)據(jù)可達(dá)目標(biāo)節(jié)點(diǎn)z。
在圖神經(jīng)網(wǎng)絡(luò)(GNN)[24]中,節(jié)點(diǎn)在不同類型邊上的信息傳播通過不同的多層感知機(jī)實(shí)現(xiàn),而邊上的傳播矩陣則表現(xiàn)為可訓(xùn)練的多層感知機(jī)權(quán)重We∈Rd×d。需要注意的是,圖4(c)中所示連接矩陣僅表示,在可達(dá)性任務(wù)上,圖模型收斂后的多層感知機(jī)權(quán)重。
GNN 模型有個(gè)迭代T 輪的節(jié)點(diǎn)狀態(tài)信息傳播過程:節(jié)點(diǎn)i 的狀態(tài)信息初始化為向量,在第t 輪迭代時(shí),每個(gè)中心節(jié)點(diǎn)i 聚集所有鄰居節(jié)點(diǎn)信息得到節(jié)點(diǎn)交互上下文,如公式(1)所示(其中Ni表示i的鄰居節(jié)點(diǎn)集合)。針對當(dāng)前交互上下文,節(jié)點(diǎn)i 更新自身在第t 輪后的狀態(tài)信息,如公式(2)所示??坍嬃斯?jié)點(diǎn)i 在圖中的拓?fù)浣Y(jié)構(gòu),當(dāng)GNN 模型達(dá)到收斂,狀態(tài)信息將達(dá)到不動點(diǎn)。此時(shí)的將作為節(jié)點(diǎn)i 最終的向量表達(dá)。
從本質(zhì)上來講,門控神經(jīng)網(wǎng)絡(luò)(GGNN)就是在GNN的基礎(chǔ)上使用了GRU 單元,即將公式(2)替換成公式(3)。GRU單元考慮在不同更新輪次,節(jié)點(diǎn)狀態(tài)信息之間的聯(lián)系。即節(jié)點(diǎn)i 在更新輪次t 時(shí),節(jié)點(diǎn)隱藏層向量表達(dá)與前一輪次的狀態(tài)信息的時(shí)序關(guān)系。
基于注意力機(jī)制的啟發(fā),通過給每個(gè)鄰居節(jié)點(diǎn)分配不同的權(quán)重來刻畫其對中心節(jié)點(diǎn)的重要性αij。αij通過神經(jīng)網(wǎng)絡(luò)實(shí)現(xiàn)函數(shù)映射a:Rd×Rd→R,a 計(jì)算中心節(jié)點(diǎn)i 與其鄰居節(jié)點(diǎn)j 的相關(guān)性系數(shù),并使用soft max函數(shù)對所有鄰居節(jié)點(diǎn)的相關(guān)性系數(shù)進(jìn)行歸一化,如公式(4)所示:
神經(jīng)網(wǎng)絡(luò)a 的權(quán)重參數(shù)只與信息傳播輪次相關(guān)。同一信息傳播輪次,a 對于所有節(jié)點(diǎn)共享。不同傳播輪次,a 具有不同的參數(shù)。節(jié)點(diǎn)i 的鄰居節(jié)點(diǎn)j 數(shù)目不定導(dǎo)致aij數(shù)目可變,不能直接調(diào)用Tensorflow 框架提供的soft max 函數(shù)。本文對soft max 進(jìn)行實(shí)現(xiàn),以適應(yīng)變化的鄰居節(jié)點(diǎn)數(shù)目(公式(5)和(6))。
因?yàn)槌绦蚍诸愂歉鶕?jù)程序算法圖EAST 的嵌入表達(dá)對程序代碼進(jìn)行分類,所以在得到最終的圖節(jié)點(diǎn)嵌入向量表達(dá)后,需要計(jì)算整個(gè)EAST 圖的嵌入向量表示hG。本工作中提出節(jié)點(diǎn)向量概率融合方法,由節(jié)點(diǎn)嵌入向量生成圖嵌入向量。如公式(8)所示。是全連接神經(jīng)網(wǎng)絡(luò),它根據(jù)節(jié)點(diǎn)屬性和拓?fù)浣Y(jié)構(gòu)信息學(xué)習(xí)節(jié)點(diǎn)i 被融合的概率。f 中的激活函數(shù)使
總的來說,EAST 圖的以下特點(diǎn)決定了GGANN 模型的適用性:(1)圖中的邊有多種類型。(2)圖中節(jié)點(diǎn)與節(jié)點(diǎn)可能存在多條不同類型的邊。(3)圖中既存在有向邊,又存在無向邊。另外,GGANN 的注意力機(jī)制摒棄了累加求和這種人為指定的交互上下文計(jì)算方式,而改用模型自主學(xué)習(xí)中心節(jié)點(diǎn)對鄰居節(jié)點(diǎn)的連接關(guān)系。這種注意力機(jī)制具備以下三個(gè)特點(diǎn):
(1)中心節(jié)點(diǎn)和其鄰居節(jié)點(diǎn)計(jì)算重要性αij可以并行,計(jì)算高效。
(2)注意力機(jī)制實(shí)現(xiàn)了模型自動學(xué)習(xí)交互上下文的計(jì)算方式,而不必考慮變化的鄰居節(jié)點(diǎn)數(shù)目。如果使用神經(jīng)網(wǎng)絡(luò)學(xué)習(xí)計(jì)算交互上下文,必然需要面臨圖中各節(jié)點(diǎn)鄰居節(jié)點(diǎn)數(shù)目不一致而導(dǎo)致的神經(jīng)網(wǎng)絡(luò)權(quán)重維度無法統(tǒng)一的問題。
(3)注意力機(jī)制考慮鄰域全局結(jié)構(gòu)以及鄰居節(jié)點(diǎn)拓?fù)浣Y(jié)構(gòu)性質(zhì)的差異。用sigmoid,其最終輸出是一個(gè)[0,1]的數(shù)值。g 同樣也使用全連接層神經(jīng)網(wǎng)絡(luò)實(shí)現(xiàn),它使用tanh 函數(shù)激活輸出。hG的計(jì)算方式和公式(7)類似,都基于注意力機(jī)制的思想。最終,程序類別lG由經(jīng)過函數(shù)softmax 得來。
為了驗(yàn)證本文提出的模型在程序分類上的有效性,不僅從程序分類準(zhǔn)確率的角度對模型做出指標(biāo)評估,還從EAST 圖節(jié)點(diǎn)嵌入表達(dá)的角度分析了模型學(xué)習(xí)拓?fù)浣Y(jié)構(gòu)的能力。為了直觀地理解模型的學(xué)習(xí)效果,部分實(shí)驗(yàn)結(jié)果采用可視化方法呈現(xiàn)出來。
本文的實(shí)驗(yàn)數(shù)據(jù)是從在線判題(OJ)系統(tǒng)中收集的。在該系統(tǒng)上,管理員發(fā)布了很多程序設(shè)計(jì)問題,而學(xué)生以源文件的形式提交了關(guān)于每個(gè)問題解決方案的代碼。對于代碼的正確性,OJ 系統(tǒng)一般先檢查代碼能夠正確編譯,然后將執(zhí)行程序后的輸出與測試樣例進(jìn)行對比,從而自動判定學(xué)生提交的代碼是否正確。因此,該數(shù)據(jù)集主要由兩部分組成:編程問題(由問題題號表示)和相應(yīng)的學(xué)生提交的源代碼。
為了排除編程語言的問題,只選C++編寫的源代碼。同時(shí)為了確保與每個(gè)問題相關(guān)的各種源代碼足夠豐富,對數(shù)據(jù)集進(jìn)行了過濾,以便只處理最常見的問題。過濾的規(guī)則很簡單,僅僅保留解決方案代碼超過350份的問題,以此組成30個(gè)程序設(shè)計(jì)問題的標(biāo)準(zhǔn)數(shù)據(jù)集。在標(biāo)準(zhǔn)數(shù)據(jù)集中,存在一些相似度很高的問題,比如A+B,A+B(I),A+B(II)等問題。這些問題的關(guān)系為:A+B(I)問題是在A+B 問題上演化而來,而A+B(II)問題是由A+B 問題演化而來。這些問題不僅在問題描述還在代碼實(shí)現(xiàn)上都保持著極高的相似性,因此對這些問題上將進(jìn)行程序分類任務(wù),問題混淆性更強(qiáng)。本文工作也充分利用具備這種性質(zhì)的問題集合(相似子數(shù)據(jù)集)用于驗(yàn)證模型的分類魯棒性和有效性。
使用開源的clang(http://clang.llvm.org)依賴庫解析C++程序設(shè)計(jì)源代碼,從而得到程序AST數(shù)據(jù)集。進(jìn)一步為每個(gè)程序設(shè)計(jì)問題的AST樹添加代表數(shù)據(jù)流信息的邊和代表函數(shù)調(diào)用圖的邊,最后得到最終的EAST數(shù)據(jù)集。在實(shí)驗(yàn)中,EAST 數(shù)據(jù)集按照3∶1∶1 的比例劃分訓(xùn)練集、驗(yàn)證集、測試集。
模型訓(xùn)練采用的優(yōu)化算法是ADAM優(yōu)化器的隨機(jī)梯度下降算法SGD[25]。損失函數(shù)采用的是交叉熵。模型中的權(quán)重參數(shù)初始化使用Glorot[26]初始化方法。在訓(xùn)練中,為了提高模型的泛化能力,主要采取了如下措施:(1)為了防止過擬合,本文使用初始值λ=0.000 5 的L2正則項(xiàng)。(2)為了解決梯度爆炸問題,實(shí)驗(yàn)中采用舍棄概率p=0.6 的dropout[27]。(3)為了快速得到一個(gè)較優(yōu)解,使用線性學(xué)習(xí)率衰減對學(xué)習(xí)率L進(jìn)行調(diào)整。L從初始學(xué)習(xí)率L0=0.000 1 下降到最終學(xué)習(xí)率L×F,其中衰減系數(shù)F ∈[0.01,1]。(4)實(shí)驗(yàn)根據(jù)模型在驗(yàn)證集上的預(yù)測準(zhǔn)確率來估算模型早停(early stopping)的時(shí)機(jī),以此減少模型過擬合。
實(shí)驗(yàn)中信息傳播層(信息迭代輪次)被設(shè)置為4層,而每個(gè)傳播層神經(jīng)元個(gè)數(shù),即傳播矩陣向量維度d,是一個(gè)超參數(shù)。該超參數(shù)的選擇主要考慮以下兩個(gè)因素:(1)模型收斂的速度;(2)模型的損失值。為此,使用實(shí)驗(yàn)來確定超參數(shù)d,實(shí)驗(yàn)結(jié)果如圖5(a)和(b)所示。圖5(a)展示了每秒鐘,模型計(jì)算EAST圖的數(shù)目隨著d 值的增加而改變的情況。而圖5(b)則展示了模型在訓(xùn)練集/測試集上隨著d 值增加,收斂后的最終損失值變化情況。從圖5(a)和(b)中可以看出,當(dāng)隱層向量維度d為270 時(shí),模型的收斂損失值相對較小,同時(shí)模型訓(xùn)練速度也相對較快。因此,將隱層向量維度d 設(shè)為270,從而完成后續(xù)實(shí)驗(yàn)。
圖5 模型參數(shù)選擇指標(biāo)
本節(jié)主要通過實(shí)驗(yàn)結(jié)果評估GGANN模型在EAST圖上程序分類準(zhǔn)確度,以及分析模型得到的節(jié)點(diǎn)嵌入表達(dá)。
4.3.1 程序分類
程序分類問題用于驗(yàn)證本文模型是否成功地從源代碼中學(xué)習(xí)到語法結(jié)構(gòu)與語義信息,即針對相同問題的不同學(xué)生實(shí)現(xiàn)的代碼是否可以被劃分為相同的類別,而針對不同問題的具有相似語法結(jié)構(gòu)的代碼能夠有效地被辨別。
在實(shí)驗(yàn)中,構(gòu)建程序二分類任務(wù),這個(gè)任務(wù)主要內(nèi)容是判斷給出的一份源代碼是否屬于某一個(gè)程序類別(問題題號)。這是一個(gè)監(jiān)督性學(xué)習(xí)問題,每個(gè)程序設(shè)計(jì)代碼使用相應(yīng)的問題題號作為標(biāo)簽。本實(shí)驗(yàn)選擇的基準(zhǔn)對比實(shí)驗(yàn)是基于樹的卷積神經(jīng)網(wǎng)絡(luò)(TBCNN),據(jù)大家所知,TBCNN 是迄今為止源代碼分類任務(wù)上性能表現(xiàn)最好的工作。此外,因?yàn)镚GANN模型是針對GGNN模型的改進(jìn),也將兩個(gè)模型在EAST 圖上進(jìn)行對比實(shí)驗(yàn)。由于TBCNN 的模型特性,導(dǎo)致TBCNN 模型不能運(yùn)用于有環(huán)的EAST 圖,對比實(shí)驗(yàn)中不考慮TBCNN 模型與EAST圖的組合實(shí)驗(yàn)。
表1和表2展示了GGANN、GGNN、TBCNN這3種模型在程序標(biāo)準(zhǔn)數(shù)據(jù)集/相似問題數(shù)據(jù)集上的分類精確度。實(shí)驗(yàn)表明,TBCNN 模型在代碼分類精確度明顯低于GGANN和GGNN模型,而GGANN較GGNN模型也有明顯的改進(jìn)。這一方面說明TBCNN過多的依賴程序代碼中間表達(dá)形式AST,導(dǎo)致TBCNN 不容易辨別語法結(jié)構(gòu)相似但是運(yùn)行時(shí)信息有差別的問題,另一方面說明GGANN 采用模型自主學(xué)習(xí)的交互上下文計(jì)算方式有效地提升了GGNN的性能。
表1 模型與中間表達(dá)形式組合對比實(shí)驗(yàn)
表2 模型在相似問題上的分類準(zhǔn)確度%
為了評估是否數(shù)據(jù)流邊和函數(shù)調(diào)用圖邊是否有用,分別移除7 種邊中的1 種,并且使用GGANN 模型對刪除某種邊后EAST圖進(jìn)行分類,以此觀察每種邊對程序分類精度的影響。
實(shí)驗(yàn)結(jié)果如圖6 所示,上劃線(----Ast)表示去掉給定類型邊(Ast)后的EAST圖。實(shí)驗(yàn)結(jié)果表明大部分程序任務(wù),刪除某一種類型的邊對程序分類精度影響不大。7種類型的邊可能存在信息冗余,因此任意某種類型的邊刪除都不會對程序分類精度產(chǎn)生顯著影響。但對于某些程序,刪除這些類型的邊可以顯著降低或提高程序分類精度(如表3 所示)。結(jié)果表明,EAST 圖中的數(shù)據(jù)信息邊能夠彌補(bǔ)AST中語義信息的缺失。
圖6 不同類型邊的貢獻(xiàn)比較
表3 受邊類型影響的程序分類任務(wù)
分別比較了GGANN、GGNN、TBCNN 在EAST、AST中間表達(dá)形式上損失值的收斂趨勢。如圖7所示,圖模型不僅最終收斂損失值較小,收斂速度也比TBCNN 快。圖網(wǎng)絡(luò)模型收斂速度較快的原因,是圖模型對AST 節(jié)點(diǎn)的約束比TBCNN 強(qiáng)。更具體地說,在TBCNN 模型中,卷積操作強(qiáng)制信息從子節(jié)點(diǎn)到父節(jié)點(diǎn)的單向傳播,而圖模型對于每個(gè)節(jié)點(diǎn),都涉及所有相鄰節(jié)點(diǎn)之間的雙向信息傳播。這種信息傳播能夠逐漸擴(kuò)散到整個(gè)圖結(jié)構(gòu)。
圖7 4個(gè)模型的損失值隨迭代次數(shù)的變化
4.3.2 節(jié)點(diǎn)聚類
基于GGANN 模型的特點(diǎn)-節(jié)點(diǎn)的特征表達(dá)都是通過學(xué)習(xí)節(jié)點(diǎn)及其鄰居節(jié)點(diǎn)構(gòu)成的子結(jié)構(gòu)而來的,因此擁有相似子結(jié)構(gòu)(相似語法結(jié)構(gòu))的節(jié)點(diǎn)具備相似的表達(dá)。為了評估模型是否學(xué)出這樣的特性,使用無監(jiān)督性聚類方法K-means 對節(jié)點(diǎn)的嵌入向量表達(dá)做聚類。部分節(jié)點(diǎn)聚類結(jié)果如表4 所示。為了分析聚類中的節(jié)點(diǎn)是否具有相似的語義信息,對各個(gè)聚類的節(jié)點(diǎn)所對應(yīng)的語義信息進(jìn)行了對比。
表4 節(jié)點(diǎn)聚類(K=5)
從表4可以看出,模型有效地將節(jié)點(diǎn)的語義特征嵌入到向量表達(dá)。比如,F(xiàn)orStmt、ContinueStmt、GotoStmt、BreakStmt等與控制流相關(guān)的節(jié)點(diǎn)因?yàn)榫哂邢嗨频恼Z義特征(嵌入空間比較接近),因此被聚類到簇3。類似地,一元運(yùn)算符UnaryOperator 和二元運(yùn)算符BinaryOperator,字符型定義StringLiteral 和整數(shù)定義IntegerLiteral聚類到了簇1,因此這些運(yùn)算符都與數(shù)據(jù)運(yùn)算/指向相關(guān);CompoundAssignOperator,?=,+=,-=聚類到了簇2,因此都是與復(fù)合運(yùn)算相關(guān)的。對于上述分析,TBCNN[11-12]的實(shí)驗(yàn)中也挖掘出類似的節(jié)點(diǎn)嵌入向量性質(zhì)。
4.3.3 節(jié)點(diǎn)融合概率分析
GGANN 對于EAST 圖的輸出,本文定義了一個(gè)圖向量表達(dá)的計(jì)算函數(shù),如公式(8)所示。其中每個(gè)節(jié)點(diǎn)v ∈V 都存在一個(gè)基于注意力機(jī)制算出的節(jié)點(diǎn)融合概率,這個(gè)概率反映了當(dāng)前節(jié)點(diǎn)與EAST 圖嵌入表達(dá)(當(dāng)前任務(wù))的相關(guān)程度。為了深度挖掘融合概率是否有意義,將其中一個(gè)EAST圖中所有節(jié)點(diǎn)的融合概率通過熱力圖的形式進(jìn)行展示。如圖8 中有104 個(gè)矩形條,每個(gè)矩形條對應(yīng)EAST圖的一個(gè)節(jié)點(diǎn)。圖中顏色越亮的點(diǎn)融合概率越高。圖8 中融合較高的節(jié)點(diǎn)有BinaryOperator節(jié)點(diǎn)(0.71)、CallExpr 節(jié)點(diǎn)(0.74)、ImplicitCastExpr 節(jié)點(diǎn)(0.75)、IfStmt 節(jié)點(diǎn)(0.75)、DeclStmt 節(jié)點(diǎn)(0.72)和CompoundStmt節(jié)點(diǎn)(0.74)。這些節(jié)點(diǎn)基本位于原始的AST較高層次的位置(較高層次一般是代碼語法結(jié)構(gòu)的抽象,其包含了更多的拓普信息),且能體現(xiàn)出程序算法的結(jié)構(gòu)骨架。對于這樣的節(jié)點(diǎn),圖嵌入表達(dá)賦予了其更大的融合概率,即更強(qiáng)的“關(guān)注”。未來的工作中將運(yùn)用深度學(xué)習(xí)模型可解釋性相關(guān)技術(shù)驗(yàn)證其一般性和適用性。
圖8 EAST節(jié)點(diǎn)融合概率
為了解決在線編程服務(wù)用戶之間有限的社會互動問題,提出了使用源代碼挖掘技術(shù)促進(jìn)互動。作為實(shí)現(xiàn)這一目標(biāo)的第一次嘗試,本文提出了一種基于圖的程序分類模型,通過理解程序的結(jié)構(gòu)和語義信息,可以對給定的程序進(jìn)行高精度的算法分類。更具體地說,在這項(xiàng)工作中,EAST 圖被提議將一個(gè)程序的源代碼轉(zhuǎn)換成一個(gè)中間表示,并將其輸入到圖網(wǎng)絡(luò)模型中,并且為程序分類應(yīng)用提出了一個(gè)圖網(wǎng)絡(luò)模型GGANN。
據(jù)了解,這是第一個(gè)將圖網(wǎng)絡(luò)模型應(yīng)用于程序分類應(yīng)用程序的工作。實(shí)驗(yàn)評價(jià)表明,本文研究成功地學(xué)習(xí)了各種編程任務(wù)的語法結(jié)構(gòu)和語義信息,與目前最先進(jìn)的程序分類工作TBCNN 相比,模型的分類精度提到提升。在未來,希望集成編譯技術(shù),進(jìn)一步挖掘源代碼。另外,GGANN 模型計(jì)算量偏大,模型訓(xùn)練時(shí)間過長,因此,希望借助鄰域采樣和池化技術(shù)加速模型的訓(xùn)練速度,并將GGANN模型擴(kuò)展到其他編程語言和其他任務(wù)。