利用機(jī)器學(xué)習(xí)學(xué)會(huì)如何自動(dòng)寫(xiě)代碼或修改代碼一直非常誘人,它不僅能減少大量工程努力,同時(shí)也能構(gòu)建更高級(jí)的智能體。在這篇論文中,谷歌大腦的研究者提出利用神經(jīng)網(wǎng)絡(luò)建模我們對(duì)源代碼的編輯,也就是說(shuō)將我們對(duì)代碼的編輯視為一個(gè)序列,然后像語(yǔ)言模型那樣學(xué)會(huì)如何「寫(xiě)代碼」。 來(lái)源 | 機(jī)器之心(ID:almosthuman2014) 總體而言,這份研究在于理解人類(lèi)編寫(xiě)代碼的過(guò)程(例如 GitHub 的 commit),并使用深度神經(jīng)網(wǎng)絡(luò)模擬這個(gè)動(dòng)態(tài)的編輯過(guò)程。只需要給定上一次的編輯信息,模型就能預(yù)測(cè)下一次代碼編輯該改什么,從而繼續(xù)修改與生成代碼。前一段時(shí)間,OpenAI 的 GPT-2 能生成逼真的自然語(yǔ)言對(duì)話,也許采用相同的模式,這種動(dòng)態(tài)代碼編輯也能生成「邏輯合理」的源代碼。 這篇論文的四位作者都來(lái)自于谷歌大腦,其中二作 David Bieber 還發(fā)布過(guò)一個(gè)可以自動(dòng)生成命令行接口的庫(kù):Python Fire。 什么是代碼建模 代碼是一種機(jī)器語(yǔ)言,它和自然語(yǔ)言一樣以一種序列的方式展現(xiàn)出來(lái)。以前機(jī)器之心曾介紹過(guò)多種代碼生成的方式,其中研究最多的是如何根據(jù) GUI 生成對(duì)應(yīng)代碼,例如 17 年提出的 Pix2Code,我們只需要輸入界面圖像就能生成對(duì)應(yīng)的前端代碼。 其次,2018 年 11 月,北大研究者首次成功用 CNN 自動(dòng)生成代碼,他們這篇 AAAI 2019 論文采用了 CNN 解碼器,并在《爐石傳說(shuō)》數(shù)據(jù)集上進(jìn)行了測(cè)試,效果超過(guò)了此前各類(lèi)業(yè)內(nèi)最佳模型。這類(lèi)研究一般都會(huì)采用結(jié)構(gòu)化的神經(jīng)網(wǎng)絡(luò)來(lái)建模代碼結(jié)構(gòu),例如北大研究者的這篇論文就根據(jù)抽象語(yǔ)法樹(shù)(AST)中的語(yǔ)法結(jié)構(gòu)規(guī)則生成代碼。 但是,這些方法都將代碼生成看成是一種「一次到位」的靜態(tài)過(guò)程。不過(guò)我們知道,代碼的編寫(xiě)是動(dòng)態(tài)的,隨著新特性的實(shí)現(xiàn)、bug 的修復(fù)以及重構(gòu)的進(jìn)行,源代碼庫(kù)一直處在變化之中。其實(shí)在人類(lèi)開(kāi)發(fā)的過(guò)程中,開(kāi)發(fā)者都需要訪問(wèn)已有的代碼庫(kù)或片段,考慮用一個(gè)或多個(gè)意圖對(duì)其進(jìn)行更改。 在本文中,谷歌大腦團(tuán)隊(duì)探討的主要問(wèn)題是如何觀察一個(gè)過(guò)去的編輯序列并預(yù)測(cè)即將發(fā)生的編輯。這是一個(gè)重要的問(wèn)題,因?yàn)闃?gòu)建更好的開(kāi)發(fā)者工具的核心挑戰(zhàn)是理解開(kāi)發(fā)者行為背后的意圖。 這也是一個(gè)有趣的研究挑戰(zhàn),因?yàn)閮H根據(jù)編輯的內(nèi)容(輸入或刪除的內(nèi)容)無(wú)法理解編輯模式。我們需要根據(jù)變更與變更之前的狀態(tài)之間的關(guān)系來(lái)理解編輯,而且,準(zhǔn)確地對(duì)編輯序列建模需要學(xué)習(xí)過(guò)去編輯的表征,這一表征允許模型泛化模式并預(yù)測(cè)未來(lái)編輯。 如圖 1 所示,圖中有兩個(gè)可能的編輯序列(History A 和 History B)。經(jīng)過(guò)兩次編輯后,兩個(gè)序列都有了相同的編碼狀態(tài)(State 2),但 History A 正在給 foo 函數(shù)添加一個(gè)額外的參數(shù),History B 正在從 foo 函數(shù)中移除第二個(gè)參數(shù)。 研究者希望通過(guò)觀察初始狀態(tài)(State 0)和編輯序列(Edits 1 & 2)讓模型具備預(yù)測(cè) Edit 3 的能力。在 History A 的情況下,要插入的特定值是不明確的,但是在該位置插入某個(gè)值這一事實(shí)應(yīng)該具有相當(dāng)高的置信度。 圖 1:兩個(gè)編輯序列圖示。History A 和 History B 共享相同的 State 2,但根據(jù)以往經(jīng)驗(yàn),History A 更有可能通過(guò)修改對(duì) foo 函數(shù)的調(diào)用來(lái)獲取一個(gè)額外的參數(shù),History B 更有可能通過(guò)修改 foo 的定義來(lái)獲取一個(gè)參數(shù)。 因此在谷歌大腦的這篇研究中,神經(jīng)網(wǎng)絡(luò)需要學(xué)習(xí)不同的編輯序列及編輯內(nèi)容,從而在給定編輯序列的情況下,模型能知道后面該怎樣繼續(xù)「寫(xiě)代碼」。這就和語(yǔ)言模型一樣,給定一小段話,模型就能接著用自然語(yǔ)言「編下去」。 谷歌大腦的解決方案 編輯建模序列的主要挑戰(zhàn)是如何開(kāi)發(fā)良好的表征,既能捕捉所需的意圖信息,又能優(yōu)雅地縮放序列長(zhǎng)度。研究者考慮了兩種編輯表征:顯式表征和隱式表征。 顯式表征明確實(shí)例化序列中每一次編輯的狀態(tài)結(jié)果,而隱式表征實(shí)例化完整的初始狀態(tài)以及更緊湊的類(lèi) diff 表征中的后續(xù)編輯。在顯式表征中,研究者將層級(jí)遞歸指針網(wǎng)絡(luò)模型視為一個(gè)強(qiáng)大但計(jì)算昂貴的基線。 在隱式表征中,研究者考慮一個(gè)簡(jiǎn)單的序列到序列模型以及一個(gè)基于注意力的雙向模型,后者擁有一個(gè)生成編輯位置的指針網(wǎng)絡(luò) head 和一個(gè)生成編輯內(nèi)容的內(nèi)容 head。這些模型顯示了源自不同問(wèn)題公式化之間的權(quán)衡,并為將來(lái)的編輯序列模型提供設(shè)計(jì)方案。 在精心設(shè)計(jì)的合成數(shù)據(jù)以及對(duì) Python 源代碼進(jìn)行細(xì)粒度編輯的大規(guī)模數(shù)據(jù)集中,研究者根據(jù)模型觀察一系列過(guò)去編輯的能力來(lái)評(píng)估模型的可擴(kuò)展性和準(zhǔn)確性,然后預(yù)測(cè)未來(lái)的編輯。 在制作合成數(shù)據(jù)集以評(píng)估模型的特定功能之后,研究者將注意力轉(zhuǎn)移到真實(shí)數(shù)據(jù)。研究者根據(jù)開(kāi)發(fā)實(shí)際代碼的專(zhuān)業(yè)開(kāi)發(fā)人員創(chuàng)建的谷歌代碼庫(kù)構(gòu)建了一個(gè)大型編輯序列數(shù)據(jù)集。 開(kāi)發(fā)人員每保存一份文件,就會(huì)創(chuàng)建一份靜態(tài)代碼狀態(tài),由此生成比典型 Git commit 等更細(xì)的粒度。研究者對(duì)不同模型觀察以往編輯和預(yù)測(cè)未來(lái)編輯的能力進(jìn)行可擴(kuò)展性和準(zhǔn)確性評(píng)估。 結(jié)果顯示,雙向注意力模型特別能夠在真實(shí)數(shù)據(jù)中實(shí)現(xiàn)高準(zhǔn)確率、精準(zhǔn)置信度和較好的可擴(kuò)展性,這使得研究者對(duì)開(kāi)發(fā)者工具的前景保持樂(lè)觀,而這些工具在開(kāi)發(fā)人員對(duì)大型和真實(shí)代碼庫(kù)進(jìn)行編輯時(shí)學(xué)習(xí)提取他們的意圖。 總之,本文將研究從編輯序列中學(xué)習(xí)和預(yù)測(cè)編輯的問(wèn)題,是對(duì)模型空間的初步探索,此外還展示了從開(kāi)發(fā)者編輯源代碼過(guò)程中學(xué)習(xí)的適用性。 論文:NEURAL NETWORKS FOR MODELING SOURCE CODE EDITS 論文地址:https:///pdf/1904.02818.pdf 摘要:編程語(yǔ)言正成為機(jī)器學(xué)習(xí)中一個(gè)充滿(mǎn)挑戰(zhàn)與趣味的領(lǐng)域。其核心任務(wù)是構(gòu)建源代碼的生成模型,這一任務(wù)近年來(lái)已受到大量關(guān)注。 但是,就目前所知,以前的生成模型總是生成靜態(tài)代碼片段。在本文中,我們將源代碼視作動(dòng)態(tài)目標(biāo),要解決的問(wèn)題是建模軟件工程師對(duì)源代碼文件進(jìn)行的編輯。 解決上述問(wèn)題需要從先前的編輯中提取意圖,然后利用它來(lái)生成后續(xù)編輯。我們開(kāi)發(fā)了幾個(gè)神經(jīng)網(wǎng)絡(luò),并利用合成數(shù)據(jù)來(lái)測(cè)試它們學(xué)習(xí)編輯模式的能力,而這需要很強(qiáng)的泛化能力。然后我們收集并在谷歌源代碼的大型數(shù)據(jù)集上訓(xùn)練了我們的模型,該源代碼包含來(lái)自數(shù)千 Python 開(kāi)發(fā)者的數(shù)百萬(wàn)次細(xì)粒度編輯。 從建模的角度來(lái)看,我們的主要結(jié)論是注意力和指針網(wǎng)絡(luò)組件的新組合提供了最好的整體性能和可擴(kuò)展性。而從應(yīng)用角度來(lái)看,我們的結(jié)果表明,開(kāi)發(fā)工具以學(xué)習(xí)預(yù)測(cè)未來(lái)的編輯是可行的。 模型方法 第一個(gè)要思考的問(wèn)題是我們?cè)撊绾伪碚骶庉嫶a的序列數(shù)據(jù)。我們定義了兩種數(shù)據(jù)格式,它們各有各的權(quán)衡。下圖 2(a) 所示為顯式格式,它將編輯序列以二維網(wǎng)格的形式表示為序列的序列,橫縱坐標(biāo)分別為兩種序列。這種格式的預(yù)測(cè)任務(wù)會(huì)根據(jù)前面 t-1 行的編輯序列預(yù)測(cè)第 t 個(gè)時(shí)間步的編輯位置與內(nèi)容。 圖 2:編輯序列的顯式和隱式表征,它們都將「BACA」轉(zhuǎn)換為「BABBCACC」,其中<S>和<E>分別為起始和終止符。 如上圖 2(b) 所示,隱式格式將初始狀態(tài)表示為一個(gè) Token 序列,并將其作為(position, content)對(duì)進(jìn)行編輯。 根據(jù)兩種數(shù)據(jù)表征格式,現(xiàn)在我們有基線顯式模型和基線隱式模型。其中基線顯式模型是一個(gè)兩階段的 LSTM 網(wǎng)絡(luò),有點(diǎn)類(lèi)似于層級(jí) RNN 模型。 在最簡(jiǎn)單的基線顯式模型中,第一階段的 LSTM 會(huì)并行地編碼每一個(gè)狀態(tài)序列,并產(chǎn)生隱藏狀態(tài);而第二階段的 LSTM 會(huì)將前面的隱藏狀態(tài)和已觀察到的編輯序列作為輸入,并產(chǎn)生解碼的隱藏狀態(tài)和輸出狀態(tài)。下圖 3(a) 有一個(gè)更形象的展示。 而基線隱式模型最自然的方式就是使用 Seq2Seq 框架,將初始狀態(tài)序列輸入到編碼器中,并期待解碼器輸出(position, content)對(duì)。 圖 3:(a):基線顯式模型;(b, c)隱式注意力模型。 除了基線模型,更強(qiáng)大的是隱式注意力模型,該模型能對(duì)隱式表征進(jìn)行操作,并能更好地捕捉到編輯內(nèi)容和編輯上下文之間的關(guān)系序列。隱式注意力模型的編碼器和解碼器在上圖 3(b, c) 中展示,其中編碼器會(huì)將初始狀態(tài)和所有已知編輯編碼為隱藏向量,解碼器會(huì)將其解碼為每一個(gè)編輯的位置、以及給定位置的編輯內(nèi)容。該模型的細(xì)節(jié)見(jiàn)原論文的附錄,它參考了 Transformer 的位置編碼與 Multi-head Attention(MHA)。 實(shí)驗(yàn) 實(shí)驗(yàn)的目標(biāo)是了解模型的能力和限制。兩個(gè)主要的因素是,模型能夠多準(zhǔn)確地識(shí)別編輯序列中的模式?它對(duì)大型數(shù)據(jù)的適應(yīng)效果如何? 表 1 中報(bào)告了能夠產(chǎn)生最佳開(kāi)發(fā)性能的步驟和超參數(shù)設(shè)置的測(cè)試性能。顯式模型和改進(jìn)的隱式模型幾乎可以解決所有任務(wù),甚至是那些涉及元字符和具有較長(zhǎng)替換序列的任務(wù)。 表 1:具有最佳開(kāi)發(fā)性能的步驟和超參數(shù)設(shè)置在合成數(shù)據(jù)集上的測(cè)試準(zhǔn)確率。準(zhǔn)確率在.5% 以?xún)?nèi)的結(jié)果用粗體顯示。POMP:Position-Oracle Match-Pattern;E:顯式基線模型;IR:隱式基線模型;IA:改進(jìn)的隱式模型。 如圖 4 所示,顯式模型始終比隱式模型要昂貴,而且隨著數(shù)據(jù)的增加,這個(gè)差距也在拉大。長(zhǎng)度為 100 的插入序列比真實(shí)數(shù)據(jù)集中的序列小十倍,但在運(yùn)行時(shí)方面已經(jīng)存在一個(gè)數(shù)量級(jí)的差異。 圖 4:(a)-(c):具有不同插入數(shù)量(10,50,100)的 n 元問(wèn)題的訓(xùn)練過(guò)程中處理序列所需的時(shí)間。注意,每個(gè)圖的 y 軸刻度不同。(d):把預(yù)測(cè)限制到模型置信度最高時(shí),模型在真實(shí)數(shù)據(jù)集上的 Token 級(jí)別準(zhǔn)確率。 |
|