一个神经网络自然语言模型当然需要神经网络的结构层次,但是在进入神经网络之前,怎么把单词表示成要输入的词向量,这也是一个非常重要的问题。其实,神经网络语言模型主要分两大部分,第一,输入词向量的表示问题,第二,神经网络结构的选择问题。只要处理好这两方面的问题,剩下的就交给训练了,当然其中还有一些细节。本文所描述的是一个一般化的多层神经网络结构,首先要说明一些标记记号:
假设一个神经网络函数为
f
θ
(
⋅
)
f_\theta(\cdot)
fθ(⋅),其参数为
θ
\theta
θ。如果有
L
L
L层的前馈网络,则认为由
f
θ
l
(
⋅
)
f_\theta^l(\cdot)
fθl(⋅)组成,
f
θ
(
⋅
)
=
f
θ
L
(
f
θ
L
−
1
(
⋅
⋅
⋅
f
θ
1
(
⋅
)
⋅
⋅
⋅
)
)
f_\theta(\cdot)=f_\theta^L(f_\theta^{L-1}(\cdot\cdot\cdot f_\theta^1(\cdot)\cdot\cdot\cdot))
fθ(⋅)=fθL(fθL−1(⋅⋅⋅fθ1(⋅)⋅⋅⋅))
再假设,给定一个矩阵
A
A
A,则
[
A
]
i
,
j
[A]_{i,j}
[A]i,j表示
A
A
A中第
i
i
i行第
j
j
j列的元素。
<
A
>
i
d
w
i
n
<A>_i^{d_{win}}
<A>idwin表示是由在矩阵
A
A
A第
i
i
i列向量周围的
d
w
i
n
d_{win}
dwin个列向量拼接而成的向量。也即
A
A
A中第
i
i
i列左右各
d
w
i
n
/
2
d_{win}/2
dwin/2个列向量拼接而成。特别的,
<
A
>
i
1
<A>^1_i
<A>i1表示矩阵
A
A
A第
i
i
i列向量。对于一个向量
v
v
v,
[
v
]
i
[v]_i
[v]i表示其第
i
i
i个标量元素。最后,序列
{
x
1
,
x
2
,
.
.
.
,
x
T
}
\{x_1,x_2,...,x_T\}
{x1,x2,...,xT}可写为
[
x
]
1
T
[x]^T_1
[x]1T,序列的第
i
i
i个元素为
[
x
]
i
[x]_i
[x]i。
##转化单词为特征向量
首先,每一个单词都有一个索引,网络的第一层就是通过一个查询表(lookup table)把单词索引映射为一个特征向量。
对每一个单词
w
∈
D
,
D
w\in D, D
w∈D,D为一个有限的字典,一个
d
w
r
d
d_{wrd}
dwrd维的特征向量由查询表层
L
T
W
(
⋅
)
LT_W(\cdot)
LTW(⋅)给出:
L
T
W
(
w
)
=
<
W
>
w
1
LT_W(w)=<W>^1_w
LTW(w)=<W>w1,
其中,
W
∈
R
d
w
r
d
×
∣
D
∣
W\in R^{d_{wrd}\times |D|}
W∈Rdwrd×∣D∣是一个要学习的矩阵参数。
<
W
>
w
1
∈
R
d
w
r
d
<W>^1_w\in R^{d_{wrd}}
<W>w1∈Rdwrd为
W
W
W的第
w
w
w列,
d
w
r
d
d_{wrd}
dwrd为单词向量维度(由用户选择的超参)。给定一个句子或任何具有
T
T
T个字典
D
D
D中的单词
[
w
]
1
T
[w]^T_1
[w]1T序列,则查询表会产生一个输出矩阵:
L
T
W
(
[
w
]
1
T
)
=
(
<
W
>
[
w
]
1
1
<
W
>
[
w
]
2
1
.
.
.
<
W
>
[
w
]
T
1
)
(1)
LT_W([w]^T_1)=(<W>_{[w]_1}^1\quad <W>_{[w]_2}^1... <W>_{[w]_T}^1)\tag{1}
LTW([w]1T)=(<W>[w]11<W>[w]21...<W>[w]T1)(1)
通过对这些特征向量的连接可以输入到后续的神经网络层中。
###扩展到单词的离散特征
更详细地,可以把每个单词向量更细分一下,即每个单词可以由多个离散的特征组成(这个对于英语语言来说,汉语好像没有这个问题)。比如一个单词,它有词根,它的小写的结尾和它大写的开头等特征,由这些特征组成这个单词的特征。
一般来说,假设一个单词由
K
K
K个离散特征表示,
w
∈
D
1
×
⋯
×
D
K
w\in D^1\times \cdots\times D^K
w∈D1×⋯×DK,其中,
D
k
D^k
Dk为第
k
k
k个特征的字典。我们把每个特征关联一个查询表
L
T
W
k
(
⋅
)
LT_{W^k}(\cdot)
LTWk(⋅),其参数
W
k
∈
R
d
w
r
d
k
×
∣
D
k
∣
W^k\in R^{d^k_{wrd}\times|D^k|}
Wk∈Rdwrdk×∣Dk∣,其中,
d
w
r
d
k
∈
N
d^k_{wrd}\in N
dwrdk∈N是一个用户设定的维度大小。给定一个单词
w
w
w,它的特征向量维度为
d
w
r
d
=
Σ
k
d
w
r
d
k
d_{wrd}=\Sigma_kd^k_{wrd}
dwrd=Σkdwrdk,也就是把组成它的离散特征拼接在一起:
L
T
W
1
,
.
.
.
,
W
K
(
w
)
=
[
L
T
W
1
(
w
1
)
⋮
L
T
W
K
(
w
K
)
]
=
[
<
W
1
>
w
1
1
⋮
<
W
K
>
w
K
1
]
LT_{W^1,...,W^K}(w)=\begin{bmatrix} LT_{W^1}(w_1)\\ \vdots\\ LT_{W^K}(w_K) \end{bmatrix} =\begin{bmatrix} <W^1>^1_{w_1}\\ \vdots\\ <W^K>^1_{w_K} \end{bmatrix}
LTW1,...,WK(w)=⎣⎢⎡LTW1(w1)⋮LTWK(wK)⎦⎥⎤=⎣⎢⎡<W1>w11⋮<WK>wK1⎦⎥⎤
上面那是一个单词的由多个离散特征向量拼接表示的特征向量。
那么,单词序列
[
w
]
1
T
[w]^T_1
[w]1T的查询表层的输出为一个矩阵:
L
T
W
1
,
.
.
.
,
W
K
(
[
w
]
1
T
)
=
[
<
W
1
>
[
w
1
]
1
1
⋯
<
W
1
>
[
w
1
]
T
1
⋮
⋮
<
W
K
>
[
w
K
]
1
1
⋯
<
W
1
>
[
w
K
]
T
1
]
(2)
LT_{W^1,...,W^K}([w]^T_1)=\begin{bmatrix} <W^1>^1_{[w_1]_1} &\cdots &<W^1>^1_{[w_1]_T}\\ \vdots&\quad &\vdots\\ <W^K>^1_{[w_K]_1}&\cdots &<W^1>^1_{[w_K]_T} \end{bmatrix}\tag{2}
LTW1,...,WK([w]1T)=⎣⎢⎡<W1>[w1]11⋮<WK>[wK]11⋯⋯<W1>[w1]T1⋮<W1>[wK]T1⎦⎥⎤(2)
其中,矩阵中的每一列为一个单词的由多个离散特征向量拼接表示的特征向量。
其实,我认为这种离散特征可以不被考虑,因为这些参数都是随机初始化的,并且在传入网络中训练,最后得到的词向量应该都会一样的,可能比较好的是,这种离散化可能提取每个词的词根向量和大小写向量。
##神经网络的输入方法
有两种方法把单词向量输入到神经网络中去,一种是基于窗口的方法;另一种是基于句子的方法,也称为卷积方法。
###基于窗口的方法
基于窗口方法认为一个单词的标注主要依赖于它近邻的单词,因此,要标注一个单词,我们使用一个固定大小为
k
s
z
k_{sz}
ksz(超参数)的窗口,窗口中的每一个单词都通过查询表(1)或(2)找到对应的词向量,这就产生一个
d
w
r
d
×
k
s
z
d_{wrd}\times k_{sz}
dwrd×ksz大小的词向量矩阵,然后把各个单词的词向量拼接成一个
d
w
r
d
k
s
z
d_{wrd}k_{sz}
dwrdksz维的列向量作为后续标准的神经网络的输入,因此可以写为:
f
θ
1
=
<
L
T
W
(
[
w
]
1
T
)
>
t
d
w
i
n
=
[
<
W
>
[
w
]
t
−
d
w
i
n
/
2
1
⋮
<
W
>
[
w
]
t
1
⋮
<
W
>
[
w
]
t
+
d
w
i
n
/
2
1
]
f_\theta^1=<LT_{W}([w]^T_1)>_t^{d_{win}}=\begin{bmatrix} <W>^1_{[w]_{t-d_{win}/2}}\\ \vdots\\ <W>^1_{[w]_t}\\ \vdots\\ <W>^1_{[w]_{t+d_{win}/2}} \end{bmatrix}
fθ1=<LTW([w]1T)>tdwin=⎣⎢⎢⎢⎢⎢⎢⎢⎡<W>[w]t−dwin/21⋮<W>[w]t1⋮<W>[w]t+dwin/21⎦⎥⎥⎥⎥⎥⎥⎥⎤
从下面一张图中可以清楚看出模型的结构:
每一个词由多个离散特征组成,通过设定窗口,再把对应各个单词的离散特征向量从查询表(记住,此查询表是需要训练的,得到的每一列是各个单词的词向量,即word embedding 或 word representation,但是具体地技术细节怎么实现训练呢?)中抽出,拼接成一个列向量,然后再经过标准的神经网络训练,此监督学习方法可以得到词性标注(POS),命名实体识别(NER)等,得到的副产品就是词向量。
基于卷积的方法
使用基于窗口的方法能解决大多数自然语言处理工作,但是对语义角色标注(SRL)力有所逮,因为假设一个单词标注依赖于一个前面的动词,但这个动词在窗口之外,那么它就不太可能标注正确,这种情况下,标注一个单词需要整个句子。这时候,基于卷积的方法就派上用场了。该卷积方法又称为时间延迟神经网络(TDNNs)。
卷基层:卷基层可以看做窗口方法的一般化,给定一个序列,其可以表示成为一个矩阵
f
θ
l
−
1
f_\theta^{l-1}
fθl−1,矩阵中的每一列都是序列中一个单词的词向量,然后对这个单词序列做卷积操作:
<
f
θ
l
>
t
1
=
W
l
<
f
θ
l
−
1
>
t
d
w
i
n
+
b
l
∀
t
<f_\theta^l>_t^1=W^l<f_\theta^{l-1}>_t^{d_{win}}+b^l\quad \forall t
<fθl>t1=Wl<fθl−1>tdwin+bl∀t
其中,权重矩阵
W
l
W^l
Wl是共享的,相当于卷积核,窗口的大小为
t
t
t,一般通过多个卷积层来提取更高级的特征。
最大池化层:卷积层的输出的大小依赖于句子长度的大小,由于神经网络的全连接层需要输入固定长度大小的特征,因此局部特征向量需要整合为一个全局特征向量,一般的最大池化层是取平均或取最大值,由于句子中大多数单词对于一个要标注单词的语义角色没多大影响,所以取平均操作没多大意义,所以可以用最大化方法。给定一个由卷积层
l
−
1
l-1
l−1输出的矩阵
f
θ
l
−
1
f_\theta^{l-1}
fθl−1,则最大池化层输出的向量为
f
θ
l
f_\theta^l
fθl:
[
f
θ
l
]
i
=
m
a
x
t
[
f
θ
l
−
1
]
i
,
t
1
≤
i
≤
n
h
u
l
−
1
[f_\theta^l]_i=max_t[f_\theta^{l-1}]_{i,t}\quad 1\le i\le n_{hu}^{l-1}
[fθl]i=maxt[fθl−1]i,t1≤i≤nhul−1
给出它的结构图形:
从上图可以清楚看出卷积层和最大池化层的操作,然后就是进入标准的神经网络结构了。
对于标准的神经网络,训练量十分庞大,如果是单纯的要训练词向量的话,可以使用Word2vec模型,它更改了神经网络中的一些结构,使得训练更具有效率,详情可看word2vec以及GloVe总结。
参考文献
【Ronan Collobert, Jason Weston, Leon Bottou, Michael Karlen, Koray Kavukcuogluy, Pavel Kuksaz】Natural Language Processing (almost) from Scratch
【Yoav Goldberg】A Primer on Neural Network Models for Natural Language Processing