9.5 神经语言模型 331
9.5 神经语言模型
神经网络提供了一种工具,只要将问题的输入和输出定义好,就可以学习输入
和输出之间的对应关系。显然,很多自然语言处理任务都可以用神经网络进行实现。
比如,在机器翻译中,可以把输入的源语言句子和输出的目标语言句子用神经网络
建模;在文本分类中,可以把输入的文本内容和输出的类别标签进行神经网络建模,
等等。
为了更好地理解神经网络和深度学习在自然语言处理中的应用。这里介绍一种
基于神经网络的语言建模方法
——
神经语言模型(Neural Language Model)。可以说,
神经语言模型是深度学习时代下自然语言处理的标志性成果,它所涉及的许多概念
至今仍是研究的热点,比如:词嵌入、表示学习、预训练等。此外,神经语言模型也
为机器翻译的建模提供了很好的思路。从某种意义上说,机器翻译的深度学习建模
的很多灵感均来自神经语言模型,二者在一定程度上是统一的。
9.5.1 基于前馈神经网络的语言模型
回顾一下第二章的内容,语言建模的问题被定义为:对于一个词序列 w
1
w
2
...w
m
,
如何计算该词序列的可能性?词序列出现的概率可以通过链式法则得到:
P (w
1
w
2
...w
m
) = P (w
1
)P (w
2
|w
1
)P (w
3
|w
1
w
2
)...P (w
m
|w
1
...w
m−1
) (9.71)
由于 P (w
m
|w
1
...w
m−1
) 需要建模 m −1 个词构成的历史信息,这个模型仍然很
复杂。于是就有了基于局部历史的 n-gram 语言模型:
P (w
m
|w
1
...w
m−1
) = P (w
m
|w
m−n+1
...w
m−1
) (9.72)
其中,P (w
m
|w
m−n+1
...w
m−1
) 可以通过相对频次估计进行计算,如公式(9.73)所示,
其中 count(·) 表示在训练数据上的频次:
P (w
m
|w
m−n+1
...w
m−1
) =
count(w
m−n+1
...w
m
)
count(w
m−n+1
...w
m−1
)
(9.73)
这里,w
m−n+1
...w
m
也被称作 n-gram,即 n 元语法单元。n-gram 语言模型是一种
典型的基于离散表示的模型。在这个模型中,所有的词都被看作是离散的符号。因
此,不同单词之间是“完全”不同的。另一方面,语言现象是十分多样的,即使在很
大的语料库上也无法得到所有 n-gram 的准确统计。甚至很多 n-gram 在训练数据中
从未出现过。由于不同 n-gram 间没有建立直接的联系,n-gram 语言模型往往面临数
据稀疏的问题。比如,虽然在训练数据中见过“景色”这个词,但是测试数据中却出
现了“风景”这个词,恰巧“风景”在训练数据中没有出现过。即使“风景”和“景
色”表达的是相同的意思,n-gram 语言模型仍然会把“风景”看作未登录词,赋予
一个很低的概率值。
332 Chapter 9. 人工神经网络和神经语言建模 肖桐 朱靖波
上面这个问题的本质是 n-gram 语言模型对词使用了离散化表示,即每个单词都
孤立的对应词表中的一个索引,词与词之间在语义上没有任何“重叠”。神经语言模
型重新定义了这个问题。这里并不需要显性地通过统计离散的 n-gram 的频度,而是
直接设计一个神经网络模型 g(·) 来估计单词生成的概率,如下所示:
P (w
m
|w
1
...w
m−1
) = g(w
1
...w
m
) (9.74)
g(w
1
...w
m
) 实际上是一个多层神经网络。与 n-gram 语言模型不同的是 g(w
1
...
w
m
) 并不包含对 w
1
...w
m
的任何假设,比如,在神经网络模型中,单词不再是离散
的符号,而是连续空间上的点。这样两个单词之间也不再是简单的非 0 即 1 的关系,
而是具有可计算的距离。此外,由于没有对 w
1
...w
m
进行任何结构性的假设,神经
语言模型对问题进行端到端学习。通过设计不同的神经网络 g(·),可以从不同的角度
“定义”序列的表示问题。当然,这么说可能还有一些抽象,下面就一起看看神经语
言模型究竟是什么样子的。
1. 模型结构
最具代表性的神经语言模型是前馈神经网络语言模型(Feed-forward Neural Net-
work Language Model,FNNLM)。这种语言模型的目标是用神经网络计算 P (w
m
|w
m−n+1
...w
m−1
),之后将多个 n-gram 的概率相乘得到整个序列的概率
[72]
。
o
i−3
o
i−2
o
i−1
(index) (index) (index)
e
1
= o
i−3
C e
2
= o
i−2
C e
3
= o
i−1
C
h
0
= Tanh([e
1
,e
2
,e
3
]H + d)
y = Softmax(h
0
U)
P (w
i
|w
i−3
w
i−2
w
i−1
)
图 9.42 4-gram 前馈神经网络语言架构
为了有一个直观的认识,这里以 4-gram 的 FNNLM 为例,即根据前三个单词
w
i−3
、
w
i−2
、
w
i−1
预测当前单词
w
i
的概率。模型结构如图
9.42所示。从结构上看,
FNNLM
是一个典型的多层神经网络结构。主要有三层:
• 输入层(词的分布式表示层),即把输入的离散的单词变为分布式表示对应的实
数向量;
• 隐藏层,即将得到的词的分布式表示进行线性和非线性变换;
• 输出层(Softmax 层),根据隐藏层的输出预测单词的概率分布。
9.5 神经语言模型 333
这三层堆叠在一起构成了整个网络,而且也可以加入从词的分布式表示直接到
输出层的连接(红色虚线箭头)。
2. 输入层
o
i−3
、o
i−2
、o
i−1
为该语言模型的输入(绿色方框),输入为每个词(如上文的
w
i−1
、w
i−2
等)的 One-hot 向量表示(维度大小与词表大小一致),每个 One-hot 向量
仅一维为 1,其余为 0,比如:(0, 0, 1, . . . , 0) 表示词表中第三个单词。之后把 One-hot 向
量乘以一个矩阵 C 得到单词的分布式表示(紫色方框)。令 o
i
为第 i 个词的 One-hot
表示,e
i
为第 i 个词的分布式表示,则分布式表示 e
i
的计算方式如下:
e
i
= o
i
C (9.75)
这里的 C 可以被理解为一个查询表,根据 o
i
中为 1 的那一维,在 C 中索引到相应的
行进行输出(结果是一个行向量)。通常,把 e
i
这种单词的实数向量表示称为词嵌
入,把 C 称为词嵌入矩阵。
3. 隐藏层和输出层
把得到的 e
1
、e
2
、e
3
三个向量级联在一起,经过两层网络,最后通过 Softmax 函
数(橙色方框)得到输出,具体过程为:
y = Softmax(h
0
U) (9.76)
h
0
= Tanh([e
i−3
,e
i−2
,e
i−1
]H + d) (9.77)
这里,输出 y 是词表 V 上的一个分布,来表示 P (w
i
|w
i−1
,w
i−2
,w
i−3
)。U、H 和 d 是
模型的参数。这样,对于给定的单词 w
i
可以用 y
i
得到其概率,其中 y
i
表示向量 y 的
第 i 维。
Softmax(·) 的作用是根据输入的 |V | 维向量(即 h
0
U),得到一个 |V | 维的分布。
令 τ
τ
τ 表示 Softmax(·) 的输入向量,Softmax 函数可以被定义为:
Softmax(τ
i
) =
exp(τ
i
)
P
|V |
i
′
=1
exp(τ
i
′
)
(9.78)
这里,exp(·) 表示指数函数。Softmax 函数是一个典型的归一化函数,它可以将输入
的向量的每一维都转化为 0-1 之间的数,同时保证所有维的和等于 1。Softmax 的另
一个优点是,它本身(对于输出的每一维)都是可微的(如图9.43所示),因此可以
直接使用基于梯度的方法进行优化。实际上,Softmax 经常被用于分类任务。也可以
把机器翻译中目标语单词的生成看作一个分类问题,它的类别数是 |V |。
334 Chapter 9. 人工神经网络和神经语言建模 肖桐 朱靖波
−6 −4 −2 0 2 4 6
0.5
1
x
Softmax(x)
图 9.43 Softmax 函数(一维)所对应的曲线
4. 连续空间表示能力
值得注意的是,在 FNNLM 中,单词已经不再是一个孤立的符号串,而是被表示
为一个实数向量。这样,两个单词之间可以通过向量计算某种相似度或距离。这导
致相似的单词会具有相似的分布,进而缓解 n-gram 语言模型的问题
——
明明意思
很相近的两个词但是概率估计的结果差异性却很大。
在 FNNLM 中,所有的参数、输入、输出都是连续变量,因此 FNNLM 也是一个
典型的连续空间模型。通过使用交叉熵等损失函数,可以很容易地对 FNNLM 进行
优化。比如,可以使用梯度下降法对 FNNLM 的模型参数进行训练。
虽然 FNNLM 形式简单,却为处理自然语言提供了一个全新的视角。首先,该模
型重新定义了“词是什么”
——
它并非词典的一项,而是可以用一个连续实数向量
进行表示的可计算的“量”。此外,由于 n-gram 不再是离散的符号序列,模型不需要
记录 n-gram,所以很好的缓解了上面所提到的数据稀疏问题,模型体积也大大减小。
当然,FNNLM 也引发后人的许多思考,比如:神经网络每一层都学到了什么?
是词法、句法,还是一些其他知识?如何理解词的分布式表示?等等。在随后的内容
中也会看到,随着近几年深度学习和自然语言处理的发展,部分问题已经得到了很
好的解答,但是仍有许多问题需要进一步探索。
9.5.2 对于长序列的建模
FNNLM 固然有效,但是和传统的 n-gram 语言模型一样需要依赖有限上下文假
设,也就是 w
i
的生成概率只依赖于之前的 n −1 个单词。很自然的一个想法是引入
更大范围的历史信息,这样可以捕捉单词间的长距离依赖。
1. 基于循环神经网络的语言模型
对于长距离依赖问题,可以通过循环神经网络(Recurrent Neural Network,或 RNN)
进行求解。通过引入循环单元这种特殊的结构,循环神经网络可以对任意长度的历
史进行建模,因此在一定程度上解决了传统 n-gram 语言模型有限历史的问题。正是
基于这个优点,循环神经网络语言模型(RNNLM)应运而生
[73]
。
在循环神经网络中,输入和输出都是一个序列,分别记为 (x
1
,...,x
m
) 和 (y
1
,...,
9.5 神经语言模型 335
y
m
)。它们都可以被看作是时序序列,其中每个时刻 t 都对应一个输入 x
t
和输出 y
t
。
循环神经网络的核心是循环单元(RNN Cell),它读入前一个时刻循环单元的输出和
当前时刻的输入,生成当前时刻循环单元的输出。图9.44展示了一个简单的循环单元
结构,对于时刻 t,循环单元的输出被定义为:
h
t
= Tanh(x
t
U + h
t−1
W) (9.79)
其中,h
t
表示 t 时刻循环单元的输出,h
t−1
表示 t−1 时刻循环单元的输出,U 和 W
是模型的参数。可以看出,循环单元的结构其实很简单,只是一个对 h
t−1
和 x
t
的线
性变换再加上一个 Tanh 函数。通过读入上一时刻的输出,当前时刻可以访问以前的
历史信息。这个过程可以循环执行,这样就完成了对所有历史信息的建模。h
t
可以
被看作是序列在 t 时刻的一种表示,也可以被看作是网络的一个隐藏层。进一步,h
t
可以被送入输出层,得到 t 时刻的输出:
y
t
= Softmax(h
t
V) (9.80)
其中,V 是输出层的模型参数。
图9.44展示了一个基于循环神经网络的语言模型结构。首先,所有输入的单词会
被转换成分布式表示(红色部分),这个过程和 FNNLM 是一样的。之后,该模型堆
叠了两层循环神经网络(绿色部分)。最后通过 Softmax 层(紫色部分)得到每个时
刻的预测结果 y
t
= P (w
t
|w
1
...w
t−1
)。
RNN Cell RNN Cell RNN Cell RNN Cell
e
1
= o
1
C e
2
= o
2
C e
3
= o
3
C e
4
= o
4
C
o
1
o
2
o
3
o
4
RNN Cell RNN Cell RNN Cell RNN Cell
Softmax(·) Softmax(·) Softmax(·) Softmax(·)
P (w
2
) P (w
3
|w
2
) P (w
4
|w
2
w
3
) P (w
5
|w
2
w
3
w
4
)
图 9.44 基于循环神经网络的语言模型结构
RNNLM 体现了一种“记忆”的能力。对于每一个时刻,循环单元都会保留一部
分“以前”的信息,并加入“现在”的信息。从这个角度说,RNNLM 本质上是一种
记忆模型。在简单的循环单元结构的基础上,也有很多改进工作,如 LSTM、GRU
等模型,这部分内容将会在第十章进行介绍。
336 Chapter 9. 人工神经网络和神经语言建模 肖桐 朱靖波
2. 其他类型的语言模型
通过引入记忆历史的能力,RNNLM 缓解了 n-gram 模型中有限上下文的局限性,
但依旧存在一些问题。随着序列变长,不同单词之间信息传递路径变长,信息传递的
效率变低。对于长序列,很难通过很多次的循环单元操作保留很长的历史信息。过长
的序列还容易引起梯度消失和梯度爆炸问题(详见9.4.4节),增加模型训练的难度。
针对这个问题,一种解决方法是使用卷积神经网络
[424]
。卷积神经网络的特点是
可以对一定窗口大小内的连续单词进行统一建模,这样非常易于捕捉窗口内单词之
间的依赖,同时对它们进行整体的表示。进一步,卷积操作可以被多次叠加使用,通
过更多层的卷积神经网络可以捕捉更大范围的依赖关系。关于卷积神经网络及其在
机器翻译中的应用,第十一章会有详细论述。
此外,研究者也提出了另一种新的结构
——
自注意力机制(Self-attention Mech-
anism)。自注意力是一种特殊的神经网络结构,它可以对序列上任意两个词的相互
作用直接进行建模,这样也就避免了循环神经网络中随着距离变长信息传递步骤增
多的缺陷。在自然语言处理领域,自注意力机制被成功地应用在机器翻译任务上,著
名的 Transformer 模型
[23]
就是基于该原理工作的。第十二章会系统地介绍自注意力机
制和 Transformer 模型。
9.5.3 单词表示模型
在神经语言建模中,每个单词都会被表示为一个实数向量。这对应了一种单词
的表示模型。下面就来看看传统的单词表示模型和这种基于实数向量的单词表示模
型有何不同。
1. One-hot 编码
One-hot 编码(也称独热编码)是传统的单词表示方法。One-hot 编码把单词表示
为词汇表大小的 0-1 向量,其中只有该词所对应的那一项是 1,而其余所有项都是 0。
举个简单的例子,假如有一个词典,里面包含 10k 个单词,并进行编号。那么每个单
词都可以表示为一个 10k 维的 One-hot 向量,它仅在对应编号那个维度为 1,其他维
度都为 0,如图9.45所示。
0
1
0
0
0
...
0
0
0
0
1
0
...
0
你
1
桌子
2
他
3
椅子
4
我们
5
...
你好
10k
桌子
椅子
cos(‘桌子’,‘椅子’) = 0
图 9.45 单词的 One-hot 表示
9.5 神经语言模型 337
One-hot 编码的优点是形式简单、易于计算,而且这种表示与词典具有很好的对
应关系,因此每个编码都可以进行解释。但是,One-hot 编码把单词都看作是相互正
交的向量。这导致所有单词之间没有任何的相关性。只要是不同的单词,在 One-hot
编码下都是完全不同的东西。比如,大家可能会期望诸如“桌子”和“椅子”之类的
词具有一些相似性,但是 One-hot 编码把它们看作相似度为 0 的两个单词。
2. 分布式表示
神经语言模型中使用的是一种分布式表示。在神经语言模型里,每个单词不再
是完全正交的 0-1 向量,而是在多维实数空间中的一个点,具体表现为一个实数向
量。很多时候,也会把单词的这种分布式表示叫做词嵌入。
单词的分布式表示可以被看作是欧式空间中的一个点,因此单词之间的关系也
可以通过空间的几何性质进行刻画。如图9.46所示,可以在一个 512 维空间上表示不
同的单词。在这种表示下,“桌子”与“椅子”之间是具有一定的联系的。
0.1
−1
2
...
0
1
2
0.2
...
−1
属性
1
属性
2
属性
3
...
属性
512
桌子
椅子
cos(‘桌子’,‘椅子’) = 0.5
图 9.46 单词的分布式表示 (词嵌入)
那么,分布式表示中每个维度的含义是什么?可以把每一维度都理解为一种属
性,比如一个人的身高、体重等。但是,神经网络模型更多的是把每个维度看作是单
词的一种抽象“刻画”,是一种统计意义上的“语义”,而非简单的人工归纳的事物的
一个个属性。使用这种连续空间的表示的好处在于,表示的内容(实数向量)可以进
行计算和学习,因此可以通过模型训练得到更适用于自然语言处理的单词表示结果。
为了方便理解,看一个简单的例子。假如现在有个“预测下一个单词”的任务:
有这样一个句子“屋里/要/摆放/一个/ ”,其中下划线的部分表示需要预测的下
一个单词。如果模型在训练数据中看到过类似于“摆放一个桌子”这样的片段,那
么就可以很自信的预测出“桌子”。另一方面,很容易知道,实际上与“桌子”相近
的单词,如“椅子”,也是可以预测的单词的。但是,“椅子”恰巧没有出现在训练数
据中,这时如果用 One-hot 编码来表示单词,显然无法把“椅子”填到下划线处;而
如果使用单词的分布式表示,很容易就知道“桌子”与“椅子”是相似的,因此预测
“椅子”在一定程度上也是合理的。
实例 9.1 屋里/要/摆放/一个/____ 预测下个词
屋里/要/摆放/一个/桌子 见过
屋里/要/摆放/一个/椅子 没见过,但是仍然是合理预测
338 Chapter 9. 人工神经网络和神经语言建模 肖桐 朱靖波
关于单词的分布式表示还有一个经典的例子:通过词嵌入可以得到如下关系:
“国王” =“女王” −“女人” +“男人”。从这个例子可以看出,词嵌入也具有一些
代数性质,比如,词的分布式表示可以通过加、减等代数运算相互转换。图9.47展示
了词嵌入在一个二维平面上的投影,不难发现,含义相近的单词分布比较临近。
图 9.47 分布式表示的可视化
语言模型的词嵌入是通过词嵌入矩阵进行存储的,矩阵中的每一行对应了一个
词的分布式表示结果。图9.48展示了一个词嵌入矩阵的实例。
e = o
C
单词 w 的 One-hot 表示
e=(8,0.2,-1,0.9,...,1)
o=(0,0,1,0,...,0)
单词 w 的分布式表示
1 0.2 −0.2 8 ... 0
0.6 0.8 −2 1 ... −0.2
8 0.2 −1 0.9 ... 2.3
1 1.2 −0.9 3 ... 0.2
... ... ... ... ... ...
1 0.3 3 0.9 ... 5.1
C
外部词嵌入系统得到的 C
图 9.48 词嵌入矩阵 C
通常,有两种方法得到词嵌入矩阵。一种方法是把词嵌入作为语言模型的一部
分进行训练,不过由于语言模型往往较复杂,这种方法非常耗时;另一种方法使用
更加轻便的外部训练方法,如 word2vec
[425]
、Glove
[168]
等。由于这些方法的效率较高,
因此可以使用更大规模的数据得到更好的词嵌入结果。
9.5.4 句子表示模型
目前,词嵌入已经成为诸多自然语言处理系统的标配,也衍生出很多有趣的研
究法方向。但是,冷静地看,词嵌入依旧存在一些问题:每个词都对应唯一的向量表
示,那么对于一词多义现象,词义需要通过上下文进行区分,这时使用简单的词嵌
入式是无法处理的。有一个著名的例子:
实例 9.2 Aaron is an employee of apple .
He finally ate the apple .
这两句中“apple”的语义显然是不同的,第一句中的上下文“Jobs”和“CEO”
可以帮助我们判断“apple”是一个公司名字,而不是水果。但是词嵌入只有一个结
9.5 神经语言模型 339
果,因此无法区分这两种情况。这个例子给我们一个启发:在一个句子中,不能孤立
的看待单词,应同时考虑其上下文的信息。也就是需要一个能包含句子中上下文信
息的表示模型。
回忆一下神经语言模型的结构,它需要在每个位置预测单词生成的概率。这个
概率是由若干层神经网络进行计算后,通过输出层得到的。实际上,在送入输出层
之前,系统已经得到了这个位置的一个向量(隐藏层的输出),因此可以把它看作是
含有一部分上下文信息的表示结果。
以 RNNLM 为例,图9.49展示了一个由四个词组成的句子,这里使用了一个两层
循环神经网络对其进行建模。可以看到,对于第三个位置,RNNLM 已经积累了从第
1 个单词到第 3 个单词的信息,因此可以看作是单词 1-3(“乔布斯 就职 于”)的一种
表示;另一方面,第 4 个单词的词嵌入可以看作是“苹果”自身的表示。这样,可以
把第 3 个位置 RNNLM 的输出和第 4 个位置的词嵌入进行合并,就得到了第 4 个位
置上含有上下文信息的表示结果。从另一个角度说,这里得到了“苹果”的一种新
的表示,它不仅包含苹果这个词自身的信息,也包含它前文的信息。
RNN Cell RNN Cell RNN Cell RNN Cell
embedding embedding embedding embedding
亚伦 任职
于
苹果
RNN Cell RNN Cell RNN Cell RNN Cell
的表示
“亚伦”
的表示
“亚伦任职”
的表示
“亚伦任职于”
的表示
“亚伦任职于苹果”
“苹果”的表示:
上下文
词
图 9.49 基于 RNN 的表示模型(词 + 上下文)
在自然语言处理中,句子表示模型是指把输入的句子进行分布式表示。不过表示
的形式不一定是一个单独的向量。现在广泛使用的句子表示模型可以被描述为:给
定一个输入的句子 {w
1
,...,w
m
},得到一个表示序列 {h
1
,...,h
m
},其中 h
i
是句子在
第 i 个位置的表示结果。{h
1
,...,h
m
} 就被看作是句子的表示,它可以被送入下游模
块。比如,在机器翻译任务中,可以用这种模型表示源语言句子,然后通过这种表示
结果进行目标语译文的生成;在序列标注(如词性标注)任务中,可以对输入的句子
进行表示,然后在这个表示之上构建标签预测模块。很多自然语言处理任务都可以
用句子表示模型进行建模,因此句子的表示模型也是应用最广泛的深度学习模型之
一。而学习这种表示的过程也被称作表示学习。
句子表示模型有两种训练方法。最简单的方法是把它作为目标系统中的一个模
340 Chapter 9. 人工神经网络和神经语言建模 肖桐 朱靖波
块进行训练,比如把句子表示模型作为机器翻译系统的一部分。也就是,并不单独
训练句子表示模型,而是把它作为一个内部模块放到其他系统中。另一种方法是把
句子表示作为独立的模块,用外部系统进行训练,之后把训练好的表示模型放入目
标系统中,再进行微调。这种方法构成了一种新的范式:预训练 + 微调(pre-training
+ fine-tuning)。图9.50对比了这两种不同的方法。
模块
目标系统
目标任务有标注数据
(a) 标准方法
模块
目标系统
语言模型
目标任务有标注数据大规模无标注数据
(b) 预训练 + 微调
图 9.50 表示模型的训练方法(与目标任务联合训练 vs 用外部任务预训练)
目前,句子表示模型的预训练方法在多项自然语言处理任务上取得了很好的效
果。预训练模型也成为了当今自然语言处理中的热点方向,相关系统也在很多评测
任务上刷榜。不过,上面介绍的模型是一种最简单句子表示模型,在第十六章会对
一些前沿的预训练方法和句子表示模型进行介绍。