深度学习文本对分类技术解析

Deep text-pair classification with Quora’s 2017 question dataset

Feb 13, 2017
13 minute read
Text Classification
Question Answering
Matthew Honnibal

某平台最近发布了其平台上的第一个数据集:一组包含 40 万个问题对的数据集,并标注了这些问题是否请求相同的信息。这个数据集规模庞大、真实且相关——这是一种罕见的组合。在本文中,我将解释如何利用新的和已有的技巧及技术,通过深度学习来解决文本对任务。

某平台数据集是自然语言处理中一个重要问题类型的例子:文本对分类。这类问题具有挑战性,因为你通常无法通过查看单个单词来解决。没有任何一个单词能告诉你两个问题是否是重复的,某个标题是否与某个故事匹配良好,或者某个有效链接是否可能指向错误的页面。你必须同时查看这两个项目。这很难——但也很有价值。而做这件事的模型正开始变得相当不错。

更新(2017年3月1日)
关于此任务的更新实验可以在我们的后续文章中找到。

某平台数据集
最近针对文本对分类的方法主要在斯坦福自然语言推理语料库上开发,该语料库由 Sam Bowman 在其研究生研究期间准备。该语料库提供了超过 50 万对短句,并有人工标注,指示句子之间是否存在蕴涵、矛盾或中性逻辑关系。SNLI 数据集比以往类似的资源大了 100 多倍,使得当前的深度学习模型能够应用于此问题。然而,该数据也相当人为化——这些文本与你可能在应用中遇到的任何文本都大不相同。

SNLI 方法论
SNLI 语料库中的文本是从某中心的微任务平台上的工作者那里收集的。工作者会看到一条图片说明——其本身是在之前的标注项目中由工作者生成的——并被要求写出三条替代说明:一条在给定原始说明下是错误的,一条是真的,以及一条可能真也可能假的。

当我第一次使用 SNLI 数据时,我担心有限的词汇量和相对直白的句子会使问题变得不切实际地简单。某平台的数据给了我们一个绝佳的机会来检验我们的进展:在 SNLI 数据上开发的模型在现实世界的任务中真的有用吗?还是人工数据导致我们得出了关于如何构建这类模型的不正确结论?

人工数据不一定糟糕
为什么要使用人工数据?世界上当然不缺文本——但是,并不是因为缺风,风洞才有用。在稍微理想化的条件下进行实验是有用的,这样可以更容易推理结果。

关于 NLP 实验应该理想化到什么程度的问题并不新鲜。然而,能有这么好的机会来检验我们方法论的可信度是很少见的。SNLI 太人工化了吗?如果是这样,它就会误导我们如何解决一个真实的任务,例如某平台数据所提出的任务。某平台数据规模大致相同,并且出现得正是时候。在接下来的几个月里观察情况会很有趣。到目前为止,来自 SNLI 语料库的结论似乎保持得相当好。

用于文本对分类的神经词袋模型
在设计用于文本对任务的神经网络时,最重要的决定可能是你希望独立地还是联合地表示文本的含义。独立表示意味着网络可以单独读取一个文本,并为其生成一个向量表示。如果你知道需要对相同文本进行大量比较(例如,如果你想找到它们的成对相似性),这非常好。然而,独立读取句子会使文本对任务变得更加困难。在将句子缩减为向量之前,先一起读取句子的模型具有准确性的优势。

我之前描述过一个共同读取句子的模型—— Parikh 等人的可分解注意力模型。在本文中,我将描述一个非常简单的句子编码模型,使用所谓的“神经词袋”。该模型使用 Thinc 实现,这是一个正在开发用于 spaCy 的小型 NLP 优化机器学习函数库。虽然 Thinc 尚未完全稳定,但我已经发现它相当高效,特别是对于应该在 CPU 上运行良好的小型模型。

运算符重载
为了保持模型定义的简洁性,Thinc 允许你临时重载 Model 类上的运算符,指向任何你喜欢的二元函数。定义是块作用域的,因此你总是可以读取运算符被别名指向了什么。

首先,我们为句子中的每个单词获取一个预训练的“词嵌入”向量。静态嵌入相当长,学习对维度进行重新加权很有用——因此我们学习一个投影矩阵,将嵌入向量映射到宽度为 width 的长度。

这给了我们两个二维数组——每个句子一个。我们想为这对问题学习一个单一的类别标签,所以我们希望为这对句子获得一个单一的向量。人们使用各种池化操作来实现这一点。我发现使用多种池化方法并拼接结果效果很好。在上面的代码中,我为逐元素平均值和最大值(分别是“平均池化”和“最大池化”)创建向量,并拼接结果。

然后,我们为每个句子创建一个向量,并拼接结果。然后将其馈送到一个深度最大输出网络,然后通过 Softmax 层进行预测。神经词袋模型在以下两个数据集上产生了准确率:

离题:Thinc,spaCy的机器学习库
Thinc 的工作方式与大多数神经网络库略有不同。没有计算图抽象——我们不编译你的计算,我们只是执行它们。为了计算反向传播,层只是返回一个回调函数。为了说明,假设我们有一个仿射层的以下实现,作为一个闭包:

层的权重 W 和 b 是私有的——它们是层内部的细节,位于函数的外部作用域中。该层返回其前向传播函数,该函数引用了封闭的权重。前向传播函数返回一个输出和回调函数 backward。然后可以使用该回调函数完成反向传播:

这种设计允许所有层具有相同的简单签名,这使得编写辅助函数以各种方式组合层变得容易。这使得定义自定义数据流变得容易——只要你定义了前向和反向传播,就可以让任何你想要的类型在模型中流动。

结果
神经词袋模型并不是最令人满意的模型,但它是一个很好的基线计算——并且一如既往,重要的是为基线做足准备,并尽可能计算该想法的最佳版本。我建议总是尝试平均和最大池化的技巧——我还没有发现一个任务上它的表现不比单独使用平均池化或最大池化差,并且通常至少要好一点。

  • Quora 准确率: 80.9(平均池化), 82.3(最大池化), 82.8(平均和最大池化)
  • SNLI 准确率 (2-class): 85.1(平均池化), 88.6(最大池化), 88.5(平均和最大池化)

宽度设置为 128,深度设置为 1(即在 Softmax 之前只使用了一个 Maxout 层)。我没有使用 dropout,因为模型中的参数很少——训练的模型小于 1MB,因为我们没有更新词向量。批量大小初始设置为 1,每次迭代增加 0.1%,最大到 256。我计划在后续文章中写这个技巧——它一直效果很好。

负面结果:最大输出窗口编码
更新(2017年3月1日) 这里的负面结果后来发现是由一个错误导致的。在更新后的实验中,最大输出窗口编码如预期那样提供了帮助。

我还尝试了使用卷积层编码有限位置信息的模型。最近有许多关于这种“穷人版”双向长短期记忆网络的提议。我在这方面的新的首选解决方案是我称之为最大输出窗口编码 的层。它非常简单:对于句子中的每个单词 i,我们通过拼接单词(i-1, i, i+1)的向量来形成一个新的向量。如果我们的句子长度为 N 个词,向量宽度为 M,那么这一步将接受一个 (N, M) 矩阵并返回一个 (N, M3) 矩阵。然后我们使用一个 maxout 层将拼接后的 3M 长度的向量映射回 M 长度的向量。

MWE 层与双向长短期记忆网络具有相同的目标:提取更好的词特征。大多数 NLP 神经网络都以嵌入层开始。在这一层之后,你的词特征是位置无关的:单词“duck”的向量总是相同的,无论它周围有什么词。我们知道这不好——我们知道单词“duck”的含义确实会根据其上下文而变化。这里显然有一个改进我们特征的机会——向上游层提供关于输入的更好信息。

上图展示了单个 MWE 块如何根据紧邻的两个单词的证据重写每个单词的向量。你可以将输出视为三元组向量——它们基于来自三个词窗口的信息。通过简单地添加另一层,我们将获得从 5-gram 计算的向量——感受野随着我们深入每一层而变宽。

为了使 MWE 单元工作,它需要学习从三元组到更短向量的非线性映射。你可以在这里使用任何非线性函数,但我发现 maxout 效果很好。其逻辑是,通过增加宽度 M 来增加层的容量是非常昂贵的,因为我们的权重层将是 (M, 3*M)。相反,maxout 单元允许我们通过添加另一个维度来增加容量。我通常使用两到三个片段。

Thinc 仓库中的 CNN 标注器示例提供了一个简单的概念验证。该示例是一个直接的标注模型,在某语料库上进行训练和评估。该模型仅接收单词 ID 作为输入——没有子词特征——并且频率低于 10 的单词被标记为未知。不使用预训练向量。

在深度为 0 时,模型只能学习每个词类型一个标签——它没有上下文信息。每一层深度都使模型对更宽的上下文范围敏感,导致准确率的小幅提升,并在深度 3 时趋于平稳。

然而,对标注和意图检测有效的方法,在文本对分类中被证明出奇地无效。这与之前我听到的关于双向长短期记忆网络在为 SNLI 任务开发的各种模型中相对无效的报告相符。我仍然没有一个好的直觉来解释为什么会这样。

总结
可以使用文本对分类模型实现许多有趣的功能。这项技术仍然相当年轻,因此其应用尚未得到很好的探索。我们拥有对单一文本进行分类的良好技术已经有一段时间了——但准确建模文本之间关系的能力是相当新的。我期待看到人们用此构建什么。

与此同时,我们正在开发一个交互式演示,以探索在某平台数据集和 SNLI 语料库上训练的不同模型。
更多精彩内容 请关注我的个人公众号 公众号(办公AI智能小助手)或者 我的个人博客 https://blog.qife122.com/
对网络安全、黑客技术感兴趣的朋友可以关注我的安全公众号(网络安全技术点滴分享)

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值