X

Pytorch学习记录-基于多层CNNSeq2Seq的GEC

Pytorch学习记录-GEC语法纠错07

五月第一周要结束了,接下来的三个月主要是文献阅读,准备8、9月的开题报告,技术类的文献集中在GEC和Text maching的应用方面,读完之后找demo复现,然后应用。 理论方面的论文也都是英文的

6. A Multilayer Convolutional Encoder-Decoder Neural Network for Grammatical Error Correction

基于多层CNNSeq2Seq的GEC,作者是新加坡国立大学的Chollampatt,他在2016年的论文《Neural network translation models for grammatical error correction》是第5篇的研究基础。这个模型也很有意思,在之前使用Pytorch实现过,是第5个模型,CNN与Seq2Seq结构相结合,其中加入attention机制,再后面就是Transformer模型了。

  • 这篇文章通过CNNSeq2Seq提升了文本中的语法、拼写、搭配错误的自动校正
  • 网络使用字符n-gram信息嵌入来实现初始化。
  • 模型评价使用CoNLL-2014和JFLEG
  • 最后的分析现实CNN在使用attention捕捉上下文上优于LSTM,能够提高语法纠正的覆盖范围。
  • 使用了集合策略

6.1 介绍

GEC是一个成熟的NLP任务。要纠正的错误不仅是语法的,也有拼写和搭配错误。

SMT已经成为主流(之前基于短语的SMT),但是仍有短板:SMT仍然受到有效访问全局源和目标上下文的限制。在解码期间将单词和短语视为离散实体也限制了其泛化能力。

Seq2Seq开始应用于GEC任务。但是效果并不理想,没有达到SOTA

原因是之前的GEC都是基于RNN的。与以前的神经方法相比,这个研究的的GEC神经方法基于CNNSeq2Seq架构,具有多层卷积和注意力。研究表明,相比RNN而言,CNN能够更有效地获取本地上下文信息(因为卷积运算是在较小的单词序列窗口上执行的)

大多数语法错误发生在相邻词汇,多层CNN和attention机制能够捕捉到更广泛上下文和远距离词之间的互动。

研究者还引入了多模型集合策略。 使用字节对编码(BPE)算法将稀有字分成多个频繁子字(sub-words)。 使用这样的英语语料库来预训练用于初始化编码器和解码器中的嵌入的字向量。 训练N-gram语言模型作为功能。

6.2 相关工作

之前的方法大多是基于构建错误类别分类器。

SMT框架在很大程度上得益于其结合大型纠错并行语料库的能力,如公开的Lang-8语料库(这是一个母语修改的社交网站,语料库更新至2013年,似乎没有中文 https://sites.google.com/site/naistlang8corpora/ ),用于训练健壮语言模型(LM)的其他英语语料库。然而,与神经方法相比,基于SMT的系统具有有限的泛化能力,并且无法有效地访问更长的源和目标上下文。为了解决这些问题,提出了几种针对GEC依赖于RNN的神经encoder-decoder方法。

6.2.1 神经encoder-decoder GEC

  • 2016,Yuan 和 Briscoe,BiRNN encoder-decoder + attention RNN,使用非监督字对齐模型和字级别SMT模型。
  • 2016,Xie 字符级别RNN encoder-decoder,在Lang-8和NUCLE语料库上进行训练。
  • 2017,Ji 基于混合机器翻译模型的混合词 - 字符模型。
  • 2017,Schmaltz 使用字级别BiLSTM网络,基于Lang-8和NUCLE语料库训练。

6.3 多层卷积encoder-decoder神经网络

6.3.1 模型

输入句子$S$,提供了m个token序列 $s1, s2, s3,…, sm$ 并且$si \in Vs$ 其中 $Vs$ 是词汇列表。最后的一个token $sm$ 是一个特殊标记,类似“eos”。

$S$ 是要经过嵌入操作。这部分参考这篇博文https://www.jianshu.com/writer#/notebooks/34004882/notes/45926192 $$si=w(si)+p(i)$$

  • $w(s_i)$ 词嵌入
  • $p(i)$ 位置嵌入

encoder和decoder是由L层构成,结构在最开始部分,完成嵌入的$S$进行线性映射,获得第一层encoder的输入向量$h1^0, h2^0, …, hm^0$,输入到第一层,线性映射公式如下 $$hi^0=W{si}+b$$

在encoder第一层,尺寸为3*h 的 2h卷积滤波器将三个连续输入矢量的每个序列映射到特征矢量$fi^1 \in R^2h$。在句子的开始和结尾均有tag(“pad”)。 $$fi^1=Conv(h^0{i-1}, hi^0, h_{i+1}^0)$$

  • Conv(.)是在完成一个GLU之后的卷积操作,

$$GLU(fi^1)=f{i,1:h}^1 ◦ \sigma(f_{i,h+1:2h}^1)$$

  • $GLU(f_i^1) \in R^h$
  • $◦ σ$ 是元素乘法和sigmoid激活函数 最后将encoder层的输入矢量添加为残余连接。第l个编码器层的输出矢量由下式给出: $$hi^l=GLU(fi^l)+hi^{l-1}$$ encoder的最后一层输出的$hi^L$要经过线性映射得到最终输出向量$ei$ $$ei=Wehi^L+b_e$$
  • $h_i^L \in R^h$ 最后一层encoder输出向量
  • $e_i \in R^d$ encoder的输出向量
  • $W_e \in R^{d * h}$ 权重
  • $b_e \in R^d$

在decoder部分,每一个decoder层都有一个attention模块,attention的权重$\alpha{n,i}^l$是由encoder的输出$ei$和$zn^l$的点积,并使用softmax归一。 $$yj^l = GLU(Conv(g{j−3}^{l-1}, g{j-2}^{l-1}, g{j−1}^{l-1})$$ $$z^ln = Wzyn^l + bz + t{n−1}$$ $$\alpha{n,i}^l=\frac{exp(ei^Tzn^l)}{\Sigma{k=1}^m exp(ek^Tzn^l)}$$

而上下文向量$xn^l$是通过将attention权重应用于encoder输出向量和源嵌入的总和来计算。 $$Xn^l=\Sigma{n=1}^m \alpha{n,i}^l(ei+si)$$

然后对上下文向量进行线性映射到$cn^l \in R^h$,这样,decoder的输出$gn^l$,就可以表示为$gn^{l-1}$、$cn^l$、$yn^l$的总和。 $$gn^l=gn^{l-1}+cn^l+y_n^l$$

这样最终的decoder输出向量就是$gn^L$,将其进行线性映射,得到$dn \in R^d$。(需要注意的是,在decoder输出、嵌入、以及每个encoder和decoder层之前都要使用dropout)然后将decoder输出矢量映射到目标词汇量大小($| Vt |$),并计算softmax以获得目标词概率。 $$on=Wodn+b_o$$

$$p(tn=wi|t1,…,t{n-1},S)=\frac{exp(o{n,i})}{\Sigma{k=1}^{|Vt|}exp(o{n,k})}$$ 其中$wi$是第i个单词在目标词汇$Vt$中。

我靠,这个模型好麻烦啊……

6.3.2 词嵌入的预训练

  • 研究者使用从大型英语语料库中学习的预训练词嵌入来初始化源语词和目标语词的嵌入词(我们之前使用的是Glove预训练,这里他们自己训练了一个新的词嵌入)。
  • 将此英语语料库中的稀有词语拆分为基于BPE的子词单元。
  • 通过使用fastText工具将单词表示为字符N-gram包并对这些字符n-gram序列的skipgram嵌入进行求和来计算单词嵌入。
  • 这些嵌入包含有关单词的基本形态的信息,并且根据经验发现它比随机初始化网络或使用word2vec(Mikolov等人2013)嵌入更好地执行,嵌入将单词视为单独的实体并且没有关于制作的字符序列的信息。

6.4 实验步骤

6.4.1 数据集

使用两个公共数据集Lang-8和NUCLE

6.4.2 评价

使用CoNLL-2014。

6.4.3 模型和训练细节

果然,这里提到了Facebook的FairSeq。他们在3个NVIDIA Titan X GPU上同时训练每个模型,每个GPU上的批量大小为32,并在另一个NVIDIA Titan X GPU上同时执行每个时期的验证。