国产日韩欧美一区二区三区三州_亚洲少妇熟女av_久久久久亚洲av国产精品_波多野结衣网站一区二区_亚洲欧美色片在线91_国产亚洲精品精品国产优播av_日本一区二区三区波多野结衣 _久久国产av不卡

?

融合圖嵌入和注意力機(jī)制的代碼搜索

2022-04-13 02:40黃思遠(yuǎn)趙宇海梁燚銘
計(jì)算機(jī)與生活 2022年4期
關(guān)鍵詞:源代碼語(yǔ)句代碼

黃思遠(yuǎn),趙宇海,梁燚銘

東北大學(xué) 計(jì)算機(jī)科學(xué)與工程學(xué)院,沈陽(yáng)110169

隨著人們對(duì)軟件的需求越來(lái)越多樣化和復(fù)雜化,程序開(kāi)發(fā)人員往往要實(shí)現(xiàn)很多復(fù)雜的功能來(lái)滿(mǎn)足用戶(hù)的要求。然而在程序的開(kāi)發(fā)過(guò)程當(dāng)中會(huì)發(fā)現(xiàn)許多功能在以往的開(kāi)發(fā)過(guò)程當(dāng)中都被實(shí)現(xiàn)過(guò),因此如何利用現(xiàn)有的源代碼來(lái)實(shí)現(xiàn)新的功能對(duì)于軟件開(kāi)發(fā)是至關(guān)重要的,在一定程度上影響著整個(gè)項(xiàng)目的開(kāi)發(fā)進(jìn)度。據(jù)相關(guān)調(diào)查表明,程序開(kāi)發(fā)人員在互聯(lián)網(wǎng)上搜索相關(guān)問(wèn)題解決辦法的時(shí)間大約占整個(gè)開(kāi)發(fā)過(guò)程的1/5。程序開(kāi)發(fā)人員在網(wǎng)絡(luò)上搜索相關(guān)代碼的動(dòng)機(jī)主要包括對(duì)現(xiàn)存在的開(kāi)源代碼的重復(fù)使用、代碼的漏洞修復(fù)與檢測(cè)以及相關(guān)代碼片段的理解。與此同時(shí),隨著計(jì)算機(jī)的不斷發(fā)展,在互聯(lián)網(wǎng)中積累了越來(lái)越多的開(kāi)源代碼庫(kù),為軟件工程的研究提供了大量可依靠的數(shù)據(jù)。根據(jù)Github 在2018 年的年度報(bào)告顯示,Github 中開(kāi)源的項(xiàng)目數(shù)量已達(dá)到9 600 萬(wàn),與2017 年相比增加40%。大規(guī)模且快速增長(zhǎng)的開(kāi)源代碼庫(kù)為代碼檢索任務(wù)提供了大量可復(fù)用的高質(zhì)量代碼,使代碼檢索任務(wù)有了很好的數(shù)據(jù)支撐。

代碼檢索是指將自然語(yǔ)言作為查詢(xún)語(yǔ)句,在代碼倉(cāng)庫(kù)中搜索滿(mǎn)足查詢(xún)要求的相關(guān)代碼片段來(lái)實(shí)現(xiàn)代碼的復(fù)用。在軟件工程領(lǐng)域,一個(gè)高效的代碼檢索工具可以極大地提高軟件的開(kāi)發(fā)效率,從而來(lái)達(dá)到滿(mǎn)足用戶(hù)日益增長(zhǎng)的需求的目的。與此同時(shí),無(wú)論是程序初學(xué)者,還是經(jīng)驗(yàn)熟練的軟件開(kāi)發(fā)者,都希望可以利用現(xiàn)有的開(kāi)源代碼來(lái)實(shí)現(xiàn)重復(fù)的功能,從而節(jié)省自己在程序開(kāi)發(fā)過(guò)程中在網(wǎng)上查找相關(guān)解決方案所浪費(fèi)的時(shí)間。為了方便理解代碼檢索任務(wù)的流程,圖1 詳細(xì)地描述了代碼檢索任務(wù)的框架結(jié)構(gòu)。代碼檢索框架結(jié)構(gòu)主要包括線下數(shù)據(jù)處理和模型訓(xùn)練,以及線上用戶(hù)查詢(xún)等相關(guān)過(guò)程。

圖1 代碼檢索任務(wù)框架Fig.1 Code retrieval task framework

代碼搜索對(duì)于提高程序員編碼效率有著顯著性的提高,因?yàn)橹苯铀阉鞣弦蟮拇a片段比閱讀各種開(kāi)源應(yīng)用程序接口(application programming interface,API)的原始說(shuō)明文檔要有效得多。甚至很多開(kāi)發(fā)人員可能甚至不知道要查找哪些API,只需要以自然語(yǔ)言的形式進(jìn)行查詢(xún)即可找到符合要求的代碼片段。在軟件開(kāi)發(fā)過(guò)程中,程序員會(huì)遇到各種各樣的問(wèn)題,例如“如何解析純文本數(shù)據(jù)”。在遇到問(wèn)題的時(shí)候大多數(shù)程序員都會(huì)選擇在百度上去查找相關(guān)問(wèn)題的答案,但是百度的檢索結(jié)果主要是依賴(lài)關(guān)鍵詞匹配等信息檢索技術(shù)。如果查詢(xún)語(yǔ)句中不存在與代碼相關(guān)的關(guān)鍵詞信息,則百度檢索返回的結(jié)果是十分糟糕的。另一個(gè)受歡迎的程序問(wèn)答網(wǎng)站是Stack Overflow,它主要以問(wèn)答的形式來(lái)呈現(xiàn)各種問(wèn)題的解決答案。當(dāng)某人在網(wǎng)站上以自然語(yǔ)言的形式提出一個(gè)編程相關(guān)問(wèn)題,會(huì)有很多人在提問(wèn)下方提供各種各樣的解決方案,并且利用投票機(jī)制對(duì)解決方案進(jìn)行排序來(lái)將大多數(shù)人認(rèn)同的答案呈現(xiàn)在頂部,它為軟件開(kāi)發(fā)人員和初學(xué)者提供了很大的便利。當(dāng)程序開(kāi)發(fā)人員想在Stack Overflow 查找“如何解析純文本數(shù)據(jù)”這一問(wèn)題的解決辦法,可能在Stack Overflow 上已經(jīng)有人問(wèn)過(guò)和回答過(guò)同樣的問(wèn)題,程序員分析和理解其他人對(duì)這個(gè)問(wèn)題的解決辦法來(lái)完成自己的任務(wù)。盡管Stack Overflow 資源豐富,但它并不包含每個(gè)問(wèn)題的答案。與此同時(shí),Stack Overflow中不討論特定于某個(gè)公司專(zhuān)有代碼和API 的問(wèn)題,針對(duì)特定領(lǐng)域或者公司的內(nèi)部相關(guān)編程問(wèn)題,無(wú)法提供相應(yīng)解決辦法。

傳統(tǒng)的基于信息檢索的源代碼檢索算法,不能充分理解自然語(yǔ)言查詢(xún)語(yǔ)句的語(yǔ)義信息。因此,構(gòu)建一個(gè)充分理解自然語(yǔ)言查詢(xún)語(yǔ)義的源代碼檢索算法來(lái)獲取相關(guān)代碼片段,實(shí)現(xiàn)代碼的復(fù)用對(duì)軟件的開(kāi)發(fā)是十分有意義的。針對(duì)上述存在的問(wèn)題,本文提出融合圖嵌入與注意力機(jī)制的代碼檢索算法GraphCS。GraphCS 算法的創(chuàng)新在于不僅考慮代碼片段的純文本語(yǔ)義信息,也考慮代碼片段復(fù)雜邏輯結(jié)構(gòu)信息,將語(yǔ)義特征與結(jié)構(gòu)特征相融合作為代碼片段特征表示。為了更好地捕捉代碼片段中包含的信息,融入注意力機(jī)制來(lái)更好地學(xué)習(xí)代碼片段表示。與CODEnn算法相比,GraphCS 算法在Frank、MRR、Precision@1/5/10 以及SuccessRate@1/5/10 指標(biāo)上有一定提升。

1 相關(guān)工作

1.1 基于信息檢索的代碼檢索算法

在軟件工程領(lǐng)域,針對(duì)代碼檢索的相關(guān)研究還處于初級(jí)階段,現(xiàn)階段的研究主要基于信息檢索和自然語(yǔ)言處理相關(guān)技術(shù)。Krugle(http://www.krugle.com/)和Ohloh(https://code.ohloh.net/)采用基于關(guān)鍵字匹配的信息檢索方法,在商業(yè)中被廣泛應(yīng)用,但是算法的檢索結(jié)果大多情況下不符合程序開(kāi)發(fā)人員的要求。Lucene(https://lucene.apache.org/)是一個(gè)傳統(tǒng)的文本搜索引擎,而Sourcerer是基于Lucene 實(shí)現(xiàn)的代碼檢索工具,將代碼屬性和代碼的受歡迎程度相結(jié)合作為評(píng)價(jià)推薦代碼質(zhì)量的評(píng)估指標(biāo)來(lái)檢索相關(guān)代碼片段。Reiss提出基于源代碼語(yǔ)義和語(yǔ)法相結(jié)合的源代碼檢索算法,它要求用戶(hù)不僅要提供自然語(yǔ)言查詢(xún)語(yǔ)句,還要提供其他規(guī)范約束,但不考慮自然語(yǔ)言查詢(xún)語(yǔ)句的語(yǔ)義信息。如果缺少對(duì)相關(guān)代碼語(yǔ)義和語(yǔ)法信息的理解,則檢索結(jié)果的準(zhǔn)確性會(huì)降低,對(duì)于初學(xué)者和大多數(shù)程序員來(lái)說(shuō)存在一定的困難。SNIFF分析相關(guān)代碼片段的API 文檔信息,并為代碼片段添加注釋信息,并建立相關(guān)索引,來(lái)進(jìn)行代碼檢索。Portfolio給定一個(gè)自然語(yǔ)言查詢(xún)語(yǔ)句,根據(jù)自然語(yǔ)言查詢(xún)語(yǔ)句來(lái)查找用戶(hù)與任務(wù)相匹配的函數(shù)定義與相關(guān)用法。Reformu以WordNet 生成的同義詞來(lái)擴(kuò)展查詢(xún)語(yǔ)句中的單詞使其與源代碼中具有類(lèi)似語(yǔ)義的單詞相同,從而提高代碼搜索結(jié)果的準(zhǔn)確性。INQRES考慮源代碼中單詞之間的關(guān)系,交互式地重新構(gòu)造搜索查詢(xún),以?xún)?yōu)化查詢(xún)質(zhì)量。SWIM算法對(duì)給定API 的自然語(yǔ)言查詢(xún)語(yǔ)句進(jìn)行分析,利用從開(kāi)源代碼庫(kù)中學(xué)習(xí)到程序編碼模式來(lái)合成相關(guān)的代碼片段。CodeHow算法提取與用戶(hù)查詢(xún)相關(guān)的潛在API,并使用檢索到的API 信息來(lái)增強(qiáng)原始查詢(xún)語(yǔ)句,使用集成擴(kuò)展的布爾模型來(lái)實(shí)現(xiàn)精確的代碼檢索結(jié)果。

1.2 基于深度學(xué)習(xí)的代碼檢索算法

基于信息檢索和自然語(yǔ)言技術(shù)的代碼檢索不能充分理解自然語(yǔ)言查詢(xún)語(yǔ)句的語(yǔ)義信息,當(dāng)代碼庫(kù)中沒(méi)有與查詢(xún)語(yǔ)句中的關(guān)鍵詞相關(guān)的代碼片段時(shí),會(huì)嚴(yán)重影響代碼的檢索結(jié)果。最近提出的基于深度學(xué)習(xí)的語(yǔ)義代碼檢索算法,以自然語(yǔ)言的形式來(lái)查找符合查詢(xún)語(yǔ)句語(yǔ)義信息的代碼片段。NCS以無(wú)監(jiān)督的方式在大規(guī)模語(yǔ)料庫(kù)上訓(xùn)練,獲取代碼片段和自然語(yǔ)言注釋部分的固定長(zhǎng)度的嵌入向量表示。在自然語(yǔ)言查詢(xún)部分以向量均值來(lái)表示,而代碼片段部分則以TF-IDF 權(quán)重的方式獲取相應(yīng)的均值表示,以余弦相似度來(lái)判斷兩個(gè)向量的相似程度。UNIF以注意力機(jī)制來(lái)組合代碼片段中每個(gè)令牌的嵌入,并生成嵌入整個(gè)代碼片段的嵌入向量表示。自然語(yǔ)言查詢(xún)語(yǔ)句嵌入是通過(guò)對(duì)查詢(xún)嵌入以詞嵌入相加求均值向量進(jìn)行表示。以NCS 中學(xué)習(xí)的嵌入矩陣為初始值,并在訓(xùn)練期間以高質(zhì)量的有監(jiān)督數(shù)據(jù)進(jìn)一步微調(diào)。SCS基于代碼到自然語(yǔ)言注釋序列的網(wǎng)絡(luò)的部分編碼器來(lái)嵌入代碼令牌序列。并以一個(gè)語(yǔ)言模型來(lái)嵌入查詢(xún)標(biāo)記序列。在推理和學(xué)習(xí)過(guò)程中將代碼片段部分嵌入轉(zhuǎn)換為查詢(xún)嵌入。CODEnn以一個(gè)端到端的方式訓(xùn)練一個(gè)代碼檢索模型。從代碼片段中提取方法名序列、API序列和令牌來(lái)表示代碼片段的特征。以雙向長(zhǎng)短期記憶單元(bi-directional long short-term memory,Bi-LSTM)模型來(lái)提取API序列、方法名序列和自然語(yǔ)言注釋部分特征來(lái)獲取相應(yīng)的向量表示,以余弦相似度的方法來(lái)判斷代碼片段特征向量和自然語(yǔ)言特征向量的相似性程度。CoaCor利用代碼總結(jié)模型的方式來(lái)生成代碼檢索任務(wù)的自然語(yǔ)言注釋?zhuān)⑶乙砸粋€(gè)代碼檢索模型來(lái)查詢(xún)相關(guān)代碼片段。

2 融合圖嵌入和注意力機(jī)制代碼搜索算法

2.1 數(shù)據(jù)提取

本文提出的融合圖嵌入和注意力機(jī)制的代碼搜索算法(GraphCS)在代碼純文本信息基礎(chǔ)上考慮代碼片段的邏輯圖結(jié)構(gòu)信息,雖然CODEnn 算法提供了千萬(wàn)級(jí)別的代碼片段和注釋數(shù)據(jù)對(duì),但是數(shù)據(jù)都是經(jīng)過(guò)預(yù)處理的,并不能從已處理的數(shù)據(jù)集中提取代碼片段的邏輯圖結(jié)構(gòu)信息。因此,為了從源程序中提取可用于圖嵌入的數(shù)據(jù),從開(kāi)源代碼庫(kù)中爬取2016—2019 年的Java 開(kāi)源項(xiàng)目,并對(duì)數(shù)據(jù)集進(jìn)行清洗操作。首先,移除包含非英文的代碼注釋數(shù)據(jù)對(duì);其次,移除注釋為非Javadoc格式代碼注釋數(shù)據(jù)對(duì);然后,移除行數(shù)小于指定閾值和超過(guò)指定閾值的代碼注釋數(shù)據(jù)對(duì);最后,移除類(lèi)的構(gòu)造方法以及類(lèi)中其他相應(yīng)的初始化方法。表1 詳細(xì)地對(duì)源代碼檢索任務(wù)的數(shù)據(jù)集規(guī)模以及格式進(jìn)行相關(guān)概述。原始數(shù)據(jù)集由3 564 213 條方法體和注釋數(shù)據(jù)對(duì)組成,經(jīng)過(guò)清洗后的數(shù)據(jù)為2 141 921條方法體和注釋數(shù)據(jù)對(duì)。為了模擬真實(shí)的代碼檢索,從開(kāi)源代碼倉(cāng)庫(kù)上提取1 569 525條只包含方法體的代碼片段作為代碼檢索數(shù)據(jù)庫(kù)。

表1 數(shù)據(jù)集介紹Table 1 Dataset introduction

為了學(xué)習(xí)程序語(yǔ)言豐富的語(yǔ)義和語(yǔ)法信息,從不同的角度來(lái)提取代碼片段的特征。代碼片段特征提取部分是以方法體為單位來(lái)做特征提取,它不僅包含豐富的文本語(yǔ)義信息,同時(shí)也包含復(fù)雜的邏輯結(jié)構(gòu)信息。因此,從代碼片段中提取文本語(yǔ)義特征包括方法名序列和令牌信息,而提取的邏輯圖結(jié)構(gòu)特征為方法體對(duì)應(yīng)的程序依賴(lài)圖(program dependency graph,PDG)信息。自然語(yǔ)言部分則為方法體對(duì)應(yīng)的注釋序列信息。其中,代碼檢索任務(wù)數(shù)據(jù)提取流程如圖2 所示。

圖2 數(shù)據(jù)處理Fig.2 Data processing

方法名提?。禾崛∶總€(gè)Java 方法片段的函數(shù)名,并以駝峰規(guī)則將函數(shù)名拆分成多個(gè)詞語(yǔ)的組合。例如,方法名readXmlFiles 將會(huì)被拆分為read、xml 以及files。

令牌提?。簽榱颂崛×钆菩畔?,提取數(shù)據(jù)集中每個(gè)Java 方法體內(nèi)部的全部令牌信息,并以駝峰規(guī)則對(duì)每個(gè)令牌進(jìn)行單詞拆分,以此作為相應(yīng)的分詞方法。針對(duì)分詞后的語(yǔ)料,移除令牌數(shù)據(jù)中重復(fù)單詞、常用的停用詞以及Java關(guān)鍵字。

自然語(yǔ)言提?。和ㄟ^(guò)Eclipse JDT 工具將Java 方法轉(zhuǎn)換為抽象語(yǔ)法樹(shù),并從抽象語(yǔ)法樹(shù)中提取JavaDoc注釋部分第一行語(yǔ)句作為自然語(yǔ)言描述。

程序圖嵌入提?。簽榱颂崛≡创a中每一個(gè)方法體的邏輯圖結(jié)構(gòu)信息,首先,提取Java 代碼片段的控制流圖,在控制流圖的基礎(chǔ)上引入圖中節(jié)點(diǎn)之間的數(shù)據(jù)依賴(lài)關(guān)系類(lèi)以及控制依賴(lài)關(guān)系,從而為代碼片段構(gòu)建出更加復(fù)雜的程序依賴(lài)圖。其次,以WL(Weisfeiler-Lehman)重標(biāo)簽算法為程序依賴(lài)圖中的每個(gè)節(jié)點(diǎn)進(jìn)行重標(biāo)簽,并提取每個(gè)程序依賴(lài)圖中的子圖結(jié)構(gòu)信息。最終,以Doc2Vec 的思想將子圖結(jié)構(gòu)作為上下文信息從而來(lái)獲取每個(gè)方法體對(duì)應(yīng)的程序依賴(lài)圖的向量嵌入表示。程序依賴(lài)圖特征向量提取過(guò)程如圖3 所示。

圖3 PDG 向量提取過(guò)程Fig.3 PDG vector extraction process

2.2 WL 重標(biāo)簽算法提取子圖信息

假設(shè)給定圖,并設(shè)定圖4 中每個(gè)節(jié)點(diǎn)的初始化標(biāo)簽為{1,1,2,3,1}。考慮迭代一次時(shí),WL 算法聚合每個(gè)中心節(jié)點(diǎn)的鄰域節(jié)點(diǎn)的標(biāo)簽。例如,圖中節(jié)點(diǎn)的鄰域節(jié)點(diǎn)為和,則聚合鄰域之后的標(biāo)簽為1-1,2。根據(jù)新的標(biāo)簽對(duì)標(biāo)簽進(jìn)行排序和壓縮,壓縮后的標(biāo)簽代表對(duì)應(yīng)的子樹(shù)模式。假設(shè)圖4 中標(biāo)簽為7 的節(jié)點(diǎn),則存在一個(gè)高度為1 的子樹(shù)模式,其中根節(jié)點(diǎn)標(biāo)簽1,它的鄰居有標(biāo)簽1 和3。以WL 算法來(lái)提取子圖信息的算法流程如算法1 所示。

圖4 G 上的WL 重標(biāo)簽Fig.4 WL relabeling for graph G

WLSubGraph(,,)

2.3 GraphCS 模型

自然語(yǔ)言與代碼片段從詞的分布的角度來(lái)考慮是不同的,因此二者是異構(gòu)數(shù)據(jù)。源代碼檢索任務(wù)考慮將代碼片段和自然語(yǔ)言?xún)蓚€(gè)異構(gòu)數(shù)據(jù)嵌入到同一個(gè)向量空間,從而使語(yǔ)義相似的代碼片段和自然語(yǔ)言在向量空間距離較近。

源代碼片段中不僅包含大量純文本語(yǔ)義信息,也包含豐富的邏輯結(jié)構(gòu)信息。因此基于圖嵌入算法在提取代碼片段的特征時(shí),不僅考慮代碼的純文本語(yǔ)義信息(方法名和令牌),也考慮了代碼的邏輯結(jié)構(gòu)信息(程序依賴(lài)圖信息)。

為了更深層次捕捉代碼序列的語(yǔ)義信息,以雙向LSTM 來(lái)學(xué)習(xí)序列的相關(guān)特征表示。其中,LSTM網(wǎng)絡(luò)結(jié)構(gòu)如圖5 所示。

圖5 LSTM 網(wǎng)絡(luò)結(jié)構(gòu)Fig.5 LSTM network structure

LSTM 是為了解決RNN 中存在的梯度爆炸和梯度消失的問(wèn)題而提出來(lái)的更高效的序列語(yǔ)義特征提取模型。LSTM 主要引入遺忘門(mén)、輸入門(mén)以及輸出門(mén)來(lái)達(dá)到門(mén)控的目的,并以高速網(wǎng)絡(luò)的方式充分保留上一時(shí)刻的細(xì)胞狀態(tài)來(lái)更好地捕捉序列的語(yǔ)義表示。LSTM 神經(jīng)網(wǎng)絡(luò)的迭代公式如下:

為了更好地提取語(yǔ)句的特征向量表示,引入雙向LSTM 時(shí)序網(wǎng)絡(luò)模型。雙向LSTM 考慮正反兩個(gè)方向上下文信息,將正反兩個(gè)方向的特征向量進(jìn)行拼接,從而達(dá)到更好捕捉語(yǔ)義信息的目的。

方法名序列,,…,name為以駝峰規(guī)則對(duì)方法名進(jìn)行分詞獲取的長(zhǎng)度為的方法名序列,以雙向LSTM 來(lái)提取方法名序列的各個(gè)時(shí)刻隱藏層的特征表示。

為了更深層次地學(xué)習(xí)方法名的語(yǔ)義特征表示,將正反LSTM 的隱藏層向量進(jìn)行拼接,并以最大池化方法來(lái)對(duì)各個(gè)隱藏層的狀態(tài)進(jìn)行壓縮,并作為方法名序列特征的最終向量表示。

令牌信息,,…,token為對(duì)方法體內(nèi)的代碼片段以駝峰規(guī)則拆分代碼語(yǔ)句后,并移除重復(fù)項(xiàng)、常用停用詞以及Java 關(guān)鍵字獲取到的長(zhǎng)度為的代碼片段。在提取令牌特征時(shí),并未考慮代碼的語(yǔ)序關(guān)系,故以多層感知機(jī)(multi-layer perceptron,MLP)方式來(lái)學(xué)習(xí)令牌的特征向量表示。

式中,emdtk是令牌中在位置處單詞的初始化嵌入向量表示,而W是全連接層中的參數(shù)矩陣。,,…,htoken為學(xué)習(xí)后令牌的嵌入向量表示,并以最大池化方法對(duì)全部令牌的向量表示進(jìn)行壓縮,作為令牌片段特征的最終向量表示。

在提取程序依賴(lài)圖特征時(shí),提取Java 代碼片段的控制流圖,在控制流圖的基礎(chǔ)上引入數(shù)據(jù)依賴(lài)關(guān)系類(lèi)以及控制依賴(lài)關(guān)系,從而構(gòu)建出代碼片段的程序依賴(lài)圖。以WL 算法從程序依賴(lài)圖中提取每個(gè)節(jié)點(diǎn)對(duì)應(yīng)的子圖集合作為每個(gè)圖的上下文信息,并以Skip-Gram 的方式學(xué)習(xí)圖的向量表示。在GraphCS算法中以多個(gè)卷積核的方式對(duì)圖特征向量以一維卷積來(lái)提取不同的子特征,獲取程序依賴(lài)圖的最終向量表示。

在特征融合部分,以注意力的方式為方法名特征向量、令牌特征向量以及程序依賴(lài)圖特征向量分配不同的權(quán)重系數(shù)。代碼片段的不同特征以不同的權(quán)重進(jìn)行融合,來(lái)學(xué)習(xí)最終的代碼片段向量表示。

為了與自然語(yǔ)言特征向量表示維度一致,會(huì)以全連接的方式將代碼片段的特征向量映射到與自然語(yǔ)言片段特征向量相等的維度。在自然語(yǔ)言描述部分,通過(guò)雙向時(shí)序神經(jīng)網(wǎng)絡(luò)來(lái)學(xué)習(xí)自然語(yǔ)言描述中所包含的語(yǔ)義特征表示??紤]自然語(yǔ)言注釋序列,,…,desc是存在語(yǔ)序關(guān)系的,故以雙向LSTM 來(lái)提取各個(gè)時(shí)刻隱藏層的特征表示。

為了更深層次地學(xué)習(xí)自然語(yǔ)言的語(yǔ)義特征表示,將正反LSTM 的隱藏層向量進(jìn)行拼接,并以最大池化方法將LSTM 的各個(gè)隱藏狀態(tài)向量表示壓縮成一個(gè)固定維度的向量作為自然語(yǔ)言片段特征的最終向量表示。

通過(guò)代碼嵌入網(wǎng)絡(luò)和自然語(yǔ)言網(wǎng)絡(luò)將代碼片段特征和自然語(yǔ)言描述分別映射成相等維度的向量表示和。將代碼片段向量表示和自然語(yǔ)言部分向量表示映射到同一個(gè)向量空間,并以余弦相似度的方式衡量?jī)蓚€(gè)向量的相似程度。

在同一個(gè)向量空間中,代碼片段向量與自然語(yǔ)言向量的余弦相似度的值越高,則代碼片段和自然語(yǔ)言描述之間的語(yǔ)義越相近。如果代碼片段與自然語(yǔ)言描述語(yǔ)義很相近,它們?cè)谙蛄靠臻g距離較近。自然語(yǔ)言與代碼片段在同一向量空間的映射如圖6所示。

圖6 向量空間映射Fig.6 Vector space mapping

圖6 中的自然語(yǔ)言查詢(xún)語(yǔ)句為append text to an existing file,在代碼庫(kù)中檢索到的相似度較高的代碼片段為方法名為append 的函數(shù)。自然語(yǔ)言與代碼片段在語(yǔ)義上相似性較高,因此在特征空間中二者距離較近。

假設(shè)給定代碼片段C,以及代碼片段對(duì)應(yīng)的自然語(yǔ)言描述,為每個(gè)代碼片段隨機(jī)分配一個(gè)負(fù)樣本。在訓(xùn)練網(wǎng)絡(luò)模型時(shí),構(gòu)建<,>和<,>訓(xùn)練語(yǔ)料,并考慮最小化排名損失。

式中,為網(wǎng)絡(luò)模型參數(shù),在訓(xùn)練過(guò)程中被設(shè)置為0.398 6。排名損失會(huì)促使代碼片段與其正確描述之間的余弦相似度上升,而代碼片段與錯(cuò)誤描述之間的余弦相似度下降。

根據(jù)代碼片段和自然語(yǔ)言片段的特征提取方法,構(gòu)建基于GraphCS 的代碼檢索算法模型網(wǎng)絡(luò)結(jié)構(gòu)如圖7 所示。

圖7 GraphCS 模型網(wǎng)絡(luò)結(jié)構(gòu)Fig.7 GraphCS model network structure

3 實(shí)驗(yàn)

3.1 性能指標(biāo)

本文采用源代碼檢索任務(wù)中公認(rèn)的評(píng)估指標(biāo)Frank、SuccessRate@、Precision@以及MRR 來(lái)驗(yàn)證代碼檢索的有效性。

Frank 是指在指定大?。?10)的返回結(jié)果列表中第一次出現(xiàn)的符合要求的結(jié)果。Frank 指標(biāo)的結(jié)果符合瀏覽信息從上而下的準(zhǔn)則,較小的Frank 意味著為找到所需結(jié)果所需的檢查工作量較小。Frank 值越小,則說(shuō)明檢索結(jié)果越靠前。因此Frank 可以衡量單個(gè)代碼搜索查詢(xún)的有效性。

MRR 表示每一個(gè)自然語(yǔ)言查詢(xún)語(yǔ)句query 檢索返回結(jié)果中指定大?。?10)的Frank 值的倒數(shù)的累加和,并對(duì)求和結(jié)果進(jìn)行均值化,在很大程度上可以衡量檢索結(jié)果的好壞。MRR 值越高,則說(shuō)明檢索性能越優(yōu)越。MRR 值越低,則說(shuō)明檢索性能越差。

其中,||代表查詢(xún)語(yǔ)句的數(shù)量,代表查詢(xún)語(yǔ)句集合中的每個(gè)查詢(xún)語(yǔ)句,Frank代表查詢(xún)語(yǔ)句對(duì)應(yīng)的Frank 值。

SuccessRate@(=1,5,10)衡量在返回的相似度排名的結(jié)果中排在前的結(jié)果中可能存在多個(gè)正確結(jié)果的查詢(xún)的百分比。

其中,函數(shù)定義為當(dāng)判斷語(yǔ)句為真時(shí)返回結(jié)果1,否則返回0。SuccessRate@評(píng)估指標(biāo)對(duì)于檢索任務(wù)來(lái)說(shuō)至關(guān)重要,因?yàn)樾阅軆?yōu)越的代碼檢索應(yīng)允許從較少的返回結(jié)果來(lái)發(fā)現(xiàn)所需的代碼。并且Success-Rate@度量值越高,則代碼搜索性能好。

Precision@(=1,5,10)指標(biāo)用來(lái)衡量每個(gè)自然語(yǔ)言查詢(xún)返回的結(jié)果中的排在前的相關(guān)結(jié)果的百分比。

Precision@可以反映查詢(xún)結(jié)果中于目標(biāo)相符合的結(jié)果的個(gè)數(shù),可以很好地提供不同用法的多種結(jié)果以學(xué)習(xí),可以降低不相關(guān)結(jié)果出現(xiàn)的次數(shù)。因此Precision@度量值越高,則代表代碼搜索性能越好。

3.2 實(shí)驗(yàn)參數(shù)

為了對(duì)模型進(jìn)行訓(xùn)練,將訓(xùn)練數(shù)據(jù)進(jìn)行隨機(jī)打亂并將批次大小設(shè)置為64。統(tǒng)計(jì)各個(gè)特征語(yǔ)料,構(gòu)建相應(yīng)的詞匯表。將詞匯表的大小設(shè)置正10 000 的時(shí)候,對(duì)語(yǔ)料庫(kù)的單詞覆蓋率達(dá)到95%以上,可以有效地學(xué)習(xí)詞匯的語(yǔ)義表示。針對(duì)不同的代碼特征,設(shè)置相應(yīng)的最大長(zhǎng)度。當(dāng)序列的長(zhǎng)度大于最大長(zhǎng)度時(shí),對(duì)序列進(jìn)行截?cái)?。?dāng)序列的長(zhǎng)度小于最大長(zhǎng)度時(shí),以數(shù)值0 進(jìn)行填充。在特征提取部分將LSTM 和嵌入向量維度設(shè)置成256,而將MLP 部分的嵌入向量維度設(shè)置成512。為了使模型有更好的泛化能力,在模型中添加Dropout 機(jī)制,將參數(shù)設(shè)置為0.25。詳細(xì)參數(shù)設(shè)置如表2 所示。

表2 參數(shù)介紹Table 2 Parameter introduction

3.3 實(shí)驗(yàn)結(jié)果

CODEnn 算法是第一個(gè)基于深度學(xué)習(xí)的學(xué)習(xí)自然語(yǔ)言查詢(xún)語(yǔ)句語(yǔ)義信息的代碼檢索算法,在一定程度上取得了不錯(cuò)的效果。但是CODEnn 算法只考慮源代碼的純文本信息,而忽略了代碼中存在的邏輯結(jié)構(gòu)信息,不能充分理解程序語(yǔ)言豐富的語(yǔ)義和語(yǔ)法信息。GraphCS 算法不僅考慮代碼的純文本信息,還考慮了代碼中的邏輯結(jié)構(gòu)信息,并且融入注意力機(jī)制來(lái)更深層次地進(jìn)行代碼片段語(yǔ)義和語(yǔ)法特征的融合。為了驗(yàn)證GraphCS算法的有效性,與CODEnn算法進(jìn)行對(duì)比。為了更直觀地展現(xiàn)檢索效果的高效性,以Frank 作為評(píng)估標(biāo)準(zhǔn),GraphCS 算法和CODEnn算法檢索的Frank 值如表3 所示。

表3 在Frank 上的評(píng)估結(jié)果Table 3 Evaluation results on Frank

GraphCS 不僅考慮代碼結(jié)構(gòu)特征中豐富的文本信息,也考慮代碼片段的邏輯結(jié)構(gòu)信息。CODEnn 中未檢索到結(jié)果個(gè)數(shù)為17個(gè),而GraphCS中未檢索到結(jié)果個(gè)數(shù)為13 個(gè),GraphCS 成功檢索到相關(guān)代碼片段明顯高于CODEnn。GraphCS算法返回的檢索結(jié)果中在Top 1 處為符合要求的代碼片段個(gè)數(shù)比CODEnn返回的結(jié)果有一定的提升。并且從整體上分析,GraphCS算法大多數(shù)檢索的結(jié)果的Frank 值比CODEnn 靠前,F(xiàn)rank 的值越小,說(shuō)明返回結(jié)果越靠前,符合自上而下的檢索方式。例如,考慮查詢(xún)語(yǔ)句check if file exists。從表3 知GraphCS 算法的Frank 值為3,則意味著在返回結(jié)果列表中第3 個(gè)代碼片段符合查詢(xún)要求;而CODEnn 算法的Frank 值為6,則意味著在返回結(jié)果列表中第6 個(gè)代碼片段符合查詢(xún)要求。大多數(shù)人在搜索問(wèn)題的過(guò)程中,都只會(huì)關(guān)注靠前的內(nèi)容,后面的結(jié)果關(guān)注較少。綜上所述,從Frank 評(píng)估指標(biāo)結(jié)果分析可知GraphCS 與CODEnn 相比有較好的提升,可以提供更加符合查詢(xún)要求的代碼片段。

本文不僅在Frank 上驗(yàn)證GraphCS 算法的有效性,還在SuccessRate@、Precision@、MRR 指標(biāo)以及時(shí)間性能上對(duì)GraphCS 和CODEnn 進(jìn)行系統(tǒng)評(píng)估。其中,SuccessRate@、Precision@、MRR 統(tǒng)計(jì)結(jié)果如表4 所示,時(shí)間性能對(duì)比結(jié)果如表5 所示。

表4 性能對(duì)比Table 4 Performance comparison

表5 檢索結(jié)果統(tǒng)計(jì)Table 5 Retrieval result statistics

GraphCS 算法在SuccessRate@5 值為0.56,則意味著存在56%的查詢(xún),可以在前5 個(gè)返回結(jié)果中找到相關(guān)的代碼段。CODEnn 算法在MRR 上的值為0.31,其中Recall@1/5/10=0.20/0.42/0.66,Precision@1/5/10=0.20/0.24/0.23。相比之下,GraphCS 算法在MRR 上的值為0.39。其中Recall@1/5/10=0.28/0.56/0.74 和Precision@1/5/10=0.28/0.35/0.36。實(shí)驗(yàn)結(jié)果表明,GraphCS 算法與CODEnn 算法相比,GraphCS在MRR 上提高了25.8%,在Recall@1/5/10 上提高了40.0%/33.3%/12.1%,在Precision@1/5/10 上提高了40.0%/45.8%/56.5%。在時(shí)間性能對(duì)比分析中可知,CODEnn 算法在CPU 上訓(xùn)練和檢索所花費(fèi)時(shí)間分別為49.3 h 和157 s;GraphCS算法在CPU上訓(xùn)練和檢索所花費(fèi)時(shí)間分別為67.4 h 和164 s。從CPU 上的時(shí)間性能分析可知二者差距不大,當(dāng)在GPU 中訓(xùn)練CODEnn 算法模型和GraphCS 算法模型時(shí)可以極大縮短訓(xùn)練和檢索所花費(fèi)的時(shí)間。因此,檢索精度的提升可以忽略時(shí)間性能的不足。綜上所述,可以證明引入邏輯圖結(jié)構(gòu)信息可以彌補(bǔ)純文本信息的不足,在訓(xùn)練和檢索時(shí)間性能差距不大的情況下可以在一定程度上提高代碼檢索的準(zhǔn)確率。從實(shí)驗(yàn)數(shù)據(jù)中可知GraphCS 算法在上述4 個(gè)評(píng)估指標(biāo)上獲得更好的精度,比CODEnn 算法獲取更多符合查詢(xún)語(yǔ)義信息的代碼片段。

大多數(shù)情況下,一個(gè)方法的方法名可以很直觀地體現(xiàn)一個(gè)代碼片段的功能。例如,一個(gè)函數(shù)方法的方法名為readXmlFiles,從方法名上可以很明顯地確認(rèn)方法所包含的功能為解析Xml 文件。為了驗(yàn)證GraphCS 算法檢索結(jié)果的有效性,分別統(tǒng)計(jì)語(yǔ)義相關(guān)代碼片段個(gè)數(shù)和方法名相關(guān)的代碼片段個(gè)數(shù),統(tǒng)計(jì)數(shù)據(jù)如表6 所示。GraphCS 算法檢索結(jié)果中,語(yǔ)義相關(guān)的代碼片段個(gè)數(shù)為37,其中24 個(gè)代碼片段是方法名相關(guān)的。而CODEnn 算法檢索結(jié)果中,語(yǔ)義相關(guān)的代碼片段個(gè)數(shù)為33,其中18 個(gè)代碼片段是方法名相關(guān)的。GraphCS 算法中方法名相關(guān)與語(yǔ)義相關(guān)的比值為0.649,而CODEnn 算法中方法名相關(guān)與語(yǔ)義相關(guān)的比值為0.545。相比之下GraphCS 檢索的結(jié)果在語(yǔ)義和語(yǔ)法上都有較好的體現(xiàn),且方法名相關(guān)得較多。例如,查詢(xún)語(yǔ)句append text to an existing file 在GraphCS算法中的返回結(jié)果如圖8所示,而在CODEnn算法中返回的結(jié)果如圖9 所示。從返回結(jié)果可知,GraphCS 返回結(jié)果考慮得更加全面嚴(yán)謹(jǐn)且在方法名上更加相關(guān),而CODEnn 返回的結(jié)果相對(duì)比較簡(jiǎn)略。

圖8 GraphCS 檢索結(jié)果Fig.8 GraphCS retrieval result

圖9 CODEnn 檢索結(jié)果Fig.9 CODEnn retrieval result

表6 檢索結(jié)果統(tǒng)計(jì)Table 6 Retrieval result statistics

本文主要與CODEnn 算法進(jìn)行了詳細(xì)的對(duì)比,為了證明GraphCS 算法的有效性,與基于RNN 和NeuralBOW 的代碼檢索算法進(jìn)行簡(jiǎn)單對(duì)比。其中,RNN和NeuralBOW 是代碼檢索任務(wù)中兩個(gè)常用的基線模型,二者都是只對(duì)代碼片段的文本信息進(jìn)行編碼,然后以余弦相似度的方式來(lái)計(jì)算代碼片段與自然語(yǔ)言注釋的語(yǔ)義相似度。在MRR、SuccessRate@指標(biāo)上的實(shí)驗(yàn)結(jié)果如表7 所示。

表7 實(shí)驗(yàn)結(jié)果統(tǒng)計(jì)Table 7 Experimental result statistics

4 結(jié)束語(yǔ)

源代碼的純文本語(yǔ)句包含大量語(yǔ)義信息,但是不能充分地體現(xiàn)代碼的邏輯結(jié)構(gòu)信息。本文提出一種基于圖嵌入的代碼檢索算法GraphCS。除了考慮源代碼的純文本信息之外,還考慮代碼的邏輯結(jié)構(gòu)特性,可以更深層次地學(xué)習(xí)源代碼的語(yǔ)義表示。與CODEnn 對(duì)比,檢索到更多符合語(yǔ)義的代碼片段。

在未來(lái)的工作中,會(huì)考慮其他不同語(yǔ)言的數(shù)據(jù)集(C#或Python)進(jìn)行全面的實(shí)驗(yàn)。為了克服代碼的圖結(jié)構(gòu)大小不均衡而導(dǎo)致的圖嵌入效果提升不明顯問(wèn)題,對(duì)代碼圖特征提取過(guò)程做進(jìn)一步優(yōu)化。

猜你喜歡
源代碼語(yǔ)句代碼
基于TXL的源代碼插樁技術(shù)研究
神秘的代碼
保護(hù)好自己的“源代碼”
一周機(jī)構(gòu)凈增(減)倉(cāng)股前20名
解密別克安全“源代碼”
一行代碼玩完19億元衛(wèi)星
近期連續(xù)上漲7天以上的股
我喜歡
冠詞缺失與中介語(yǔ)句法損傷研究
作文語(yǔ)句實(shí)錄