雷锋网按:本文为AI研习社编译的技术博客,原标题 How To Create Natural Language Semantic Search For Arbitrary Objects With Deep Learning,作者为 Hamel Husain 。
翻译 | 陈涛 赵朋飞 汪星宇 校对 | 刘娇 整理 | MY
本文展示了一个端到端的实例,说明如何构建一个可以语义化搜索对象的系统。项目作者是Hamel Husain和 Ho-Hsiang Wu 。
Hubot 的图片
项目的动机:
不可否认的是,现代的搜索引擎非常强大:你可以随时从互联网上搜集到知识信息。美中不足的是,它还不是万能的。在许多情况下,搜索只是被当做严格的关键字搜索,亦或者当对象不是文本时,搜索便无用武之地。此外,严格的关键字搜索不允许用户进行语义化搜索,这意味着无法查询到相关信息。
今天,我们分享一个可复现的最小可行性产品,以此来说明如何对任意对象进行 [语义搜索]!具体来说,我们将向您演示如何创建一个可对 python 代码进行语义化搜索的系统——但该方法同样可以被推广到搜索其他实体(比如图片或者声音片段)
为什么语义搜索如此何令人兴奋?考虑下下文的例子。
对 python 代码进行语义化搜索。*请参阅后文的免责申明
图中提交的搜索查询是「Ping REST api and return results」。然而,搜索能够返回合理的结果,即使该结果的代码和注释中不包含单词 Ping、REST 或 api。
这彰显了语义搜索的强大之处:除了通过关键字,我们还可以通过意思搜索内容,从而最大限度地提高了用户找到所需信息的机会。语义搜索具有重要意义——比如,此搜索过程将允许开发人员在仓库中搜索代码,即使他们并不熟悉代码的相关语法,亦或是没能输入正确的关键字。更重要的是,你可以将此方法推广到其他对象的搜索,诸如图片、音频以及其他我们尚未想到的内容。
如果这还不够令人兴奋,那么现在就演示一下当你读完本教程后能够构建的系统:
有时候,当我无法建立一个漂亮网站时,我会使用 Jupyter notebooks 及其自定义魔术功能来创建演示。这是一种交互式演示工作的快速方法。
直观了解构建共享向量空间的过程
在深入了解技术细节之前,最好还是先对如何实现语义搜索有一个直观了解。核心思想是将搜索文本和我们想要搜索的对象(代码)表示在同一个共享向量空间中,如下所示:
例子:文本 2 和代码应由类似的向量所表示,因为它们直接相关
目标是将代码映射到自然语言的向量空间中,经过余弦相似度的距离度量后,描述相同概念的(文本,代码)组中的向量距离更近,而无关的(文本,代码)组中的向量离得更远。
有许多方法可以实现这一目标,然而我们将演示使用预训练模型的方法。该模型从代码中提取特征,并对此模型进行微调,从而将潜在代码特征映射到自然语言的向量空间中。需要注意的是:我们在本教程中交替地使用术语向量和嵌入。
先修知识
在阅读本教程之前,我们建议你先熟悉以下内容:
序列到序列模型:复习前一个教程中的知识会很有帮助。
仔细阅读这篇论文并充分理解其中提出的方法。我们在本文中使用了相似的概念。
概述:
本教程将分为 5 个具体步骤。这些步骤如下图所示,可以作为你阅读教程时的一个有用参考。当你完成教程后,回看此图将有助于你进一步了解所有步骤是如何组合在一起的。
本教程的思维导图。高清版本在这里
1-5 的每个步骤对应于这里的 Jupyter notebook。我们将在后文详细讨论每个步骤。
第一部分——获取和解析数据
第一部分笔记
谷歌公司收集了开源社区 GitHub 中的数据,并将其存储于BigQuery中。这是一个很好的公开数据集,适用于各种有趣的数据科学项目,也包括本项目!当你注册了 Google Cloud 账号后,你将会得到 300 美元,这足以查询到此次练习所需要的数据。获取数据非常方便,因为你可以使用 SQL 查询语句来选择要寻找的文件类型以及其他关于仓库的元数据,例如提交数和打星数等。
笔记中介绍了获取数据的步骤。幸运的是,一些谷歌 Kubeflow 团队中的牛人已经完成了这些步骤,并且贴心地存放好了此次练习需要用到的数据,详见其中的信息。
搜集到数据后,我们需要将这些文件解析为(代码,文档字符串)组形式的数据。对于本教程,一个代码单元可以是顶级函数可以是方法。我们希望收集这些数据组作为模型的训练数据,该模型能对代码进行概括(具体我们过会再说)。我们还想删除代码中的所有注释,只保留代码本身。这似乎是一项艰巨的任务。但是在Python 的标准库中有 ast 库,其可用于提取函数、方法和文档字符串。我们可以通过先将代码转换为抽象语法树,然后使用Astor包将其转回代码,从而将代码中的注释删除。本教程不涉及抽象语法书及其相关工具的工作原理,但这些都是非常有趣的主题。
关于此代码使用的场景,详见于笔记
为了给建模准备数据,我们将数据分为训练集、验证集和测试集。我们还保存了原始文件(我们将其命名为 lineage),以便记录每个(代码,文档字符串)组的来源。最后,我们对不包含文档字符串的代码应用相同的转换,并分开保存,因为我们也希望能够搜索此类代码。
第二部分 :使用 Seq2Seq 模型构建代码归纳器
第 2 部分笔记
从概念上讲,我们可以建立一个 Seq2Seq 模型来归纳代码,与我们之前介绍的GitHub issue summarizer完全相同——我们使用 python 代码代替原来的 issues 数据,并且使用 docstring 来代替 issue 标题。
然而,与 GitHub 的 issue 文本不同的是,代码不属于自然语言。为了充分利用代码中的信息,我们可以引入特定领域的优化方法,如tree-based LSTMs和语法感知标记 (syntax-aware tokenization)。简单起见,在本教程中我们将代码当作自然语言进行处理(最终获得了合理的结果)。
......
想要继续阅读,请移步至我们的AI研习社社区:https://club.leiphone.com/page/TextTranslation/707
领取专属 10元无门槛券
私享最新 技术干货