02.26 程序增強:通過眾包進行程序合成

程序增強:通過眾包進行程序合成

1.引用

Cochran R A, D'Antoni L, Livshits B, et al. Program boosting: Program synthesis via crowd-sourcing[C].Proceedings of the 42nd Annual ACM SIGPLAN-SIGACT Symposium on Principles of Programming Languages. 2015: 677-688.

2.摘要

在本文中,我們研究了一種基於眾包的程序合成方法。在眾包的幫助下,我們力求捕捉“眾人的智慧”,以找到解決固有棘手編程任務的好的(即使不是完美的)解決方案,這些任務缺乏易於形式化的規範,甚至連專家級開發人員都難以理解。

我們將這種方法稱為“程序增強”,它將為開發人員遇到的一個棘手編程問題眾包一些不夠完善的解決方法,然後將這些程序融合在一起以提高其正確性。

我們在 CROWDBOOST 系統中實現了這種方法,並在我們的實驗中展示了一些有趣並且且有價值的任務(例如 URL 或電子郵件地址的正則表達式)可以有效地眾包。我們證明,將眾包結果混合在一起可以協調一致地對程序進行增強,所產生的程序要好於任何初始的程序。我們對 465 個程序對進行實驗,結果顯示出一致的準確率提升,這證明了可以以相對低的成本來進行程序增強。

3.技術介紹

3.1 眾包背景

在過去的幾年中,我們看到在一些非技術性任務(識別圖片中是否有貓,重新格式化文本數據,糾正句子中的語法)和技術性任務(根據要求提供插圖或圖形設計,撰寫產品的簡短說明)中使用眾包的情況有所增加。

Amazon 的 Mechanical Turk(通常縮寫為 asmturk)就是一個很好的非專業工作眾包網站例子;oDeskis 是另一個廣泛使用的平臺,該平臺主要用於技術性的任務。這兩個平臺均可用於眾包編程任務,儘管兩者都不是專門用於此目的。注意,可以將 StackOverflow 和其他類似的編程幫助站點視為一種非正式的眾包類型。確實,這些站點非常擅長提供解決棘手的編程問題的方法,以至於某些開發人員在編寫代碼時經常瀏覽 StackOverflow。

Bountify(http://bountify.co)允許人們發佈程序任務,其中一些涉及從頭開始編寫新代碼(編寫JavaScript函數以生成給定顏色的多種陰影),而其他則涉及修復現有代碼中的錯誤(為什麼 我的 HTML 表格看起來不符合我的期望,我應該如何調整 CSS 使其看起來正確?)。這些編程任務通常不會太耗時;一個典型的任務大約支付 5 美元。回覆是公開發表的,這使得其他開發者可以從中進行學習。最後,發佈者決定將獎金授予哪個開發者。

請注意,交互式眾包並不是特定編程任務的唯一代碼源。確實,人們可以輕鬆地使用代碼搜索引擎來從開源項目中尋找。使用專用代碼引擎搜索諸如 urlregex 之類的術語將生成一些可能的正則表達式用來過濾 URL。

3.2 程序增強

程序增強:通過眾包進行程序合成

圖 2 顯示了我們系統的體系結構。我們從一個文本測試任務規範和(正負)示例的初始訓練集(也稱為“黃金集”)開始。為了將指定任務的解決方案眾包,我們利用了兩個人群:由開發人員組成的熟練人群和由常規計算機用戶組成的未經訓練的人群。前者包含通過諸如 Bountify 之類的服務進行僱傭的開發人員,他們通常精通一種或多種語言(如 Java 和 C ++),而後者則由在 Mechanical Turk 上找到的常規計算機用戶組成。

方法:為簡單起見,本文將重點放在二分類任務上,即(1)使用單一輸入的程序;(2)產生布爾值(是/否)輸出;(3)對於任何輸入,非專業的計算機用戶都可以決定其答案應該是是或否。 此類任務的示例包括確定輸入是否為格式正確的電話號碼的程序,或確定輸入圖像是否包含長頸鹿的程序。

​ 最後一個要求是改善程序的必要條件,即在未經訓練的人群的幫助下確定棘手案例的正確結果。我們的觀察是,儘管未經培訓的人群不會幫助我們程序,但他們將能夠識別正確或不正確的程序行為。通過類推的方式,雖然外行人可能無法編寫識別圖像中是否存在長頸鹿的計算機視覺程序,但人類非常擅長識別給定圖片中是否包含長頸鹿。這種兩人群的方法有助於我們詢問未經培訓人群來消歧,從而既可以收集候選程序,又可以系統地擴展輸入空間。

雖然存在其他合適的標準,但在這篇論文中,我們關注的是提高合成程序在正反面例子上的準確性。

3.3 通過遺傳編程進行程序增強

為了實現以上示例中所提出的方法,一種常見的技術是遺傳編程,它是遺傳算法的一種特殊形式。遺傳編程是程序領域中的一種搜索技術,其目的是在一系列迭代中提高程序的適用性。成功的遺傳編程方法取決於實現兩種操作:交叉和突變。

給定一組初始的眾包程序,該程序增強算法需要進行多次迭代。在我們的電話號碼示例的上下文中,這些初始程序可以是兩個初始正則表達式。在每一代,它都將交叉和變異操作結合在一起。(在我們的示例中,這可能會將正則表達式的各個部分調整為像-和.這樣的電話號碼分隔符)作為一種改進形式,之後我們將新示例添加到訓練集中。例如,在我們的正則表達式實現中,優化的目標是通過將非顯而易見的情況例如 212.555−1212or1−)212)555−1212 作為有效或無效電話號碼添加到不斷髮展的進化訓練集中來達到 100%的狀態覆蓋率。最後,選擇適應性最高的候選者繼續下一代。

3.4 程序增強算法

圖 3 用偽代碼顯示了我們的程序增強算法。Σ 為所有程序集,Φ 為所有輸入集。在每次迭代中,我們更新當前考慮的程序和當前的示例.

程序增強:通過眾包進行程序合成

請注意,該算法本質上是迭代的:增強收益的過程類似於通常執行遺傳編程的方式。總體目標是在 Σ 中找到最適合的程序。每代產生一個新的 Φ 樣本併發送給人群以取得共識。

​ 稍後我們將展示如何使用 SFA 實現與正則表達式的函數 β,μ,δ 和 η 相對應的運算。請注意,在實踐中,為了更快地完成代碼,我們通常將迭代次數限制在一個設置的限制(例如 10)中。

我們的實現受益於並行運算。在特殊情況下,我們使算法的第 6 行和第 12 行的兩個循環並行進行。儘管我們在執行過程中需要小心謹慎,以避免出現共享狀態,但這種相對簡單的更改最終會能夠幾乎完全利用具有 8 或 16 個內核的計算機。

1 有限符號自動機:儘管正則表達式簡潔明瞭,相對容易理解,但對代數來說卻不容易操縱。特別是,沒有直接的算法可以互補或相交。因此,我們選擇了有限自動機。經典確定性有限自動機(DFA)具有許多閉包性質和友好的複雜性,但是每個 DFA 轉換隻能攜帶一個字符,從而導致 DFA 中的轉換數量與字母的大小成比例。當字母表很大(UTF16 具有 2 的 16 次方個元素)時,這種表示不切實際。

符號有限自動機(SFA)擴展了帶有符號字母的經典自動機。在 SFA 中,每個邊都標記有謂詞,而不是單個輸入字符,這使自動機可以簡潔地表示多個具體轉換。例如,在圖 7 的 SFA 中,從狀態 10 到狀態 11 的轉換用謂詞[^#-\\ /?\\ s]標記。由於 UTF16 集的大小,經典自動機中的這個轉換將由數千個具體轉換來表示。

2 適應度計算 :作為用於程序增強的遺傳程序設計方法的一部分,我們需要能夠評估特定程序的適用性。對於正則表達式,這相當於在訓練集上計算精度。適應度計算過程本身可能會非常耗時。原因是當我們考慮成千上萬的 SFA 和數百個例子時,運行一些大的例子,並計算有多少被 SFA 正確接受是一個擴展性很差的過程。相反,我們構造 SFA P 和 N,分別表示所有肯定組和所有否定組的語言。對於任何 SFA A,我們計算交集的基數(參見圖 4 中的虛線區域),兩者都可以使用 SFA 操作來快速計算。然後可以將精確度計算限制在範圍為 0 到 1。我們的改進技術固有的挑戰是我們進化的示例集可能會與最初的黃金集大相徑庭。儘管不完美,但我們仍然希望將黃金集視為更可靠的真理來源,為此,我們使用加權為整體適應度計算中的黃金集賦予更高的權重。在我們的實驗評估中,如果將黃金:進化示例權重設置為 9:1,我們將獲得可靠的良好結果。

程序增強:通過眾包進行程序合成

3 交叉 交叉操作是將兩個 SFA 通過混合他們的行為,交叉成單個 SFA。這個操作的說明示例如圖 6 所示。給定兩個 SFA A 和 B,交叉算法通過重定向兩個轉換(一個從 A 到 B,一個從 B 到 A)來創建新的 SFA。此類操作的目標是使用包含 A 的 B 的組件。

程序增強:通過眾包進行程序合成

程序增強:通過眾包進行程序合成

4 變異 在其經典定義中,變異算子會更改輸入程序的一個或多個值,併產生一個變異的值。SFA 的值要更改的太多(每個轉換都可以攜帶 2 的 16 次方個元素),“盲目”方法會產生太多變異。相反,我們考慮使用引導方法,其中將變異作為 SFA A 的輸入和反例 s(s 是一個正例子但它不屬於 L(A)或者 s 是一個反例但它屬於 L(A))。使用這些額外的信息,我們僅以會導致正確分類的方式進行變異。這種操作背後的直覺是執行最小的語法改變以正確分類反例。

5 示例生成 生成一個字符串通常不足以描述 SFA 的語言。在生成示例中,我們遵循下列不變式:為了生成 SFA 的全覆蓋,我們需要進行下一個迭代。迭代算法示例如圖 8 所示;給定包含 k 個狀態的 SFA,它最多迭代 k 輪終止。該算法只是在每次迭代中生成一個新的字符串,強制覆蓋至少一個尚未覆蓋的狀態。

程序增強:通過眾包進行程序合成

4.本文主要貢獻

本文提出了一種新穎的眾包方法來進行程序合成,稱為程序增強。我們主要關注即使是最熟練的開發人員存在困難的編程任務。我們的見解是,可以將群眾的智慧集中到這些艱鉅的任務上。在本文中,我們展示瞭如何使用兩個人群:一群熟練的開發人員和一群未經培訓的計算機工作者來成功地為涉及擬定正則表達式的複雜任務生成解決方案。

我們已經在名為 CROWDBOOST 的工具中實現了程序增強,並進行了測試。在四個複雜的任務上,我們從 Bountify 和其他幾個來源眾包了 33 個正則表達式,並對其進行成對增強。我們發現我們的程序增強技術是穩定的:當在 465 對眾包程序上進行測試時,它產生了一致性的精確性增強。即使是從合格的開發人員眾包而來的高質量初始程序開始合成,我們也始終如一地能夠提高準確率,平均達到 16.25%。

致謝

國家重點研發計劃課題:基於協同編程現場的智能實時質量提升方法與技術(2018YFB1003901)和國家自然科學基金項目:基於可理解信息融合的人機協同移動應用測試研究(61802171)

本文由南京大學軟件學院 2020 級碩士王一博轉述


分享到:


相關文章: