2017年7月26日更新:有关其他上下文,HackerNews对此帖的讨论。
目录:
本文收集了在自然语言处理中使用神经网络的最佳方法。我会将随着新的见解的发布而定期更新,以便跟踪我们对NLP深度学习的深入了解。
在NLP社区中有一个笑话,一个受关注的LSTM将会在任何任务中产生最先进的性能。尽管在过去的两年中这已经是事实,但是NLP社区正在慢慢地从这个现在的标准基线转向更有趣的模型。
然而,作为一个社区,我们不希望在接下来的两年中独立(重新)发现下一个 LSTM。我们不想重塑已经显示出来的技巧或方法。尽管许多现有的深度学习库已经编码了通常用于神经网络的最佳实践,例如初始化方案,但许多其他细节,特别是任务或特定领域的考虑,都留给了实践者。
这篇文章并不是要跟踪最新的技术,而是要收集与广泛任务相关的最佳方法。换句话说,这篇文章不是描述一个特定的体系结构,而是旨在收集那些不太成功的体系结构。虽然其中许多功能对于推动最新技术最为有用,但我希望通过更广泛的知识来进行更强大的评估,更有意义地与基线进行比较,并通过塑造我们对有效的直觉的启发。
我假设你熟悉神经网络应用于NLP(如果不是的话,我推荐Yoav Goldberg优秀的入门指南 [ 43 ]),并且对NLP一般或特定的任务感兴趣。本文的主要目标是让您了解相关的最佳方法,以便尽快做出有意义的努力。
我将首先介绍与大多数任务相关的最佳方法。然后,我将概述与最常见任务相关的方法,特别是分类,序列标签,自然语言生成和神经机器翻译。
免责声明:根据最佳方法来处理是非常困难的:根据什么最好?如果有更好的选择呢?这篇文章是基于我(必然不完整)的理解和经验。下面,我将只讨论至少由两个不同的小组独立报告的独立方法。我会尽量给每个最佳方法至少两个参考。
在最近的NLP历史中,文字嵌入可以说是最广为人知的最佳方法。众所周知,使用预先训练嵌入的帮助(Kim,2014)[ 12 ]。词嵌入的最佳维度主要取决于任务:较小的维度适用于更多的语法任务,如命名实体识别(Melamud等人,2016)[ 44 ]或词类(POS)标记(Plank 等人人,2016)[ 32 ],而较大的维数为多个语义任务,如情绪分析(罗德等人,2016)[ 45 ]。
虽然我们暂时还没有深入到计算机视觉的深处,但是NLP中的神经网络已经变得越来越深入。最新的方法现在经常使用深层Bi-LSTM,通常由3-4层组成,例如用于POS标记(Plank等人,2016)和语义角色标注(He 等人,2017)[ 33 ]。一些任务的模型可以更深入,可以参考Google有8个编码器和8个解码器层的NMT模型(Wu 等人,2016)[ 20 ]。然而,在大多数情况下,使模型比2层更深的性能改进是最小的(Reimers&Gurevych,2017)[ 46 ]。
这些观察结果适用于大多数序列标记和结构预测问题。对于分类来说,深层或非常深层的模型只有在字符层次输入的情况下才能表现良好,而浅层次的字层次模型仍然是最先进的(Zhang 等人,2015; Conneau 等人,2016; Le 等人,2017)[ 28,29,30 ]。
为了训练深度神经网络,一些技巧对于避免渐变梯度问题是必不可少的。已经提出了不同的层和连接。在这里,我们将讨论三个:i)高速层,ii)剩余连接,以及iii)密集连接。
高速层(Srivastava等,2015)[ 1 ]受到LSTM的启发。首先让我们假设一个单层MLP,它采用仿射变换,然后是非线性ggg到它的输入x:
\mathbf{h} = g(\mathbf{W}\mathbf{x} + \mathbf{b})
公路层然后计算下面的函数:
\mathbf{h} = \mathbf{t} \odot g(\mathbf{W} \mathbf{x} + \mathbf{b}) + (1-\mathbf{t}) \odot \mathbf{x} 其中⊙是元素乘法,\mathbf{t} = \sigma(\mathbf{W}_T \mathbf{x} + \mathbf{b}_T)被称为变换门,(1-\mathbf{t})被称为进位门。正如我们所看到的,高速公路层是类似于LSTM的,所述门它们自适应地携带的输入的某些尺寸直接输出。
高速层已被用于预显性来实现状态的最先进的结果语言建模(Kim等人,2016; Jozefowicz等人,2016; Zilly等人,2017)[ 2,3,4 ] ,但也被用于语音识别等其他任务(Zhang 等人,2016)[ 5 ]。Sristava的页面包含更多关于高速公路层的信息和代码。
残余连接 残留连接(He等人,2016)[ 6 ]首先被提出用于计算机视觉,并且是获得ImageNet 2016的主要因素。残余连接比高速层更加直接,学习以下功能:
\mathbf{h} = g(\mathbf{W}\mathbf{x} + \mathbf{b}) + \mathbf{x}
它通过快捷连接简单地将当前图层的输入添加到其输出。这个简单的修改减轻了消失的梯度问题,因为如果该层不是有利的,模型可以默认使用标识函数。
密集连接 而不是仅仅添加来自每层的层到下一层,密集的连接(Huang 等人,2017)[ 7 ](CVPR 2017的最佳论文奖)增加了从每层到所有后续层的直接连接。让我们增加图层输出hhh和图层输入xxx指数为l升l指示当前层。密集连接然后将来自所有先前层的级联输出作为输入馈送到当前层:
\mathbf{h}^l = g(\mathbf{W}[\mathbf{x}^1; \ldots; \mathbf{x}^l] + \mathbf{b})
其中[⋅;⋅]表示串联。密集连接已成功用于计算机视觉。他们也发现对于不同的NLP任务的多任务学习是有用的(Ruder等人,2017)[ 49 ],而使用求和的残差变量已被证明始终优于神经机器翻译的残差连接(Britz等人, 2017)[ 27 ]。
虽然计算机视觉批量归一化已经使其他规则化器在大多数应用中被淘汰,但是丢弃(Srivasta等人,2014)[ 8 ]仍然是NLP中深度神经网络的前向规则化器。在大多数情况下,丢弃率0.5被证明是有效的(Kim,2014)。近年来,已经提出了适应性丢弃(Ba&Frey,2013)[ 9 ]和进化丢弃(Li 等人,2016)[ 10 ] 等丢弃方式的变化,但没有一个在社区中被广泛采用。阻碍NLP中丢弃的主要问题是,它不能应用于经常性连接,因为聚合丢失掩码将随着时间的推移有效地将嵌入消除。
复发丢弃 复发丢弃(Gal&Ghahramani,2016)[ 11 ]通过在第3层中跨越时间步长应用相同的丢弃解决此问题。这样避免了沿序列放大噪声,导致序列模型的有效正则化。复发性丢失已被用于例如在语义角色标注(He等人,2017)和语言建模(Melis等人,2017)[ 34 ]中获得最新的结果。
如果有更多的数据可用,通常可以使用多任务学习(MTL)来提高目标任务的性能。看看这个博客文章了解更多关于MTL的信息。
辅助目标 我们经常可以找到对我们关心的任务有用的辅助目标(Ruder,2017)[ 13 ]。虽然我们已经可以预测周围的单词,以预训练词嵌入(Mikolov等,2013),我们也可以用它作为培训期间的辅助目标(Rei,2017)[ 35 ]。(Ramachandran等,2016)[ 36 ] 也使用了一个类似的目标,用于序列到序列模型。
任务特定的层 虽然NLP的MTL的标准方法是硬参数共享,但让模型学习任务特定的层是有益的。这可以通过将一个任务的输出层放在较低的层次来完成(Søgaard&Goldberg,2016)[ 47 ]。另一种方法是诱导私有和共享的子空间(Liu等人,2017;罗德等人,2017)[ 48,49 ]。
注意是序列到序列模型中最常用的参与编码器状态,但也可用于任何序列模型来回顾过去的状态。使用注意力,我们获得一个上下文向量\mathbf{c}_i 基于隐藏状态\mathbf{s}_1,... ,…,…, \mathbf{s}_m可以与当前隐藏状态一起使用\mathbf{h}_i进行预测。上下文向量\mathbf{c}_i在位置处被计算为以关注分数a加权的先前状态的平均值\mathbf{a}_i:
\begin{align}\begin{split} \mathbf{c}_i &= \sum\limits_j a_{ij}\mathbf{s}_j\\ \mathbf{a}_i &= \text{softmax}(f_{att}(\mathbf{h}_i, \mathbf{s}_j)) \end{split}\end{align}
注意功能f_{att}(\mathbf{h}_i, \mathbf{s}_j)在当前隐藏状态的非标准化对齐分数\mathbf{h}_i和上一个隐藏的状态 \mathbf{s}_j之间计算非规范对齐分数。在下文中,我们将讨论四种注意力变体:i)加性注意力,ii)倍增注意力,iii)自我注意力,以及iv)关键值注意力。
附加关注 最初的注意机制(Bahdanau等人,2015)[ 15 ]使用一个隐藏层前馈网络来计算注意对齐:
f_{att}(\mathbf{h}_i, \mathbf{s}_j) = \mathbf{v}_a{}^\top \text{tanh}(\mathbf{W}_a[\mathbf{h}_i; \mathbf{s}_j])
其中 \mathbf{v}_a和\mathbf{W}_a是学习的关注参数。类似地,我们也可以使用矩阵\mathbf{W}_1 和\mathbf{W}_2为h学习单独的转换\mathbf{h}_i和\mathbf{s}_j 分别进行总结:
f_{att}(\mathbf{h}_i, \mathbf{s}_j) = \mathbf{v}_a{}^\top \text{tanh}(\mathbf{W}_1 \mathbf{h}_i + \mathbf{W}_2 \mathbf{s}_j)
乘性注意 乘性注意(Luong 等人,2015)[ 16 ]通过计算以下函数来简化注意力操作:
f_{att}(h_i, s_j) = h_i^\top \mathbf{W}_a s_j
加法和乘法注意在复杂性上是相似的,尽管乘法注意在方法中更快,更节省空间,因为它可以使用矩阵乘法更高效地实现。两种变体进行了小维类似dhdhd_h 的解码器状态,但是对于更大的尺寸,附加的关注表现更好。减轻这一点的一个方法是通过1/\sqrt{d_h}扩展f_{att}(\mathbf{h}_i, \mathbf{s}_j)(Vaswani等人,2017)[ 17 ]。
注意力不仅可以用于关注编码器或以前的隐藏状态,而且还可以获得关于其他特征的分布,例如用于阅读理解的文本嵌入词(Kadlec等人,2017)[ 37 ]。然而,注意并不直接适用于不需要额外信息的分类任务,如情感分析。在这样的模型中,LSTM的最终隐藏状态或诸如最大池或平均的聚合函数经常用于获得句子表示。
自我关注 然而,没有任何额外的信息,我们仍然可以从句子中提取相关的方面,允许自己使用自我注意(Lin等人,2017)[ 18 ]。自我关注,也被称为内部关注已成功地用于各种任务,包括阅读理解(Cheng等人,2016)[ 38 ],文本包含(Parikh等人,2016)[ 39 ]和抽象概括(Paulus等人,2017)[ 40 ]。
我们可以简化添加注意力来计算每个隐藏状态的非标准化对齐分数\mathbf{h}_i:
f_{att}(\mathbf{h}_i) = \mathbf{v}_a{}^\top \text{tanh}(\mathbf{W}_a \mathbf{h}_i)
以矩阵形式,对于隐藏状态 \mathbf{H} = \mathbf{h}_1, \ldots, \mathbf{h}_n我们可以计算注意向量\mathbf{a}和最后的句子表示\mathbf{c} 如下:
\begin{align}\begin{split} \mathbf{a} &= \text{softmax}(\mathbf{v}_a \text{tanh}(\mathbf{W}_a \mathbf{H}^\top))\\ \mathbf{c} & = \mathbf{H} \mathbf{a}^\top \end{split}\end{align}
我们可以通过使用矩阵V来执行几次关注,而不是只提取一个向量一个\mathbf{V}_a而不是\mathbf{v}_a,这使我们能够提取一个注意矩阵\mathbf{A}:
\begin{align}\begin{split} \mathbf{A} &= \text{softmax}(\mathbf{V}_a \text{tanh}(\mathbf{W}_a \mathbf{H}^\top))\\ \mathbf{C} & = \mathbf{A} \mathbf{H} \end{split}\end{align}
在实践中,我们执行以下正交性约束来惩罚冗余,并以平方Frobenius范数的形式鼓励注意向量的多样性:
\Omega = \|(\mathbf{A}\mathbf{A}^\top - \mathbf{I} \|^2_F
Vaswani等人也使用类似的多头注意力。(2017年)。
关键值注意 最后,关键值注意(Daniluk等人,2017)[ 19 ]是一种最近的关注变体,通过为注意力计算保留单独的向量来将形式与功能分开。对于不同的文档建模任务也是有用的(Liu&Lapata,2017)[ 41 ]。具体而言,键值注意将每个隐藏向量分割\mathbf{h}_i成为一个关键 \mathbf{k}_i和值\mathbf{v}_i: [\mathbf{k}_i; \mathbf{v}_i] = \mathbf{h}_i。这些密钥用于计算注意力分配\mathbf{a}_i使用添加剂注意:
\mathbf{a}_i = \text{softmax}(\mathbf{v}_a{}^\top \text{tanh}(\mathbf{W}_1 [\mathbf{k}_{i-L}; \ldots; \mathbf{k}_{i-1}] + (\mathbf{W}_2 \mathbf{k}_i)\mathbf{1}^\top))
那里LLL是关注窗口的长度和11\mathbf{1}是一个向量。然后使用这些值来获得上下文表示\mathbf{c}_i:
\mathbf{c}_i = [\mathbf{v}_{i-L}; \ldots; \mathbf{v}_{i-1}] \mathbf{a}^\top
为了进行预测,\mathbf{c}_i 与当前值一起使用\mathbf{v}_i 。
优化算法和方案通常是原样使用的模型的一部分,并被视为黑盒子。有时,即使算法稍有改变,例如在Adam中减少\beta_2的值(Dozat&Manning,2017)[ 50 ]可以对优化行为产生很大的影响。
优化算法 Adam(Kingma&Ba,2015)[ 21 ]是最流行和广泛使用的优化算法之一,通常是NLP研究人员的优化算法。人们经常认为亚当明显优于香草随机梯度下降(SGD)。然而,尽管收敛速度远快于新元,但学习速度退火的新元稍微超过了亚当(Wu 等人,2016)。最近的工作还表明,新加坡经过适当调整的势头胜过了亚当(Zhang等人,2017)[ 42 ]。
优化方案 当Adam在内部调整每个参数的学习率时(Ruder,2016)[ 22 ],我们可以明确地使用与Adam的SGD式退火。特别是,我们可以重新开始学习速率退火:我们设置一个学习速率,训练模型,直到收敛。然后,我们减半学习速度,重新加载之前最好的模型。在亚当的情况下,这会导致优化器忘记其每个参数的学习速度,并开始新的。Denkowski&Neubig(2017)[ 23 ]表明Adam重新开始2次学习速率退火的速度更快,并且退火效果比SGD好。
通过平均预测结果将多个模型组合成一个集合是改进模型性能的经过验证的策略。虽然在测试期间用集合预测是昂贵的,但是最近蒸馏的进展使得我们能够将昂贵的集合压缩成更小的模型(Hinton等人,2015; Kuncoro等人,2016; Kim&Rush,2016)[ 24,25,26 ]。
如果评估模型的多样性增加,则集合是确保结果仍然可靠的重要方法(Denkowski&Neubig,2017)。而ensembling一个模型的不同检查点已被证明是有效的(Jean 等人,2015; Sennrich等人,2016)[ 51,52 ],它是在模型多样性的成本。周期性学习率可以帮助减轻这种影响(Huang 等人,2017)[ 53 ]。但是,如果资源可用,我们更倾向于集合多个独立训练模型来最大化模型多样性。
而不是预先定义或使用现成的超参数,只需调整我们模型的超参数就可以比基线产生显着的改善。贝叶斯优化的最新进展使其成为神经网络超参数黑箱优化的理想工具(Snoek 等人,2012)[ 56 ],并且比广泛使用的网格搜索更有效。LSTM超参数的自动调整导致了语言建模方面的最新成果,超越了复杂得多的模型(Melis等人,2017)。
学习初始状态 我们通常用初始化初始的LSTM状态000向量。我们可以像其他参数一样学习,而不是固定初始状态,这可以提高性能,也是Hinton推荐的。参考这个博客文章的Tensorflow实现。
绑定输入和输出嵌入 输入和输出嵌入占了LSTM模型中参数的最大数量。如果LSTM预测单词作为语言建模,输入和输出参数可以共享(伊南等人,2016;按&狼,2017)[ 54,55 ]。这对于不允许学习大量参数的小数据集特别有用。
梯度范数限制 降低梯度爆炸风险的一种方法是限制其最大值(Mikolov,2012)[ 57 ]。然而,这并不能改善表现(Reimers&Gurevych,2017)。而不是独立地裁剪每个梯度,削减梯度的全局规范(Pascanu等人,2013)[ 58 ]产生更显着的改进(Tensorflow实现可以在这里找到)。
向下投影 为了进一步减少输出参数的数量,可以将LSTM的隐藏状态投影到更小的尺寸。这对于具有大量输出的任务特别有用,如语言建模(Melis等,2017)。
下面我们将讨论特定于任务的最佳实践。这些大多数执行最好的特定类型的任务。其中一些可能仍然适用于其他任务,但应该在之前进行验证。我们将讨论以下任务:分类,序列标签,自然语言生成(NLG),以及 - 作为NLG - 神经机器翻译的特例。
与序列任务相比,由于更有效的卷积操作,CNN只是最近才发现应用程序,所以CNN在NLP中的分类任务中已经很流行。以下最佳实践与CNN相关,并捕获一些最佳的超参数选择。
CNN滤波器 将最佳滤波器尺寸附近的滤波器尺寸组合在一起,例如(3,4,5)效果最好(Kim,2014; Kim等,2016)。特征图的最佳数量在50-600之间(Zhang&Wallace,2015)[ 59 ]。
聚合函数 1-max-pooling优于平均池和k至k最大池(Zhang&Wallace,2015)。
序列标签在NLP中无处不在。虽然现有的许多最佳实践是关于模型架构的特定部分,但以下指南讨论了模型的输出和预测阶段的选择。
标记方案 对于可以将标签分配给文本片段的某些任务,可以使用不同的标记方案。它们是:BIO,标记带有B-标记的段中的第一个标记,带有I-标记的段中所有剩余的标记,以及带有O-标记的段之外的标记; IOB,类似于BIO,但只有在B使用-如果前一个标记是相同的类,但不是该部分的一部分; 和IOBES,它们还区分单令牌实体(S-)和段(E-)中的最后一个令牌。使用IOBES和BIO产生相似的性能(Lample等人,2017)
CRF输出层 如果输出之间存在任何依赖关系,例如在命名实体识别中,最终的softmax层可以用线性条件随机场(CRF)替代。这已经显示出产生一致的改进对于需要约束的建模任务(Huang等人,2015;最大值&Hovy,2016; Lample等人,2016)[ 60,61,62 ]。
约束解码 与使用CRF输出层不同,约束解码可以用作拒绝错误序列的替代方法,也就是说,不会产生有效的BIO转换(He 等人,2017)。受约束的解码具有可以以这种方式强制执行任意约束的优点,例如任务特定或语法约束。
大多数现有的最佳实践可以应用于自然语言生成(NLG)。实际上,到目前为止提出的许多技巧都是源于语言建模方面的进步,这是最典型的NLP任务。
覆盖建模 重复是许多NLG任务中的一个大问题,因为目前的模型不能很好地记住它们已经产生的输出。在模型中明确地建模覆盖率是解决这个问题的好方法。一个清单可以使用,如果它是已知的进步,哪些实体应在输出中提到,例如食谱配料(Kiddon等人,2016)[ 63 ]。如果使用注意力,我们可以跟踪一个覆盖矢量 \mathbf{c}_i,这是人们关注的总和分布\mathbf{a}_t比以前的时间步长(Tu 等人,2016;参见等人,2017 ..)[ 64,65 ]:
\mathbf{c}_i = \sum\limits^{i-1}_{t=1} \mathbf{a}_t
这个矢量捕捉了我们对源码中所有单词的多少关注。现在我们可以在这个覆盖矢量上额外注意附加关注,以便鼓励我们的模型不要重复地重复同样的单词:
f_{att}(\mathbf{h}_i,\mathbf{s}_j,\mathbf{c}_i) = \mathbf{v}_a{}^\top \text{tanh}(\mathbf{W}_1 \mathbf{h}_i + \mathbf{W}_2 \mathbf{s}_j + \mathbf{W}_3 \mathbf{c}_i )
另外,我们可以添加一个辅助损失来捕获我们想要得到的特定于任务的关注行为:对于NMT,我们希望有一个大致的一对一对齐; 如果最终的覆盖向量在每个指标上大于或小于1,我们就惩罚模型(Tu等人,2016)。总结一下,如果模式重复到同一地点,我们只想惩罚模型(参见等人。,2017)。
尽管神经机器翻译(NMT)是NLG的一个实例,NMT却受到如此多的关注,许多方法都是专门为这个任务开发的。同样,许多最佳实践或超参数选择都只适用于它。
嵌入维度 2048维嵌入产生最好的性能,但只能做小幅度的。即使是128维嵌入的表现也令人惊讶,收敛速度几乎快了一倍(Britz等人,2017)。
编码器和解码器深度 编码器不需要比2 - 4更深2−42-4层。更深的模型跑赢更浅的,但超过444 解码器不需要层(Britz等人,2017)。
指向性 双向编码器的性能优于单向编码器。Sutskever等(2014)[ 67 ]提出反转源序列以减少长期相关性的数量。单向编码器中的源序列反转优于其非反转部分(Britz等,2017)。
光束搜索策略 中等光束大小在10左右1010长度归一化罚分为1.01.01.0 (Wu等,2016)产生最好的表现(Britz等人,2017)。
子词翻译 Senrich 等人(2016)[ 66 ]提出基于字节对编码(BPE)将单词拆分成子单词。BPE迭代地合并频繁的符号对,最终导致频繁的字符n-gram被合并成单个符号,从而有效地消除了词汇之外的单词。尽管它最初是为了处理罕见的单词,但是一个带有分词单元的模型全面超过了全字词系统,其中32,000个是对于分词单元有效的词汇量(Denkowski&Neubig,2017)。
我希望这篇文章有助于启动你对一个新的NLP任务的学习。即使你已经熟悉了大部分这些,我希望你还是学到了一些新东西,或者刷新了你对有用技巧的了解。
我相信我已经忘记了许多应该列在这份名单上的最佳做法。同样,解析,信息提取等工作也有很多,我不太了解如何提出建议。如果你有一个最好的做法应该在这个名单上,请让我知道下面的评论。请提供至少一个参考和您的归属处理。如果这得到了非常的协作,我可能会打开一个GitHub仓库,而不是在这里收集反馈(我将无法接受直接提交到本文生成的HTML源代码的PR)。
扫码关注腾讯云开发者
领取腾讯云代金券
Copyright © 2013 - 2025 Tencent Cloud. All Rights Reserved. 腾讯云 版权所有
深圳市腾讯计算机系统有限公司 ICP备案/许可证号:粤B2-20090059 深公网安备号 44030502008569
腾讯云计算(北京)有限责任公司 京ICP证150476号 | 京ICP备11018762号 | 京公网安备号11010802020287
Copyright © 2013 - 2025 Tencent Cloud.
All Rights Reserved. 腾讯云 版权所有