• <fieldset id="82iqi"></fieldset>
    <tfoot id="82iqi"><input id="82iqi"></input></tfoot>
  • 
    <abbr id="82iqi"></abbr><strike id="82iqi"></strike>
  • 滅霸來了?微軟發布BugLab:無需標注,GAN掉bug

    【導讀】程序員的死對頭就是各種bug!最近微軟在NeurIPS 2021上帶來了一個好消息,研究人員設計了一個類似GAN的網絡,通過選擇器和檢測器來互相寫和改bug,而且還不需要標注數據!

    常言道,「一杯茶,一包煙,一個bug改一天」。

    寫代碼是軟件工程師們每天的工作,但當你辛辛苦苦寫了一大堆代碼,卻發現無法運行的時候,內心一定是崩潰的。

    找bug不僅費時費力,最關鍵的是還經常找不著,并且有時候改了一個bug又會引入更多bug,子子孫孫無窮盡也。

    簡直就是找bug找到吐血。

    隨著AI技術的發展,各大公司開發的代碼助手如GitHub Copilot等也能幫你少寫一些有bug的代碼。

    但這還遠遠不夠!

    深度學習要是能幫我把代碼里的bug也給修了,我上班只負責摸魚,豈不是美滋滋!

    微軟在NeurIPS 2021上還真發了一篇這樣的論文,其中提出了一個新的深度學習模型BugLab,并通過自監督的學習方法,可以在不借助任何標注數據的情況下檢測和修復代碼中的bug,堪稱程序員的救世主!

    https://arxiv.org/pdf/2105.12787.pdf

    修bug難在哪?

    所謂的bug,就是代碼的實際運行和自己的預期不符。

    該運行的沒運行,該輸出a,結果卻輸出個b,這種代碼故意找茬的行為都屬于bug。

    所以想要找到并修復代碼中的bug,不僅需要對代碼的結構進行推理,還需要理解軟件開發者在代碼注釋、變量名稱等方面留下的模糊的自然語言提示。

    例如一段程序的意圖是,如果名字的長度超過了22個字符,那就只截取前22個。但原始代碼中錯誤地把大于號寫成了小于號,導致條件判斷錯誤,程序運行結果和預期不符。

    這種小錯誤在寫代碼的過程也是太常見了,稍不注意就會把條件弄反。

    還有一種bug就是使用了錯誤的變量,例如下面的例子里面write和read弄錯了,就會導致條件判斷失敗,這種bug的修復只有在理解了變量名的意義后才能修復,傳統的修復手段對此是無能為力。

    這種錯誤看起來很簡單,但往往盯著看代碼的時候卻很難發現,屬于一改改一天的那種。

    并且每個程序員有自己的編程風格,比如不同的命名、縮進、判斷以及重構的方式,想讓代碼來給自己找bug,一個字,難!

    對于微軟來說,好在有GitHub代碼庫可以用來訓練模型。但問題來了,GitHub上帶bug的代碼有那么多嗎?有bug誰還commit啊?就算能找到代碼,也沒人來標注數據啊!

    微軟提出的BugLab使用了兩個相互競爭的模型,通過玩躲貓貓(hide and seek)游戲來學習,主要的靈感來源就是生成對抗網絡(GAN)。

    由于有大量的代碼實際上都是沒有bug的,所以需要設計一個bug selector來決定是否修改正確的代碼來引入一個bug,以及以何種方式引入bug(例如把減號改為加號等)。當選擇器確定了bug的類別后,就通過編輯源代碼的方式引入bug。

    另一個用來對抗的是bug detector,用來判斷一段代碼是否存在bug,如果存在的話,它需要定位并修復這個bug。

    選擇器和檢測器都能夠在沒有標記數據的情況下共同訓練,也就是說整個訓練過程都是以自監督的方式進行,并成功在數百萬個代碼片段上訓練。

    selector負責寫bug,并把它藏(hide)起來,而detector負責找bug,并修復,整個過程就像躲貓貓一樣。

    隨著訓練的進行,selector寫bug越來越熟練,而detector也能夠應對更復雜的bug。

    整個過程與GAN的訓練大體相似,但目的卻大不相同。GAN的目的是獲得一個更好的生成器來修改圖片,但BugLab的目的是找到一個更好的檢測器(GAN中的判別器)。

    并且整個訓練也可以看作是一個teacher-student模型,選擇器教會檢測器如何定位并修復bug。

    為開源社區修bug!

    雖然從理論上來說,使用這種hide and seek的方式可以訓練更復雜的selector來生成更多樣的bug,從而detector的修bug能力也會更強。

    但以目前的AI發展水平來說,還無法教會selector寫更難的bug。

    所以研究人員表示,我們需要集中精力關注那些更經常犯的錯誤,包括不正確的比較符,或者不正確的布爾運算符,錯誤的變量名引用等等其他一些簡單的bug。并且為了簡單起見,實驗中只針對python代碼進行研究訓練。

    雖然這些解釋聽起來都像是借口。

    為了衡量模型的性能,研究人員從Python包索引中手動注釋了一個小型bug數據集,和其他替代方案(例如隨機插入bug的selector)相比,使用hide and seek方法訓練的模型性能最多可以提高30%

    并且實驗表明大約26%的bug都可以被發現并自動修復。在檢測器發現的bug中,有19個在現實生活中的開源GitHub代碼中都屬于是未知的bug。

    但模型也會對正確的代碼報告存在bug,所以這個模型在離實際部署上線還有一段距離。

    如果更深入地研究selector和detector模型的話,就會引出那個老生常談的問題:深度學習模型到底有沒有,又怎么樣去「理解」一段代碼的作用?

    過去的研究表明,將代碼表示為一個token序列就能夠產生次優的(suboptimal)效果。

    但如果想要利用代碼中的結構,例如語法、數據、控制流等等,就需要將代碼中的語法節點、表達式、標識符、符號等等都表示為一個圖上的節點,并用邊來表示節點間的關系。

    有了圖以后就可以使用神經網絡來訓練detector和selector了。研究人員使用圖神經網絡(GNN)和relational transformer都進行了實驗,結果發現GNN總體上優于relational transformer。

    如何讓AI幫助人類來寫代碼和改bug一直都是人工智能研究中的一項基礎任務,任務過程中AI模型需要理解人類對程序代碼、變量名稱和注釋提供的上下文線索來理解代碼的意圖。

    雖然BugLab離真正解放程序員改bug還很遙遠,但距離我們消滅bug總算又向前走了一步!

    參考資料:

    https://www.microsoft.com/en-us/research/blog/finding-and-fixing-bugs-with-deep-learning/

    本文來自微信公眾號“新智元”(ID:AI_era),編輯:LRS,36氪經授權發布。