【大模型基础_毛玉仁】1.2 基于RNN的语言模型
1.2 基于RNN的语言模型
循环神经网络 (RecurrentNeuralNetwork,RNN)是一类网络连接中包含环路的神经网络的总称。
给定一个序列,RNN的环路用于将历史状态叠加到当前状态上。 沿着时间维度,历史状态被循环累积,并作为预测未来状态的依据。
基于RNN的语言模型,以词序列作为输入,基于被循环编码的上文和当前词来预测下一个词出现的概率。
本节将先对原始RNN 的基本原理进行介绍,然后讲解如何利用RNN构建语言模型。
1.2.1 循环神经网络RNN
按推理过程中信号流转的方向,神经网络正向传播范式分为两类:前馈传播范式和循环传播范式,对应网络如下:
-
前馈神经网络(Feed-forward Neural Network,FNN):计算逐层向前"不走回头路"。
-
循环神经网络(RecurrentNeuralNetwork, RNN):某些层计算结果会通过环路 反向引回前面层中,形成"螺旋式前进"。
FNN和RNN:
以包含输入层、隐藏层、输出层的神经网络为例。图1.2中展示了最简单的FNN和RNN的网络结构示意图:
图1.2: 前馈传播范式与循环传播范式的对比。
设输入序列为 { x 1 , x 2 , x 3 , . . . , x t } \{x_1,x_2,x_3,...,x_t\} {x1,x2,x3,...,xt},隐状态为 { h 1 , h 2 , h 3 , . . . , h t } \{h_1,h_2,h_3,...,h_t\} {h1,h2,h3,...,ht},对应输出为 { o 1 , o 2 , o 3 , . . . , o t } \{o_1, o_2,o_3,..., o_t\} {o1,o2,o3,...,ot},
输入层、隐藏层、输出层对应的网络参数分别为 W I W_I WI, W H W_H WH, W O W_O WO。 g(·) 为激活函数,f(·)为输出函数。
将输入序列一个元素接着一个元素地串行输入时,
对于FNN,当前的输出只与当前的输入有关,即: (此处为方便对比,省去了偏置项)
o t = f ( W O g ( W I x t ) ) o_t = f(W_Og(W_I x_t)) ot=f(WOg(WIxt))
RNN在串行输入的过程中,前面的元素会被循环编码成隐状态,并叠 加到当前的输入上面。其在t时刻的输出如下:
h t = g ( W H h t − 1 + W I x t ) = g ( W H g ( W H h t − 2 + W I x t − 1 ) + W I x t ) = ⋯ ⋯ h_t = g(W_H h_{t-1} + W_I x_t) = g(W_H g(W_H h_{t-2} + W_I x_{t-1}) + W_I x_t) = \cdots \cdots ht=g(WHht−1+WIxt)=g(WHg(WHht−2+WIxt−1)+WIxt)=⋯⋯
o t = f ( W O h t ) o_t = f(W_O h_t) ot=f(WOht)
其中, t > 0, h0 = 0。将此过程按照时间维度展开,可得到RNN的推理过程,如 图1.3所示。
图1.3: RNN推理过程从时间维度拆解示意图。
FNN和RNN总结:
可以发现,在这样一个元素一个元素依次串行输入的设定下,
RNN: 可以将历史状态以隐变量的形式循环叠加到当前状态上 ,对历史信息进行考虑,呈现出螺旋式前进的模式。
FNN: 缺乏环路,仅对当前状态进行考虑,无法兼顾历史状态。
FNN和RNN问题:
如果FNN想要做到对历史信息进行考虑,则需要将所有元素同时输入到模型中去,这将导致模型参数量的激增。
虽然,RNN的结构可以让其在参数量不扩张的情况下实现对历史信息的考虑,但是这样的环路结构给RNN的训练带来了挑战。 在训练RNN时,涉及大量的矩阵联乘操作,容易引发梯度消失 或梯度爆炸问题。
RNN梯度问题:
-
梯度消失:
- 训练过程中,由于连续乘积中包含大量小于1的梯度,导致网络中较早时间步的梯度变得非常小,几乎接近于零。这使得网络难以学习到长距离的依赖关系。
-
梯度爆炸:
- 训练过程中,由于连续乘积中包含大量大于1的梯度,导致网络中较早时间步的梯度变得非常大,以至于更新权重时会导致模型不稳定。
RNN具体分析如下:
设 RNN 语言模型的训练损失为:
L = L ( x , o , W I , W H , W O ) = ∑ i = 1 t l ( o i , y i ) L = L(x, o, W_I, W_H, W_O) = \sum_{i=1}^{t} l(o_i, y_i) L=L(x,o,WI,WH,WO)=∑i=1tl(oi,yi)
其中, l ( ⋅ ) l(\cdot) l(⋅) 为损失函数,$y_i $ 为标签。
损失L关于参数 W H W_H WH的梯度为:
∂ L ∂ W H = ∑ i = 1 t ∂ l t ∂ o t ⋅ ∂ o t ∂ h t ⋅ ∂ h t ∂ h i ⋅ ∂ h i ∂ W H \frac{\partial L}{\partial W_H} = \sum_{i=1}^{t} \frac{\partial l_t}{\partial o_t} \cdot \frac{\partial o_t}{\partial h_t} \cdot \frac{\partial h_t}{\partial h_i} \cdot \frac{\partial h_i}{\partial W_H} ∂WH∂L=∑i=1t∂ot∂lt⋅∂ht∂ot⋅∂hi∂ht⋅∂WH∂hi
其中,
∂ h t ∂ h i = ∂ h t ∂ h t − 1 ∂ h t − 1 ∂ h t − 2 ⋯ ∂ h i + 1 ∂ h i = ∏ k = i + 1 t ∂ h k ∂ h k − 1 \frac{\partial h_t}{\partial h_i} = \frac{\partial h_t}{\partial h_{t-1}} \frac{\partial h_{t-1}}{\partial h_{t-2}} \cdots \frac{\partial h_{i+1}}{\partial h_i} = \prod_{k=i+1}^{t} \frac{\partial h_k}{\partial h_{k-1}} ∂hi∂ht=∂ht−1∂ht∂ht−2∂ht−1⋯∂hi∂hi+1=∏k=i+1t∂hk−1∂hk
并且,
∂ h k ∂ h k − 1 = ∂ g ( z k ) ∂ z k W H \frac{\partial h_k}{\partial h_{k-1}} = \frac{\partial g(z_k)}{\partial z_k} W_H ∂hk−1∂hk=∂zk∂g(zk)WH
其中,$ z_k = W_H h_{k-1} + W_I x_k$ 。综上,有
∂ L ∂ W H = ∑ i = 1 t ∂ l t ∂ o t ⋅ ∂ o t ∂ h t ⋅ ∏ k = i t ∂ g ( z k ) ∂ z k W H ⋅ ∂ h i ∂ W H \frac{\partial L}{\partial W_H} = \sum_{i=1}^{t} \frac{\partial l_t}{\partial o_t} \cdot \frac{\partial o_t}{\partial h_t} \cdot \prod_{k=i}^{t} \frac{\partial g(z_k)}{\partial z_k} W_H \cdot \frac{\partial h_i}{\partial W_H} ∂WH∂L=∑i=1t∂ot∂lt⋅∂ht∂ot⋅∏k=it∂zk∂g(zk)WH⋅∂WH∂hi
从上式中可以看出,求解 W H W_H WH的梯度时涉及大量的矩阵级联相乘。这会导致其数值被级联放大或缩小。
-
当 W H W_H WH的最大特征值小于1时,会发生梯度消失;
-
当 W H W_H WH的最大特征值大于1时,会发生梯度爆炸。
梯度消失和爆炸导致训练上述RNN非常困难。为了解决梯度消失和爆炸问题,GRU和LSTM引入门控结构,取得了良好效果,成为主流的RNN网络架构。
1.2.2 基于RNN的语言模型
1)概率说明:
对词序列 { x 1 , x 2 , x 3 , . . . , x t } \{x_1,x_2,x_3,...,x_t\} {x1,x2,x3,...,xt},基于RNN的语言模型每次根据当前词 w i w_i wi和循环输入的隐藏状态 h i − 1 h_{i−1} hi−1,来预测下一个词 w i + 1 w_{i+1} wi+1出现的概率,即:
P ( w i + 1 ∣ w 1 : i ) = P ( w i + 1 ∣ w i , h i − 1 ) P(w_{i+1} ∣w_{1:i} )=P(w_{i+1} ∣w_i ,h_{i−1} ) P(wi+1∣w1:i)=P(wi+1∣wi,hi−1)
说明:给定前面的词序列 w 1 : i w_{1:i} w1:i,下一个词 w i + 1 w_{i+1} wi+1 的概率,可简化为只依赖于当前词 w i w_i wi 和前一个隐藏状态 h i − 1 h_{i−1} hi−1。
整个句子序列的概率:(整个句子)
P ( w 1 : N ) = ∏ i = 1 N − 1 P ( w i + 1 ∣ w i , h i − 1 ) P(w_{1:N}) = \prod_{i=1}^{N-1} P(w_{i+1} | w_i, h_{i-1}) P(w1:N)=∏i=1N−1P(wi+1∣wi,hi−1)
RNN的语言模型中,输出为一个向量,其中每一维代表着词典中对应 词的概率。
设词典D中共有|D|个词 { w ^ 1 , w ^ 2 , w ^ 3 , . . . , w ^ ∣ D ∣ } \{\hat{w}_1, \hat{w}_2, \hat{w}3, ..., \hat{w}{|D|}\} {w^1,w^2,w^3,...,w^∣D∣},基于RNN的语言模型 的输出可表示为 o i = { o i [ w ^ d ] } d = 1 ∣ D ∣ o_i = \{o_i[\hat{w}d]\}{d=1}^{|D|} oi={oi[w^d]}d=1∣D∣,其中, o i [ w ^ d ] o_i[\hat{w}_d] oi[w^d] 表示词典中的词 w ^ d \hat{w}_d w^d 出现的概率。因此,对基于RNN的语言模型有:
P ( w 1 : N ) = ∏ i = 1 N − 1 P ( w i + 1 ∣ w 1 : i ) = ∏ i = 1 N o i [ w i + 1 ] P(w_{1:N}) = \prod_{i=1}^{N-1} P(w_{i+1} | w_{1:i}) = \prod_{i=1}^{N} o_i[w_{i+1}] P(w1:N)=∏i=1N−1P(wi+1∣w1:i)=∏i=1Noi[wi+1]
示例: 设有词典 D={我,喜欢,吃,苹果},并且有一个句子"我喜欢吃苹果"。我们用RNN来建模这个句子的概率。
首先,我们初始化隐藏状态 h0,然后逐个词输入到RNN中。
-
输入第一个词"我",计算隐藏状态 h1 和输出向量 o1。
-
输入第二个词"喜欢",基于 h1 计算 h2 和 o2。
-
输入第三个词"吃",基于 h2 计算 h3 和 o3。
-
输入第四个词"苹果",基于 h3 计算 h4 和 o4。
每一步的输出向量 oi 都是一个4维的概率分布,对应词典中的每个词。
例如,假设 o1=[0.1,0.2,0.3,0.4]=[(我)的概率, (喜欢)的概率, (吃)的概率, (苹果)的概率],那么 o1[苹果]=0.4。
根据公式,整个句子的概率就是:
- P(我, 喜欢, 吃, 苹果)=o1[喜欢]×o2[吃]×o3[苹果]
假设 o1[喜欢]=0.2,o2[吃]=0.3,o3[苹果]=0.4,那么:
- P(我, 喜欢, 吃, 苹果)=0.2×0.3×0.4=0.024
所以,这个句子的概率就是0.024。
2)损失函数
基于以上预训练任务,对RNN语言模型进行训练时,可选用如下交叉熵函数作为损失函数。
l C E ( o i ) = − ∑ d = 1 ∣ D ∣ I ( w ^ d = w i + 1 ) log o i [ w i + 1 ] = − log o i [ w i + 1 ] l_{CE}(o_i) = -\sum_{d=1}^{|D|} I(\hat{w}d = w{i+1}) \log o_i[w_{i+1}] = -\log o_i[w_{i+1}] lCE(oi)=−∑d=1∣D∣I(w^d=wi+1)logoi[wi+1]=−logoi[wi+1]
其中,$ I(\cdot) $ 为指示函数,当 $ \hat{w}d = w {i+1} $ 时等于 1,当 $ \hat{w}d \neq w{i+1} $ 时等于 0。
设训练集为 S ,RNN 语言模型的损失可以构造为:
L ( S , W I , W H , W O ) = 1 N ∣ S ∣ ∑ s = 1 ∣ S ∣ ∑ i = 1 N l C E ( o i , s ) L(S, W_I, W_H, W_O) = \frac{1}{N|S|} \sum_{s=1}^{|S|} \sum_{i=1}^{N} l_{CE}(o_{i,s}) L(S,WI,WH,WO)=N∣S∣1∑s=1∣S∣∑i=1NlCE(oi,s)
其中, o i , s o_{i,s} oi,s 为 RNN 语言模型输入第s个样本的第i个词时的输出。
3)问题
"自回归"过程存在着两个问题:
-
错误级联放大: 错误循环输入,将会不断的放大错误,导致模型不能很好拟合训练集;
-
串行计算效率低:因为下一个要预测的词依赖上一次的预测,每次预测之间是串行的,难以进行并行加速。
为解决上述问题,有以下方法:
-
Teacher Forcing: 每轮都仅将输出结果与"标准答案"(GroundTruth)进行拼接作为下 一轮的输入。将导致曝光偏差(ExposureBias)的问题。
-
曝光偏差:是指Teacher Forcing 训练模型的过程和模型在推理过程存在差异。
-
Teacher Forcing 在训练中,模型将依赖于"标准答案"进行下一次的预测,但是在推理预测中,模型"自回归"的产生文本,没有"标准答案"可参考。所以模型在训练过 程中和推理过程中存在偏差,可能推理效果较差。
-
-
ScheduledSampling: 其在TeacherForcing的 训练过程中循序渐进的使用一小部分模型自己生成的词代替"标准答案",在训练 过程中对推理中无"标准答案"的情况进行预演。
.
其他参考:【大模型基础_毛玉仁】系列文章
声明:资源可能存在第三方来源,若有侵权请联系删除!