刁旭煬,吳 凱,陳 都,周俊峰,高 璞
(上海機電工程研究所,上海 201109)
軟件穩定性是衡量軟件質量的重要標準,成千上萬行復雜代碼往往存在會導致軟件失效的風險。為了幫助開發和測試人員更加高效地定位潛在缺陷,軟件缺陷預測技術正廣泛運用在軟件的代碼審查階段,是軟件工程[1]研究領域中的重要研究方向之一。
軟件缺陷預測技術[2-3]利用軟件代碼庫中的歷史項目進行缺陷度量元的設計與提取,并將基于靜態度量元的特征放入缺陷預測分類器中進行模型訓練,最終得到的缺陷預測模型能夠有效識別存在缺陷的代碼模塊。軟件開發與測試人員可根據預測結果對相關模塊進行復核校驗,從而節省了查找定位缺陷的時間,提升了軟件質量維護與保證的效率。軟件缺陷預測主要分為同項目軟件缺陷預測[4]與跨項目軟件缺陷預測[5-6]兩個研究方向。此外,依據提取的程序特征顆粒度,可將軟件缺陷預測技術分為基于文件級、函數級、變更級的缺陷預測。
傳統的缺陷預測方法通常是基于人工設計的靜態度量元特征來構建軟件缺陷預測模型。相關研究人員已經設計出了相關有辨別度的特征可以有效區分有缺陷和無缺陷的程序模塊,主要包括基于運算符和操作數的Halstead[7]特征、基于依賴的McCabe[8]特征、基于面向對象程序語言的CK[9]特征以及基于多態、耦合的MOOD[10]特征。
然而,由于靜態度量元特征值是基于專家經驗設計的統計值,存在有缺陷代碼模塊和無缺陷代碼模塊出現相同值導致無法區分的情況。ASTs[11]是一種基于源代碼的特征樹表示方式,蘊含著豐富的程序上下文信息。通過運用深度學習技術挖掘基于ASTs的語法語義特征,可以得到比靜態度量元更具代表性的缺陷特征,從而構建出性能更好的缺陷預測模型。
為了充分運用程序上下文中潛在的語法語義信息,論文提出了一種基于混合注意力機制的軟件缺陷預測方法。首先,使用詞嵌入方法將特征序列表示為可被學習的多維向量,然后使用基于正余弦函數進行位置編碼,接著運用多頭注意力機制自學習每個位置在上下文中的語法語義信息,最后使用全局注意力機制提取整個程序模塊的關鍵特征,從而構建出更加具有鑒別力的缺陷預測模型。論文選取了7個Apache開源項目作為數據集,與5種典型的基于靜態度量元和程序語法語義學習的方法進行比較,實驗結果表明論文提出的DP-MHA方法在F1上平均提升了17.86%。
在基于靜態度量元的方法中,Chen[12]等人使用多目標決策優化算法對軟件缺陷預測特征進行篩選;Huda[13]等人采用包裹和過濾式特征選擇方法識別重要的缺陷特征;Okutan[14]等人使用貝葉斯網絡來分配靜態度量元與缺陷傾向性之間的影響概率;此外,Xu[15]等人提出了一種基于圖的半監督缺陷預測方法來解決有標簽數據不足和噪聲問題。在基于程序語法語義學習的方法中,Wang[16]等人使用深度置信網絡生產隱式的語法語義特征進行缺陷預測;Dam[17]等人建立了一種基于深度學習樹的缺陷預測模型來盡可能多地保留ASTs的初始結構特征信息;Li[18]等人建立了嵌入靜態度量元的卷積神經網絡缺陷預測模型;此外,Phan[19]等人基于圖神經網絡從控制流圖中挖掘軟件的語法語義特征信息用來構建缺陷預測模型。
但是由于存在長期記憶依賴問題,基于RNN和CNN生產的語法語義信息可能存在信息的丟失。為了充分挖掘特征序列中每一位置的上下文信息,DP-MHA采用多頭注意力機制進行上下文自學習編碼,然后將生產的隱式語法語義特征放入全局注意力機制網絡中提取關鍵特征信息,用于缺陷預測模型的訓練與預測。
本節對基于混合注意力機制的軟件缺陷預測方法DP-MHA的總體架構進行了詳細闡述,詳見圖1。
首先,DP-MHA將項目中的每個程序文件提取為ASTs樹結構,然后從中選取關鍵節點并運用深度遍歷方法獲得序列向量,接著通過字典映射和詞嵌入技術擴展為可學習的多維向量,其次運用正余弦函數進行位置編碼,將編碼后的向量放入多頭注意力機制層,進一步挖掘每個位置的上下文語義,最后運用全局注意力機制提取程序文件中關鍵的語法語義特征,放入預測輸出模型進行訓練與預測。

圖1 DP-MHA總體架構
為了將程序文件中的源代碼用向量形式進行表征,需要選擇合適顆粒度,如字符、單詞或ASTs等形式對源程序進行特征提取。ASTs是源代碼語法結構的一種抽象表示,它以樹狀的形式表現編程語言的語法結構,樹上的每個節點都表示源代碼中的上下文語義信息。基于ASTs的表示形式能映射出源程序中的語法結構和語義信息,具有多維度的特征信息可供缺陷預測模型進行學習,因此論文采用該形式對源代碼程序進行抽象表征。
根據先前的研究,論文只提取3種類型節點作為ASTs樹特征值。第一類為方法和類實例的創建節點,此類提取方法名稱和類名稱;第二類為聲明節點,包括方法、類型、枚舉等聲明,此類提取它們的具體值;第三類為控制流節點,包括分支、循環、異常拋出等控制流節點用它們的類型值記錄。所有被選擇的AST節點值如圖2所示。

圖2 選取的AST節點類型
在本次實驗中,論文采用基于Python的開源數據分析包javalang對Java源代碼進行分析提取為AST抽象語法樹,然后采用深度遍歷的方法將提取的節點值轉化為一個序列向量,詳細描述見算法1。
算法1:將源程序文件提取為ASTs字符向量
輸入:
F:源程序文件{f1,f2,…,fn}
R:選取的節點類型{r1,r2,…,rn}
輸出:
S:字符向量{s1,s2,…,sn}
1. For i = 1→n do
2. 構建源程序fi的AST抽象語法樹ASTi;
3. For node in DFT(ASTi) then
4. If node in R then
5. Add node into ;
6. End
7. End
8. Addsiinto S;
9. End
10.Return S;
ASTs序列向量存儲著大量程序模塊的語法語義信息,兩段代碼模塊可能具有相同的靜態度量元特征值,但它們的ASTs結構存在差異,這使得基于ASTs序列可學習生成更具有辨別力的特征。為了讓提取的ASTs序列向量具備可學習性,采用字典映射技術將序列中的節點映射為一個整型數字,假設節點的數量為m,每個節點用一個整型數字表示,那么映射范圍就是從1到m。算法2為ASTs序列編碼的詳細描述,首先統計每個節點出現的頻率,并按照頻率從高到底排序,然后將ASTs字符向量映射成數字向量,接著需要將長短不一的數字向量統一為固定長度,少于固定長度的向量通過填充0來補齊長度,超出固定長度的向量將頻率低的節點依次剔除直至長度與固定值一致,最終為了使得映射的數字向量具備可學習性,構建可被訓練的高維詞字典,采用詞嵌入技術將每一個數字節點轉化為一個多維向量。
算法2:ASTs序列編碼
輸入:
S:ASTs字符向量{s1,s2,…,sn}
M:字符向量的長度
StrFreq:字符頻率字典
StrtoInt:字符轉整型字典
StrFreqList:字符頻率列表
輸出:
V:編碼后的整型向量{v1,v2,…,vn}
1. 初始化V、StrFreq、StrtoInt和StrFreqList
2. For i = 1→n do
3. For j=1→len(si) do
4. if sijnot in StrFreq.keys then
5. StrFreq[sij]=0;
6. End
7. StrFreq[sij]+=1;
8. End
9. End
10. For key in StrFre.keys then
11. StrFreqList.add((key, StrFreq[key]));
12. SortbyStrFreq(StrFreqList) ;//按頻率降序排列
13. For i=1→len(SortbyStrFreq) do
14. Str= SortbyStrFreq[i][0];
15. StrtoInt[Str]=i;
16. End
17. For i = 1→n do
18. For j=1→len() do
19.vij=StrtoInt[sij];//將字符映射為整型,頻率高的字符靠前
20. End
21. If len(vi) 22. Add M-len(vi) 0 s intovi; 23. End 24. Else if len(vi) >Mthen 25. For k=1→len(vi)-m do 26. z=vi.index(max(vi));//找到頻率最低的字符所對應的序號 27. Delviz//刪除該字符 28. End 29. End 30. Addviinto V; 31. End 32. Return V; 軟件倉庫中的缺陷數據通常是類不平衡的,其中有缺陷的程序文件往往只占據很小的一部分。直接采用原始數據集訓練的到模型存在偏向于大多數(無缺陷)類的偏差。為了解決該問題,通常采用過采樣或欠采樣技術對數據集進行平衡處理。過采樣通過復制少數類的實例來實現類間平衡,而欠采樣則是將多數類中的實例進行剔除。考慮到欠采樣或導致數據信息的丟失,從而導致欠擬合的情況,因此論文采用過采樣技術將少數(有缺陷)類的實例進行復制,從而構造出兩類平衡的數據集。 DP-MHA神經網絡架構如圖3所示,主要包含節點嵌入層、位置編碼層、多頭注意力層、全局注意力層和預測輸出層。 圖3 DP-MHA神經網絡架構 2.3.1 節點嵌入層 一維數字符號無法充分描述一個AST節點的上下文信息,論文采用詞嵌入技術將每一個一維數字向量映射為一個高維向量,詳細公式見式(1)所示。 F:M→Rn (1) 其中:M代表一個一維AST節點向量,Rn代表一個n維實數向量空間,F代表一個參數化函數,能將M中的每個數字符號映射為一個n維向量。映射得到n維向量緊接著被放入位置編碼層學習節點的位置信息。 運用詞嵌入技術不僅可以將節點的語法語義表示形式限制在有限維度的空間內,節省網絡訓練的成本,避開維數災難,而且節點之間的語法語義特征相似度也可以通過余弦距離公式來進行度量,極大地提升了網絡學習語法語義特征的效率。 2.3.2 位置編碼層 在DP-MHA模型中沒有涉及到循環和卷積的神經網絡,為了充分利用AST向量的序列特性,DP-MHA將節點嵌入層輸出的向量放入位置編碼層進行相對位置關系的學習,位置編碼后的向量維度與節點嵌入后的向量維度相同,以便兩者相加得到最終包含相對位置關系的高維節點向量,作為多頭注意力層的輸入。 根據先前的研究,論文采用基于正弦和余弦函數進行位置編碼,其計算公式如式(2)、式(3)所示: PE(pos,2i)=sin(pos/10 0002i/dmodel) (2) PE(pos,2i+1)=cos(pos/10 0002i/dmodel) (3) 其中:pos代表第pos個向量,i代表第pos個向量中的第i個維度,dmodel為節點嵌入的維度。即每個偶數位置的位置編碼對應正弦函數,每個奇數位置的位置編碼對應余弦函數,函數波長為2π到10 000*2π的幾何級數。對于任意固定偏移量k,PEpos+k能用PEpos的線性函數所表示,因此采用正余弦函數能較好的表示節點之間的相對位置關系。 2.3.3 多頭注意力層 多頭注意力層由6(num_blocks)個相同的神經網絡層組成。每層由一個多頭注意力機制和位置轉化前向反饋網絡組成,每個子層計算得到的輸出與原始輸入進行殘差連接與正則化處理,其公式表達如式(4)所示: LayerNormalization(x+SubLayerFun(x)) (4) 其中:SubLayerFun為多頭注意力機制和位置轉換前向反饋網絡兩個子層的函數,將SubLayerFun(x)與原始輸入x相加得到殘差連接并進行正則化處理,所有子層的輸入輸出向量維度與初始節點嵌入的維度相同。 多頭注意力機制由h個基于點積的注意力函數組成,首先將節點嵌入的維度縮小dmodel/h倍,使得神經網絡的計算代價與帶有整個節點維度的單個頭注意力機制的計算代價相同,然后并行應用h個注意力函數,得到的輸出進行全連接得到最終的上下文語法語義特征,具體機制架構詳見圖4所示。 圖4 單個多頭注意力層 每個點積注意力函數的輸入為矩陣Q,K,V組成,計算公式如式(5)所示: (5) 圖5 多頭注意力機制的函數架構 在運用多頭注意力機制后,DP-MHA采用一個全連接的前向反饋神經網絡進行位置轉換,該網絡層由兩個線性函數和一個ReLU激活函數組成,其計算公式如式(6)所示: FFN(x)=max(0,xW1+b1)W2+b2 (6) 2.3.4 全局注意力層 從多頭注意力層中可以得到一個序列所有位置節點的上下文語法語義信息,這些位置節點對整個序列的語法語義貢獻是不同的。為了提取其中關鍵的語法語義特征,DP-MHA采用了全局注意力函數,每個節點都會分配相應權重,進行加權和即可得到關鍵特征,其具體計算公式如式(7)~(9)所示: uit=tanh(Wnhit+bn) (7) (8) si=∑tαithit (9) 其中,全局注意力機制首先將節點hit放入一個多層感知器(MLP)來生成uit作為節點的隱式特征表示,然后設定一個全局上下文向量un,作為在每一個序列中搜尋關鍵節點信息的高階表示向量,接著計算uit與un的點積相似度并通過softmax函數進行歸一化處理。最終計算所有節點的加權和作為學習得到的全局關鍵語法語義特征向量si。 2.3.5 預測輸出層 預測輸出層由一層帶有sigmoid激活函數的多層感知器組成,損失函數采用基于softmax的交叉信息熵,具體計算公式如式(10)、式(11)所示: Yi=sigmoid(siWo+bo) (10) (11) 本文選取了6個公開Java項目作為實驗數據集,所有數據集均可在Github Apache 項目集中獲得。每個項目選取兩個版本,其中前置版本作為模型的訓練集,后置版本作為衡量模型的測試集。在軟件缺陷預測研究數據集中,靜態度量元數據是一種公認的特征集,針對Java面向對象程序語言的特點,Jureczko[20]等專家已進行相關研究并提取出了20個典型的靜態度量元,其中包含了軟件規模、代碼復雜度以及與面向對象程序語言特性相關的特征。詳細見表1所示。此外,程序的語法語義特征則由深度學習模型自動學習生成。 表1 選取的20個靜態度量元特征值 表2列舉出了實驗中項目數據集的相關信息,主要包括了項目名稱、版本號、程序模塊數量(以代碼文件為單位)以及總體缺陷率。 表2 Java項目數據集信息 3.2.1 實驗環境 本次實驗的硬件配置為一臺帶有Intel i7酷睿處理器、8G內存和GTX1060顯卡的臺式機,操作系統為Windows10,使用到的開發語言為Python及其相關機器學習與深度學習模塊Scikit-learn和Tensorflow,開發工具為pycharm。 DP-MHA網絡架構的輸入向量長度(vector_len)為1 500,節點嵌入維度(dmodel)為32;多頭注意力機制query、key與value向量的維度為32,h為2,num_blocks為6;全局注意力層的輸出維度dglobal_attention為32,其余參數詳見表3。 表3 DP-MHA網絡參數配置信息 3.2.2 評價指標 本文從F1值角度對DP-MHA方法的軟件缺陷預測性能進行衡量。通常情況下,當查全率(R)上升的同時,會降低查準率(P),F1值綜合了查準率(P)和查全率(R),對預測框架的綜合性能進行了考量,越高代表著缺陷預測模型的穩定性越好,F1值的范圍為[0,1],其計算公式如下: (12) (13) (14) 其中:c為無缺陷程序文件,d為有缺陷程序文件。Nd→d表示預測和真實值都為有缺陷的數量;Nd→d+Nc→d為所有預測結果為有缺陷的數量;Nd→d+Nd→c為所有真實值為有缺陷的數量。 在實證研究階段,論文選取了5個經典方法與DP-MHA方法進行比較,分別為基于靜態度量元的RF,基于無監督學習方法的RBM+RF和DBN+RF以及基于深度學習的CNN和RNN,詳見表4所示。 表4 選取的5個經典缺陷預測方法 方法名稱說明RF基于20個靜態度量元的隨機森林方法RBM+RF基于RBM提取程序語法語義特征的RF方法DBN+RF基于DBN提取程序語法語義特征的RF方法 CNN基于textCNN提取程序語法語義特征的方法RNN基于Bi-LSTM提取程序語法語義特征的方法 如表5所示,DP-MHA方法相較于其他5種方法在F1值上平均提升了17.86%。由此可見,基于混合注意力機制學習得到的上下文語法語義特征提升了缺陷預測模型的穩定性和準確度。 表5 DP-MHA相較于5種經典方法的F1值提升比率 為了說明DP-MHA方法相較于基于靜態度量元方法的優越性,本文選取了基于20個靜態度量元特征的RF方法進行對比分析。表6列出了DP-MHA與基于靜態度量元特征方法RF之間的F1對比結果。相較于基于靜態度量元的RF方法,DP-MHA在F1的W/T/L上全部占優,在F1的平均值上提升了16.6%。綜合上述比較結果,可判得DP-MHA方法的軟件缺陷預測模型穩定性能要優于基于靜態度量元特征的缺陷預測方法。 表6 DP-MHA與基于靜態度量元方法之間的F1值比較 為了說明DP-MHA方法相較于基于無監督學習方法的優越性,本文選取了具有典型代表的兩種無監督學習方法RBM和DBN來提取程序的語法語義特征,然后將兩者學習到的特征分別放入RF分類器訓練得到最終的缺陷預測模型。表7列出了DP-MHA與基于無監督學習方法RBM+RF和DBN+RF之間的F1值對比結果。DP-MHA比RBM+RF在F1值的W/T/L上贏了6次;相較于DBN+RF,也全部占優。此外從F1值的平均值來看,DP-MHA相較于RBM+RF和DBN+RF方法分別提升了34.3%、26.4%。綜合以上比較結果,可判得在缺陷預測模型穩定性方面,DP-MHA都要比基于無監督學習方法提取程序語法語義特征的方法來得更優。 表7 DP-MHA與基于無監督學習方法之間的F1值比較 為了說明DP-MHA方法相較于基于其他深度學習方法的優越性,本文選取了具有典型代表的兩種深度學習方法CNN和RNN來提取程序的語法語義特征并自動訓練與預測。CNN采用1維卷積核提取隱藏特征,RNN采用Bi-LSTM的雙向循環神經網絡學習隱式語法語義特征。 表8列出了DP-MHA與基于深度學習方法CNN和RNN之間的F1值對比結果。DP-MHA比CNN和RNN在F1值的W/T/L上分別都贏了5次。此外從F1值的平均值來看,DP-MHA相較于CNN和RNN方法分別提升了7.1%、4.9%。綜合以上比較結果,可判得在缺陷預測模型穩定性方面,DP-MHA都要比基于CNN和RNN的深度學習方法提取程序語法語義特征的方法來得更優。 表8 DP-MHA與基于深度學習方法之間的F1值比較 本文針對同項目軟件缺陷預測問題,提出了一種基于混合注意力機制的軟件缺陷預測方法DP-MHA,運用節點嵌入與位置編碼技術提取AST特征信息,放入多頭注意力層中學習節點的上下文語法語義信息,然后使用全局注意力機制提取關鍵特征,放入預測輸出層中進行訓練與預測,該方法學習得到的程序語法語義特征有效提升了軟件缺陷預測模型的性能。該方法仍有一些工作值得后續開展研究,具體而言為:(1)考慮跨項目軟件缺陷預測的應用場景,并驗證該方法是否能提升預測性能;(2)在實際工程項目[21-22]數據集中進一步驗證該缺陷預測方法的效果與性能。2.3 DP-MHA神經網絡構建





3 實驗設計
3.1 實驗數據集


3.2 實驗環境與評價指標

4 結果的分析和討論
4.1 選取的經典缺陷預測方法


4.2 與基于靜態度量元方法的性能比較

4.3 與基于無監督學習方法的性能比較

4.4 與基于深度學習方法的性能比較

5 結束語