【每周一文】Natural Language Processing (almost) From Scratch
2016-02-16 23:46
323 查看
概述
本文介绍了一个统一的神经网络架构用于解决自然语言处理各种的各种任务,主要是序列标注任务,包括词性标注(POS)、词语组块分析(Chunking)、命名实体识别(NER)以及语义角色标注(SRL)等。本文主要介绍如何构建这个统一的神经网络以及如何运用一些技巧去提高效果,结论是不需要特殊构建特征工程就可以得到State-of-art结果。统一标识
为方面后续介绍,提前介绍各类标识。NN:神经网络
前向神经网络:fθ(.)=fLθ(fL−1θ(...f1θ(.)...))f_\theta(.)=f_\theta^L(f_\theta^{L-1}(...f_\theta^1(.)...))
矩阵A中的值:[A]i,j[A]_{i,j}
矩阵A中的列组合成的向量:<A>dwini_i^{d_win}表示第i列附件的d列组合而成的向量,[Adwini]T=([A]1,i−dwin/2...[A]d1,i−dwin/2,...,[A]1,i+dwin/2...[A]d1,i+dwin/2)[A_i^{d_win}]^T=([A]_{1,i-d_win/2}...[A]_{d1,i-d_win/2},...,[A]_{1,i+d_win/2}...[A]_{d1,i+d_win/2})
即d个列向量按照从前到后拼接成一个列向量。
向量x中的某个元素 [x]i[x]_i
一个向量集合:x1,x2,...,xT{x_1,x_2,...,x_{T}}表示为[x]T1[x]_1^T
神经网络构建
词向量构建
将一个词表示为一个向量,即表示为连续空间中的一个点,而不是最原始的ont-hot表示。1. 每一个词表示为一个向量存储在表中供查询,lookup table(LW),对于每个词向量为LTW(w)=<W>1wLT_W(w)=_w^1即大表中的第w列。其中W∈Rdwrd∗|D|,其中d表示词向量长度,D表示词空间W \in R^{d_wrd*|D|},其中d表示词向量长度,D表示词空间
2. 对于一个输入序列可以表示一个矩阵 LTW([w]T1)=(<W>1w1 ... <W>1wT)LT_W([w]_1^T) = (_{w1}^1 \ ... \ _{wT}^1)
3. 对于任何离散型特征可以进行扩展,如果每个词有多个离散特征,则每一个离散特征对应一个查询表,将多个离散特征进行拼接也可以得到输入矩阵。例如LTkWLT_W^k表示第k个离散特征对应的查询表,对于有k个特征的输入序列有,单个词向量表示为LTW1,...,WK(w)=⎡⎣⎢LT1W(w1)...LTKW(wK)⎤⎦⎥LT_{W^1,...,W^K}(w)=\left[
\begin{array}{cc}
LT_W^1(w1)\\
... \\
LT_W^K(wK)
\end{array}
\right]即将k个特征向量进行拼接,对于一个序列则表示为一个矩阵。
基于窗口方法
基于窗口方法架构如下图所示方法关键点介绍如下
1.输入层:对于一个输入序列,每一个词对应一个tag并且有一个超参数kszk_{sz},根据特征个数以及查询表,将输入表示为一个dwrd∗kszd_{wrd}*k_{sz}矩阵,可以拼接成一个固定长度(dwrd ∗kszd_{wrd}\ *k_{sz})向量,即f1θ=⎡⎣⎢⎢⎢⎢⎢⎢⎢⎢⎢<W>1[w]t−dwin/2...<W>1[w]t...<W>1[w]t+dwin/2⎤⎦⎥⎥⎥⎥⎥⎥⎥⎥⎥f_\theta^1=\left[
\begin{array}{cc}
_{[w]_{t-d_{win/2}}}^1 \\
... \\
_{[w]_t}^1 \\
... \\
_{[w]_{t+d_{win/2}}}^1
\end{array}
\right]
2. 线性层:和标注神经网络类似,将输入特征向量进行线性变换flθ=Wlfl−1θ+blf_\theta^l=W^lf_\theta^{l-1}+b^l
3. 非线性变换层:进行HardTanh变换HardTanh(x)=⎧⎩⎨−1,x,1,if x < -1if -1 ≤ x ≤ 1if x > 1HardTanh(x) =
\begin{cases}
-1, & \text{if $x$ < -1} \\
x, & \text{if -1 $\le$ x $\le$ 1} \\
1, & \text{if $x$ > 1}
\end{cases}
4.输出层:根据目标函数进行损失函数选择一般情况选择为maxsoft。
5.其他考虑,对于一个长度为T的序列,将会产生T个输入,每一个词组成一个输入。并且窗口k是一个超参数可以采用CV进行选择。另外对于窗口小于k的词,可以添加PADDING词进行代替。
6.该方法能够解决大部分的序列标注问题,但是对于SRL问题,常常需要指定某个谓词作为输入,此时该方法不能适用,需要考虑句子全部特征。
基于句子方法
基于句子方法整体架构如下相比于基于窗口的方法,加入卷积层照顾到全局特征。
输入层:和基于窗口方法类似,不同的是对于某个待标记的词需要考虑整个句子特征,因此常常加入两个相对特征i−posv,i−poswi-pos_v,i-pos_w即距离谓词v和待标记词的相对距离。
2.卷积层:对于相继的每一个窗口t都要计算一遍线性变换,即对于某个窗口长度t,对应线性变换为<flθ>1t=Wl<fl−1θ>dwint+bl_t^1=W^l_t^{d_{win}}+b^l,对于所有的窗口t计算t次变换,此时得到t个卷积结果
最大化层:对于上述卷积结果常常有两种处理方式平均和最大化,对于该问题使用最大化[flθ]=maxt[fl−1θ][f_\theta^l]=\max_t[f_\theta^{l-1}]
剩余步骤和基于窗口方法类似。
训练
对于标注问题可以转换为多分类过程,常常选用maxsoft作为输出层。词级别log释然(WLL)
对于每个词仅仅考虑该词的分类不考虑整个句子特征,此时p(i|x,θ)=efiθ∑efjθp(i|x,\theta)=\frac{e^{f_\theta^i}}{\sum{e^{f_\theta^j}}}定义logadd(zi)=log(∑iezi)logadd(z_i)=log(\sum_i{e^{z_i}})则对于某个训练样本(x,y),其log释然表示为p(y|x,θ)=fyθ−logadd(fjθ)p(y|x,\theta)=f_\theta^y-logadd(f_\theta^j)
句子级别log释然
区别于词级别处理流程,考虑tag到tag的转换概率,寻找一条有效路径进行优化。该方法略为复杂详细介绍如下:1.将整个句子综合考虑,句子所有输出表示为fθ(xT1)f_\theta(x_1^T),它是一个矩阵其中行表示每一个词对应各个tag的输出。fi,tf_{i,t}表示第t个词对应第i个tag的打分,即⎡⎣⎢⎢⎢⎢⎢ft1,w1ft2,w1....ftM,w1......fti,wj...ft1,wTft2,wT...ftM,wT⎤⎦⎥⎥⎥⎥⎥ \left[
\begin{array}{cc}
f_{t1,w1}&...&f_{t1,wT}\\
f_{t2,w1} & ... & f_{t2,wT}\\
.... & f_{ti,wj} & ...\\
f_{t_M,w1} & ... & f_{t_M,wT}
\end{array}
\right] 假设标签个数为M,句子长度为T
2.标签间的转换概率表示[A]i,j[A]_{i,j}表示相继两个标签相互转换概率,转换概率也是参数需要求解
3.则某条路径的输出为s(xT1,iT1)=∑Tt=1(Ait−1,it+fit,t)s(x_1^T,i_1^T)=\sum_{t=1}^T(Ai_{t-1,i_t}+f_{i_t},t),即每一条路径的结果该路径上标签转换之和加上神经网络输出。距离对于三个词长度的输入w=(x1,x2,x3)和路径为tag=(t1,t2,t3)w=(x1,x2,x3)和路径为tag=(t1,t2,t3)该路径得分为A0,t1+fx1,t1+At1,t2+fx2,t2+At2,t3+fx3,t3A_{0,t1}+f_{x1,t1}+A_{t1,t2}+f_{x2,t2}+A_{t2,t3}+f_{x3,t3}
4. 输出层可以表示为logp(yT1|xT1)=s(xT1,yT1)−logadd(s(xT1,jT1))log p(y_1^T|x_1^T)=s(x_1^T,y_1^T)-logadd(s(x_1^T,j_1^T))此时需要遍历所有可能路径,所有可能路径为TMT^M
5.然而该计算可以采用动态规划进行求解,主要运用了log的结合律,详细介绍如下log∑i∑j(zi,j)=log∑ielog∑j(zi,j)=logaddi logaddj(zi,j)log \sum_i \sum_j(z_{i,j})=log \sum_i e^{log\sum_j(z_{i,j}})=logadd_i \ logadd_j(z_{i,j})
logadd(c)=log∑(et)=log(n∗et)=t+log(n)logadd(c)=log \sum(e^t)=log(n*e^t)=t+log(n)
δt(k)=logaddjt1∩jt=ks(xt1,jt1)=logaddi logaddjt1∩jt−1=i∩jt=ks(xt1,jt−11)+Ajt−1,k+fk,t=logaddiδt−1(i)+Ai,k+fk,t=fk,t+logaddi(δt−1(i)+Ai,k)\begin{align}
\delta_t(k) & = logadd_{j_1^t \cap j_t=k}s(x_1^t, j_1^t) \\
& = logadd_i \ logadd_{j_1^t \cap j_{t-1}=i\cap j_t=k}s(x_1^t, j_1^{t-1})+A_{j_{t-1},k}+f_{k,t} \\
& = logadd_i \delta_{t-1}(i) +A_{i,k}+f_{k,t}\\
& = f_{k,t} + logadd_i (\delta_{t-1}(i) +A_{i,k})
\end{align}
解释如下:δt(k)表示第t个词为标签k打分\delta_t(k)表示第t个词为标签k打分,则输出层最后一项表示为logadd(s(xT1,jT1))=logaddi(δT(i))logadd(s(x_1^T,j_1^T))=logadd_i(\delta_T(i)),即最后一个词取所有标签结果之和。
6.推理过程可以采用维特比算法
求解
总体求解过程可以采用SGD进行优化,标准神经网络求解过程BP算法,每一步都是可导的。两个小trick,一是fan-in即在初始化是某层初始化参数采用特定分布,即中心一致分布,方差为fan-in平方根的导数;二是学习率为fan-in倒数,保持不变。
提高效果手段
采用上述标准流程基本上能够接近最优解,然后要达到理想效果还需要一些手段进行优化,举例如下1. 输出层可以采用排序标准而不是基于熵
2. 利用语言模型进行初始化,wordensemble过程
3. 多任务学习,多个任务同时学习认为共享中间参数,最后几层作为特定任务的输出,结构如下
4. 后缀处理
5. Gazetteers:特征字典
6. 级联,将多个学习任务进行串联
7. 模型组合
8. 结构分析-Parsing
9. 固定特征工程
总结
1.本文给出一个统一神经网络架构能够处理多种NLP任务,简单结构能够处理大部分问题,但是效果一般。2.想要得到更好结果需要考虑句子级别特征以及句子级别释然函数,此时训练复杂度很高。
3.可见天下没有免费午餐,任何标准框架想要得到理想结果,还需要深入探索优化。
4.但是其中对文本表示为神经网络的思路还是非常值得学习和了解。
相关文章推荐
- 从头认识Spring-2.6 在注解中使用表达式@Value(2)-使用表达式注入其他对象的值
- [mvc]记一次“项目”的历程
- /etc/host 配置主机名字
- asp.net mvc 如何调用微信jssdk接口:分享到微信朋友(圈)| 分享到qq空间
- web过滤器
- 【每周一文】A Few Usefull Things to know about Machine Learning
- socket超时设置详解(connect/read/write)
- 梯度下降实现案例(含python代码)
- java如何将一个序列化对象添加到压缩文件中
- parse()与stringify()
- Java学习之静态修饰符:static
- 一道有趣的题目
- [HDOJ1394]Minimum Inversion Number(线段树,逆序数)
- 太阳神电商业务辅助工具1.5
- 51nod 1405 树的距离之和
- nefuoj-549:气球
- 在程序中添加广告
- UVA 297
- 蓝桥杯 未名湖边的烦恼 (算法训练)
- 使用ServerSocketChannel与SocketChannel实现的CS模式