孟 堯,祝躍飛
1(信息工程大學(xué) 網(wǎng)絡(luò)空間安全學(xué)院,鄭州 450001)2(數(shù)學(xué)工程與先進(jìn)計算國家重點實驗室,鄭州 450001)
為了保持軟件運行的穩(wěn)定性,軟件工程師需要花費大量的時間進(jìn)行軟件維護(hù).據(jù)文獻(xiàn)報道,軟件維護(hù)的過程最多占據(jù)軟件開發(fā)生命周期的90%[1].作為軟件維護(hù)的基礎(chǔ)步驟,維護(hù)人員需要閱讀項目的文檔和注釋,理解現(xiàn)存代碼的功能和結(jié)構(gòu)特性.然而,大多數(shù)程序員不愿意在軟件開發(fā)的過程中,同步編寫詳細(xì)的源代碼注釋.面對海量不規(guī)范的代碼摘要和注釋,人們很難讀懂陳舊的源代碼的含義[2].在軟件工程領(lǐng)域,合格的代碼摘要注釋應(yīng)該符合以下3個特點[3]:①正確性.代碼摘要必須準(zhǔn)確地描述源代碼實現(xiàn)的函數(shù)功能.②流利性.由于源代碼摘要和注釋采用自然語言編寫,它們必須符合自然語言的語法規(guī)范和表達(dá)方式,程序開發(fā)者和維護(hù)者能夠輕易地理解摘要的語義.③一致性.在整個項目中,源代碼摘要和注釋應(yīng)該遵循統(tǒng)一的格式和標(biāo)準(zhǔn),方便后期的軟件維護(hù)人員理解代碼.為了快速地產(chǎn)生符合規(guī)范的代碼摘要,軟件工程領(lǐng)域的學(xué)者們開始研究代碼自動摘要工具,期望將軟件開發(fā)人員從重復(fù)的代碼摘要撰寫工作中解脫出來,進(jìn)一步地提高軟件開發(fā)效率.
早期的代碼摘要生成算法大部分都基于傳統(tǒng)的自然語言處理技術(shù)(NLP),使用人工邏輯編寫計算機(jī)程序,自動地生成函數(shù)或類的相關(guān)注釋.研究者們主要使用模板匹配、內(nèi)容選擇等常見的信息檢索技術(shù)(Information Retrieval)生成代碼摘要.Giriphrasad等人[1]通過分析源代碼的語法特征,構(gòu)造了若干個模板來生成注釋.而Sridhara等人[4]根據(jù)自然語言處理中常見的SWUM技術(shù)生成提取模板,從源代碼的符號序列中抽取關(guān)鍵字組成短摘要信息.經(jīng)典的摘要生成算法雖然能夠快速地生成代碼注釋,但是過于依賴相關(guān)領(lǐng)域?qū)<姨峁┑幕谔囟ň幊陶Z言的轉(zhuǎn)換規(guī)則,很難被運用于其他語言的程序代碼.
隨著深度學(xué)習(xí)技術(shù)的興起,研究者們開始使用各種神經(jīng)網(wǎng)絡(luò)模型生成源代碼的摘要注釋.在自然語言翻譯任務(wù)中大放異彩的神經(jīng)機(jī)器翻譯模型(Neural Machine Translation,NMT),獲得了相關(guān)領(lǐng)域研究者的廣泛關(guān)注.一個典型的NMT基于序列結(jié)構(gòu)(seq2seq)搭建,使用事先收集的語料集進(jìn)行模型的監(jiān)督訓(xùn)練,最終實現(xiàn)一種自然語言到另外一種自然語言的翻譯過程(諸如英語到法語的句子翻譯[5]).在軟件工程領(lǐng)域,人們嘗試使用NMT技術(shù)將一種程序的源代碼翻譯成自然語言組成的代碼摘要.由于神經(jīng)網(wǎng)絡(luò)強(qiáng)大的特征提取和表述能力,基于深度學(xué)習(xí)的代碼摘要生成技術(shù)很快取代了基于信息提取的傳統(tǒng)的摘要生成技術(shù).然而,程序語言和自然語言之間的巨大差異使機(jī)器翻譯中的NMT技術(shù)難以直接移植到代碼摘要生成的任務(wù)中.源代碼的編碼器無法自動提取程序語言的語法和語義特征,對抽象語法樹的遍歷也存在著較大的問題.
結(jié)合深度神經(jīng)網(wǎng)絡(luò)技術(shù)和注意力機(jī)制,本文提出了一個基于監(jiān)督學(xué)習(xí)的源代碼摘要生成型At-ComGen.該模型使用NMT框架,由源代碼編碼器和摘要生成解碼器組合搭建.At-ComGen模型首先使用混合編碼器將源代碼函數(shù)映射為高維空間的向量表示,再通過與之相連的循環(huán)神經(jīng)網(wǎng)絡(luò)(RNN)解碼器將代碼向量輸出為若干詞匯組成的摘要信息.為了保持源代碼豐富的結(jié)構(gòu)特征,At-ComGen在編碼過程中使用兩個獨立的RNN編碼器分別提取代碼的詞匯特征和語法特征.而在解碼器內(nèi)部,At-ComGen使用BERT預(yù)訓(xùn)練模型對摘要詞向量進(jìn)行解碼處理.混合注意力機(jī)制的使用,使每個輸出詞匯的向量表示都是所有輸入向量的加權(quán)求和.通過注意力權(quán)重的差異,重點的詞匯和語法結(jié)構(gòu)在輸出向量中得到了加強(qiáng).對比實驗表明,At-ComGen的性能超過了業(yè)內(nèi)主流的代碼摘要生成模型.
本文內(nèi)容分為7節(jié):第1節(jié)介紹了代碼摘要生成的背景和本文提出的At-ComGen模型的基本情況.第2節(jié)回顧了源代碼摘要生成領(lǐng)域內(nèi)的最近研究成果.第3節(jié)介紹了本領(lǐng)域內(nèi)的相關(guān)概念與背景知識.第4節(jié)詳細(xì)介紹了At-ComGen模型的架構(gòu)和實現(xiàn)細(xì)節(jié).在第5節(jié)中,通過實驗展示了At-ComGen和其他基準(zhǔn)模型的性能.第6節(jié)基于對比實驗的結(jié)果,分析了影響At-ComGen模型性能的關(guān)鍵結(jié)構(gòu).本文結(jié)束的節(jié)節(jié)討論了此項研究工作的未來方向和發(fā)展前景.
作為軟件工程領(lǐng)域內(nèi)的一項關(guān)鍵任務(wù),有關(guān)源代碼摘要生成的研究吸引了業(yè)內(nèi)學(xué)者的廣泛關(guān)注.摘要生成模型以源代碼函數(shù)作為輸入,通過內(nèi)部的編碼器和解碼器,自動地輸出一段用自然語言敘述的文字摘要.根據(jù)源代碼的處理方式,摘要生成算法通常被分為基于信息提取的傳統(tǒng)模式和基于數(shù)據(jù)訓(xùn)練的神經(jīng)網(wǎng)絡(luò)編碼模式.
在早期的有關(guān)代碼摘要的研究中,人們分析特定任務(wù)的代碼結(jié)構(gòu),總結(jié)代碼規(guī)律生成相關(guān)模板,提取源代碼的關(guān)鍵詞組合成摘要.基于軟件詞匯用途模型技術(shù)SWUM,Sridhara等人[4]利用人工規(guī)則從Java類中提取函數(shù)名等關(guān)鍵詞匯構(gòu)成代碼摘要.他們又在后續(xù)的研究中嘗試使用不同的模板提高生成摘要的準(zhǔn)確度.學(xué)者M(jìn)oreno等人[6]預(yù)先定義了若干條啟發(fā)性的規(guī)則.他們的模型能夠根據(jù)規(guī)則從Java類中提取相關(guān)信息組成代碼注釋.這類方法的關(guān)鍵是使用人工定義的模板直接從源代碼段中抽取關(guān)鍵詞匯,組成符合自然語言語法規(guī)則的摘要注釋.
信息提取技術(shù)在代碼摘要生成領(lǐng)域中也得到了廣泛的應(yīng)用.研究者們[7,8]使用了諸如向量空間模型(VSM)和潛在語義索引(LSI)等信息提取領(lǐng)域中常見的技術(shù),提取輸入代碼片段的關(guān)鍵詞匯,生成相關(guān)摘要.由于功能相似的代碼段通常擁有相似的代碼摘要描述,部分專家嘗試使用代碼克隆檢測的算法在目標(biāo)庫搜索輸入代碼段的相似代碼,然后將克隆代碼段的摘要復(fù)制給目標(biāo)代碼.學(xué)者Wong等人[9]提出的AutoComment模型,使用已知的代碼克隆技術(shù)搜索相似代碼的相關(guān)注釋,合成目標(biāo)代碼段的摘要.
隨著深度學(xué)習(xí)技術(shù)的興起,人們嘗試在各個領(lǐng)域內(nèi)使用深度神經(jīng)網(wǎng)絡(luò)搭建模型,解決原有的難題.軟件工程領(lǐng)域的研究者們積極地引入多層感知機(jī)、循環(huán)神經(jīng)網(wǎng)絡(luò)、卷積神經(jīng)網(wǎng)絡(luò)等常見的深度學(xué)習(xí)模型[10-12],對源代碼進(jìn)行向量表征.他們精心地收集各類數(shù)據(jù)構(gòu)造相關(guān)領(lǐng)域的語料庫,通過監(jiān)督或非監(jiān)督訓(xùn)練的方式更新神經(jīng)網(wǎng)絡(luò)模型的參數(shù),提高模型精度.與傳統(tǒng)的基于信息提取技術(shù)或者經(jīng)典機(jī)器學(xué)習(xí)技術(shù)實現(xiàn)的源代碼編碼器相比,深度神經(jīng)網(wǎng)絡(luò)編碼器能夠更加精確地提取到代碼內(nèi)部的結(jié)構(gòu)和語義特征.
學(xué)者Iyer等人[13]首先將NMT技術(shù)引入了代碼摘要的研究領(lǐng)域.他們結(jié)合LSTM神經(jīng)網(wǎng)絡(luò)和注意力機(jī)制,搭建了一個基于編碼器-解碼器架構(gòu)的摘要生成模型.在數(shù)據(jù)預(yù)處理階段,他們將源代碼看成純文檔(plain text),利用常見的NLP技術(shù)將源代碼轉(zhuǎn)化成詞匯向量的集合.詞匯向量被順序地輸入到模型的編碼器中,通過LSTM神經(jīng)網(wǎng)絡(luò)取得源代碼的最終向量表述.在生成摘要的階段,模型的解碼器利用源代碼的向量表述,依次輸出對應(yīng)摘要的每個詞匯.Iyer等人使用循環(huán)神經(jīng)網(wǎng)絡(luò)的技術(shù)分別實現(xiàn)了摘要生成模型的編碼器和解碼器.而Allamanies等人[14]使用卷積神經(jīng)網(wǎng)絡(luò)的結(jié)束,實現(xiàn)了生成模型的編碼器.利用卷積核能夠逐層提取特征的性質(zhì),他們的模型能夠自動地抽取源代碼片段的核心詞匯,進(jìn)而預(yù)測函數(shù)的變量名稱.
與傳統(tǒng)的自然語言相比,程序設(shè)計語言包含人工設(shè)計的復(fù)雜結(jié)構(gòu).人們利用經(jīng)典的信息提取算法,很難得到隱藏在代碼內(nèi)部的結(jié)構(gòu)和語義特征.近年來,研究者們先后嘗試了基于詞匯特征、語法結(jié)構(gòu)以及語義結(jié)構(gòu)的編碼算法分析源代碼片段,生成相關(guān)的摘要和注釋.學(xué)者Hu等人提出了基于編碼器-解碼器結(jié)構(gòu)的著名摘要生成模型DeepCom,該模型通過對抽象語法樹的特殊遍歷算法得到富含結(jié)構(gòu)特征的代碼向量,然后使用基于LSTM神經(jīng)網(wǎng)絡(luò)的解碼器將生成的代碼向量解碼為自然語言摘要.他們發(fā)明了一種特殊的結(jié)構(gòu)化遍歷算法(SBT),能夠無損地將二維的抽象語法樹轉(zhuǎn)化為樹節(jié)點的一維序列.DeepCom模型的編碼器基于標(biāo)準(zhǔn)的LSTM神經(jīng)網(wǎng)絡(luò)搭建,在編碼過程中能夠提取樹節(jié)點的順序信息.
為了克服監(jiān)督訓(xùn)練導(dǎo)致的曝光偏差(exposure bias)問題,Wan等人[3]創(chuàng)新地使用了強(qiáng)化學(xué)習(xí)的技術(shù)訓(xùn)練摘要生成模型.他們首先使用編碼器-解碼器框架搭建摘要生成模型,然后使用強(qiáng)化學(xué)習(xí)中的AC模式(actor-critic)對生成模型進(jìn)行參數(shù)訓(xùn)練,也取得了較好的效果.
在2018年提出的預(yù)訓(xùn)練語言模型BERT[15],完全改變了詞嵌入技術(shù)的發(fā)展方向.人們提出各種基于BERT的預(yù)訓(xùn)練模型,在NLP相關(guān)的各項研究中取得了突破性的進(jìn)展.研究人員Kanade等人[16]率先將預(yù)訓(xùn)練的BERT模型引入到源代碼的向量化過程中,取得了良好的成績.他們通過實驗得出結(jié)論:基于BERT預(yù)訓(xùn)練技術(shù)的搜索模型在性能上同時超過了基于LSTM和word2vec詞向量[17]技術(shù)的常規(guī)模型和基于transformer架構(gòu)的新型模型.
為了解決傳統(tǒng)的循環(huán)神經(jīng)網(wǎng)絡(luò)(RNN)中的梯度消失的問題,學(xué)者Hochreiter和Schmidhuber在1997年提出了長短時記憶門結(jié)構(gòu)(LSTM)[18].LSTM模型的具體結(jié)構(gòu)如圖1所示,它的核心記憶單元由3個門控制器組成,包括一個記憶單元Ct、一個輸出門it、一個輸出門ot和一個遺忘門ft.在原始的RNN的基礎(chǔ)上,LSTM借助門控單元丟棄某些歷史時刻的無意義信息,避免了系統(tǒng)因梯度消失的問題導(dǎo)致訓(xùn)練失敗,有效地解決了長期依賴問題.
圖1 LSTM的基本機(jī)構(gòu)圖
LSTM神經(jīng)網(wǎng)絡(luò)的計算過程參見公式(1)-公式(5),其中Wi和bi是輸入門的權(quán)重矩陣和偏置向量,Wf和bf是遺忘門的權(quán)重矩陣和偏置向量,Wo和bo是輸入門的權(quán)重矩陣和偏置向量,σ和tanh是模型的激活函數(shù).LSTM神經(jīng)網(wǎng)絡(luò)的模型參數(shù)通過監(jiān)督訓(xùn)練求解.
ft=σ(Wf·[ht-1,xt]+bf)
(1)
it=σ(Wi·[ht-1,xt]+bi)
(2)
Ct=ft×Ct-1+it×tanh(Wf·[ht-1,xt]+bc)
(3)
ot=σ(Wo·[ht-1,xt]+bo)
(4)
ht=ot·tanh(Ct)
(5)
近年來提出的神經(jīng)機(jī)器翻譯模型(NMT)是一種基于序列到序列(Seq2Seq)理論搭建而成的編碼器-解碼器模型框架.NMT理論最初由Bahdanau[5]等人提出,經(jīng)過其他的研究者[19,20]不斷地改進(jìn)和完善.本節(jié)對NMT模型進(jìn)行基本描述,建議希望進(jìn)一步了解NMT的讀者參閱相關(guān)的文獻(xiàn).
根據(jù)序列到序列(sequence to sequence)學(xué)習(xí)的理論,NMT模型包括獨立的編碼器和解碼器,編碼器的輸出端連接著解碼器的輸入端.為了處理序列數(shù)據(jù),編碼器和解碼器通常使用諸如LSTM、GRU等常見的循環(huán)神經(jīng)網(wǎng)絡(luò)架構(gòu)實現(xiàn).NMT的工作流程如下所示:模型將預(yù)處理后的源數(shù)據(jù)片段(token1,token2,…,tokenN)依次輸入到編碼器的循環(huán)結(jié)構(gòu),得到隱層向量序列(h1,h2,…,hN);解碼器結(jié)構(gòu)再將編碼器輸出的(h1,h2,…,hN)輸入到另外的循環(huán)神經(jīng)網(wǎng)絡(luò)進(jìn)行解碼,最終通過softmax函數(shù)依次計算預(yù)測詞匯的概率分布.本文提出的At-ComGen模型就是基于NMT框架搭建而成的,模型的詳細(xì)結(jié)構(gòu)在第4節(jié)進(jìn)行說明.
本節(jié)詳細(xì)介紹At-ComGen模型的架構(gòu).使用基于混合注意力機(jī)制的編碼器-解碼器框架,At-ComGen能夠充分地提取源代碼片段的詞匯和語法特征,輸出符合自然語言規(guī)范的代碼摘要.圖2所示的是At-ComGen模型的整體架構(gòu).
如圖2所示,At-ComGen模型由編碼器和解碼器兩個部分組成.作為模型的核心,源代碼編碼器部件使用兩個獨立的LSTM神經(jīng)網(wǎng)絡(luò)分別搭建詞匯編碼器(Lexical Encoder)和結(jié)構(gòu)編碼器(Syntactical Encoder),將源代碼片段映射到統(tǒng)一的向量空間.而解碼器(Decoder)基于混合的注意力機(jī)制將兩個編碼器的輸出向量序列進(jìn)行混合解碼,生成源代碼函數(shù)的摘要.
圖2 At-ComGen模型的整體架構(gòu)圖
At-ComGen模型的工作流程主要包括兩個階段:離線模型訓(xùn)練和在線摘要生成.在離線模型訓(xùn)練階段,At-ComGen模型首先將離線訓(xùn)練集合中的標(biāo)簽數(shù)據(jù)進(jìn)行預(yù)處理,分別提取出當(dāng)前源代碼片段的詞匯序列和抽象語法樹的節(jié)點序列;然后將處理后的數(shù)據(jù)序列依次輸入摘要生成模型進(jìn)行監(jiān)督訓(xùn)練,得到解碼器和編碼器模型的正確參數(shù).在模型的在線摘要生成階段,At-ComGen模型將待生成摘要的源代碼函數(shù)輸入編碼器,并從解碼器中輸出基于自然語言的目標(biāo)摘要.模型的詳細(xì)設(shè)計見下.
At-ComGen模型的源代碼編碼器由兩個獨立的子編碼器組成.詞匯編碼器負(fù)責(zé)提取源代碼函數(shù)中的關(guān)鍵詞匯信息,而結(jié)構(gòu)編碼器負(fù)責(zé)提取源代碼函數(shù)中的結(jié)構(gòu)信息.
詞匯編碼器
源代碼的函數(shù)體內(nèi)包含了大量反映函數(shù)功能的關(guān)鍵詞匯,諸如函數(shù)名稱、變量名稱、枚舉類型等.在實際操作過程中,很多程序員直接使用這些重點詞匯構(gòu)成代碼摘要.研究者們受此啟發(fā),在代碼摘要生成模型中廣泛設(shè)置詞匯編碼器(lexical encoder),對函數(shù)內(nèi)部的重點詞匯(token)進(jìn)行編碼.早期的摘要生成模型主要關(guān)注于源代碼中的重點詞匯的提取和預(yù)處理過程[13].本文的代碼摘要模型使用一個標(biāo)準(zhǔn)的LSTM神經(jīng)網(wǎng)絡(luò)實現(xiàn)詞匯編碼器,其輸入為預(yù)處理后的詞匯向量序列.假設(shè)經(jīng)過預(yù)處理后,源代碼函數(shù)生成的輸入向量序列為X=x1,x2,…,xn.在某個時間節(jié)點t,詞匯編碼器輸入為詞匯向量xt,循環(huán)結(jié)構(gòu)通過公式(6)更新當(dāng)前狀態(tài)的隱層變量ht.
ht=f(ht-1,xt)
(6)
其中f是詞匯編碼器中的LSTM單元映射,ht-1是上一個時間節(jié)點的隱層狀態(tài)變量.詞匯向量序列X經(jīng)過詞匯編碼器的循環(huán)計算后,得到隱層狀態(tài)集合h=[h1,h2,…,hn].
在詞匯編碼器的預(yù)處理過程中,系統(tǒng)對源代碼中的關(guān)鍵字和操作符等進(jìn)行過濾,而數(shù)字和字符串變量值分別用NUM和STR代替.對于由多個詞匯復(fù)合組成的函數(shù)名、用戶自定義變量名和枚舉變量等,At-ComGen模型使用以往模型的處理方式[3,21],根據(jù)駝峰或者下劃線等標(biāo)識符對復(fù)合詞匯進(jìn)行拆分.這些常見的預(yù)處理步驟能夠有效地降低生成字典語料庫的規(guī)模.
結(jié)構(gòu)編碼器
對比自然語言書寫的普通文檔,源代碼程序蘊(yùn)含著非常復(fù)雜的結(jié)構(gòu)信息.早期的代碼摘要生成算法將源程序看成是普通的文檔,完全忽略了程序語言的結(jié)構(gòu)特征,無法生成令人滿意的摘要.抽象語法樹是一種常見的能夠完整表達(dá)源程序結(jié)構(gòu)信息的數(shù)據(jù)結(jié)構(gòu).為了提取輸入代碼片段的結(jié)構(gòu)特征,At-ComGen的結(jié)構(gòu)編碼器首先將源代碼表示為抽象語法樹,然后使用先根序(pre-order)的遍歷方法,從頂向下取得樹節(jié)點集合的排序,最后將這些節(jié)點生成的向量依次輸入到另外一個獨立的LSTM網(wǎng)絡(luò)中進(jìn)行編碼.
假設(shè)X′=x′1,x′2,…,x′n是模型經(jīng)過先根序遍歷后得到的抽象語法樹的節(jié)點集合經(jīng)過向量映射后的特定序列.在某個時間節(jié)點t,結(jié)構(gòu)編碼器輸入為樹節(jié)點向量x′t,循環(huán)結(jié)構(gòu)通過公式(7)當(dāng)前狀態(tài)的隱層變量h′t.
h′t=f(h′t-1,x′t)
(7)
其中f是結(jié)構(gòu)編碼器中的LSTM單元映射,h′t-1是上一個時間節(jié)點的隱層狀態(tài)變量.抽象語法樹經(jīng)過結(jié)構(gòu)編碼器的編碼映射,最終形成隱層轉(zhuǎn)態(tài)h′=[h′1,h′2,…,h′n].
抽象語法樹的遍歷順序決定著在結(jié)構(gòu)編碼器中的輸入向量的順序.隨著深度學(xué)習(xí)技術(shù)的發(fā)展,人們在代碼表述領(lǐng)域中提出了大量基于語法樹的遍歷方法[11,12,22].本文第六節(jié)具體討論基于不同的語法樹遍歷算法實現(xiàn)的摘要生成模型的性能.實驗證明復(fù)雜的語法樹遍歷算法并不能夠有效地提高生成摘要的描述能力.At-ComGen的結(jié)構(gòu)編碼器使用傳統(tǒng)的基于先根序的訪問方法,完成語法樹從根節(jié)點到葉子節(jié)點的遍歷過程.算法1描述的是先根序遍歷算法的實現(xiàn)過程.
算法1.先根序遍歷算法
procedurePOT(r) //輸入為以r為樹根的抽象語法樹
//遍歷結(jié)束后,seq中存放的是所有樹節(jié)點的特定序列
seq←seq+r//將根節(jié)點r存入seq序列中
ifr.hasChildthen
forcinchildsdo
POT(c)
endfor
endif
endprocedure
圖3描繪的是使用算法1對抽象語法樹進(jìn)行先根序遍歷,生成節(jié)點序列的示意圖.圖4(a)表示的是源代碼生成的抽象語法樹,圖中的圓圈代表樹的節(jié)點,其中1號節(jié)點是樹根;
圖3 抽象語法樹的遍歷示意圖
而圖4(b)表示的是經(jīng)過先根序遍歷后生成的節(jié)點序列.
At-ComGen模型的解碼器由一個獨立的、基于混合注意力機(jī)制的LSTM神經(jīng)網(wǎng)絡(luò)結(jié)構(gòu)搭建而成,根據(jù)編碼器的隱層狀態(tài)向量依次輸出每個預(yù)測摘要詞匯的概率分布.公式(8)定義了解碼器預(yù)測當(dāng)前階段的摘要生成詞匯yi的概率分布:
p(yi│y1,y2,…,yi-1)=g(yi-1,si,ci)
(8)
其中g(shù)是用來預(yù)測生成詞匯yi的概率分布的非線性變換,在實踐中通常使用神經(jīng)網(wǎng)絡(luò)層搭建softmax函數(shù);而si表示解碼器當(dāng)前階段的隱層輸出向量,ci是注意力機(jī)制中定義的環(huán)境向量,其計算方式參見下文.在At-ComGen模型中,解碼器生成的當(dāng)前階段的詞匯輸出概率是由上個階段的預(yù)測詞匯輸出、當(dāng)前階段的隱層狀態(tài)變量和注意力機(jī)制中定義的環(huán)境向量共同決定的.
在自然語言處理領(lǐng)域,注意力機(jī)制(attention)能夠使模型專注于核心詞匯和重點語句的處理過程.通過環(huán)境變量(Context Vector)的設(shè)置,解碼器模型能夠使用編碼器模型全部的隱層向量預(yù)測當(dāng)前階段的詞匯概率分布.Bahdanau等人[5]率先將注意機(jī)制應(yīng)用于機(jī)器翻譯領(lǐng)域內(nèi),使用注意力權(quán)重值的差異突出了重點詞匯在譯文中的貢獻(xiàn),取得了很好的效果.
如圖2所示,At-ComGen模型的編碼器使用兩個獨立的LSTM子編碼器分別處理源代碼詞匯和語法樹結(jié)構(gòu).與經(jīng)典的NMT模型不同,At-ComGen模型的解碼器需要同時從兩個LSTM子編碼器中提取有用信息完成編碼過程.為了使詞匯編碼器和結(jié)構(gòu)編碼器中的核心詞匯向量都能夠得到加強(qiáng),At-ComGen模型使用了混合注意力機(jī)制,基于兩個子編碼器的隱層輸出構(gòu)造環(huán)境向量,其計算過程如下:
公式(9)定義的是基于混合注意力機(jī)制實現(xiàn)的解碼器的環(huán)境向量ci的計算方法,它是詞匯編碼器和結(jié)構(gòu)編碼器的隱層輸出向量與注意力權(quán)重系數(shù)的加權(quán)和:
(9)
其中hj和h′j分別是詞匯編碼器和結(jié)構(gòu)編碼器的隱層狀態(tài)變量,而αij和α′ij分別是詞匯編碼器和結(jié)構(gòu)編碼器的注意力系數(shù),它們的計算方式參見公式(10)和公式(12).
公式(10)定義了詞匯編碼器的隱層狀態(tài)向量hj所對應(yīng)的注意力系數(shù)αij的計算方法.公式(11)表示的是詞匯編碼器狀態(tài)向量hj和解碼器狀態(tài)向量si-1的對齊程度eij的計算方法,其中α是注意力機(jī)制中的相似度計算函數(shù).
(10)
eij=a(si-1,hj)
(11)
公式(12)定義結(jié)構(gòu)編碼器的隱層狀態(tài)向量h′j所對應(yīng)的注意力系數(shù)α′ij的計算方法.公式(13)表示的是結(jié)構(gòu)編碼器狀態(tài)向量h′j和解碼器狀態(tài)向量si-1的對齊程度e′ij的計算方法,其中a是相同的相似度計算函數(shù).
(12)
e′ij=a(si-1,h′j)
(13)
本文使用常見的最小化的交叉熵定義模型訓(xùn)練的損失函數(shù),如公式(16)所示[21]:
(16)
為了全面評估At-ComGen模型的性能,本文選擇業(yè)內(nèi)有代表性的幾個摘要生成模型進(jìn)行對比實驗,其中包括基于注意力機(jī)制的CODE-NN模型[13],基于代碼結(jié)構(gòu)解析的DeepCom模型[21],基于強(qiáng)化訓(xùn)練的摘要生成模型等.下面簡要介紹這幾種對比模型的結(jié)構(gòu).
第1個對比模型是經(jīng)典的CODE-NN模型[13].該模型直接使用循環(huán)神經(jīng)網(wǎng)絡(luò)結(jié)構(gòu)搭建了一個端到端的摘要生成系統(tǒng),根據(jù)源代碼的詞向量生成相關(guān)摘要.注意力機(jī)制的引入不但突出了重點詞匯在解碼過程中的貢獻(xiàn),而且解決了過長代碼生成的摘要難以滿足需要的問題.本文對原始的CODE-NN模型進(jìn)行了必要的修改,使原來處理C#和SQL的模型編碼器能夠適用于JAVA數(shù)據(jù)集.
第2個對比模型是基于序列到序列學(xué)習(xí)算法(Seq2Seq)實現(xiàn)的代碼摘要生成模型.該模型的編碼器和解碼器分別使用獨立的LSTM神經(jīng)網(wǎng)絡(luò)搭建,能夠提取源代碼的詞匯特征生成摘要.該模型輸入源代碼函數(shù)的重點詞匯序列,輸出該函數(shù)相關(guān)的英文摘要.
第3個對比模型是DeepCom模型.為了提取源代碼中隱藏的結(jié)構(gòu)信息,DeepCom首先通過特殊的遍歷算法將抽象語法樹輸出為特定順序的節(jié)點序列,再使用經(jīng)典的編碼器-解碼器模型生成目標(biāo)代碼的摘要.作者認(rèn)為DeepCom使用的遍歷算法能夠無損地表達(dá)抽象語法樹的結(jié)構(gòu)特征,生成的摘要也能準(zhǔn)確地描述源代碼的功能特性.
第4個對比模型是wan等人近期提出的基于actor-critic模式進(jìn)行參數(shù)訓(xùn)練的強(qiáng)化學(xué)習(xí)模型.與業(yè)內(nèi)常見的代碼摘要生成模型不同,作者創(chuàng)新性地使用了強(qiáng)化學(xué)習(xí)的方式更新模型參數(shù),能夠進(jìn)一步地降低曝光誤差(exposure bias).作者通過對比實驗證明,他們提出的強(qiáng)化學(xué)習(xí)模型的性能超過了以往所有的基線模型.
由于代碼摘要生成領(lǐng)域內(nèi)可供使用的標(biāo)簽數(shù)據(jù)十分稀少,本文使用論文[21]中構(gòu)造的Java數(shù)據(jù)集進(jìn)行對比實驗.數(shù)據(jù)集的作者在GitHub中大量收集的帶有注釋的Java函數(shù)段,使用函數(shù)注釋的首句作為相關(guān)代碼段的摘要標(biāo)簽.
如表1所示,本文使用的Java數(shù)據(jù)集包含超過58萬條帶摘要的函數(shù)片段,按照大約8∶1∶1的比例劃分實驗使用的數(shù)據(jù)集、驗證集和測試集合.表2描述了Java代碼函數(shù)的長度統(tǒng)計信息,而表3描述了標(biāo)簽摘要的長度統(tǒng)計信息.源代碼和標(biāo)簽摘要的平均長度分別是99.94和8.86行,源代碼的長度遠(yuǎn)大于標(biāo)簽摘要的長度.超過95%的代碼摘要的長度少于50個單詞,而超過90%的Java源代碼的長度少于200個詞匯.
表1 Java數(shù)據(jù)集的統(tǒng)計信息
表2 Java函數(shù)的長度統(tǒng)計
表3 Java函數(shù)注釋的長度統(tǒng)計
在進(jìn)行數(shù)據(jù)預(yù)處理的過程中,編碼器模型首先使用javalang(1)https//github.com/c2nes/javalang和NLTK等工具將源代碼和相關(guān)摘要拆分成小詞匯(token),然后將詞匯進(jìn)行小寫化處理,數(shù)字和字符串分別用
為了方便計算,At-ComGen模型設(shè)置詞匯編碼器中的LSTM循環(huán)體長度最大為300.系統(tǒng)對預(yù)處理后低于300詞的代碼序列添加
本文中的實驗使用16核心CPU的Intel服務(wù)器,基于CUDA9.0的GPU加速,訓(xùn)練深度學(xué)習(xí)模型的參數(shù).服務(wù)器總共花費了大約95個小時,對At-ComGen模型進(jìn)行了50輪的監(jiān)督訓(xùn)練.At-ComGen模型使用機(jī)器學(xué)習(xí)框架Tensorflow搭建,設(shè)置詞向量和LSTM隱層狀態(tài)為768維.監(jiān)督訓(xùn)練使用隨機(jī)梯度下降(SGD)算法優(yōu)化模型參數(shù),設(shè)置Batch_size為64,使用Adam優(yōu)化器并設(shè)置學(xué)習(xí)率為0.05.為了防止模型參數(shù)過擬合,模型設(shè)置dropout值為0.5.
對比實驗使用了自然語言處理領(lǐng)域內(nèi)常見的BLEU,METEOR和ROUGE-L度量值,評價各種模型生成的摘要和參考摘要之間的相似度.為了防止N-gram取0導(dǎo)致的對數(shù)趨于負(fù)無窮的情況出現(xiàn),對比實驗中的BLEU參數(shù)使用NLTK工具包提供的平滑修正的方法.表4顯示了At-ComGen模型和CODE-NN,Seq2Seq模型、DeepCom模型和強(qiáng)化學(xué)習(xí)模型的實驗數(shù)據(jù).對比結(jié)果表明At-ComGen模型生成摘要的性能,在3種評價指標(biāo)中均領(lǐng)先于其他的基線模型.
表4 摘要生成模型的對比實驗結(jié)果
CODE-NN模型沒有使用語言模型,而是通過端對端的循環(huán)神經(jīng)網(wǎng)絡(luò)系統(tǒng)直接從源代碼中提取詞匯信息生成相關(guān)的摘要.在所有參加實驗的模型中,CODE-NN模型生成的摘要質(zhì)量最差,BLEU測量值只有27.89%.而Seq2Seq模型忽略了代碼的結(jié)構(gòu)特性,也沒有使用注意力機(jī)制突出重點詞匯的作用,生成摘要的質(zhì)量也不夠理想.DeepCom模型在對源代碼的編碼過程中,通過抽象語法樹的遍歷算法提取了部分的結(jié)構(gòu)特征,生成摘要的準(zhǔn)確性也得到進(jìn)一步提高.而近期提出的強(qiáng)化學(xué)習(xí)模型放棄了傳統(tǒng)的監(jiān)督學(xué)習(xí)的方式,使用了強(qiáng)化學(xué)習(xí)對模型進(jìn)行訓(xùn)練,進(jìn)一步降低模型的曝光誤差.在所有的模型中,強(qiáng)化學(xué)習(xí)模型的性能僅次于本文提出的At-ComGen模型.At-ComGen模型不但在編碼器中融合了兩個獨立的LSTM神經(jīng)網(wǎng)絡(luò)結(jié)構(gòu),同步提取源代碼的詞匯特征和結(jié)構(gòu)特征,而且在解碼器中還創(chuàng)新地引入BERT預(yù)訓(xùn)練模型對摘要詞匯進(jìn)行編碼和解碼.由于出色的摘要生成性能,At-ComGen已經(jīng)成為代碼摘要生成領(lǐng)域中新的基線模型.
在2018年前后,谷歌提出的transformer架構(gòu)[19]和隨后產(chǎn)生的BERT預(yù)訓(xùn)練模型,在文本處理、文本閱讀、情感分類等任務(wù)中取得了突破性的進(jìn)展.自然語言處理領(lǐng)域的研究者們紛紛使用BERT預(yù)訓(xùn)練模型進(jìn)行單詞映射編碼.受此啟發(fā),本文在搭建At-ComGen模型的過程中,也嘗試使用BERT預(yù)訓(xùn)練模型對摘要詞匯進(jìn)行向量映射.通過在相同數(shù)據(jù)集上的對比實驗,討論不同的詞向量映射技術(shù)對代碼摘要生成模型產(chǎn)生的影響.
基于At-ComGen模型的基本框架,本節(jié)使用不同的詞向量映射技術(shù)搭建了3種模型進(jìn)行對比實驗.模型1是基礎(chǔ)版本的At-ComGen,它使用Word2vec技術(shù)對源代碼中提取的詞匯和語法樹節(jié)點進(jìn)行詞向量映射,使用谷歌提供的“BERT-Base,Uncased”預(yù)訓(xùn)練模型對代碼摘要進(jìn)行詞向量映射.模型2使用了Word2vec技術(shù)對源代碼詞匯、語法樹節(jié)點和代碼摘要進(jìn)行詞向量映射,源代碼和生成摘要使用不同的語料字典.模型3使用谷歌提供的“BERT-Base,Uncased”預(yù)訓(xùn)練模型對源代碼詞匯、語法樹節(jié)點和代碼摘要進(jìn)行詞向量的映射.3種模型在Java測試集上生成摘要的性能對比如圖4所示.
圖4 基于不同的抽象語法樹遍歷算法實現(xiàn)的摘要模型的對比實驗
圖4顯示了模型1(At-ComGen模型)生成的摘要在BELU,METEOR和ROUGE-L等評價參數(shù)上領(lǐng)先于其它兩個模型.模型2使用了相對陳舊的Word2vec技術(shù),無法動態(tài)地表述摘要詞向量之間的關(guān)系,在模型性能上稍遜一籌.而令人意外的是全面使用BERT預(yù)訓(xùn)練技術(shù)的模型3,竟然在生成摘要的質(zhì)量上落后于前兩個模型.本文認(rèn)為模型3性能較差的原因是由于源代碼中出現(xiàn)的某些詞匯,特別是抽象語法樹的內(nèi)部節(jié)點諸如InfixExpression,SimpleName等都是罕見的復(fù)合詞匯.由于不屬于自然語言中的常用詞,這些復(fù)合詞匯無法根據(jù)谷歌提供的預(yù)訓(xùn)練模型的字典進(jìn)行詞向量映射.而模型2在使用Word2vec進(jìn)行詞向量映射之前,會根據(jù)所有產(chǎn)生的詞匯生成語料字典,而Word2vec能夠根據(jù)包含高頻罕見詞匯的語料字典生成相關(guān)詞匯的向量表示.代碼摘要中出現(xiàn)的都是常見的自然語言詞匯,它們大都包含在谷歌的預(yù)處理模型的字典中,因此針對代碼摘要能夠直接使用BERT預(yù)訓(xùn)練模型進(jìn)行正常地轉(zhuǎn)碼.
受計算機(jī)硬件性能的限制,At-ComGen模型目前無法利用自己的語料庫從頭訓(xùn)練BERT模型.筆者希望未來能夠解決算力問題,訓(xùn)練一個適用于源代碼的BERT模型,使At-ComGen能夠同時在編碼器和解碼器內(nèi)使用BERT進(jìn)行詞向量映射.
為了充分地提取源代碼中的結(jié)構(gòu)特征,人們在以代碼表述為基礎(chǔ)的研究中,先后提出了若干種基于抽象語法樹的遍歷算法[10,12,14,21].為了研究各種抽象語法樹遍歷算法的影響,本節(jié)接著設(shè)計對比實驗:在原有的At-ComGen模型框架上,分別使用樹形LSTM神經(jīng)網(wǎng)絡(luò)(Tree-LSTM)[23],結(jié)構(gòu)遍歷(SBT)和先根序遍歷(pre-order)算法實現(xiàn)模型的結(jié)構(gòu)編碼器.實驗結(jié)果如圖5所示,實驗結(jié)果表明復(fù)雜的抽象語法樹遍歷算法并不能夠提高模型生成摘要的質(zhì)量.基于Tree-LSTM神經(jīng)網(wǎng)絡(luò)實現(xiàn)的結(jié)構(gòu)編碼器,反而略微降低了生成摘要的性能.某些抽象語法樹的層次過多可能是產(chǎn)生這種現(xiàn)象的原因.為了更新Tree-LSTM網(wǎng)絡(luò)的模型參數(shù),編碼器首先需要將原始的多分支語法樹轉(zhuǎn)化為普通的二叉樹.復(fù)雜的轉(zhuǎn)化操作會加深語法樹的層次,加劇模型訓(xùn)練的困難,造成模型可能的性能下降.而基于SBT算法實現(xiàn)的編碼器模型,和基于先根序算法實現(xiàn)的模型在生成摘要的質(zhì)量上并無明顯差距.考慮到算法的實現(xiàn)難易程度和時間復(fù)雜度,At-ComGen模型在編碼過程中使用了簡單的先根序遍歷算法.
圖5 基于不同詞向量映射算法實現(xiàn)的摘要模型的對比實驗
本文針對源代碼摘要的生成任務(wù),提出了一種基于注意力機(jī)制的深度代碼摘要生成模型At-ComGen.該模型基于神經(jīng)機(jī)器翻譯(NMT)架構(gòu)搭建,將輸入的源代碼轉(zhuǎn)化成用自然語言描述的代碼摘要.與其他基線模型相比,At-ComGen擁有以下優(yōu)勢:1)在編碼過程中同時使用基于詞匯的編碼器和基于結(jié)構(gòu)的編碼器,更加全面地提取源代碼特征;2)混合注意力機(jī)制的使用,使代碼中的核心詞匯和重要語法節(jié)點在代碼表述的過程中得到進(jìn)一步地加強(qiáng);3)在對代碼結(jié)構(gòu)進(jìn)行預(yù)處理的過程中,語法樹葉子節(jié)點的特殊處理可以大大減少生成語料庫的規(guī)模和“UNK”的出現(xiàn)次數(shù);4)在解碼器中使用BERT預(yù)訓(xùn)練模型對代碼摘要詞匯進(jìn)行向量化,明顯地提高了生成摘要的表達(dá)能力.
通過遷移學(xué)習(xí),本文提出的代碼表述算法能夠運用在軟件工程的許多領(lǐng)域內(nèi),諸如代碼搜索、代碼克隆、代碼補(bǔ)全等.未來版本的At-ComGen模型計劃從源代碼和語法樹中提取詞匯構(gòu)成全新的語料庫,使用自身訓(xùn)練的BERT模型進(jìn)行詞匯向量化,進(jìn)一步提高生成摘要的描述能力.