前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Android Smart Linkify 支持机器学习

Android Smart Linkify 支持机器学习

作者头像
Android 开发者
发布2018-08-28 15:31:00
9440
发布2018-08-28 15:31:00
举报
文章被收录于专栏:Android 开发者Android 开发者

文 / Lukas Zilka,软件工程师,谷歌人工智能,苏黎世

上半周,我们发布了 Android 9 Pie,这是 Android 的最新版本,它的机器学习应用使您的手机更简单易用。 Android 9 中有一项功能是 Smart Linkify,这是一种新的 API,可在文本中检测到某些类型的实体时添加可点击链接。 这个功能很有用,例如,当您从朋友的消息传递 app 中收到一个地址,想要在地图上查找时,如果使用 Smart Linkify-annotated 文本,它就变得容易多了!

Smart Linkify 是现有 Android Linkify API 的最新版本。 它采用小型前馈神经网络(每种语言 500kB),低延迟(谷歌 Pixel 手机上不到 20 毫秒)和小推理代码(250kB),并采用与智能文本选择相同的机器学习技术(作为 Android Oreo 的一部分发布),现在也能创建链接。

在 Android 中,Smart Linkify 作为开源文本分类 API 推出(作为生成链接的方法)。 使用 TensorFlow 训练模型并将其导出到由 TensorFlow Lite 和 FlatBuffers 支持的自定义推理库。 这些模型的 C ++ 推理库在此处作为 Android 开源框架的一部分提供,并在每个文本选择和 Smart Linkify API calls 上运行。

寻找对象

在文本中查找电话号码和邮寄地址是一个难题。 不仅是因为人们五花八门的编写方式,而且各类对象的呈现方式通常也很模糊(例如:“确认号码:857-555-3556” 不是电话号码,即便它呈现了与电话号码类似的形格式)。

为了寻求解决方案,我们设计了一种推理算法,其核心是两个小的前馈神经网络。 该算法足以执行除地址和电话号码外的各种实体对象的程序分块。

总的来说,该系统架构如下:给定的输入文本首先被分成单词(基于空格分离),然后生成所有可能的限定最大长度的单词子序列(在我们的示例中为 15 个单词),并且对于每个候选单词,打分神经网络根据它是否代表有效对象来分配一个值(介于 0 和 1 之间):

对于给定的文本字符串,第一个网络为非实体对象分配低分,为正确选择了整个电话号码的候选单词分配高分 接下来,将重叠的生成对象删除,促成较高得分者与较低得分者来一决高下。 现在,我们有一组对象,但仍然不知道它们的类型到底是什么。所以现在第二神经网络将对象的类型分类,要么是电话号码,地址,要么在某些情况下将之分类成非实体对象。

在我们的示例中,唯一没有冲突的对象是 “并且明天请打电话给 857 555 3556。”(“857 555 3556” 被归类为电话号码),“并且明天打电话给 857 555 3556。”(“并且” 被归类为非实体对象)。我们可以轻松地在屏幕上显示的文本中为它们加上下划线,并在点击时运行正确的应用程序。

文字特征

目前为止,我们已经对 Smart Linkify 在一串文本中定位和分类实体对象的方式进行了综述。 在这里,我们还将详细介绍如何处理文本并将其提供给网络。

假设在输入文本中的实体对象候选者,网络的任务是确定该实体对象是否有效,然后对其进行分类。 为此,网络需要知道实体对象周围的上下文(除了实体本身的文本字符串)。 在机器学习中,通过将这些部分表现为独立的特征来完成。 实际上,输入文本被分成若干部分,分别馈送到网络:

给定候选实体跨度,我们会提取:左边上下文:实体之前的五个单词,实体开始:实体的前三个单词,实体结束:实体的最后三个单词(如果碰到重叠,可以与前一个特征重复,或者没有那么多单词的话将直接填充),右上下文:实体后的五个单词,实体内容:实体内部的单词包和实体长度:实体的单词数量的大小。 然后将它们连接在一起并作为神经网络的输入馈送。 特征提取用单词操作,我们使用字符 n-gram 和大写特征将单个单词表示为适合作为神经网络输入的真实向量:

字符 N-grams。 并非使用标准单词嵌入技术来代表单词,而是为模型中的每个单词保留单独的向量,由于存储较大,对移动设备来说并不可行,因此我们使用散列字符嵌入。 这个技术将该单词表示为一定长度的所有字符子序列的集合。 使用长度为 1 到 5。这些字符串被额外散列并映射到固定数量的桶(有关该技术的更多详细信息,请参阅此处)。 最终模型仅存储每个散列桶的向量,而不是每个字/字符子序列,这样可以精简大小。 我们使用的散列符号的嵌入矩阵有 20,000 桶和 12 个维度。

二进制功能,指示单词是否以大写字母开头。 这对网络来说很重要,因为邮政地址中的大写是非常独特的,并且有助于网络区分。

培训数据集

我们想要很容易地训练网络,但是并没有明显的数据集来完成这项任务,因此我们提出了一种训练算法,可以从实际部分生成合成示例。 具体地说,我们从 Web(使用 Schema.org 注释)收集了地址,电话号码和命名实体(如产品,地点和公司名称)和其他随机单词的列表,并使用它们来合成神经网络的训练数据。 我们按原样获取实体对象并围绕它们生成随机文本上下文(来自 Web 上的随机单词列表)。 此外,我们在电话号码的负面培训数据中添加 “确认号码:” 或 “ ID:” 等短语,以教会网络在这些情况下禁止电话号码匹配。

使之有效运行

我们必须使用许多附加技术来培训网络并进行实际的移动部署:

将嵌入矩阵量化为 8 位。 我们发现,通过将嵌入矩阵值量化为 8 位整数,我们可以在不影响性能的情况下将模型的大小减小近4倍。

在选择和分类网络之间共享嵌入矩阵。 这可以在几乎毫发无伤的情况下使模型缩小 2 倍,改变实体之前/之后的上下文的大小。 在移动屏幕上,文本通常很短,没有足够的上下文,因此网络也需要在培训期间接触到这一点。

从分类网络的正面示例中创建人为的负面示例。 例如,对于正面示例:“今天给我打电话 857 555-3556”,标签为 “电话”,我们生成 “今天给我打电话 857 555-3556” 作为带有 “其他” 标签的反面示例。 这教导分类网络更精确地面对实体跨度。 如果不这样做,不管跨度如何,网络将只是一个检测器,用来检测输入中的某个地方是否有电话号码,仅此而已。

国际化很重要

我们使用的自动数据提取可以更轻松地训练特定语言的模型。 但是,使它们能够适用于所有语言是一项挑战,需要专家仔细检查语言的细微差别,并获得可接受的培训数据量。 我们发现,适应所有拉丁文脚本语言的那个模型运作良好(例如捷克语,波兰语,德语,英语),但对于中文,日文,韩文,泰文,阿拉伯文和俄文则需要单独的模型。 Smark Linkify 目前支持 16 种语言,但我们正在尝试支持更多语言的模型,考虑到移动模型的大小限制以及不在空格上分割单词的语言,这尤其具有挑战性。

下一步

虽然这篇文章中描述的技术能够快速准确地注释文本中的电话号码和邮政地址,但是对航班号,日期和时间或 IBAN 的识别,目前只能使用标准正则表达式这类更传统的技术来实现。 但是,我们正在研究创建日期和时间的 ML 模型,特别是用于识别消息传递上下文中普遍存在的非正式相对日期/时间规范,例如 “下周四” 或 “三周内”。

小型号和二进制大小以及低延迟对于移动部署非常重要。 我们开发的模型和代码是开源的,可作为 Android 框架的一部分。 我们相信该架构可以扩展到其他设备上的文本注释问题,我们期待在我们的开发人员社区看到更多新的用例!

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2018年08月22日,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 寻找对象
  • 文字特征
  • 培训数据集
  • 使之有效运行
  • 国际化很重要
  • 下一步
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档