在軟件缺陷預測中使用軟件可視化和遷移學習
文章的動機是避開源代碼的中間表示,將源代碼表示為圖像,直接提取代碼的語義信息以改進缺陷預測的性能。
首先,看到如下圖所示的motivation示例。File1.java和File2.java兩個示例中,雖然都包含了1個if語句、2個for語句和4個函數調用,但代碼的語義和結構特征是不相同的。為驗證將源代碼轉換成圖像是否有助于區分不同的代碼,作者進行了實驗:將源代碼根據字符的ASCII十進制數對應到像素,排列成像素矩陣,獲取源代碼的圖像。作者指出,不同的源代碼圖像存在差異。
Fig. 1 Motivation Example
文章主要的貢獻如下:
將代碼轉換成圖像,從中提取語義和結構信息;
提出一種端到端的框架,結合自注意力機制和遷移學習實現缺陷預測。
文章提出的模型框架如圖2所示,分為兩個階段:源代碼可視化和深度遷移學習建模。
Fig. 2 Framework
1.源代碼可視化
文章將源代碼轉換成6個圖像,過程如圖3所示。將源代碼字符的10進制ASCII碼轉換成8bit無符號整數向量,按行和列對這些向量進行排列,生成圖像矩陣。8bit整數直接對應到灰度等級。為解決原始數據集較小的問題,作者在文章中提出了一種基于顏色增強的數據集擴充方法:對R、G、B三個顏色通道的值進行排列組合,產生6個彩色圖。這里看著挺迷的,變換了通道值后,語義和結構信息應該有所改變吧?但是作者在腳注上進行了解釋,如圖4所示。
Fig. 3 源代碼可視化流程
Fig. 4 文章腳注2
2.深度遷移學習建模
文章使用DAN網絡來捕獲源代碼的語義和結構信息。為增強模型對重要信息的表達能力,作者在原始DAN結構中加入了Attention層。訓練與測試流程如圖5所示,其中conv1-conv5來自于AlexNet,4個全連接層fc6-fc9作為分類器。作者提到,對于一個新的項目,訓練深度學習模型需要有大量的標簽數據,這是困難的。所以,作者首先在ImageNet 2012上訓練了一個預訓練模型,使用預訓練模型的參數作為初始參數來微調所有卷積層,進而減少代碼圖像和ImageNet 2012中圖像的差異。
Fig. 5 訓練與測試流程
3.模型訓練和預測
對Source項目中有標簽的代碼和Target項目中無標簽的代碼生成代碼圖像,同時送入模型;二者共享卷積層和Attention層來提取各自的特征。在全連接層計算Source和Target之間的MK-MDD(Multi Kernel Variant Maximum Mean Discrepancy)。由于Target沒有標簽,所以只對Source計算交叉熵。模型使用mini-batch隨機梯度下降沿著損失函數訓練模型。對每一個<source, target>對的500個epoch,根據最好的F-measure從中選出一個epoch。
在實驗部分,作者選擇了PROMISE數據倉庫中所有開源的Java項目,收集了它們的版本號、class name、是否存在bug的標簽。根據版本號和class name在github中下載源碼。最終,共采集了10個Java項目的數據。數據集結構如圖6所示。
Fig. 6 數據集結構
對于項目內缺陷預測,文章選擇如下baseline模型進行對比:
對于跨項目缺陷預測,文章選擇如下baseline模型進行對比:
總結一下,雖然是兩年前的論文了,但感覺思路還是比較新奇的,避開AST等一系列代碼中間表示,直接將代碼轉換成圖像提取特征。但是還是比較疑惑,代碼轉換成的圖像真的包含源代碼語義和結構信息嗎?感覺可解釋性不太強,哈哈。后面需要做實驗分析下吧。