亚洲免费av电影一区二区三区,日韩爱爱视频,51精品视频一区二区三区,91视频爱爱,日韩欧美在线播放视频,中文字幕少妇AV,亚洲电影中文字幕,久久久久亚洲av成人网址,久久综合视频网站,国产在线不卡免费播放

        ?

        基于深度學(xué)習(xí)的程序生成與補(bǔ)全技術(shù)研究進(jìn)展?

        2019-06-11 07:39:30星,李戈,劉芳,金
        軟件學(xué)報 2019年5期
        關(guān)鍵詞:代碼研究者語法

        胡 星,李 戈,劉 芳,金 芝

        1(北京大學(xué) 信息科學(xué)技術(shù)學(xué)院,北京 100871)

        2(高可信軟件技術(shù)教育部重點實驗室(北京大學(xué)),北京 100871)

        如何有效地提高軟件開發(fā)的效率和質(zhì)量,一直是軟件工程領(lǐng)域關(guān)心的問題.一直以來,許多研究者都通過改善軟件開發(fā)方法和運用技術(shù)手段來提高軟件開發(fā)的自動化水平.其中,程序自動生成技術(shù)被認(rèn)為是提高軟件開發(fā)自動化程度和最終質(zhì)量的重要方法,一直受到學(xué)術(shù)界和工業(yè)界的廣泛關(guān)注.程序自動生成技術(shù)指利用某些技術(shù)自動地為軟件生成源代碼,達(dá)到根據(jù)用戶的需求機(jī)器自動編程的目的.該技術(shù)極大程度地減輕了程序員的開發(fā)負(fù)擔(dān),使得程序員可以更加關(guān)注于程序的設(shè)計工作.

        目前,程序自動生成方法主要通過兩種方式實現(xiàn):程序生成和代碼補(bǔ)全.程序生成和代碼補(bǔ)全是程序綜合問題的兩個分支,它們從不同程度上輔助甚至代替程序員的開發(fā)工作.代碼補(bǔ)全技術(shù)是最常見的程序自動生成技術(shù),是現(xiàn)代集成開發(fā)環(huán)境(integrated development environment,簡稱 IDE)的重要組成部分.代碼補(bǔ)全技術(shù)有效地幫助程序員預(yù)測代碼的類名、方法名、關(guān)鍵字等,提高了程序開發(fā)的效率,并減少了編碼過程中的拼寫錯誤.目前,代碼補(bǔ)全工具通常對代碼進(jìn)行靜態(tài)分析,用于補(bǔ)全的候選項通常按字母順序排列.程序生成要求根據(jù)用戶給定的需求自動構(gòu)建程序,該技術(shù)在一定程度上讓機(jī)器代替程序員編寫代碼的工作.傳統(tǒng)的程序生成方法要求程序員設(shè)計邏輯規(guī)約,使得機(jī)器可以根據(jù)這些邏輯規(guī)約自動生成源代碼.然而這些方法不僅對程序員的要求較高,而且生成的代碼往往功能比較單一,無法完成復(fù)雜的任務(wù).

        近年來,人工智能技術(shù)取得了長足的發(fā)展與進(jìn)步,這一進(jìn)步對軟件工程領(lǐng)域的研究形成了重要的促進(jìn).人工智能的方法旨在使計算機(jī)理解程序中的語義信息和結(jié)構(gòu)信息,這些信息可以用于軟件工程的多個領(lǐng)域,使得程序員從重復(fù)的任務(wù)中解放出來.深度學(xué)習(xí)技術(shù)在2006年被正式提出后,在近10年里得到了巨大的發(fā)展,使得人工智能產(chǎn)生了革命性的突破.在大量數(shù)據(jù)和計算資源的支持下,深度神經(jīng)網(wǎng)絡(luò)已在圖像處理[1]、語音處理[2]、自然語言處理[3,4]等多個領(lǐng)域均有廣泛的應(yīng)用,并已取得了令人矚目的效果.當(dāng)前,深度神經(jīng)網(wǎng)絡(luò)正在向更多的應(yīng)用領(lǐng)域延伸擴(kuò)展.以GitHub和Stack Overflow等網(wǎng)站為代表的開源代碼網(wǎng)站和開源社區(qū)的發(fā)展,給研究人員提供了大量、高質(zhì)量的源代碼.這些代碼中隱含著許多知識,這些知識可被用于軟件開發(fā)中,這使得大規(guī)模代碼的學(xué)習(xí)成為可能.在軟件工程領(lǐng)域,程序生成和代碼補(bǔ)全技術(shù)是當(dāng)前人工智能發(fā)展的最大的挑戰(zhàn)之一,也是在軟件工程-程序語言領(lǐng)域最熱門的方向之一.由于計算能力的增長和深度神經(jīng)網(wǎng)絡(luò)的興起,程序生成和代碼補(bǔ)全研究中的許多局限已經(jīng)慢慢被攻克,并且出現(xiàn)了復(fù)興的態(tài)勢,在很多領(lǐng)域得到了使用[5],例如代碼補(bǔ)全、基于功能描述的程序生成、基于輸出輸出的程序生成.

        目前,基于深度學(xué)習(xí)的程序自動生成任務(wù)大多遵循圖1的架構(gòu).該架構(gòu)主要包括4個部分:代碼資源庫、任務(wù)輸入、深度學(xué)習(xí)模型和輸出軟件代碼.如圖1所示,基于深度學(xué)習(xí)的程序自動生成框架的基礎(chǔ)是代碼資源庫的構(gòu)建,這些代碼資源庫中的源代碼被挖掘處理后,利用深度神經(jīng)網(wǎng)絡(luò)建立程序語言的模型,從而學(xué)習(xí)代碼資源中隱含的特征和知識.對于不同類型的程序自動生成任務(wù),模型的輸入輸出不同,例如在代碼補(bǔ)全任務(wù)中,模型的輸入是部分代碼,輸出是當(dāng)前位置需要補(bǔ)全的Token或者API調(diào)用.

        Fig.1 Automatic program generation architecture based on deep learning圖1 基于深度學(xué)習(xí)的程序自動生成框架

        目前,該方向的研究已經(jīng)得到了學(xué)術(shù)界和工業(yè)界的廣泛關(guān)注.一些著名的 IT公司,如 Microsoft、Google、Facebook、百度等都在該方向展開研究,他們的研究成果在國際上引起轟動,例如 Google公司提出的 NPI、Microsoft公司提出的RobustFill、英特爾的AI Programmer等.程序自動生成已經(jīng)成為當(dāng)前軟件工程和人工智能領(lǐng)域最重要的前沿方向之一,在軟件工程和人工智能的國際頂級會議(如ICSE、FSE、ASE、IJCAI、ICML、ICLR等)都有該方向的論文發(fā)表以及研討,極大地促進(jìn)了越來越多的學(xué)者投入到相關(guān)的研究中.

        本文第1節(jié)主要介紹程序生成與代碼補(bǔ)全的背景知識以及研究問題和文獻(xiàn)的檢索方式.第2節(jié)闡述深度學(xué)習(xí)在程序生成上的應(yīng)用.第3節(jié)闡述深度學(xué)習(xí)在代碼補(bǔ)全上的應(yīng)用.第4節(jié)根據(jù)現(xiàn)有的相關(guān)工作的分析與研究,對目前主流的可以用于程序生成和代碼補(bǔ)全的深度學(xué)習(xí)模型進(jìn)行詳細(xì)的描述.第 5節(jié)針對可以用于深度學(xué)習(xí)的代碼數(shù)據(jù)集進(jìn)行總結(jié).第6節(jié)對該方向的挑戰(zhàn)與未來方向進(jìn)行總結(jié).最后,在第7節(jié)對全文進(jìn)行總結(jié).

        1 主要研究問題和文獻(xiàn)檢索方式

        1.1 研究背景

        代碼補(bǔ)全和程序生成是程序綜合(program synthesis)的重要分支,其目的在于輔助甚至代替程序員編寫程序.程序綜合是指根據(jù)用戶需求自動地構(gòu)建計算機(jī)程序[5],程序綜合常見的用戶需求包括:基于邏輯的形式化規(guī)約、自然語言描述、輸入輸出樣例、程序執(zhí)行的路徑[6].

        程序綜合問題最早可以追溯到1932年,Kolmogoroff[7]提出在構(gòu)造性數(shù)學(xué)中(constructive mathematics)可以通過編寫小的子程序,然后將其組合起來構(gòu)造成一個算法.但是在當(dāng)時,這種想法大多用于數(shù)學(xué)上,直到 20世紀(jì)60年代末,研究者開始逐漸關(guān)注基于邏輯推導(dǎo)的程序綜合(deductive program synthesis)問題[8-10].之后,越來越多的研究者投入到該方向的研究[11,12].基于邏輯推導(dǎo)的程序綜合方法依賴于邏輯學(xué)的理論推導(dǎo)過程,擁有嚴(yán)格的理論依據(jù),能夠保證生成的程序的正確性.因此,該方法在程序驗證領(lǐng)域被廣泛地使用.然而,基于邏輯推導(dǎo)的程序綜合通常需要用戶提供完整的邏輯規(guī)約,許多情況下,用戶寫的邏輯規(guī)約幾乎和程序的復(fù)雜度相同,并沒有達(dá)到減輕人類編程負(fù)擔(dān)的目的.因此,有研究者開始了針對歸納程序綜合(inductive program synthesis)的研究.相對于基于邏輯推導(dǎo)的程序綜合技術(shù),基于歸納的程序綜合技術(shù)是一個從一般到抽象的程序綜合過程.基于歸納的程序綜合最初由Summer[13]在1977年提出,他提出,在特定的約束限制下,一個循環(huán)的LISP程序是能夠從輸入輸出樣例中計算出來的,而不用在程序空間中進(jìn)行搜索.他的這個觀點影響了許多后續(xù)的基于歸納的程序綜合問題[14-19].2009年,Kitzelmann[20]對幾種典型的基于歸納的程序綜合方法做了簡單的綜述.到了2010年左右,微軟的Gulwani團(tuán)隊開始將程序綜合的方法用到實際的應(yīng)用中去.Gulwani團(tuán)隊研發(fā)的應(yīng)用于Microsoft Excel的FlashFill[21,22]是目前用戶最熟悉的程序綜合應(yīng)用.Gulwani[6]定義了程序綜合的3個維度,即用戶需求、搜索空間和搜索技術(shù),并且對程序綜合的發(fā)展現(xiàn)狀做了綜述.隨著機(jī)器學(xué)習(xí)和深度學(xué)習(xí)的快速發(fā)展,我們正在進(jìn)入智能化時代.越來越多的研究者將深度學(xué)習(xí)技術(shù)用于程序生成和代碼補(bǔ)全中.

        程序生成指根據(jù)用戶需求自動地生成代碼片段,其用戶需求通常是高層次的描述,例如功能描述、輸入輸出樣例.程序生成一定程度上實現(xiàn)了機(jī)器代替程序員完成開發(fā)的工作,即機(jī)器編程.代碼補(bǔ)全是程序綜合中最直接也是最成功的應(yīng)用.大多數(shù)現(xiàn)代代碼編輯器和集成開發(fā)環(huán)境都具有根據(jù)前面編寫的部分程序自動補(bǔ)全下一個Token的功能.該應(yīng)用極大地減輕了程序員的開發(fā)負(fù)擔(dān),加快了開發(fā)速度.

        1.2 主要研究問題

        本文的研究聚焦在基于深度學(xué)習(xí)的程序生成和代碼補(bǔ)全.與傳統(tǒng)程序綜合和代碼自動生成方法的不同在于,該問題旨在將深度學(xué)習(xí)技術(shù)與程序分析技術(shù)相結(jié)合,從大量高質(zhì)量代碼庫中學(xué)習(xí)其中的知識,并利用這些知識進(jìn)行程序自動化開發(fā).

        本文的主要目的是總結(jié)基于深度學(xué)習(xí)的程序生成和代碼補(bǔ)全的相關(guān)工作,并給出未來的研究方向.根據(jù)圖1所示的程序自動生成框架,本文將框架中涉及到的技術(shù)總結(jié)成程序自動生成的 4個維度,并對其展開研究,如圖2所示.

        1)代碼語料庫.利用深度學(xué)習(xí)模型的前提是有高質(zhì)量的數(shù)據(jù)集,即代碼語料庫,數(shù)據(jù)集的質(zhì)量直接影響深度神經(jīng)網(wǎng)絡(luò)學(xué)習(xí)到的代碼知識.

        2)程序表示.其次,研究者需要確定程序的表示粒度.通常,研究者用Token序列、抽象語法樹、數(shù)據(jù)流圖、API調(diào)用圖來表示程序.程序的不同表示從不同的角度反映了程序的特征,例如,程序的Token序列反映了程序的語法和詞法特征,程序的抽象語法樹反映了代碼的抽象語法特征而忽略語法實現(xiàn)細(xì)節(jié).

        3)模型.不同粒度的程序表示往往使用不同的深度學(xué)習(xí)模型,也就是第 3個維度,即深度學(xué)習(xí)模型的選擇.研究者往往利用語言模型來對Token序列建模,因為語言模型可以學(xué)習(xí)到Token之間的序列關(guān)系;在使用抽象語法樹來表示程序時,研究者往往會設(shè)計基于樹的網(wǎng)絡(luò)來學(xué)習(xí).

        4)應(yīng)用.訓(xùn)練好的模型將被用于實際的任務(wù)場景中,即第 4個維度,程序生成和代碼補(bǔ)全的實際應(yīng)用場景.不同的應(yīng)用場景通常輸入和輸出都不一樣,例如,代碼補(bǔ)全應(yīng)用以部分代碼作為輸入,輸出往往為基于當(dāng)前位置預(yù)測的Token;基于功能描述的程序生成通常輸入為自然語言查詢,輸出為代碼片段.

        Fig.2 Four dimensions of program generation and code completion process based on deep learning圖2 基于深度學(xué)習(xí)的程序生成和代碼補(bǔ)全過程的4個維度

        具體而言,本文采用自頂向下的方式對當(dāng)前的相關(guān)工作進(jìn)行綜述.主要集中在程序生成和代碼補(bǔ)全的應(yīng)用、相關(guān)的深度學(xué)習(xí)模型以及相關(guān)數(shù)據(jù)集的介紹.因為程序表示形式通常與應(yīng)用和深度學(xué)習(xí)模型息息相關(guān).在對這兩方面綜述時會對其加以描述,因此,本文不再對程序的表示形式單獨綜述.程序生成應(yīng)用的介紹主要包括兩個方面:基于輸入輸出樣例的程序生成和基于功能描述的程序生成.對相關(guān)深度神經(jīng)網(wǎng)絡(luò)介紹時,分為兩個大類:語言模型和結(jié)構(gòu)模型.最后,本文對研究者工作中提供的高質(zhì)量數(shù)據(jù)集進(jìn)行了相關(guān)的綜述.

        1.3 文獻(xiàn)檢索方式

        本文在檢索文獻(xiàn)時,主要通過谷歌學(xué)術(shù)搜索、ACM Digital Library、IEEE Xplore Digital Library及Springer Link Online Library等.利用深度神經(jīng)網(wǎng)絡(luò)的程序生成和代碼補(bǔ)全的研究,屬于軟件工程與機(jī)器學(xué)習(xí)的交叉領(lǐng)域,而其本質(zhì)上是基于機(jī)器學(xué)習(xí)的代碼分析方法的延伸.因此,發(fā)表的論文主要分布在軟件工程和人工智能領(lǐng)域.檢索的論文主要是發(fā)表在軟件工程-系統(tǒng)軟件-程序設(shè)計語言領(lǐng)域和人工智能領(lǐng)域的國際頂級會議 ESEC/FSE、ICSE、ASE、PLDI、NIPS、IJCAI、AAAI、ICML、ACL、ICLR.

        本文通過對人工智能領(lǐng)域和軟件工程領(lǐng)域頂級會議自2014年至今錄用的文章進(jìn)行統(tǒng)計,從中篩選出與深度學(xué)習(xí)與程序生成和代碼補(bǔ)全相關(guān)的論文,統(tǒng)計結(jié)果見表1(由于一些會議還未召開,例如FSE、ASE等,所以未完全統(tǒng)計在內(nèi)).

        從數(shù)量上看,目前這個研究方向的論文還不算多,各個領(lǐng)域?qū)Τ绦蛏珊痛a補(bǔ)全任務(wù)的錄取情況有很大的差別.與軟件工程領(lǐng)域相比,人工智能領(lǐng)域在該方面的成果較多,占了總發(fā)表論文的88.5%,其中,ICLR和ACL在該方面的成果占了大部分.

        Table 1 Statistics of accepted articles each year表1 歷年錄用論文統(tǒng)計結(jié)果

        如圖3所示(圖3的統(tǒng)計包含了一些在arXiv上預(yù)發(fā)表的論文),該方向的研究在2016年迅速引起研究者的重視,2016年的論文數(shù)量是2015年論文數(shù)量的11倍.

        Fig.3 Illustration of literature distribution by year圖3 文獻(xiàn)年代分布情況

        此外,不同的應(yīng)用發(fā)表的論文數(shù)量也不盡相同,如圖4所示,從論文數(shù)量上來看,基于輸入輸出的程序生成的研究成果最多,而代碼補(bǔ)全的相關(guān)工作較少.通過分析可以發(fā)現(xiàn):基于輸入輸出的程序生成的研究成果中,ICLR會議發(fā)表的論文占了 50%;也能看得出,ICLR會議對此類程序生成問題更為感興趣.ACL會議主要的方向是計算語言,因此,基于自然語言功能描述的程序生成的成果中,ACL會議發(fā)表的論文占了66.7%.其主要研究目標(biāo)是建立自然語言與程序語言的關(guān)系,從而達(dá)到從自然語言的功能描述到程序語言的轉(zhuǎn)化過程.從兩個領(lǐng)域的論文數(shù)量上來看,軟件工程領(lǐng)域?qū)ι疃葘W(xué)習(xí)應(yīng)用于程序生成和代碼補(bǔ)全的研究相對滯后,還有很大的發(fā)展?jié)摿?然而軟件工程領(lǐng)域研究成果更加廣泛,深度學(xué)習(xí)被用于各種軟件工程任務(wù)中,包括代碼搜索、代碼注釋生成、缺陷檢測等.

        Fig.4 Analysis of the research content of articles圖4 相關(guān)論文研究內(nèi)容分析

        本文在后面的第2節(jié)、第3節(jié)分別對基于深度學(xué)習(xí)的程序生成和代碼補(bǔ)全方面的最新研究進(jìn)展進(jìn)行綜述,第 4節(jié)對經(jīng)常用于程序生成和代碼補(bǔ)全的深度神經(jīng)網(wǎng)絡(luò)進(jìn)行綜述,最后,對該方向已有的數(shù)據(jù)集進(jìn)行簡要總結(jié).表2是對現(xiàn)有相關(guān)工作的總結(jié),后文會展開介紹.

        Table 2 Summary of existing studies of code generation and completion based on deep learning表2 基于深度學(xué)習(xí)的程序生成與補(bǔ)全現(xiàn)有工作的方法總結(jié)

        1.4 程序性質(zhì)

        直觀上,程序語言與自然語言有很多相似之處,比如都是由符號(token)組成、都可以表達(dá)為語法樹(parse tree)、在一定程度上都具有重復(fù)性和可預(yù)測性等.這些相似的地方也是我們利用深度學(xué)習(xí)技術(shù)來解決程序自動生成問題的基礎(chǔ).但是相對于在自然語言領(lǐng)域的應(yīng)用,深度學(xué)習(xí)在自動編程領(lǐng)域并沒有展現(xiàn)出它獨特的優(yōu)勢,這與程序語言和自然語言的區(qū)別分不開.在自然語言中具有大量的不確定性和歧義性,所以基于規(guī)則的方法很難處理大量的特殊情況.而程序語言則是人為的根據(jù)規(guī)則嚴(yán)格定義和設(shè)計的語言.在語法層面或者低端的語義方面,機(jī)器(比如編譯器)都可以準(zhǔn)確地解析和理解.因此在這個層面上,基于規(guī)則的方法具有天然的優(yōu)勢.研究者利用深度學(xué)習(xí)實現(xiàn)程序自動生成任務(wù)時,考慮程序自身獨特的性質(zhì)是十分重要的.程序語言相對于自然語言有如下性質(zhì).

        1)強(qiáng)結(jié)構(gòu)性.雖然自然語言的句子可以被解析為依存語法樹或成分樹,但由于使用的語法規(guī)則是由語言學(xué)家在語料中歸納得到,往往不能包含全部情況,且自然語言先天具有歧義性,其結(jié)構(gòu)性較弱.而程序語言具有強(qiáng)結(jié)構(gòu)性.通常,一段代碼可以按定義的語法規(guī)則解析為唯一對應(yīng)的抽象語法樹.

        2)無限制的字典.字典是訓(xùn)練語言模型所必需的,程序語言和自然語言都有無限的字典.對于自然語言來說,一種語言常用的詞是有限的,人們很少會遇到罕見的詞匯.而程序語言則不同,程序員會定義不同的變量和方法名,這使得同樣規(guī)模的語料庫中,程序語言包含的字典大小往往會大于自然語言.

        3)演化速度快.自然語言發(fā)展至今,雖然也存在種種演化,但其速度較慢.而程序語言的語料庫大多選自一些開源的代碼庫,對于一個軟件系統(tǒng)來說,版本演化是很常見的現(xiàn)象,演化過程通常伴隨著對系統(tǒng)缺陷的修復(fù)和添加新的功能特征.這一演化速度,使得研究者們需要不斷地更新自己使用的語料庫.

        4)局部性特征.與自然語言相比,程序語言在一定范圍內(nèi)會重復(fù)出現(xiàn).例如,我們在定義一個變量后,該變量往往會在后文代碼出現(xiàn);當(dāng)我們引入一個庫后,通常在后文中會調(diào)用該庫中的API.如何更好地利用局部性特征來輔助程序生成,是許多研究者所關(guān)注的問題.

        2 程序生成

        基于深度學(xué)習(xí)的程序生成主要分為兩種:基于輸入輸出樣例的程序生成和基于功能描述的程序生成.現(xiàn)有的研究工作在實現(xiàn)上有不同的技術(shù)特點.表3總結(jié)了基于深度學(xué)習(xí)的程序生成現(xiàn)有工作的技術(shù)特點.

        Table 3 Techniques summary of exsiting studies for program generation based on deep learning表3 基于深度學(xué)習(xí)的程序生成現(xiàn)有工作的技術(shù)總結(jié)

        2.1 基于輸入輸出樣例的程序生成

        基于輸入輸出樣例的程序生成又被稱為歸納程序綜合(inductive program synthesis,簡稱 IPS)或?qū)嵗幊?programming by examples,簡稱PBE),是程序綜合的一類,IPS通過給定的輸入-輸出樣例來學(xué)習(xí)生成程序.建立一個IPS系統(tǒng)需要解決兩個問題.

        (1) 搜索問題:通過在合適的程序集合中找到與輸入-輸出一致的程序.

        (2) 排序問題:如何對多個與輸入-輸出一致的程序進(jìn)行排序,然后返回最佳程序[29].

        目前,歸納程序綜合任務(wù)主要在兩種數(shù)據(jù)上實現(xiàn):一種是不局限于某一種程序語言,而是使用定義好的領(lǐng)域建模語言(domain-specific language,簡稱DSL);另一種是在實際的Microsoft Excel數(shù)據(jù).由于可能程序的假設(shè)空間很大,在如此大的搜索空間中找到符合相應(yīng)輸入輸出的程序是很具有挑戰(zhàn)性的.目前,利用學(xué)習(xí)的方法來進(jìn)行DSL語言的歸納程序綜合任務(wù)大多遵循圖5的框架.

        Fig.5 Architecture of inductive program synthesis system圖5 歸納程序綜合系統(tǒng)框架

        2015年,Reed等人[37]開發(fā)了一個名為NPI(neural programmer-interpreter)的框架,利用該框架可以解釋執(zhí)行程序.在他們的方法中,程序被視為一組詞向量,利用神經(jīng)網(wǎng)絡(luò)來生成程序執(zhí)行所需要的語句以及參數(shù).Cai等人[38]、Xiao等人[39]、Chen等人[40]在Reed等人工作的基礎(chǔ)上對NPI進(jìn)行改進(jìn),從而提高程序生成的準(zhǔn)確率.2016年出現(xiàn)了大量的基于深度學(xué)習(xí)的程序生成工作[29,32,51].Balog等人[29]提出利用神經(jīng)網(wǎng)絡(luò)來輔助搜索與一組輸入-輸出樣例一致的代碼,而不是直接預(yù)測整個代碼片段.Gong等人[51]提出了一種層級的卷積神經(jīng)網(wǎng)絡(luò)HGCNN.HGCNN根據(jù)輸入-輸出樣例自動的給出程序的每行指令.Parisotto等人[32]提出用兩個神經(jīng)網(wǎng)絡(luò)模塊來完成 IPS任務(wù):一個模塊用于生成輸入輸出對的向量表示,另一個模塊利用一個基于樹的網(wǎng)絡(luò)結(jié)構(gòu)來根據(jù)輸入輸出的向量表示來逐步擴(kuò)展程序.2017年,Shu等人[30]提出一種基于深度神經(jīng)網(wǎng)絡(luò)的模型,用該模型來生成一些解決字符串處理的程序.其生成的程序由一系列的原子操作組成,每個原子操作可能會使用前一個原子操作的執(zhí)行結(jié)果,因此,該模型在只用幾個定義好的原子操作情況下可以合成復(fù)雜的程序.

        Microsoft Excel的字符轉(zhuǎn)換功能是 PBE任務(wù)中較為成功的應(yīng)用.作為 Microsoft Excel的一個重要特性,FlashFill[21,22]根據(jù)用戶提供的輸入輸出的字符串樣例,可以自動將其余輸入數(shù)據(jù)轉(zhuǎn)化為輸出數(shù)據(jù)格式.例如,利用FlashFill從地址中抽取郵編或轉(zhuǎn)換時間戳格式等.Shu等人[30]提出了NPBE(neural programming by example)完成45種字符串操作.NPBE的意圖是讓模型從輸入輸出字符串中學(xué)習(xí)相關(guān)的特征,并用學(xué)到的特征來歸納正確的程序.其核心模塊 Program Generator分別生成方法和參數(shù)的詞向量,最后融合兩部分向量,模塊 Symbol Selector利用融合的向量從方法和相應(yīng)的參數(shù)列表中選擇合適的方法和參數(shù).Parisotto等人[32]提出的R3NN模型通過在FlashFill數(shù)據(jù)上驗證發(fā)現(xiàn):雖然其模型對多數(shù)Excel字符串操作都有效,但是當(dāng)需要4個及以上Concat操作時,該方法會失效.Devlin等人[33]提出一種變長注意力機(jī)制循環(huán)神經(jīng)網(wǎng)絡(luò)結(jié)構(gòu),該網(wǎng)絡(luò)可以有效地對變長無序的輸入輸出樣例集合進(jìn)行編碼.不僅如此,為了驗證其魯棒性,對FlashFill數(shù)據(jù)人工注入各種噪聲數(shù)據(jù)后,驗證不同方法的準(zhǔn)確率.實驗結(jié)果顯示,該方法在有大量噪聲的情況下依然保持較高的準(zhǔn)確率,而基于人工的方法在有少部分噪聲的情況下其準(zhǔn)確率就會大幅度降低.

        2.2 基于功能描述的程序生成

        人們通常利用自然語言來描述程序功能,從自然語言描述到程序的自動翻譯是極具挑戰(zhàn)性的問題.自然語言文本和程序的多樣性、文本的二義性以及代碼的復(fù)雜結(jié)構(gòu),使得建立文本和代碼的聯(lián)系成為一個難題.利用深度學(xué)習(xí)可以有效地解決代碼和文本中二義性的問題.

        許多研究者利用深度學(xué)習(xí)的方法從自然語言生成 If-This-Then-That(IFTTT)代碼[41,43-45].IFTTT程序相對于常用的編程語言來說,其結(jié)構(gòu)更加簡單,也更容易學(xué)習(xí)其結(jié)構(gòu)規(guī)則.IFTTT程序通過創(chuàng)建一個流程(recipe)來完成特定的功能需求.This表示所要進(jìn)行的操作被稱為觸發(fā)器(trigger),也就是在某個網(wǎng)絡(luò)服務(wù)的操作行為;而That則意味著連鎖反應(yīng)所帶來的另外一個網(wǎng)絡(luò)服務(wù)行為動作(action).Dong等人[45]提出了一種基于注意力機(jī)制的編碼器-解碼器模型.該模型利用循環(huán)神經(jīng)網(wǎng)絡(luò)對自然語言進(jìn)行編碼,利用樹形的循環(huán)神經(jīng)網(wǎng)絡(luò)生成程序.2016年,Liu等人[43]提出了一種隱注意力機(jī)制,該機(jī)制可以有效地學(xué)習(xí)自然語言中哪些詞對觸發(fā)器的預(yù)測更重要,哪些詞對動作的預(yù)測更加重要.同年,Beltagy等人[44]將IFTTT程序生成問題當(dāng)做語義分析問題,其目標(biāo)是根據(jù)自然語言描述生成衍生樹.

        與生成IFTTT程序相比,根據(jù)功能描述生成常用程序語言(例如Java、Python等)的難度大得多.在2016年,Gu等人[46]提出了一個利用深度學(xué)習(xí)根據(jù)自然語言問題生成 API序列的工具 DEEPAPI.該工具利用編碼器-解碼器模型將自然語言問題的語義與API序列的語義建立關(guān)聯(lián).DEEPAPI在一定程度上實現(xiàn)了程序生成功能,在API序列的生成上取得了較高的準(zhǔn)確率.2017年,Yin等人[42]提出了一個語法模型,實現(xiàn)了從功能描述生成Python程序.該語法模型分為兩個部分:APPLYRULE和GENTOKEN.APPLYRULE在當(dāng)前節(jié)點上應(yīng)用生成規(guī)則來按照深度優(yōu)先和從左至右的順序來生成程序結(jié)構(gòu);GENTOKEN既可以從預(yù)定義的詞表中生成終結(jié)節(jié)點,也可以直接從自然語言描述中復(fù)制一些詞來作為終結(jié)節(jié)點.

        查詢關(guān)系型數(shù)據(jù)庫要求用戶理解查詢語言,例如 SQL,這對于非專業(yè)人員來說是相當(dāng)困難的.因此,許多研究者考慮根據(jù)自然語言生成 SQL語句.2017年,Zhong等人[49]提出了 Seq2SQL模型,將自然語言描述翻譯為SQL查詢語句.在SQL查詢語句中,查詢條件是無序的,這導(dǎo)致了SQL生成查詢條件時不適合利用傳統(tǒng)的交叉熵來優(yōu)化,因此,他們采用基于策略的強(qiáng)化學(xué)習(xí)來生成查詢條件.2018年,Cai等人[50]提出將深度學(xué)習(xí)方法與傳統(tǒng)的查詢解析技術(shù)相結(jié)合來提高生成 SQL的準(zhǔn)確率.在生成 SQL語句時,他們通過加入 SQL的巴克斯范式(Backus-Naur form,簡稱BNF)來約束SQL的生成.

        3 代碼補(bǔ)全

        代碼補(bǔ)全技術(shù)是最常見的程序自動化技術(shù),也是現(xiàn)代集成開發(fā)環(huán)境的重要組成部分.代碼補(bǔ)全極大地提高了程序開發(fā)的效率,并且減少了編碼過程中的拼寫錯誤.代碼補(bǔ)全技術(shù)通常幫助程序員預(yù)測代碼的類名、方法名、關(guān)鍵字等.下一個Token的預(yù)測是代碼補(bǔ)全最常見的形式,也是目前主流IDE所采用的補(bǔ)全方式.在常用的IDE中,推薦的Token往往按字母排序,增加了程序員對候選Token的選擇時間.

        傳統(tǒng)的代碼補(bǔ)全主要分為兩種:一種是利用靜態(tài)類型信息結(jié)合各種啟發(fā)式規(guī)則來決定要預(yù)測的 Token,例如方法名、參數(shù)等,這種方法通常很少考慮代碼的前文語義信息,例如主流的代碼補(bǔ)全系統(tǒng)Eclipse,Eclipse利用靜態(tài)的類別信息給用戶推薦 Java方法,推薦的方法名通常按照字母序排列;另一種方法利用代碼樣例和前文語義來補(bǔ)全Token.2009年,Bruch等人[52]利用k-Nearest Neighbor(kNN)算法對當(dāng)前的補(bǔ)全語義與之前的代碼樣例做匹配,從而提高代碼補(bǔ)全的準(zhǔn)確率.利用前文語義幫助代碼補(bǔ)全的技術(shù)通常利用特殊類別的上下文信息,例如前文中調(diào)用的API集合,來輔助代碼補(bǔ)全.2010年,Huo等人[53]提出了名為BCC的代碼補(bǔ)全技術(shù),該方法對API進(jìn)行排序和篩選來提高 Eclipse基于類型的代碼補(bǔ)全系統(tǒng).這些方法通常需要人工定義很多啟發(fā)式規(guī)則來規(guī)范上下文的語義集合,如果當(dāng)前補(bǔ)全位置的上下文語義與定義的語義集合不匹配,這種方法就會失效.

        深度學(xué)習(xí)方法從大規(guī)模代碼中學(xué)習(xí)代碼Token之間的概率分布,來提高Token推薦的準(zhǔn)確率.對代碼Token序列進(jìn)行概率建模,由Hindle等人[54]在2012年首次提出,他們指出:程序語言從理論上說是由人類寫的,具有重復(fù)性的語言,因此具有一些可以被預(yù)測的統(tǒng)計特征,這些統(tǒng)計特征可以被語言模型所捕捉.這一假說成為利用概率模型乃至深度學(xué)習(xí)對程序語言進(jìn)行學(xué)習(xí)的基石.對下一個Token預(yù)測最直接的方法就是利用程序的Token序列對當(dāng)前補(bǔ)全位置進(jìn)行預(yù)測.目前,利用深度學(xué)習(xí)來完成代碼補(bǔ)全問題的主要流程如圖6所示.該流程主要包括兩部分:訓(xùn)練階段和代碼補(bǔ)全階段.研究者首先從開源代碼庫或者開源社區(qū)獲得大量的數(shù)據(jù)作為深度學(xué)習(xí)的語料庫.為了更好地學(xué)習(xí)語料庫中的代碼,研究者通常利用代碼解析器對源代碼進(jìn)行處理,例如將源代碼轉(zhuǎn)化為Token序列或者轉(zhuǎn)化為抽象語法樹.之后,研究者選擇或者設(shè)計一個合適自己任務(wù)的深度神經(jīng)網(wǎng)絡(luò),并對語料庫中的數(shù)據(jù)進(jìn)行訓(xùn)練.

        Fig.6 Architecture of deep learning on code completion圖6 基于深度學(xué)習(xí)的代碼補(bǔ)全框架

        目前,在代碼補(bǔ)全任務(wù)中經(jīng)常用到的深度神經(jīng)網(wǎng)絡(luò)是語言模型,例如循環(huán)神經(jīng)網(wǎng)絡(luò).語言模型可以有效地學(xué)習(xí)程序的序列特征,并且將該特征用于代碼補(bǔ)全任務(wù).在代碼補(bǔ)全階段輸入部分代碼片段,在當(dāng)前補(bǔ)全位置調(diào)用訓(xùn)練好的深度學(xué)習(xí)模型,該模型根據(jù)輸入代碼片段的語義或結(jié)構(gòu)特征來預(yù)測需要補(bǔ)全的Token或者API等.表4是對基于深度學(xué)習(xí)的代碼補(bǔ)全工作技術(shù)特點的總結(jié).

        Table 4 Technique summary of existing studies of code completion based on deep learning表4 基于深度學(xué)習(xí)的代碼補(bǔ)全現(xiàn)有工作技術(shù)總結(jié)

        2014年,Tu等人[55]在Hindle等人[54]的基礎(chǔ)上提出代碼的Token在局部范圍內(nèi)具有一定的重復(fù)性.語言模型可以學(xué)習(xí)代碼全局的規(guī)律,然而卻忽略了程序的局部性特征.因此,Tu等人[55]在語言模型的基礎(chǔ)上加入了“緩存”機(jī)制來維護(hù).實驗結(jié)果顯示,該方法比之前的方法提升了16%~45%.Hellendoorn等人[24]通過對比循環(huán)神經(jīng)網(wǎng)絡(luò)與帶有“緩存”機(jī)制的N-gram,發(fā)現(xiàn)代碼的局部性特征對于Token的預(yù)測有極大的幫助.

        如何有效地利用程序的結(jié)構(gòu)信息來提高代碼補(bǔ)全的準(zhǔn)確率,一直是許多研究人員的關(guān)注熱點.在利用代碼結(jié)構(gòu)進(jìn)行代碼補(bǔ)全時,研究者通常從兩個方向展開研究:將樹結(jié)構(gòu)轉(zhuǎn)化為序列和直接對樹結(jié)構(gòu)進(jìn)行建模.Li等人[27]和Liu等人[23]通過AST序列對程序的終結(jié)節(jié)點和非終結(jié)節(jié)點進(jìn)行預(yù)測.這種基于AST序列對Token進(jìn)行預(yù)測不僅可以預(yù)測下一個終結(jié)節(jié)點即實際代碼 Token的預(yù)測,而且可以預(yù)測代碼的結(jié)構(gòu)信息即非終結(jié)節(jié)點.在對AST序列進(jìn)行建模時,要求AST序列既能保證程序的語義信息,又能保證程序的結(jié)構(gòu)信息.因此,研究者在將AST轉(zhuǎn)化為序列時,需要保證AST序列唯一表示一個代碼片段.2018年,Li等人[27]在對AST節(jié)點進(jìn)行編碼時額外加了兩位,用來表示該節(jié)點是否有子節(jié)點和右兄弟節(jié)點.直接對代碼結(jié)構(gòu)進(jìn)行建模需要設(shè)計相應(yīng)結(jié)構(gòu)的網(wǎng)絡(luò)結(jié)構(gòu)對其進(jìn)行建模.2016年,Raychev等人[56]利用決策樹來對程序的樹結(jié)構(gòu)直接建模來預(yù)測代碼的Token.

        除了對下一個Token進(jìn)行補(bǔ)全以外,應(yīng)用程序接口(application programming interface,簡稱API)的補(bǔ)全也受到了極大的關(guān)注.API的使用,極大地提高了程序員的開發(fā)效率.如何利用深度學(xué)習(xí)方法來補(bǔ)全多個API并且保持較高的準(zhǔn)確率,是API補(bǔ)全的難點.API級別的補(bǔ)全通常學(xué)習(xí)API的使用模式,利用API的使用模式來完成大規(guī)模的API補(bǔ)全.Raychev等人[25]在2014年提出利用語言模型根據(jù)上下文信息來補(bǔ)全API調(diào)用.他們提出的工具SLANG可以有效地補(bǔ)全API的調(diào)用和API的參數(shù).2016年,Gu等人[46]利用序列到序列模型訓(xùn)練了大規(guī)模的自然語言描述和API序列對,從而建立了自然語言和API序列的映射關(guān)系,其模型DEEPAPI有效地根據(jù)自然語言查詢返回API的調(diào)用序列.2018年,Gu等人[57]利用API序列遷移的方法生成相似程序語言的API序列,其利用API序列及其自然語言功能描述來學(xué)習(xí)API序列的向量表示.功能相似的API序列在向量空間中的的距離也相近,因此可以利用向量的相似度來生成相同功能、不同程序語言的API序列.

        從目前的工作來看,深度學(xué)習(xí)方法的出現(xiàn)極大地促進(jìn)了程序生成任務(wù)和代碼補(bǔ)全任務(wù)的發(fā)展,但是目前的工作還局限于生成規(guī)模較小、功能單一的程序.依據(jù)給定輸入輸出樣例生成的程序往往通用性較差,目前主要應(yīng)用在DSL語言和Excel處理上,而不能普遍地適用于通用編程語言,例如Java,Python等.如何利用深度學(xué)習(xí)生成可以實際運行的程序,仍然是目前亟待解決的問題.

        4 程序自動生成深度學(xué)習(xí)模型

        4.1 基于語言模型的程序生成技術(shù)

        語言模型廣泛地應(yīng)用于各種自然語言處理問題,例如機(jī)器翻譯、語音識別、問答系統(tǒng)等等.語言模型定義了自然語言中 Token序列的概率分布.基于程序語言的自然性,語言模型也被應(yīng)用于程序的建模.語言模型通常將解析過的代碼片段(通常在詞或字符級別)當(dāng)做文本直接作為輸入,該模型的目標(biāo)是對程序語言的文本的概率分布進(jìn)行建模,也就是說,概率模型用于估計一個代碼片段s的概率分布P(s).對于一個代碼片段s={w1,…,wm}來說,許多語言模型通過計算每一個詞基于已經(jīng)生成的詞的條件概率來計算整個代碼片段的概率分布,即

        在程序語言處理中,常用到的語言模型有N-gram和循環(huán)神經(jīng)網(wǎng)絡(luò)(recurrent neural network,簡稱RNN),其中,循環(huán)神經(jīng)網(wǎng)絡(luò)是基于深度神經(jīng)網(wǎng)絡(luò)的語言模型.

        N-gram是最早用于程序?qū)W習(xí)的語言模型,在N-gram模型中,下一個單詞wi的概率依賴于前n-1個詞,即

        因此,N-gram模型可以在一定程度上捕捉句子的局部信息.在Hindle等人[54]將N-gram模型應(yīng)用于代碼建模后,有許多利用N-gram的工作隨后出現(xiàn).N-gram雖然可以有效地學(xué)習(xí)代碼片段的局部上下文,但是不能理解代碼片段的語義信息.為了解決這些問題,許多研究者結(jié)合軟件工程任務(wù)的特點對N-gram 模型進(jìn)行了改進(jìn).Nguyen等人[58]提出的SLAMC模型將全局信息加入N-gram模型,SLAMC結(jié)合了語義信息,并對語義標(biāo)注的規(guī)則進(jìn)行建模,該方法在代碼推薦的準(zhǔn)確率上較普通的N-gram有顯著的提升.Raychev等人[25]將N-gram模型與循環(huán)神經(jīng)網(wǎng)絡(luò)結(jié)合,在Java在API調(diào)用級別進(jìn)行代碼補(bǔ)全.為了解決代碼具有局部性特征的挑戰(zhàn),Tu等人[55]和Hellendoorn[24]等人提出了將緩存機(jī)制加入到N-gram 模型中,利用標(biāo)識符會在較近的范圍內(nèi)重復(fù)出現(xiàn)的特性,從而在代碼預(yù)測上取得了顯著的效果.

        與N-gram相比,RNN不僅可以捕獲句子中詞之間的規(guī)律性,而且可以捕捉距離較遠(yuǎn)的詞之間的關(guān)系.為了更進(jìn)一步解決長距離依賴問題,許多基于RNN的變體,例如長短記憶模型(long short-term memory,簡稱LSTM)、門限循環(huán)單元(gated recurrent unit,簡稱GRU)被提出并得到廣泛應(yīng)用(如圖7所示).利用RNN模型可以有效地對源代碼進(jìn)行建模,并且學(xué)習(xí)源代碼的向量表示.Nguyen等人[59]、Nguyen等人[60]和Gu等人[57]利用RNN學(xué)習(xí)分別Java語言和C#的API向量表示,將學(xué)到的向量表示應(yīng)用于這兩種語言的API遷移任務(wù)中,從而在API級別生成代碼.許多學(xué)者將RNN模型用于代碼Token預(yù)測補(bǔ)全,并且取得了顯著的效果[26].大多數(shù)研究工作都是利用RNN在詞的級別對代碼進(jìn)行建模學(xué)習(xí),但是由于代碼大量的變量導(dǎo)致學(xué)習(xí)難度很大,有一些工作開始在字符級別對代碼進(jìn)行學(xué)習(xí)[61].

        Fig.7 An illustration of basic RNN and LSTM structures圖7 基礎(chǔ)循環(huán)神經(jīng)網(wǎng)絡(luò)和長短記憶網(wǎng)絡(luò)結(jié)構(gòu)

        程序語言在本地(localness)上具有一定的重復(fù)性,例如,一個定義過的變量往往會在后邊重復(fù)使用.然而,這些變量在很大程度上往往會被當(dāng)成詞典外的詞(out-of-vocabulary,簡稱OoV),通常被記為UNK.給程序員預(yù)測一個 UNK對于他們的編程是毫無幫助的,因此,研究者考慮將指針網(wǎng)絡(luò)機(jī)制加入到語言模型,來準(zhǔn)確預(yù)測本地重復(fù)出現(xiàn)的詞.利用指針網(wǎng)絡(luò)可以有效地從輸入的代碼片段中復(fù)制需要重復(fù)使用的詞.指針網(wǎng)絡(luò)(pointer networks)由 Vinyals等人[62]在 2015年提出,最初被用于解決組合優(yōu)化問題,是神經(jīng)機(jī)器翻譯模型(即序列到序列模型,Seq2Seq模型)的一個變種.在指針網(wǎng)絡(luò)中,注意力更簡單,它不考慮輸入元素,而是在概率上指向它們.

        2016年,Bhoopchand等人[26]提出了一種精簡指針網(wǎng)絡(luò)(sparse pointer network),該網(wǎng)絡(luò)主要解決了自定義標(biāo)識符預(yù)測的問題(例如類名、方法名、變量名等).論文中定義了“內(nèi)存(memory,簡稱M)”的概念,該“內(nèi)存”用于存儲前K個標(biāo)識符.此外,該方法維護(hù)了一個向量m=[id1,…,idK]用于記錄標(biāo)識符在全局詞表中的位置,即指向全局詞表的指針.在每個時刻進(jìn)行預(yù)測時,該網(wǎng)絡(luò)結(jié)合全局的語言模型概率分布,自定義標(biāo)識符的指針概率分布以及當(dāng)前的代碼輸入來決定輸出的詞.與傳統(tǒng)循環(huán)神經(jīng)網(wǎng)絡(luò)(不帶有注意力機(jī)制)相比,該方法在 Python自定義標(biāo)識符預(yù)測準(zhǔn)確率上提高了25%左右.

        Li等人[27]在2018年提出一種結(jié)合注意力機(jī)制的語言模型和指針網(wǎng)絡(luò)的模型進(jìn)行代碼補(bǔ)全,其模型對抽象語法樹序列進(jìn)行建模.該模型不僅可以預(yù)測語法樹的節(jié)點類型,而且可以預(yù)測節(jié)點的值,即要預(yù)測的代碼.直覺上,在預(yù)測代碼時,父親節(jié)點對于孩子節(jié)點的預(yù)測幫助更大,因此,其注意力機(jī)制在傳統(tǒng)的注意力機(jī)制上結(jié)合了語法樹“父親-孩子”節(jié)點關(guān)系.論文利用指針網(wǎng)絡(luò)從輸入的代碼片段中復(fù)制單詞來預(yù)測詞表外的詞,即OoV.論文中通過定義一個選擇器(switcher)來決定是根據(jù)語言模型在全局詞表上的分布來預(yù)測下一個詞,還是利用指針網(wǎng)絡(luò)從輸入的代碼片段中復(fù)制一個詞.該方法在兩個數(shù)據(jù)集上進(jìn)行了驗證,分別是 Python和 JavaScript.結(jié)果表明,其方法在預(yù)測OoV詞上有顯著的提高.

        4.2 結(jié)構(gòu)化代碼生成網(wǎng)絡(luò)

        代碼的強(qiáng)結(jié)構(gòu)性問題對于深度學(xué)習(xí)模型來說既是一個挑戰(zhàn),也是一個機(jī)遇.由于程序語言是一種強(qiáng)結(jié)構(gòu)性語言,每個代碼片段都對應(yīng)一個唯一的抽象語法樹.不同于自然語言的語言模型,許多研究者致力于對代碼結(jié)構(gòu)進(jìn)行建模并實現(xiàn)代碼的生成.與基于序列的建模方式不同,結(jié)構(gòu)化的建模通常描述結(jié)構(gòu)(如抽象語法樹)生成過程的概率分布.因此,許多工作都從結(jié)構(gòu)是如何生成的來對程序結(jié)構(gòu)進(jìn)行建模.利用深度學(xué)習(xí)對程序結(jié)構(gòu)建模從而生成程序主要分為兩種:基于抽象語法樹的網(wǎng)絡(luò)和基于圖的網(wǎng)絡(luò).

        4.2.1 基于抽象語法樹的網(wǎng)絡(luò)

        基于抽象語法樹的網(wǎng)絡(luò)是對程序結(jié)構(gòu)進(jìn)行建模時最常見的網(wǎng)絡(luò)結(jié)構(gòu).研究者主要從兩個方向上運用抽象語法樹,將語法樹的節(jié)點遍歷成序列形式結(jié)合序列化模型和直接設(shè)計樹形的網(wǎng)絡(luò)對語法樹建模.

        1) 將抽象語法樹遍歷成序列,并利用基于序列的模型對其建模.

        該方法相對于設(shè)計樹形網(wǎng)絡(luò)要簡單許多,其難點在于如何保證一個序列唯一對應(yīng)一個程序,即保證序列無二義性.在 Liu等人[23]的工作中,將代碼補(bǔ)全問題看做是在給定部分抽象語法樹的情況下預(yù)測樹的下一個節(jié)點.他們在遍歷抽象語法樹時,利用中序深度優(yōu)先遍歷得到序列.Li等人[27]在其工作中將抽象語法樹也是按照中序深度優(yōu)先的方法進(jìn)行遍歷得到序列,通過帶有指針網(wǎng)絡(luò)的語言模型對該序列進(jìn)行學(xué)習(xí).與 Liu等人[23]的工作不同,為了保證該序列唯一對應(yīng)一個代碼片段,他們在對節(jié)點進(jìn)行編碼時額外加了兩位,用來表示該節(jié)點是否有孩子節(jié)點和是否有右兄弟節(jié)點.其結(jié)果與Liu等人[23]等結(jié)果相比,在預(yù)測節(jié)點的Type和Value的準(zhǔn)確率上均提高了4%左右.

        2) 樹形網(wǎng)絡(luò).

        利用樹形網(wǎng)絡(luò)生成代碼時,通常按照從上到下從左至右的順序生成樹的子節(jié)點.一般來說,生成樹結(jié)構(gòu)的深度學(xué)習(xí)模型很難學(xué)習(xí):首先,這種模型計算成本很高;其次,對樹生成過程的上下文建模需要更加復(fù)雜的數(shù)據(jù)結(jié)構(gòu)(與序列模型相比).一些研究者利用機(jī)器學(xué)習(xí)的方法對抽象語法樹建模,Bielik等人[63]和Raychev等人[56]分別利用上下文無關(guān)文法和決策樹對抽象語法樹建模并預(yù)測代碼.深度學(xué)習(xí)方法比機(jī)器學(xué)習(xí)網(wǎng)絡(luò)結(jié)構(gòu)更為復(fù)雜,需要根據(jù)抽象語法樹的結(jié)構(gòu)定制新的網(wǎng)絡(luò).Rabinovich等人[64]提出一種抽象語法網(wǎng)絡(luò)(abstract syntax network,簡稱ASN),該網(wǎng)絡(luò)是標(biāo)準(zhǔn)編碼器-解碼器框架的擴(kuò)展形式.與序列模型不同,其解碼器是由許多子模塊組成,每個子模塊都與抽象語法樹的一個語法結(jié)構(gòu)對應(yīng).在解碼過程中,循環(huán)神經(jīng)網(wǎng)絡(luò)的狀態(tài)從一個模塊傳遞到另一個模塊,從而實現(xiàn)模塊之間信息的傳遞.在樹的生成過程中,根據(jù)當(dāng)前的狀態(tài)選擇不同的模塊執(zhí)行不同的網(wǎng)絡(luò),從而實現(xiàn)樹結(jié)構(gòu)的預(yù)測.與 Rabinovich等人[64]根據(jù)樹的語法結(jié)構(gòu)設(shè)計不同的模塊不同,Dong等人[45]提出一種層級的樹解碼器 SEQ2TREE.解碼器根據(jù)編碼器得到的結(jié)果之后,利用循環(huán)神經(jīng)網(wǎng)絡(luò)生成樹深度為1的Token,當(dāng)預(yù)測為非終結(jié)節(jié)點時,將非終結(jié)節(jié)點的狀態(tài)作為輸入預(yù)測樹的下一層,直到?jīng)]有非終結(jié)節(jié)點.

        4.2.2 基于圖的網(wǎng)絡(luò)

        Nguyen等人[65]提出對Java程序的API調(diào)用的圖表示方法.與Gu等人[46,57]將Java方法中的API按序列表示其關(guān)系不同,Nguyen等人[65]在對API的調(diào)用關(guān)系建圖時,圖中的節(jié)點包括動作(即API調(diào)用、重載操作和域的訪問)和控制點(即控制結(jié)構(gòu)的分支if,while,for等).圖的邊表達(dá)了這些節(jié)點的依賴關(guān)系.Allamanis等人[28]提出利用基于圖的網(wǎng)絡(luò)來表示代碼結(jié)構(gòu)的句法和語義特征,其模型利用不同的邊來表達(dá)不同Token之間的句法和語義關(guān)系.如圖8所示,其圖的模型在抽象語法樹的基礎(chǔ)上對節(jié)點的關(guān)系進(jìn)一步刻畫,圖中的邊包括兩類:Child和NextToken,其中,Child邊連接抽象語法樹的節(jié)點.為了進(jìn)一步表示非終結(jié)節(jié)點的孩子節(jié)點中葉子節(jié)點的順序,該模型用NextToken邊將其連接起來.

        Fig.8 Graph representation model of AST in Allamanis,etal.[28]圖8 Allamanis等人提出的基于抽象語法樹的圖表示模型[28]

        5 用于深度學(xué)習(xí)的代碼語料庫

        代碼數(shù)據(jù)集是利用深度學(xué)習(xí)實現(xiàn)程序生成和代碼補(bǔ)全的前提,規(guī)范、高質(zhì)量的代碼語料庫更有利于深度神經(jīng)網(wǎng)絡(luò)的學(xué)習(xí).在圖像識別和自然語言處理中,有許多公開的數(shù)據(jù)集供研究者展開研究.然而在程序語言中,很少有公開的數(shù)據(jù)集供研究者使用,許多研究者需要自己去構(gòu)造數(shù)據(jù)集.目前,一些研究者在論文中公開了自己的數(shù)據(jù)集,這些數(shù)據(jù)集可以被其他研究者使用.本文對文獻(xiàn)中的相關(guān)數(shù)據(jù)集進(jìn)行了總結(jié),見表5.

        Table 5 Code corpora proposed by existing studies表5 現(xiàn)有工作提出的代碼語料庫

        目前,這些數(shù)據(jù)集被用于許多軟件工程任務(wù)中.例如,Mou等人[68]提出的104類的C程序被用于程序分類任務(wù)和代碼克隆檢測任務(wù);源代碼以及對應(yīng)注釋的數(shù)據(jù)集被用于代碼摘要生成任務(wù)中.已有工作的數(shù)據(jù)集大多來源于 GitHub,為了保證數(shù)據(jù)集的質(zhì)量,大多研究工作都選擇星級(star)或復(fù)刻(fork)較高的項目,然后從這些項目中抽取相應(yīng)的代碼片段作為代碼語料庫.然而,這些語料庫中仍有一些噪聲,對源碼的學(xué)習(xí)帶來影響,這些噪聲主要來源于以下幾個方面.

        · 代碼編寫不規(guī)范.許多項目開發(fā)人員在編寫代碼時,沒有按照統(tǒng)一的規(guī)范來開發(fā),尤其在注釋書寫上有很大的差異性,主要體現(xiàn)在:各國語言同時使用:注釋并不是解釋代碼片段的功能需求:缺少規(guī)范的注釋,例如Javadoc注釋.

        · 存在大量相似甚至重復(fù)的代碼片段.在項目開發(fā)過程中,由于重載或重寫機(jī)制,許多代碼片段十分相似,這就導(dǎo)致在模型的訓(xùn)練過程中容易出現(xiàn)過擬合現(xiàn)象.對于Online Judge這類提交解決方案代碼的數(shù)據(jù)集,這種現(xiàn)象更加明顯.對于同一個方案的不同提交,它們之間的差異性很小.

        因此,我們在使用這些數(shù)據(jù)集時,應(yīng)該根據(jù)自己的需求對于數(shù)據(jù)集一定程度上的清洗,通過定義一些規(guī)則過濾掉可能產(chǎn)生噪聲的數(shù)據(jù),從而達(dá)到生成符合編程規(guī)范的程序的目的.

        6 挑戰(zhàn)與未來方向

        總體來看,當(dāng)前利用深度學(xué)習(xí)技術(shù)的程序生成和代碼補(bǔ)全還處于起步階段.從介紹的相關(guān)工作中可以看出,利用深度學(xué)習(xí)代碼補(bǔ)全與傳統(tǒng)方法相比有了較大的提升,而程序生成技術(shù)還無法用于工業(yè)化.目前的研究工作還難以滿足實際軟件自動化開發(fā)的需求,主要面臨著以下的挑戰(zhàn).

        1)實驗缺乏統(tǒng)一的自動化評估標(biāo)準(zhǔn).現(xiàn)有的文獻(xiàn)中,用來評測模型能力的指標(biāo)包括預(yù)測下一個 token的準(zhǔn)確率、信息檢索領(lǐng)域使用的指標(biāo)MRR和機(jī)器翻譯領(lǐng)域使用的指標(biāo)BLEU等.這些指標(biāo)之間無法直接轉(zhuǎn)化,也就難以將各種模型能力進(jìn)行直接比較.此外,這些指標(biāo)的高低與程序的正確性與否之間的關(guān)系還難以清晰表述.因此,如何找到一種能夠自動評估生成程序正確性的指標(biāo),是將現(xiàn)有研究工作投入到實際開發(fā)中的一項重要挑戰(zhàn).

        2)訓(xùn)練語料的質(zhì)量參差不齊.現(xiàn)有的工作中,用來訓(xùn)練深度學(xué)習(xí)模型的語料大致可以分為兩類:一類是基于DSL人為構(gòu)造出的程序;另一類是從開源社區(qū),如GitHub等網(wǎng)站上爬取的項目.基于DSL的程序往往語法較為簡單,程序長度較短,易于訓(xùn)練和測試,但同時,針對 DSL設(shè)計的模型也難以推廣到其他語言上使用;而開源社區(qū)上爬取的項目雖然更接近于實際軟件開發(fā),但是也難以保證代碼的質(zhì)量——低質(zhì)量、不規(guī)范的代碼會給神經(jīng)網(wǎng)絡(luò)帶來額外的噪聲,而使用不同編程規(guī)范的代碼則會使神經(jīng)網(wǎng)絡(luò)模型在訓(xùn)練和預(yù)測時產(chǎn)生混淆.如何獲取統(tǒng)一規(guī)范的高質(zhì)量程序語料庫也是一項挑戰(zhàn).

        結(jié)合當(dāng)前程序生成和代碼補(bǔ)全的研究現(xiàn)狀,以下幾個方面可能成為進(jìn)一步的研究方向:

        1)結(jié)合編譯技術(shù)提高程序生成質(zhì)量.現(xiàn)有的模型自動生成代碼時,由于沒有考慮到是否符合語法,會產(chǎn)生大量無法編譯通過的部分代碼片段.而實際上,這些錯誤可以由程序員或IDE的語法檢查功能查出并修復(fù).因此,將程序語言的語法和規(guī)范引入到程序自動生成模型中,作為模型的一部分或在生成token時作為約束和限制,有可能提高程序自動生成技術(shù)的可靠性,更好地輔助程序員快速開發(fā).

        2)使模型具有更強(qiáng)的用戶可自定義性.神經(jīng)網(wǎng)絡(luò)模型往往基于大規(guī)模語料庫訓(xùn)練并測試,但在項目開發(fā)過程中,程序員可能會依照實際需求使用新的自定義標(biāo)識符編寫未在此前語料庫中出現(xiàn)過的代碼片段.因此,為了提升用戶體驗,我們需要使得模型具有更強(qiáng)的用戶可自定義性,即可以根據(jù)用戶自己編寫的代碼來更新模型.

        7 結(jié)束語

        為了減輕程序員的開發(fā)負(fù)擔(dān),提高軟件開發(fā)的自動化程度,提高軟件開發(fā)的效率和質(zhì)量,學(xué)界和工業(yè)界都不斷嘗試研究程序自動生成技術(shù).盡管常用的集成開發(fā)環(huán)境中往往整合了代碼補(bǔ)全工具,但現(xiàn)有的代碼補(bǔ)全工具通常只簡單地基于靜態(tài)詞頻統(tǒng)計,候選結(jié)果則按照字典順序排列,低準(zhǔn)確率的代碼補(bǔ)全工具在實際場景中可能反而會增加程序員的開發(fā)成本.此外,更進(jìn)一步地,研究者們也致力于直接生成執(zhí)行某一特定功能的代碼片段或完整程序,即程序生成.人工智能的發(fā)展極大地促進(jìn)了程序自動生成技術(shù)的進(jìn)步,但是由計算機(jī)直接生成代碼仍然十分困難,目前的程序生成技術(shù)還局限于生成規(guī)模較小、功能單一、領(lǐng)域特定的程序,對于復(fù)雜的程序,其技術(shù)還是十分受限.

        隨著深度學(xué)習(xí)技術(shù)的再次火熱,越來越多的研究者開始將深度神經(jīng)網(wǎng)絡(luò)模型應(yīng)用于提升程序自動生成技術(shù)的性能.由于程序語言也屬于人類創(chuàng)造的語言,整體來看,研究者們傾向于將原本用于對自然語言建模的模型應(yīng)用于程序語言上,如許多工作中將語言模型用于對程序語言建模.但與自然語言相比,程序語言具有結(jié)構(gòu)性強(qiáng)、擁有無限制大的詞表以及演化速度快等特點,這給研究者們帶來了更多的挑戰(zhàn),同時也提供了新的可能性.例如,代碼可以轉(zhuǎn)換成與其對應(yīng)的抽象語法樹,最近已經(jīng)有越來越多的工作致力于對抽象語法樹建模,并取得了比只對詞序列建模的方法更好的效果.此外,如何更好地處理程序語言中過大的詞匯表.也是進(jìn)行基于深度學(xué)習(xí)的程序自動生成技術(shù)研究的一條可選道路.隨著深度學(xué)習(xí)技術(shù)的快速發(fā)展,相信在將來,越來越多的重復(fù)性的程序開發(fā)將由機(jī)器代替,程序員將更關(guān)注于上層的開發(fā)與設(shè)計工作.

        猜你喜歡
        代碼研究者語法
        高等教育中的學(xué)生成為研究者及其啟示
        研究者稱,經(jīng)CRISPR技術(shù)編輯過的雙胞胎已出生。科學(xué)將如何回應(yīng)?
        英語文摘(2019年2期)2019-03-30 01:48:40
        跟蹤導(dǎo)練(二)4
        KEYS
        創(chuàng)世代碼
        動漫星空(2018年11期)2018-10-26 02:24:02
        創(chuàng)世代碼
        動漫星空(2018年2期)2018-10-26 02:11:00
        創(chuàng)世代碼
        動漫星空(2018年9期)2018-10-26 01:16:48
        創(chuàng)世代碼
        動漫星空(2018年5期)2018-10-26 01:15:02
        研究者調(diào)查數(shù)據(jù)統(tǒng)計
        中華手工(2018年6期)2018-07-17 10:37:42
        Keys
        极品少妇人妻一区二区三区| 毛片网站视频| 日本道免费精品一区二区| 亚洲视频观看一区二区| 中文字日产幕码三区的做法大全| 国产l精品国产亚洲区久久| 久久中文字幕av一区二区不卡| 欧美片欧美日韩国产综合片| 日韩精品免费在线视频一区| 91麻豆精品久久久影院| 国产精品美女久久久网站三级 | 丝袜人妻无码中文字幕综合网| 激情亚洲不卡一区二区| 亚洲av乱码一区二区三区按摩| 后入内射欧美99二区视频| 亚洲AV无码一区二区三区少妇av | av天堂一区二区三区| 国产黄污网站在线观看| 精品国产乱码久久久久久影片| 一本一道波多野结衣av中文| 国产在线看不卡一区二区| 亚洲av无码国产精品色| 国产va在线观看免费| 精品18在线观看免费视频| 人妻被公上司喝醉在线中文字幕| 国产日韩精品suv| 亚洲av久久无码精品九九| 亚洲国产剧情一区在线观看| 国产成人国产三级国产精品| 无码人妻人妻经典| 一区一级三级在线观看| 看大陆男女真人草逼视频| 亚洲日韩成人无码| 日本大片在线看黄a∨免费| 人妻少妇看A偷人无码电影| 熟妇人妻精品一区二区视频免费的 | 一级a免费高清免在线| 中文字幕av中文字无码亚| 精品成人乱色一区二区| 国产日产亚洲系列av| 日本熟女人妻一区二区|