資源 | 自然語言語義代碼搜索之路
選自
GithubEngineering
作
者: hamelsmu、hohsiangwu
機器之心編譯
參與
:Geek AI、張倩
在本文中,作者向讀者分享了如何利用深度學習技術促進自然語言語義搜索的發展。此外,他們還分享了一個開源的示例,以及復現結果所需的代碼和數據。
研究動機
目前,在 GitHub 上搜索代碼還局限於關鍵字搜索。這建立在假設用戶了解句法,或者可以預測出他們要找的代碼周圍的注釋中可能有什麼關鍵字的基礎上。我們的機器學習科學家一直在研究能夠對代碼進行語義搜索(https://en.wikipedia.org/wiki/Semantic_search)的方法。
如果讀者想要充分了解語義搜索的概念,可以想一想下面的搜索查詢「ping REST api and return results」
請注意,即使在搜索查詢和文本之間並不存在共有的關鍵字(在代碼和注釋中並沒有找到「Ping」、「REST」或「api」字樣),我們的語義搜索演算法也能返回有意義的結果!通過語義搜索增強關鍵字搜索是意義深遠的。例如,這種能力可以加快新的軟體工程師上手軟體項目的過程,並且普遍提高代碼被發現的可能性。
在本文中,我們想向讀者分享我們是如何利用深度學習技術在自然語言語義搜索領域取得進步的。我們也分享了一個開源的示例,以及復現這些結果所需的代碼和數據。
引言
目前,對實體的表示學習是 GitHub 上正在進行的機器學習研究的關鍵領域之一,這裡的實體包括代碼倉庫、代碼、問題單、文件和用戶。我們通過學習與文本共享一個向量空間的代碼的表徵,在促進語義搜索方面取得了顯著的進步。我們不妨看一看下面的示意圖中的例子:
在上面的例子中,Text 2(藍色)是對代碼的合理描述,而 Text1(紅色)則與代碼完全無關。我們的目標是讓學習到的描述相同概念的文本、代碼對的表徵比較接近。而不相關的文本、代碼對的表徵的距離較遠。通過在相同的向量空間中表徵代碼和文本,我們可以將用戶的搜索查詢向量化,並查找最接近的表示代碼的向量。下面是我們目前用來完成這項任務的方法的四個步驟:
1. 學習代碼的表徵
為了學習代碼的表徵,我們訓練了一個序列到序列(Seq2Seq)模型,它能夠學著對代碼進行總結。在 Python 環境下實現這一目的一種方法是提供(代碼,文檔字元串)對,其中文檔字元串是模型試圖預測的目標變數。對我們來說,引入對特定領域(如基於樹結構的 LSTM、門控圖網路以及有語法意識的分詞處理)的優化是一個熱點的研究領域。下圖展示了代碼總結模型的工作過程。在這個例子中,有兩個 python 函數作為輸入,在這兩種情況下,模型都將合理的代碼總結作為輸出:
應當指出,在上面的例子中,模型通過使用整段代碼塊而不僅僅是函數名來生成對代碼的總結。
構建代碼總結器本身是一個非常激動人心的項目,然而,我們還可以利用這個模型的編碼器作為代碼的通用特徵提取器。從這個模型中提取出編碼器後,我們可以對它進行調優,從而建立代碼到自然語言的向量空間的映射。
我們可以客觀地使用 BLEU 得分來評估這個模型。目前,我們已經能夠使用 fairseq-py 代碼庫(https://github.com/pytorch/fairseq)構建 Seq2Seq 模型,在一個 python 代碼驗證集上獲得 13.5 的 BLEU 得分。
2. 學習短文本的表徵
除了學習代碼的表徵以外,我們還需要為短文本(例如在 Python 文檔字元串中找到的句子)找到合適的表徵。最初,我們嘗試使用通用的句子編碼器,這是一個預訓練好的文本編碼器,可以從 TensorFlow Hub(https://www.tensorflow.org/hub/modules/google/universal-sentence-encoder/1)上獲取。儘管目前嵌入技術的性能已經很好,我們發現學習針對於軟體開發的辭彙和語義的嵌入仍然是有益的。目前正在進行一個研究領域旨在評估用於訓練我們模型的不同特定領域的語料庫,其範圍涵蓋從 GitHub 問題單到第三方數據集的諸多領域。
為了學習短文本的表徵,我們利用 fast.ai 庫訓練了一個神經語言模型。這個庫讓我們可以很容易使用像 AWD LSTM 這樣最先進的架構,以及類似帶隨機重啟的周期性學習率(cyclical learning rates with random restarts)這樣的技術。我們使用
《Universal Language Model Fine-tuning for Text Classification》中提出的級聯池化(concat pooling)技術通過總結隱藏狀態從該模型中抽取出對短文本的表徵。
這項工作一個最具挑戰性的方面是評估這些嵌入的質量。我們目前正在構建各種類似於《SentEval: evaluation toolkit for sentence embeddings》(https://github.com/facebookresearch/SentEval)中概述 (https://github.com/facebookresearch/SentEval) 的下游監督任務,它們將幫助我們客觀地評估這些嵌入的質量。與此同時,我們還通過手動檢驗相似短文本之間的相似程度來檢查我們的嵌入。下面的截圖展示了一些示例,我們在這裡根據用戶提供的短文本和向量化的文檔字元串間的相似程度進行搜索。
3. 將代碼表征映射到具有相同向量空間的文本上
接下來,我們將把從代碼總結模型(第 1 部分)中學到的代碼表征映射到文本的向量空間。我們通過對該模型的編碼器進行調優來實現這一點。這個模型的輸入仍然是代碼塊,然而模型的目標變數現在變成了文檔字元串的向量化版本。這些文檔字元串使用上一節介紹的方法進行了向量化處理。
具體而言,我們使用餘弦近似損失(即預測值與真實標籤的餘弦距離平均值的相反數)進行多維回歸,將編碼器的隱藏狀態帶入與文本相同的向量空間。
我們正在積極研究直接學習代碼和自然語言的聯合向量空間的方法,我們的研究借鑒了《Efficient Natural Language Response Suggestion for Smart Reply》中介紹的一些思路。
4. 創建一個語義搜索系統
最後,在成功地創建了一個可以將代碼向量化到與文本相同的向量空間的模型之後,我們可以創建一個語義搜索機制。最簡單的形式是,我們可以在一個資料庫中存儲所有代碼的向量化版本,對向量化的搜索查詢執行最近鄰查找。
我們研究的另一個熱點領域是確定用語義結果增強現有關鍵字搜索的最佳方法,以及如何引入上下文語境和相關性等額外的信息。此外,我們正在積極探索如何評估搜索結果的質量,使我們能夠在這個問題上快速迭代開發。我們未來將在博文中繼續討論這些話題。
總結
下面的示意圖總結了我們當前的語義搜索工作流程中所有的步驟:
我們正在探索如何改進這種方法的幾乎每一個組成部分,包括數據準備、模型架構、評估過程以及整體的系統設計。本文所介紹的只是一個基礎的最小的示例。
開源示例
我們的開源端到端教程(https://towardsdatascience.com/semantic-code-search-3cd6d244a39c)包含了本文中概述的方法的詳細演示過程,以及你可以用來複現結果的代碼和數據。(https://towardsdatascience.com/semantic-code-search-3cd6d244a39c)
該開源示例(進行了一些修改)也被用作 kubeflow 項目的教程,具體實現請參閱:https://github.com/kubeflow/examples/tree/master/code_search
局限性及可能的用例場景
我們認為,相對於通常使用的「如何...」這種形式的查詢,語義代碼搜索將最有益於針對諸如代碼倉庫、組織或用戶等特定實體的代碼搜索。在我們最近發布的實驗網站(https://blog.github.com/2018-09-18-introducing-experiments-an-ongoing-research-effort-from-github/)上,語義代碼搜索的實時演示(https://blog.github.com/2018-09-18-introducing-experiments-an-ongoing-research-effort-from-github/)不允許用戶針對代碼倉庫進行特定的搜索。實際上,這種演示只是為了分享可能得到的效果,並且只搜索一組受限的、靜態的 python 代碼集。
此外,與所有的機器學習技術一樣,該方法的效果也受限於使用的訓練數據。例如,用於訓練這些模型的數據是(代碼,文檔字元串)對。因此,與文檔字元串最相似的搜索查詢成功的幾率最大。另一方面,如果查詢與文檔字元串差別很大或者含有支撐數據很少的概念,該模型可能不會產生很好的搜索結果。因此,這對於我們進行實時演示是一個挑戰。儘管如此,我們初步的結果表明,這是一個碩果累累的研究領域,我們很高興與你們分享。
語義代碼搜索還有更多的用例場景。例如,我們可以對本文介紹的想法進行擴展,允許用戶使用他們選擇的自然語言(法語、普通話、阿拉伯語等)同時對用許多不同的編程語言編寫的代碼進行搜索。
原文鏈接:https://githubengineering.com/towards-natural-language-semantic-code-search/
2018AIIA人工智慧開發者大會將於2018年10月15日到16日在蘇州國際博覽中心舉辦。點擊閱讀原文鏈接報名。
※百鍊智能姚從磊:在互聯網公開信息中「大海撈針」,為一億機構人物建立「全息檔案」
※華為麒麟980:雙核NPU,全球首款7nm手機晶元正式發布
TAG:機器之心 |