王瀚森,王 婷,陳鐵明,季白楊
(浙江工業(yè)大學(xué) 計(jì)算機(jī)科學(xué)與技術(shù)學(xué)院,杭州 310023)
伴隨互聯(lián)網(wǎng)的發(fā)展,軟件數(shù)量、規(guī)模都急劇增大,代碼開(kāi)發(fā)和維護(hù)工作中的程序理解問(wèn)題已成為一大難題.據(jù)統(tǒng)計(jì),在軟件開(kāi)發(fā)周期中,有59%的工作用于理解和維護(hù)相關(guān)軟件源代碼[1],相當(dāng)耗時(shí)耗力,影響工作效率.代碼的維護(hù)和復(fù)用往往需要對(duì)代碼有透徹的理解,程序理解是任何代碼復(fù)用和修改的先決條件,代碼注釋對(duì)于輔助程序員理解代碼含義是十分重要的[2].現(xiàn)如今,開(kāi)源代碼倉(cāng)庫(kù)的實(shí)際項(xiàng)目中存在大量代碼沒(méi)有含義清晰明確的注釋,這導(dǎo)致軟件開(kāi)發(fā)人員在瀏覽代碼時(shí),不得不耗費(fèi)大量時(shí)間去理解代碼的功能,極大影響了開(kāi)源資源的復(fù)用.因此,代碼注釋生成技術(shù)需要更加深入的研究.通過(guò)深度學(xué)習(xí)構(gòu)建編程語(yǔ)言到自然語(yǔ)言注釋的映射模型,在大規(guī)模數(shù)據(jù)庫(kù)上學(xué)習(xí)代碼的抽象特征表示,自動(dòng)生成含義清晰準(zhǔn)確的代碼注釋,不僅可以省去開(kāi)發(fā)人員寫(xiě)注釋的時(shí)間,同時(shí)可以用來(lái)幫助理解代碼,具有相當(dāng)大的應(yīng)用價(jià)值.
早期方法是通過(guò)預(yù)定義人工模板生成注釋.基于預(yù)定義的啟發(fā)式規(guī)則從給定源代碼中提取關(guān)鍵字,添加到人工模板中,合成基于自然語(yǔ)言描述的注釋[3-6].此外,基于信息檢索的方法也廣泛應(yīng)用于代碼注釋生成技術(shù)[7-13].這類(lèi)方法基于信息檢索模型,通過(guò)識(shí)別出目標(biāo)模塊內(nèi)的關(guān)鍵單詞,嘗試從軟件倉(cāng)庫(kù)中尋找與目標(biāo)模塊相似的代碼段,并利用這些相似代碼片段的摘要、注釋或討論生成代碼注釋.深度學(xué)習(xí)的最新進(jìn)展催生了新一代數(shù)據(jù)驅(qū)動(dòng)的代碼注釋生成技術(shù).這種技術(shù)很大程度上是受到神經(jīng)機(jī)器翻譯(Neural Machine Translation,NMT)領(lǐng)域的啟發(fā),使用端到端的神經(jīng)網(wǎng)絡(luò)生成注釋.
相較于結(jié)構(gòu)化較弱的自然語(yǔ)言,編程語(yǔ)言是形式化語(yǔ)言,用它們編寫(xiě)的源代碼具有明確的語(yǔ)法結(jié)構(gòu)[14].源代碼具有語(yǔ)法結(jié)構(gòu)信息和順序語(yǔ)義信息.將結(jié)構(gòu)化的代碼應(yīng)用到自然語(yǔ)言的神經(jīng)機(jī)器翻譯方法中,難免會(huì)丟失編程語(yǔ)言結(jié)構(gòu)特性包含的信息.要理解代碼內(nèi)容并生成含義準(zhǔn)確且可讀性強(qiáng)的代碼注釋,這兩部分信息是必不可少的.過(guò)往研究大多只利用其中一種信息,如何將編程語(yǔ)言的語(yǔ)義信息與語(yǔ)法結(jié)構(gòu)信息進(jìn)行結(jié)合,還需要更深入的研究.
針對(duì)上述問(wèn)題,本文提出一種融合語(yǔ)法結(jié)構(gòu)信息和順序語(yǔ)義信息的代碼注釋生成方法,通過(guò)將代碼片段轉(zhuǎn)化為AST,并對(duì)AST節(jié)點(diǎn)類(lèi)型進(jìn)行控制,簡(jiǎn)化AST結(jié)構(gòu).應(yīng)用多路樹(shù)-LSTM[15]以獲得樹(shù)形結(jié)構(gòu)的節(jié)點(diǎn)表示.再結(jié)合源代碼序列表示的語(yǔ)義信息,輸入Transformer[16],以?xún)煞N類(lèi)型的代碼信息為指導(dǎo)訓(xùn)練注釋生成模型.為了評(píng)估本文方法的有效性,本文在大型Java數(shù)據(jù)集上進(jìn)行了實(shí)驗(yàn)[17].實(shí)驗(yàn)結(jié)果表明,本文方法生成的代碼注釋在BLEU[18]、METEOR[19]和ROUGE[20]評(píng)價(jià)指標(biāo)上的得分高于對(duì)照模型.
隨著深度學(xué)習(xí)技術(shù)的發(fā)展,基于端到端神經(jīng)網(wǎng)絡(luò)模型的代碼注釋生成研究不斷深入.這一類(lèi)方法將代碼注釋自動(dòng)生成任務(wù)建模為神經(jīng)機(jī)器翻譯問(wèn)題.Iyer等[21]首次將深度學(xué)習(xí)應(yīng)用到代碼摘要研究中,并提出CODE-NN方法,使用LSTM和注意力機(jī)制,生成C#代碼片段和SQL查詢(xún)語(yǔ)句的描述.Allamanis等[22]使用CNN和注意力機(jī)制作為編碼器,解碼器使用GRU,通過(guò)卷積操作將源代碼總結(jié)為簡(jiǎn)短的、描述性的函數(shù)名稱(chēng).Wei等[23]提出一種對(duì)偶學(xué)習(xí)的方法,通過(guò)代碼摘要和代碼生成兩個(gè)任務(wù)之間的對(duì)偶性訓(xùn)練模型.針對(duì)RNN模型對(duì)于長(zhǎng)代碼序列進(jìn)行建模時(shí)難以捕獲長(zhǎng)距離依賴(lài)問(wèn)題,Ahmad等[24]利用Transformer模型來(lái)生成代碼注釋,并利用復(fù)制注意力機(jī)制和相對(duì)位置編碼,有效捕獲長(zhǎng)距離依賴(lài)(long-range dependencies).
除以上方法外,近期研究人員越發(fā)關(guān)注代碼的語(yǔ)法結(jié)構(gòu)信息,開(kāi)始將研究重心轉(zhuǎn)移到利用AST表示源代碼.其中最具代表性的方法是Hu等[25]提出的DeepCom.通過(guò)AST表示源代碼,以保留源代碼的語(yǔ)法結(jié)構(gòu)信息,并提出一種AST遍歷方法SBT(Structure-base Traversal),將AST遍歷成序列結(jié)構(gòu).隨后,他們基于DeepCom,進(jìn)一步提出Hybrid-DeepCom[17]方法,結(jié)合了源代碼語(yǔ)義信息和AST提供的語(yǔ)法結(jié)構(gòu)信息,并通過(guò)使用分隔標(biāo)識(shí)符的方法緩解OOV(out of vocabulary,即需要生成的注釋可能含有未在代碼中出現(xiàn)的單詞)問(wèn)題.然而這種將AST轉(zhuǎn)化為序列進(jìn)行編碼的方式不可避免地丟失了源代碼的語(yǔ)法結(jié)構(gòu)信息.因此,一些工作嘗試使用樹(shù)形結(jié)構(gòu)編碼輸入.包括Mou等[26]設(shè)計(jì)的基于樹(shù)的卷積神經(jīng)網(wǎng)絡(luò)(TBCNNs)、Shido等[15]提出的Tree-LSTM,以及Harer等[27]提出的Tree-Transformer.
由于AST節(jié)點(diǎn)數(shù)量多,導(dǎo)致訓(xùn)練開(kāi)銷(xiāo)大,加重模型訓(xùn)練負(fù)擔(dān).為了平衡語(yǔ)法結(jié)構(gòu)信息的保留和降低訓(xùn)練難度,Chen等[28]提出了一種將長(zhǎng)代碼段分割為短AST路徑的方法,從而縮短輸入長(zhǎng)度.Wan等[29]將AST轉(zhuǎn)換為二叉樹(shù),以丟失部分信息為代價(jià)減少訓(xùn)練開(kāi)銷(xiāo).Alon等[30]將代碼片段表示為AST中的組合路徑集.Zhang等[31]將抽象語(yǔ)法樹(shù)拆分成多個(gè)規(guī)模更小的語(yǔ)句樹(shù),每次只關(guān)注一條語(yǔ)句,降低訓(xùn)練難度.
總體來(lái)看,AST在代碼注釋自動(dòng)生成技術(shù)中的應(yīng)用為這一方向的研究提供了新的技術(shù)途徑.其優(yōu)勢(shì)在于可以保留源代碼的語(yǔ)法結(jié)構(gòu)信息,將源代碼的語(yǔ)法結(jié)構(gòu)信息和語(yǔ)義信息結(jié)合,生成高質(zhì)量的代碼注釋.
本節(jié)將著重介紹源代碼的抽象語(yǔ)法結(jié)構(gòu)化表示.編程語(yǔ)言相較于自然語(yǔ)言,不僅包含語(yǔ)義信息,還有其獨(dú)特的語(yǔ)法結(jié)構(gòu)信息.通常情況下,可以采用抽象語(yǔ)法樹(shù)(AST)捕捉源代碼的語(yǔ)法結(jié)構(gòu)信息.AST是一種用于表示源代碼語(yǔ)法的抽象樹(shù)形結(jié)構(gòu).AST的葉節(jié)點(diǎn)表示代碼中的標(biāo)識(shí)符或變量值,非葉節(jié)點(diǎn)表示語(yǔ)言的語(yǔ)法和層次結(jié)構(gòu).圖1顯示了一個(gè)Java代碼片段及其AST的示例.
圖1 Java代碼片段和對(duì)應(yīng)的AST示例Fig.1 Example of Java code snippet and the abstract syntax tree
現(xiàn)有研究在利用抽象語(yǔ)法樹(shù)提取源代碼語(yǔ)法結(jié)構(gòu)信息時(shí),通常將AST經(jīng)過(guò)特殊的遍歷方法轉(zhuǎn)化為順序序列,旨在提取語(yǔ)法過(guò)程中盡可能地保留源代碼的結(jié)構(gòu)信息.由于完整的AST深度大且結(jié)構(gòu)復(fù)雜,通過(guò)此類(lèi)基于結(jié)構(gòu)的遍歷方式生成的序列通常包含冗余語(yǔ)義信息,導(dǎo)致訓(xùn)練困難.為了更有效地捕獲代碼的結(jié)構(gòu)信息,本文提出一種依據(jù)節(jié)點(diǎn)類(lèi)型的AST簡(jiǎn)化方法,目的是簡(jiǎn)化AST結(jié)構(gòu),減小其編碼難度,提供簡(jiǎn)潔的語(yǔ)法結(jié)構(gòu)關(guān)系來(lái)指導(dǎo)訓(xùn)練.然后通過(guò)Tree-LSTM模型提取語(yǔ)法結(jié)構(gòu)信息.
控制流圖(Control Flow Gragh,CFG)[32]使用圖的表示方式,記錄代碼的結(jié)構(gòu)和執(zhí)行路徑.控制流圖中的每個(gè)頂點(diǎn)對(duì)應(yīng)一個(gè)代碼區(qū)塊.本文希望從AST中刪除不影響控制流圖結(jié)構(gòu)的節(jié)點(diǎn).由源代碼轉(zhuǎn)化成的AST,節(jié)點(diǎn)類(lèi)型大致包括4類(lèi):基本語(yǔ)句節(jié)點(diǎn)、調(diào)用式節(jié)點(diǎn)、表達(dá)式節(jié)點(diǎn)、和不包含在上述類(lèi)型中的其他類(lèi)型節(jié)點(diǎn)(主要包括聲明式節(jié)點(diǎn)等).其中,基本語(yǔ)句節(jié)點(diǎn)定義了代碼段的層次結(jié)構(gòu),例如分支結(jié)構(gòu),循環(huán)結(jié)構(gòu)等.調(diào)用式節(jié)點(diǎn)通常決定程序流程走向,屬于影響代碼結(jié)構(gòu)的部分.而表達(dá)式節(jié)點(diǎn),聲明式節(jié)點(diǎn)和其他類(lèi)型節(jié)點(diǎn)通常不會(huì)單獨(dú)構(gòu)成控制流圖中的頂點(diǎn),本文認(rèn)為其不對(duì)代碼結(jié)構(gòu)起決定性影響,屬于冗余的語(yǔ)義信息,此類(lèi)型往往位于AST的葉子節(jié)點(diǎn)處.
圖2給出了兩個(gè)源代碼及其注釋的示例.其中陰影部分是生成注釋時(shí)重點(diǎn)關(guān)注的部分.可以看出,在樣例1中,其關(guān)注點(diǎn)在分支結(jié)構(gòu)和調(diào)用式節(jié)點(diǎn)paths.add(s)上.樣例2中,生成注釋的關(guān)注點(diǎn)主要在方法名和參數(shù)上,方法體中大量聲明式節(jié)點(diǎn)和表達(dá)式節(jié)點(diǎn)是被忽略的.
圖2 源代碼及其注釋示例Fig.2 Example of the source code and comment
通過(guò)移除聲明式,表達(dá)式和其他類(lèi)型的節(jié)點(diǎn),使樹(shù)編碼組件專(zhuān)注對(duì)源代碼層次結(jié)構(gòu)的學(xué)習(xí)而不去關(guān)注語(yǔ)義細(xì)節(jié).這些節(jié)點(diǎn)所包含的語(yǔ)義信息則通過(guò)源代碼序列的形式在Transformer中學(xué)習(xí),在此刪除這些節(jié)點(diǎn)并不會(huì)帶來(lái)語(yǔ)義信息的缺失.形式化地,將某個(gè)ASTt的節(jié)點(diǎn)集合定義為V(t),G(t)?V(t)代表t中決定語(yǔ)法結(jié)構(gòu)的節(jié)點(diǎn),主要包括基本語(yǔ)句節(jié)點(diǎn)和調(diào)用式節(jié)點(diǎn);S(t)?V(t)代表t中涵蓋語(yǔ)義信息的節(jié)點(diǎn),主要包括聲明式節(jié)點(diǎn)和部分表達(dá)式節(jié)點(diǎn).這部分節(jié)點(diǎn)在代碼庫(kù)中大量重復(fù),直接影響了AST的規(guī)模并且干擾語(yǔ)法結(jié)構(gòu)的訓(xùn)練.通過(guò)算法1將這部分節(jié)點(diǎn)從AST中刪除獲得簡(jiǎn)化的AST.
算法1.簡(jiǎn)化AST
輸入:ASTtwith node setV(t)
輸出:G(t)
1.forv←V(t) do
2.if Children(v)inS(t) then
3. Children(v)←Children(Children(v));
4.returnt;
Tree-LSTM[33]是一種處理樹(shù)形結(jié)構(gòu)數(shù)據(jù)的神經(jīng)網(wǎng)絡(luò)框架,是對(duì)標(biāo)準(zhǔn)LSTM[34]在樹(shù)形結(jié)構(gòu)上的泛化.相較于標(biāo)準(zhǔn)LSTM的每個(gè)時(shí)間步接受一個(gè)隱藏狀態(tài)向量,Tree-LSTM的每個(gè)父節(jié)點(diǎn)可以接受多個(gè)子節(jié)點(diǎn)隱藏狀態(tài)向量,并將信息從葉子傳播到根.考慮到多路樹(shù)-LSTM可以處理多分支且節(jié)點(diǎn)有序的樹(shù)形結(jié)構(gòu),符合AST的結(jié)構(gòu)特點(diǎn),保證在處理任意數(shù)量的子節(jié)點(diǎn)時(shí),同時(shí)考慮子節(jié)點(diǎn)間的順序交互.本文通過(guò)多路樹(shù)-LSTM對(duì)AST進(jìn)行編碼,將每個(gè)AST轉(zhuǎn)化為向量表示,用以表示源代碼的語(yǔ)法結(jié)構(gòu)信息.
對(duì)于給定輸入AST的任意節(jié)點(diǎn)向量xj,C(j)表示其子節(jié)點(diǎn)集合,nj表示C(j)集合數(shù)量;其第k個(gè)子節(jié)點(diǎn)的隱藏狀態(tài)為hjk,cell狀態(tài)為cjk,多路樹(shù)-LSTM的隱藏狀態(tài)hj計(jì)算方式如公式(1)~公式(10)所示:
(1)
(2)
(3)
(4)
(5)
(6)
(7)
(8)
cj=∑k∈C(j)ck⊙fjk+ij⊙uj
(9)
hj=oj⊙tanh(cj)
(10)
給定一個(gè)ASTt,t包含一組節(jié)點(diǎn)G(t).將G(t)中的每個(gè)節(jié)點(diǎn)轉(zhuǎn)化成type_value格式的唯一標(biāo)記,作為輸入嵌入到固定維度的向量中.例如,節(jié)點(diǎn)類(lèi)型為BasicType,節(jié)點(diǎn)值為int的節(jié)點(diǎn)表示為BasicType_int.對(duì)于所有非葉節(jié)點(diǎn)j,該節(jié)點(diǎn)輸出的隱藏向量hj由輸入xj和該節(jié)點(diǎn)的所有子節(jié)點(diǎn)的隱藏向量hC(j)通過(guò)多路樹(shù)-LSTM生成,如公式(11)所示:
hj=F(xj,hC(j))
(11)
對(duì)于不包含任何子節(jié)點(diǎn)的葉子節(jié)點(diǎn),本文選擇創(chuàng)建虛擬的子節(jié)點(diǎn)并隨機(jī)初始化,方便計(jì)算其隱藏向量.最終,獲得根節(jié)點(diǎn)的輸出作為表示ASTt的語(yǔ)法結(jié)構(gòu)向量.
本文通過(guò)Transformer神經(jīng)網(wǎng)絡(luò)對(duì)源代碼的語(yǔ)法結(jié)構(gòu)信息和順序語(yǔ)義信息進(jìn)行融合.由于AST的深層特性,傳統(tǒng)的Seq2Seq模型在捕獲長(zhǎng)距離依賴(lài)關(guān)系的表現(xiàn)上不如Transformer神經(jīng)網(wǎng)絡(luò)[16].Transformer的自注意力機(jī)制是純數(shù)據(jù)驅(qū)動(dòng)的,并且Transformer的位置編碼可以學(xué)習(xí)輸入令牌之間的依賴(lài)關(guān)系,因此可以將代碼的語(yǔ)法結(jié)構(gòu)信息和順序語(yǔ)義信息融合到Transformer編碼器的輸入中.
圖3 模型框架Fig.3 Framework of model
(12)
此外,源代碼中標(biāo)記的位置和排列順序是非常重要的信息,他們不僅是代碼語(yǔ)法結(jié)構(gòu)的組成部分,同時(shí)表達(dá)重要的語(yǔ)義信息.由于Transformer完全采用注意力機(jī)制,丟失了詞序信息,因此需要為每個(gè)嵌入向量加入位置編碼(Positional Encoding).位置編碼遵循模型學(xué)習(xí)到的特定模式,將位置編碼加入到嵌入向量中,有助于捕獲長(zhǎng)期依賴(lài)關(guān)系,更好地對(duì)標(biāo)記間相對(duì)關(guān)系建模[35].
Transformer遵循編碼器解碼器結(jié)構(gòu).編碼組件由一組堆疊的編碼器組成,所有編碼器結(jié)構(gòu)相同,但不會(huì)共享參數(shù).編碼器由兩個(gè)子層組成,即多頭自注意力層(Multi-Head Self Attention)和前饋神經(jīng)網(wǎng)絡(luò)層.編碼器接收到的句子首先通過(guò)自注意力子層,隨著模型處理輸入序列中的每個(gè)標(biāo)記,自注意力會(huì)關(guān)注整個(gè)輸入序列中的標(biāo)記,幫助模型更好地理解當(dāng)前標(biāo)記和其他標(biāo)記的對(duì)應(yīng)關(guān)系.自注意力的計(jì)算方法如公式(13)所示:
(13)
其中Q,K,V分別由權(quán)重矩陣WQ,WK,WV和輸入向量X相乘獲得.此外,dk作為比例因子防止過(guò)大值通過(guò)softmax函數(shù)導(dǎo)致的梯度消失問(wèn)題.
Transformer的自注意力是多頭的,多頭自注意力機(jī)制允許模型在不同的表示子空間里學(xué)習(xí)相關(guān)的信息.每個(gè)自注意力頭定義為headi=Attention(Qi,Ki,Vi),然后將h個(gè)自注意力頭拼接,再經(jīng)過(guò)一次線(xiàn)性變換獲得多頭自注意力的輸出,如公式(14)所示:
MultiHead(Q,K,V)=Concat(head1,…,headh)Wo
(14)
每個(gè)自注意力子層的輸出會(huì)傳遞到前饋神經(jīng)網(wǎng)絡(luò)層.此外,在編碼器的每個(gè)子層后都應(yīng)用了殘差連接并伴隨層歸一化步驟[36],用于消除隨著層數(shù)加深帶來(lái)的信息損失問(wèn)題.
Transformer解碼器負(fù)責(zé)根據(jù)先前編碼器的輸出和當(dāng)前編碼狀態(tài)生成代碼注釋.解碼器結(jié)構(gòu)與編碼器相似,包含兩個(gè)多頭自注意力層.第1層的自注意力機(jī)制采用了Masked操作,使自注意力層只被允許處理輸出序列中更靠前的那些位置.第2層為編碼-解碼自注意力層,根據(jù)先前編碼器輸出的一個(gè)包含鍵向量K,值向量V的注意力向量集C,從上層解碼器得到的查詢(xún)向量Q,幫助解碼器關(guān)注輸入序列.隨后,解碼器組輸出的向量通過(guò)一個(gè)全連接層,投射到單詞表維度的向量中.最終通過(guò)Softmax層生成對(duì)應(yīng)位置注釋單詞的概率.
本節(jié)將從實(shí)驗(yàn)設(shè)置、評(píng)價(jià)方法以及實(shí)驗(yàn)結(jié)果分析3方面展開(kāi)論述.
本文使用大規(guī)模Java數(shù)據(jù)集進(jìn)行實(shí)驗(yàn)[17].該數(shù)據(jù)集搜集自GitHub,是目前代碼注釋生成方向使用最為頻繁的數(shù)據(jù)集[37].該數(shù)據(jù)集由一對(duì)Java語(yǔ)言編寫(xiě)的方法源代碼和JavaDoc文檔注釋組成.以90∶5∶5的比例將數(shù)據(jù)集劃分為訓(xùn)練集,驗(yàn)證集和測(cè)試集.本文從驗(yàn)證集和測(cè)試集中刪除了出現(xiàn)在訓(xùn)練集中的數(shù)據(jù).將單詞表大小限制在30000個(gè),超過(guò)限制的低頻標(biāo)記采用
將數(shù)據(jù)集源代碼中的數(shù)字和字符串替換為特殊標(biāo)記
表1 數(shù)據(jù)集統(tǒng)計(jì)Table 1 Statistics of datasets
本文將數(shù)據(jù)集中源代碼長(zhǎng)度上限設(shè)置為100,摘要的最大長(zhǎng)度設(shè)置為30.使用特殊標(biāo)記
本文實(shí)驗(yàn)基于pyhton3.6和TensorFlow框架實(shí)現(xiàn),在Linux服務(wù)器(Ubuntu16.04,Intel?CoreTM i9-10900X CPU @ 3.70GHz,GeForce RTX 2080 Ti×4 GPU)上運(yùn)行.
為了驗(yàn)證代碼注釋生成方法的有效性,文本使用在神經(jīng)機(jī)器翻譯領(lǐng)域內(nèi)應(yīng)用最廣泛的評(píng)價(jià)指標(biāo)BLEU[18]、METEOR[19]和ROUGE[20]指導(dǎo)實(shí)驗(yàn).這些指標(biāo)可以評(píng)估預(yù)測(cè)文本(即代碼注釋生成方法生成的文本)和參考文本(即源數(shù)據(jù)集中手工方式生成的文本)的相似程度.
BLEU指標(biāo)用于比較預(yù)測(cè)文本和參考文本中n元詞組的重合程度,隨著n增大,BLEU指標(biāo)可以進(jìn)一步衡量文本流暢性,本文使用BLEU-4作為實(shí)驗(yàn)指標(biāo).BLEU計(jì)算公式如式(15)所示:
(15)
其中BP代表預(yù)測(cè)文本較短的懲罰因子,wn是正權(quán)重,Pn是修改后的n-gram精度的幾何平均值.雖然有短文本懲罰因子,但從整體上來(lái)看,BLEU指標(biāo)更偏向于較短的候選文本[19].因此本文還使用了METEOR和ROUGE作為評(píng)價(jià)指標(biāo),以彌補(bǔ)BLEU指標(biāo)的不足.
METEOR指標(biāo)引入了同義詞匹配,通過(guò)句子級(jí)別的相似度來(lái)評(píng)估翻譯效果.METEOR可通過(guò)公式(16)計(jì)算:
METEOR=(1-Pen)Fmean
(16)
其中Pen是懲罰系數(shù),Fmean是精確率和召回率的加權(quán)調(diào)和平均.分別由公式(17)、公式(18)計(jì)算:
(17)
(18)
其中γ、θ和α均為用于評(píng)價(jià)的默認(rèn)參數(shù).ch是塊(候選文本和參考文本能對(duì)齊,并且在排列上連續(xù)的單詞稱(chēng)作一個(gè)塊)的數(shù)量,m是匹配項(xiàng)的數(shù)量.Pm和Rm分別代表精確率和召回率.
ROUGE是一種基于召回率的相似性度量指標(biāo),可以考察候選文本的充分性.本文選用ROUGE-L作為評(píng)價(jià)指標(biāo),通過(guò)公式(19)~公式(22)計(jì)算.
(19)
(20)
(21)
(22)
其中,LCS(X,Y)代表預(yù)測(cè)文本和參考文本的最大長(zhǎng)度公共子序列,m和n分別是候選文本和參考文本的長(zhǎng)度.
本小節(jié)將全面評(píng)估本文所提出模型的實(shí)驗(yàn)結(jié)果,分別從兩個(gè)方面評(píng)價(jià)模型性能:1)通過(guò)與以往先進(jìn)的代碼注釋生成模型在相同數(shù)據(jù)集上進(jìn)行的對(duì)比實(shí)驗(yàn);2)探究了本文提出的AST簡(jiǎn)化方法和樹(shù)編碼組件對(duì)模型的影響.最后,本文從數(shù)據(jù)集中選取了3個(gè)樣例說(shuō)明本文模型的有效性.
5.3.1 對(duì)比實(shí)驗(yàn)
本文選取了其他3種以往先進(jìn)的基于神經(jīng)機(jī)器翻譯的基線(xiàn)方法與本文模型進(jìn)行對(duì)比實(shí)驗(yàn),實(shí)驗(yàn)結(jié)果如表2所示.表2中所涉及的對(duì)比模型如下.
表2 對(duì)比實(shí)驗(yàn)結(jié)果Table 2 Comparison of experimental results
CodeNN[21]:在編碼和解碼時(shí)均基于LSTM和注意力機(jī)制.
Hybrid-DeepCom[17]:通過(guò)將AST序列化,使用GRU構(gòu)建了一個(gè)抽象語(yǔ)法樹(shù)編碼器,另一個(gè)GRU構(gòu)建了源代碼標(biāo)記編碼器,使用注意力機(jī)制融合兩部分信息.考慮了源代碼的部分結(jié)構(gòu)信息.
Multi-way Tree-LSTM[15]:提出擴(kuò)展的Tree-LSTM直接對(duì)AST編碼,通過(guò)Tree2Seq結(jié)構(gòu)的模型生成注釋.
根據(jù)表2,可以發(fā)現(xiàn)本文方法優(yōu)于3種對(duì)照方法.本文提出的融合源代碼語(yǔ)法結(jié)構(gòu)信息和順序語(yǔ)義信息的方法相較于Hybrid-DeepCom,在BLEU-4指標(biāo)上提高了6.86,METEOR指標(biāo)提高了6.76,ROUGLE-L指標(biāo)提高了9.92.Hybrid-DeepCom使用兩個(gè)編碼器,一個(gè)對(duì)源代碼序列編碼,另一個(gè)對(duì)抽象語(yǔ)法樹(shù)經(jīng)由SBT方法轉(zhuǎn)化的序列編碼.他們的方法優(yōu)于單純使用源代碼序列的CodeNN,證明了源代碼中這兩部分信息對(duì)于模型理解源代碼的重要性.但由于代碼結(jié)構(gòu)的復(fù)雜性,這種融合源代碼語(yǔ)法結(jié)構(gòu)和順序語(yǔ)義的方式可能會(huì)丟失部分結(jié)構(gòu)信息.此外,本文方法在3項(xiàng)指標(biāo)上的得分均高于Multi-way Tree-LSTM.上述實(shí)驗(yàn)結(jié)果表明,本文所提出的融合源代碼結(jié)構(gòu)信息和語(yǔ)義信息的方法是有效的,優(yōu)于其他對(duì)照方法,相較于只使用語(yǔ)義信息的方法提升巨大.本文模型在代碼注釋生成方向上有著更好的性能,在生成注釋的質(zhì)量上有明顯提高.
本文還分析了代碼注釋生成模型的性能受源代碼長(zhǎng)度的影響.實(shí)驗(yàn)結(jié)果如圖4所示.可以看到3種模型隨著源代碼序列變長(zhǎng),模型性能會(huì)逐漸下降,尤其是對(duì)于Seq2Seq結(jié)構(gòu)的Hybrid-DeepCom,在源代碼序列長(zhǎng)度超過(guò)100后,BLEU-4評(píng)分顯著降低.這是由于Seq2Seq模型將源代碼信息編碼為固定長(zhǎng)度的向量,從而導(dǎo)致越長(zhǎng)的序列會(huì)丟失越多的信息.Tree2Seq結(jié)構(gòu)的Multi-way Tree-LSTM模型隨著代碼序列長(zhǎng)度變長(zhǎng),波動(dòng)同樣劇烈,因?yàn)門(mén)ree2Seq對(duì)抽象語(yǔ)法樹(shù)建模,而源代碼序列的長(zhǎng)度通常決定抽象語(yǔ)法樹(shù)規(guī)模.由于本文所提出的AST簡(jiǎn)化方法可以縮小AST規(guī)模,且Transformer模型可以捕獲長(zhǎng)距離依賴(lài)信息,所以文本方法相對(duì)于Hybrid-DeepCom模型和Multi-way Tree-LSTM模型受源代碼序列長(zhǎng)度影響最小,并且即便在長(zhǎng)序列下,BLEU-4的得分仍要高于另外兩種模型.
圖4 3種模型在不同代碼長(zhǎng)度下的性能表現(xiàn)Fig.4 Performance of the three models at different code lengths
5.3.2 消融實(shí)驗(yàn)
為了更細(xì)致地分析本文模型各組件的有效性,本文進(jìn)行了相應(yīng)的消融實(shí)驗(yàn),以了解不同子模塊對(duì)完整模型效果的影響.消融實(shí)驗(yàn)結(jié)果展示在表3.可以發(fā)現(xiàn),樹(shù)編碼組件和簡(jiǎn)化AST都有助于模型效果的提升,但程度各不相同.具體地,刪除樹(shù)編碼組件后,僅通過(guò)Transformer對(duì)源代碼序列進(jìn)行語(yǔ)義建模,在Transformer有效捕獲長(zhǎng)距離依賴(lài)的強(qiáng)大加持下,性能優(yōu)于表2的CodeNN和Hybrid-DeepCom.這表明Transformer比LSTM或GRU更適合代碼注釋生成任務(wù).加入樹(shù)編碼組件后,BLEU-4提升了3.66,METEOR和ROUGE-L分別提高了3.93和3.52.這表明融入源代碼語(yǔ)法結(jié)構(gòu)信息對(duì)于學(xué)習(xí)代碼特征的重要性,缺乏這部分信息會(huì)對(duì)代碼注釋生成任務(wù)帶來(lái)巨大影響.
表3 消融實(shí)驗(yàn)結(jié)果Table 3 Ablation study results
進(jìn)一步地,本文發(fā)現(xiàn)將源代碼序列轉(zhuǎn)化為AST后,樹(shù)深度相對(duì)較大,會(huì)導(dǎo)致編碼困難,削弱了神經(jīng)網(wǎng)絡(luò)捕獲復(fù)雜語(yǔ)義的能力.簡(jiǎn)化AST結(jié)構(gòu)后,模型性能優(yōu)于對(duì)完整AST進(jìn)行編碼,分別在BLEU-4、METEOR和ROUGE-L指標(biāo)上提升了1.45,1.22,1.83.這表明由于AST結(jié)構(gòu)過(guò)于復(fù)雜,某些冗余節(jié)點(diǎn)的存在對(duì)模型學(xué)習(xí)起阻礙效果.簡(jiǎn)化AST可以減少語(yǔ)法結(jié)構(gòu)編碼中和語(yǔ)義信息冗余的部分,簡(jiǎn)化訓(xùn)練.
為了探究為何簡(jiǎn)化AST對(duì)模型性能起到提升作用,以更直觀地分析不同粒度下AST對(duì)模型性能的影響,本文探究了不同程度簡(jiǎn)化AST下的實(shí)驗(yàn)結(jié)果并進(jìn)行了詳細(xì)對(duì)比.將AST節(jié)點(diǎn)類(lèi)型按照對(duì)代碼的層次結(jié)構(gòu)影響從高到低劃分為基本語(yǔ)句節(jié)點(diǎn),調(diào)用式節(jié)點(diǎn),表達(dá)式節(jié)點(diǎn)和聲明式節(jié)點(diǎn).最簡(jiǎn)約版本只包含基本語(yǔ)句節(jié)點(diǎn),其余3個(gè)版本根據(jù)節(jié)點(diǎn)類(lèi)型優(yōu)先級(jí)依次疊加.4個(gè)版本AST平均節(jié)點(diǎn)數(shù)分別為4.8,13.6,19.1,21.6.
圖5給出了不同程度下簡(jiǎn)化AST的4個(gè)版本在BLUE-4、METEOR和ROUGE-L指標(biāo)上度量方面的性能變化.橫坐標(biāo)中的a,b,c和d分別代表平均節(jié)點(diǎn)數(shù)為4.8,13.6,19.1和21.6的4個(gè)簡(jiǎn)化程度不同的版本.結(jié)果發(fā)現(xiàn),模型性能隨著AST平均長(zhǎng)度的增加先升高后降低;過(guò)于簡(jiǎn)略的AST和過(guò)于復(fù)雜的AST都不會(huì)生成最佳的結(jié)果.在刪除聲明式節(jié)點(diǎn)和表達(dá)式節(jié)點(diǎn)后,平均長(zhǎng)度為13.6的AST獲得最高的BLEU-4和METEOR分?jǐn)?shù).實(shí)驗(yàn)結(jié)果表明,本文所提出的簡(jiǎn)化AST方法有效縮小了AST規(guī)模,簡(jiǎn)化AST可以提煉更加準(zhǔn)確的語(yǔ)法結(jié)構(gòu)信息,增大內(nèi)容結(jié)構(gòu)的層次性,從而提升注釋質(zhì)量.
圖5 簡(jiǎn)化AST對(duì)模型性能的影響Fig.5 Impact of simplified AST on model performace
5.3.3 模型樣例分析
圖6給出了3個(gè)數(shù)據(jù)集中的實(shí)際例子.其中Reference表示相應(yīng)源代碼由人工標(biāo)注的真實(shí)注釋.陰影部分是生成注釋重點(diǎn)關(guān)注的部分.可以看出,樣例1中本文方法生成的注釋可以清晰表示源代碼的含義,其關(guān)注點(diǎn)在基本語(yǔ)句節(jié)點(diǎn)return和調(diào)用式節(jié)點(diǎn)_stream.read()上.樣例2中可以看到注釋的關(guān)注點(diǎn)在方法名以及分支結(jié)構(gòu)中,并且本文方法生成的注釋和參考注釋含義一樣.樣例3中,生成注釋的關(guān)注點(diǎn)主要在方法名和參數(shù)上,方法體中大量聲明式節(jié)點(diǎn)和表達(dá)式節(jié)點(diǎn)在語(yǔ)法結(jié)構(gòu)編碼階段是被忽略的,但仍可以在語(yǔ)義編碼階段被捕捉,生成幾乎和參考注釋相同的文本.此外,本文分析生成的注釋在部分?jǐn)?shù)據(jù)中得分較低的情況(如樣例1),這是因?yàn)閷?shí)際項(xiàng)目中編寫(xiě)注釋時(shí)開(kāi)發(fā)人員會(huì)參考方法上下文或加入自己的主觀意識(shí),但這在方法級(jí)別的注釋生成任務(wù)中是難以實(shí)現(xiàn)的.不難看出,如果只關(guān)注獨(dú)立存在的方法,本文方法生成的注釋可以清晰地表達(dá)源代碼含義.
圖6 源代碼,參考注釋和生成注釋示例Fig.6 Example of the source code,reference and the generated comments
本文提出一種同時(shí)學(xué)習(xí)源代碼語(yǔ)法結(jié)構(gòu)特征和順序語(yǔ)義特征的代碼注釋生成方.本文設(shè)計(jì)了一種AST簡(jiǎn)化方法,縮小AST規(guī)模,通過(guò)基于AST的樹(shù)編碼組件學(xué)習(xí)代碼結(jié)構(gòu)信息,并在Transformer中將語(yǔ)法結(jié)構(gòu)信息和語(yǔ)義信息融合.本文在大規(guī)模Java數(shù)據(jù)集上進(jìn)行了全面實(shí)驗(yàn).實(shí)驗(yàn)結(jié)果表明,本文方法在BLEU-4、METEOR和ROUGE-L指標(biāo)上的得分均高于3種對(duì)照方法.
未來(lái)研究可以集成更大的語(yǔ)料庫(kù),并結(jié)合其他基于深度學(xué)習(xí)的方法,探索對(duì)語(yǔ)法結(jié)構(gòu)信息和順序語(yǔ)義信息更高效的融合方法,進(jìn)而提高自動(dòng)生成代碼注釋的質(zhì)量.