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