李?!≮w逢禹 劉亞
關(guān)鍵詞:代碼注釋;類注釋模板;類原型;雙編碼器;深度學(xué)習(xí)
中圖分類號(hào):TP311 文獻(xiàn)標(biāo)志碼:A
0 引言(Introduction)
在許多軟件系統(tǒng)中,代碼源文件的注釋經(jīng)常出現(xiàn)不完整、過(guò)時(shí)甚至缺失等情況,對(duì)這些系統(tǒng)代碼進(jìn)行維護(hù)與完善時(shí),開發(fā)人員需要花費(fèi)大量時(shí)間理解代碼[1]。當(dāng)代碼內(nèi)部有較準(zhǔn)確的注釋文本時(shí),開發(fā)人員可以通過(guò)瀏覽注釋文本快速理解相關(guān)代碼片段的含義,從而節(jié)省維護(hù)時(shí)間,提高維護(hù)質(zhì)量。
自動(dòng)代碼注釋生成技術(shù)是用于提高代碼可讀性和可維護(hù)性的有效方法,目前針對(duì)代碼注釋自動(dòng)生成的研究大致分為以下兩類:基于模板的注釋自動(dòng)生成和基于深度學(xué)習(xí)的注釋自動(dòng)生成?;谀0遄詣?dòng)生成的代碼注釋可讀性較高,但缺乏對(duì)具體代碼結(jié)構(gòu)信息的獲取能力,而基于深度學(xué)習(xí)的代碼注釋生成研究大多應(yīng)用于方法粒度,對(duì)于復(fù)雜的類結(jié)構(gòu)的注釋生成比較困難。
針對(duì)上述兩類自動(dòng)代碼注釋生成技術(shù)存在的問(wèn)題,本文結(jié)合模板與深度學(xué)習(xí)技術(shù),提出一種為類自動(dòng)生成注釋的方法,首先確定當(dāng)前類所屬的類原型,并選擇對(duì)應(yīng)類注釋模板,提取類中的信息填充到模板中,其次針對(duì)類中方法的注釋生成問(wèn)題,提出構(gòu)建一種基于注意力機(jī)制的雙編碼器模型,實(shí)現(xiàn)代碼到注釋的映射,最后通過(guò)實(shí)驗(yàn)驗(yàn)證了本方法的可行性與實(shí)際應(yīng)用效果。
1 相關(guān)研究(Related research)
基于模板的注釋生成方法,首先需要預(yù)定義一組啟發(fā)式規(guī)則,其次提取代碼的關(guān)鍵信息并通過(guò)啟發(fā)式規(guī)則生成自然語(yǔ)言描述。HILL等[2]提出一種基于軟件單詞使用模型(SoftwareWord Usage Model,SWUM)分析Java方法簽名的方法,為Java方法生成自然語(yǔ)言注釋。SRIDHARA等[3]在HILL等研究的基礎(chǔ)上進(jìn)一步考慮了方法體內(nèi)含有的代碼,提出一種基于啟發(fā)式規(guī)則的方法為方法代碼生成注釋,該方法主要分為內(nèi)容選擇和注釋生成兩個(gè)階段。MORENO等[4]將關(guān)注的代碼粒度從方法級(jí)別提升到類級(jí)別,首先確定類和方法的原型,其次通過(guò)結(jié)合原型信息與預(yù)先定義的基于方法和數(shù)據(jù)成員訪問(wèn)級(jí)別的啟發(fā)式規(guī)則,并通過(guò)現(xiàn)有的文本生成工具對(duì)Java類生成描述性摘要。基于規(guī)則模板生成的代碼注釋容易理解,但受限于模板只能為特定的代碼結(jié)構(gòu)生成注釋,對(duì)于模板之外的代碼無(wú)法靈活地生成有效的代碼注釋。
基于深度學(xué)習(xí)的注釋生成方法通過(guò)神經(jīng)網(wǎng)絡(luò)對(duì)代碼中包含的信息進(jìn)行挖掘,得到其特征向量表示,并通過(guò)模型進(jìn)行訓(xùn)練,最終得到自然語(yǔ)言描述。目前,大量的研究主要采用神經(jīng)機(jī)器翻譯(Neural Machine Translation,NMT)模型,通過(guò)提取不同的代碼特征信息,使用不同的神經(jīng)網(wǎng)絡(luò)結(jié)構(gòu)進(jìn)行訓(xùn)練得到代碼注釋。IYER等[5]率先將深度神經(jīng)網(wǎng)絡(luò)引入自動(dòng)代碼摘要研究,提出代碼-描述嵌入神經(jīng)網(wǎng)絡(luò)(Code-DescriptionEmbedding Neural Network,CODENN)方法,在長(zhǎng)短期記憶網(wǎng)絡(luò)(Long-Short Term Memory,LSTM)的基礎(chǔ)上通過(guò)引入注意力機(jī)制構(gòu)建一個(gè)端到端的學(xué)習(xí)網(wǎng)絡(luò),從而自動(dòng)生成代碼摘要。HUANG等[6]采用門控循環(huán)單元(Gated Recurrent Units,GRU)作為編碼器和解碼器,并為代碼塊生成注釋,GRU是對(duì)LSTM網(wǎng)絡(luò)的一種改進(jìn),能夠保留較長(zhǎng)的上下文信息[7]。CAI等[8]提出使用樹形長(zhǎng)短期記憶網(wǎng)絡(luò)(Tree-LSTM),通過(guò)引入語(yǔ)法類型信息對(duì)程序代碼進(jìn)行結(jié)構(gòu)化編碼,并在解碼時(shí)采用多種策略對(duì)抽象語(yǔ)法樹的節(jié)點(diǎn)進(jìn)行篩選,最終生成代碼注釋?;谏疃葘W(xué)習(xí)的自動(dòng)代碼注釋方法可以較靈活地為代碼片段生成注釋,在面對(duì)復(fù)雜程序代碼時(shí),仍然具有良好的結(jié)構(gòu)學(xué)習(xí)能力,但目前大多只應(yīng)用于方法粒度,針對(duì)類粒度的代碼片段無(wú)法生成較為全面的注釋。
2 類注釋生成方法(Class annotation generationmethod)
本文提出的基于類原型與深度學(xué)習(xí)為類生成注釋的方法活動(dòng)圖如圖1所示,主要包括以下幾步:第一步,提取類中方法,確定類中方法原型,并通過(guò)類中方法原型的分布確定類原型;第二步,為不同的類原型選擇不同的類注釋模板;第三步,針對(duì)類注釋模板中各部分的信息設(shè)計(jì)相應(yīng)的提取規(guī)則,并將提取到的信息填充到類注釋模板中;第四步,對(duì)于類中的主要方法通過(guò)深度學(xué)習(xí)模型得到方法注釋,將方法代碼注釋填充到類注釋模板中,得到完整類注釋。
2.1 類原型分類
類原型是項(xiàng)目設(shè)計(jì)中類的角色和責(zé)任的簡(jiǎn)單抽象,開發(fā)人員可以通過(guò)類原型較快地了解類在系統(tǒng)中的一般職責(zé)。在軟件的維護(hù)和發(fā)展過(guò)程中,對(duì)類原型的準(zhǔn)確描述是必要的,STARON等[9]驗(yàn)證了類原型信息在程序理解任務(wù)中的有效性。本文首先對(duì)類的原型進(jìn)行識(shí)別,確定類的職責(zé),其次為不同的類原型選擇不同的類注釋模板。
目前,在類與方法的原型識(shí)別領(lǐng)域已有大量研究,文獻(xiàn)[10]首先提出了一種方法原型的自動(dòng)識(shí)別技術(shù),并給出了方法原型的分類法;文獻(xiàn)[11]在此基礎(chǔ)上提出一種根據(jù)方法原型分布確定類原型的方法,并給出了類原型的分類法。為了構(gòu)建符合類職責(zé)的注釋模板,本文參照文獻(xiàn)[11]對(duì)方法原型和類原型的分類方法進(jìn)行重新定義,將方法原型分類為5類,類原型分類為4類,其中方法原型分布是類原型分類的重要特征。表1給出了本文定義的方法原型分類及原型描述,表2中給出了本文定義的類原型分類、原型描述及分類規(guī)則。
在表2的類原型分類規(guī)則中,acc 表示類中訪問(wèn)器類型方法的數(shù)量,mut表示類中變換器類型方法的數(shù)量,con 表示類中構(gòu)造方法的數(shù)量,col 代表類中協(xié)作方法的數(shù)量,cont 表示類中控制器類型方法的數(shù)量,mtd 表示類中方法的總數(shù)。
2.2 類注釋模板
不同類原型代表不同的職責(zé),代碼注釋主要關(guān)注的信息也不同,例如Entity類型代表實(shí)體類,重點(diǎn)關(guān)注繼承關(guān)系、類中屬性以及類在項(xiàng)目中的使用情況,由于Entity類中方法大多數(shù)為訪問(wèn)器、變換器及創(chuàng)建方法,因此不需要對(duì)類中方法進(jìn)行注釋;Boundary類型代表邊界類,多用于與其他類進(jìn)行通信,因此重點(diǎn)關(guān)注類在項(xiàng)目中的使用情況和類中方法的功能;Controller類型代表控制類,主要負(fù)責(zé)處理外部對(duì)象數(shù)據(jù),重點(diǎn)關(guān)注繼承關(guān)系、實(shí)現(xiàn)關(guān)系、類在項(xiàng)目中的使用情況和類中方法的功能。受篇幅限制,本文以Controller類原型為例,展示其注釋模板(如表3所示)。
2.3 類中信息提取規(guī)則
表4給出了類注釋模板中各部分注釋內(nèi)容的提取規(guī)則。首先,通過(guò)代碼抽象語(yǔ)法樹(Abstract Syntax Tree,AST)結(jié)構(gòu)提取父類、接口的實(shí)現(xiàn)類和類中屬性;其次,在項(xiàng)目中進(jìn)行代碼搜索提取其子類及該類在其他類中的使用情況,將上述信息填充到預(yù)定義的類注釋模板中。類中方法是類功能的具體實(shí)現(xiàn),類中方法的注釋生成是類注釋的難點(diǎn)。針對(duì)這一問(wèn)題,本文首先識(shí)別類中的主要方法,對(duì)主要方法使用深度學(xué)習(xí)的技術(shù)建立方法代碼到代碼注釋的映射模型,通過(guò)該模型獲得方法代碼的注釋并填充到類注釋模板中,最終獲得完整的類注釋。
3 基于注意力機(jī)制的雙編碼器方法代碼注釋生成模型(A model for code annotation generation inbi-encoder method based on attention mechanism)
由于方法代碼結(jié)構(gòu)復(fù)雜,包含較多的序列信息和結(jié)構(gòu)信息,因此僅使用預(yù)定義規(guī)則提取,無(wú)法為方法代碼生成較為準(zhǔn)確的注釋,而深度學(xué)習(xí)可以捕捉代碼的結(jié)構(gòu)信息,并可以通過(guò)大量訓(xùn)練得到從代碼到注釋的映射,本文使用深度學(xué)習(xí)技術(shù)為方法代碼生成代碼注釋。本文在經(jīng)典編碼器-解碼器模型的基礎(chǔ)上,提出了一種雙編碼器-解碼器的方法代碼注釋生成模型,其中雙編碼器包括一個(gè)序列編碼器和一個(gè)樹結(jié)構(gòu)編碼器,圖2展示了該模型網(wǎng)絡(luò)結(jié)構(gòu)。該模型首先對(duì)數(shù)據(jù)進(jìn)行預(yù)處理,在源碼文件中提取以方法為粒度的代碼,構(gòu)建算法提取代碼序列和代碼抽象語(yǔ)法樹結(jié)構(gòu)信息;其次分別將代碼序列和抽象語(yǔ)法樹序列的向量表示輸入各自對(duì)應(yīng)的編碼器中進(jìn)行訓(xùn)練;最后經(jīng)過(guò)注意力機(jī)制關(guān)注解碼重點(diǎn),將序列向量和抽象語(yǔ)法樹向量進(jìn)行拼接后,由解碼器解碼得到方法代碼注釋序列。
3.1 序列編碼器
在經(jīng)典編碼器-解碼器模型中,編碼器通常使用循環(huán)神經(jīng)網(wǎng)絡(luò)(RNN)按照時(shí)序提取代碼序列特征,據(jù)目前已有的研究可知,當(dāng)序列較長(zhǎng)時(shí),基于遞歸機(jī)制的RNN可能存在梯度消失或者梯度爆炸問(wèn)題。GERS等[12]提出了一種長(zhǎng)短期記憶網(wǎng)絡(luò)(LSTM),相對(duì)于RNN而言,LSTM在處理長(zhǎng)序列數(shù)據(jù)時(shí)表現(xiàn)更為出色。因此,本文選擇LSTM 作為雙編碼器中的序列編碼器處理代碼序列信息。
為了構(gòu)造序列編碼器中的輸入方法代碼序列,首先利用Antlr4語(yǔ)法分析器生成工具將方法代碼轉(zhuǎn)化為抽象語(yǔ)法樹(AST),其次對(duì)方法AST進(jìn)行前序遍歷,組成代碼序列。算法1給出了提取方法代碼序列的算法。
通過(guò)自底向上的遍歷,最終獲取根節(jié)點(diǎn)的輸出作為樹編碼器的輸出,在圖2中通過(guò)結(jié)構(gòu)向量ht 表示該向量。
3.3 解碼器
本文采用融合注意力機(jī)制的LSTM 作為解碼器,首先將序列編碼器輸出的序列表示向量hs 和樹編碼器輸出的結(jié)構(gòu)表示向量ht 分別通過(guò)注意力機(jī)制進(jìn)行加權(quán)求和重新計(jì)算權(quán)重。其次將注意力機(jī)制篩選后的向量進(jìn)行拼接,得到綜合編碼向量作為解碼器的輸入向量。至此,解碼器就同時(shí)融合了代碼的序列信息和結(jié)構(gòu)信息。
4 實(shí)驗(yàn)結(jié)果與分析(Experimental results andanalysis)
為了全面評(píng)估本文提出的基于類原型與深度學(xué)習(xí)為類自動(dòng)生成注釋的方法,將從以下兩個(gè)方面進(jìn)行實(shí)驗(yàn)驗(yàn)證:一是評(píng)估本文提出的基于注意力機(jī)制的雙編碼器方法代碼注釋生成模型的性能;二是評(píng)估本文提出的結(jié)合類原型與深度學(xué)習(xí)的類粒度注釋生成的準(zhǔn)確性。
4.1 數(shù)據(jù)集
本文采用文獻(xiàn)[14]提供的Java-med數(shù)據(jù)集進(jìn)行實(shí)驗(yàn),該數(shù)據(jù)集收集于軟件項(xiàng)目托管平臺(tái)GitHub,包括1 000個(gè)Java頂級(jí)項(xiàng)目。該數(shù)據(jù)集包含約400萬(wàn)個(gè)方法,涵蓋模型需要的源代碼信息和注釋信息。本文將數(shù)據(jù)集按照8∶2的比例劃分訓(xùn)練集和測(cè)試集,其中訓(xùn)練集用于訓(xùn)練雙編碼器-解碼器模型,測(cè)試集用于評(píng)估雙編碼器-解碼器模型性能及Java類注釋生成效果。
4.2 評(píng)估指標(biāo)
本文從兩個(gè)方面評(píng)估本文提出方法的應(yīng)用效果。對(duì)于方法代碼注釋自動(dòng)生成的雙編碼器-解碼器模型的評(píng)估問(wèn)題,采用BLEU[15]、ROUGE[16]和METEOR[17]評(píng)估生成方法代碼注釋的質(zhì)量,這些指標(biāo)廣泛應(yīng)用于機(jī)器翻譯領(lǐng)域。其中,BLEU表示生成句子和真實(shí)句子的相似程度,更側(cè)重于準(zhǔn)確率,本文選擇其中的BLEU-4作為評(píng)估指標(biāo);ROUGE與BLEU類似,但更加關(guān)注召回率,ROUGE-L基于生成句子和真實(shí)句子的最長(zhǎng)公共子序列共現(xiàn)統(tǒng)計(jì)召回率和準(zhǔn)確率;METEOR引入了同義詞匹配,在計(jì)算得分時(shí)考慮了詞性變換和同義詞的情況。三種機(jī)器翻譯性能評(píng)估指標(biāo)與生成的自然語(yǔ)言注釋質(zhì)量呈正相關(guān)。
針對(duì)類粒度注釋的準(zhǔn)確性與完整性評(píng)估問(wèn)題,由于類粒度注釋生成的相關(guān)研究與通用數(shù)據(jù)集較少,因此本實(shí)驗(yàn)采用具有Java軟件領(lǐng)域開發(fā)經(jīng)驗(yàn)的工程師對(duì)類注釋進(jìn)行人工方式的準(zhǔn)確性評(píng)估。
4.3 實(shí)驗(yàn)結(jié)果分析
4.3.1 方法粒度的注釋生成模型性能對(duì)比
本文提出的雙編碼器-解碼器模型基于Python編程語(yǔ)言和PyTorch深度學(xué)習(xí)框架實(shí)現(xiàn),在訓(xùn)練過(guò)程中,使用Adam作為優(yōu)化器,初始學(xué)習(xí)率設(shè)置為0.001。其中,雙編碼器和解碼器均具有兩個(gè)隱藏層,隱藏狀態(tài)設(shè)為256維,嵌入單詞的維度也設(shè)為256維。
為了評(píng)估本文在方法粒度的注釋自動(dòng)生成中提出的雙編碼器-解碼器模型的有效性,選用方法注釋生成領(lǐng)域中常見的注釋生成模型進(jìn)行實(shí)驗(yàn)對(duì)比。
(1)Seq2Seq模型+注意力機(jī)制[5]。Seq2Seq模型將源代碼序列信息輸入LSTM中進(jìn)行編碼,引入注意力機(jī)制,最終由解碼器進(jìn)行解碼獲得注釋。
(2)Code2Seq模型+注意力機(jī)制[14]。Code2Seq模型通過(guò)使用抽象語(yǔ)法樹中組合路徑的集合表示代碼片段,使用BiLSTM作為編碼器,并在解碼時(shí)使用注意力機(jī)制選擇相關(guān)的路徑最終解碼獲得注釋序列。
(3)Tree2Seq模型+注意力機(jī)制[18]。Tree2Seq模型使用Tree-LSTM作為編碼器,將源代碼轉(zhuǎn)化為抽象語(yǔ)法樹結(jié)構(gòu),使用編碼器自下而上遞歸對(duì)AST節(jié)點(diǎn)進(jìn)行編碼,然后由基于注意力機(jī)制的解碼器進(jìn)行解碼。
表5展示了4種模型在選定的Java數(shù)據(jù)集上的實(shí)驗(yàn)評(píng)估結(jié)果對(duì)比。從表5中可以看到,本文提出的雙編碼器-解碼器模型的BLEU-4分?jǐn)?shù)達(dá)到35.2,并且在各項(xiàng)指標(biāo)上均優(yōu)于其他三種對(duì)照方法。相對(duì)于其他三種模型,本文模型既融合了代碼的序列信息,又融合了代碼的結(jié)構(gòu)信息,同時(shí)引入了注意力機(jī)制(Attn),能充分地獲取代碼信息,進(jìn)而提升了注釋生成效果。
4.3.2 類粒度的注釋生成性能評(píng)估
為了評(píng)估本文結(jié)合類原型與深度學(xué)習(xí)生成類注釋的性能,從類原型識(shí)別的準(zhǔn)確性及類注釋的準(zhǔn)確性兩個(gè)方面進(jìn)行評(píng)估。首先在測(cè)試數(shù)據(jù)集中選擇部分類,通過(guò)人工識(shí)別方式進(jìn)行類原型分類;其次使用本文提出的類原型識(shí)別方法對(duì)這些類進(jìn)行原型識(shí)別。從表6可以看出,本文提出的類原型識(shí)別規(guī)則能較準(zhǔn)確地識(shí)別類的原型。
為了評(píng)估生成類注釋的準(zhǔn)確性,評(píng)估者閱讀選定類的主要功能和結(jié)構(gòu)并給出對(duì)相應(yīng)類的注釋描述,然后與本文生成的類注釋進(jìn)行對(duì)比。表6展示了對(duì)不同類原型的類注釋準(zhǔn)確性的評(píng)估,評(píng)估者認(rèn)定當(dāng)類原型為實(shí)體類和邊界類時(shí),本文方法能較準(zhǔn)確地生成符合該類職責(zé)的注釋,對(duì)于類中方法數(shù)量較少的控制類能夠較為準(zhǔn)確地描述類的使用情況,但對(duì)于類的功能描述信息較少,對(duì)于大類(Large class)能較為準(zhǔn)確地描述類中具體方法的功能,從而反映類的功能。
4.4 示例展示
本文首先通過(guò)確定類的原型選擇類注釋模板,其次提取類中信息填充到模板中,最終生成完整的類注釋,表7展示了實(shí)驗(yàn)中類原型為Controller類最終生成的類注釋結(jié)果。
5 結(jié)論(Conclusion)
本文通過(guò)結(jié)合類原型與深度學(xué)習(xí)技術(shù),提出一種為類生成注釋的方法,首先通過(guò)確定類原型選擇類注釋模板,其次提取類中的信息填充模板,對(duì)于類中的方法使用帶有注意力機(jī)制的雙編碼器模型訓(xùn)練后得到方法注釋,最終得到完整的類代碼注釋。實(shí)驗(yàn)表明,本文在方法粒度中提出的雙編碼器模型在性能和效果上優(yōu)于對(duì)比模型,完整的類粒度的注釋經(jīng)人工評(píng)估后確定具有較高的準(zhǔn)確性。未來(lái),可以結(jié)合信息搜索以及其他深度學(xué)習(xí)方法,融合更多的代碼信息與注釋文本,進(jìn)一步提高自動(dòng)生成類注釋的質(zhì)量。
作者簡(jiǎn)介:
李 睿(1999-),女,碩士生。研究領(lǐng)域:自然語(yǔ)言處理,深度學(xué)習(xí)。
趙逢禹(1963-),男,博士,教授。研究領(lǐng)域:計(jì)算機(jī)軟件與軟件系統(tǒng)安全,軟件工程與軟件質(zhì)量控制,軟件可靠性。
劉 亞(1983-),女,博士,副教授。研究領(lǐng)域:信息安全,密碼學(xué)。