cs224n 笔记8 RNN和语言模型

前言

cs224n第八讲,介绍传统的RNN。

传统语言模型

语言模型是计算一个单词序列,也就是一个句子的概率的模型。
传统的语言模型就是利用待预测单词前窗口内的单词序列进行预测,假设窗口大小为n,则根据马尔科夫假设,可以用以下公式进行表示:
p ( w 1 , w 2 . . . w m ) = ∏ i = 1 i = m p ( w i ∣ w 1 , w 2 . . . w i − 1 ) = ∏ i = 1 i = m p ( w i ∣ w i − 1 , w i − 2 . . . w i − n ) p(w_1,w_2...w_m)=\prod_{i=1}^{i=m}p(w_i|w_1,w_2...w_{i-1})=\prod_{i=1}^{i=m}p(w_i|w_{i-1},w_{i-2}...w_{i-n}) p(w1,w2...wm)=i=1i=mp(wiw1,w2...wi1)=i=1i=mp(wiwi1,wi2...win)
式中概率的计算方法:
p ( w 2 ∣ w 1 ) = C o u n t ( w 1 , w 2 ) C o u n t ( w 1 ) p(w_2|w_1)=\frac{Count(w_1,w_2)}{Count(w_1)} p(w2w1)=Count(w1)Count(w1,w2)
p ( w 3 ∣ w 1 , w 2 ) = C o u n t ( w 1 , w 2 , w 3 ) C o u n t ( w 1 , w 2 ) p(w_3|w_1,w_2)=\frac{Count(w_1,w_2,w_3)}{Count(w_1,w_2)} p(w3w1,w2)=Count(w1,w2)Count(w1,w2,w3)
这种方法会消耗大量的内存和时间。
Bengio et al提出了第一个大规模深度学习自然语言处理模型,只不过是用前n个单词的词向量来做同样的事情(上文建模)而已,其网络结构如下:在这里插入图片描述
这种方法就是简单是利用窗口内单词的词向量进行预测,公式如下: y ^ = s o f t m a x ( W ( 2 ) t a n h ( W ( 1 ) x + b ( 1 ) ) + W ( 3 ) x + b ( 3 ) ) \hat{y}=softmax(W^{(2)}tanh(W^{(1)}x+b^{(1)})+W^{(3)}x+b^{(3)}) y^=softmax(W(2)tanh(W(1)x+b(1))+W(3)x+b(3))
这里 W ( 3 ) x + b ( 3 ) W^{(3)}x+b^{(3)} W(3)x+b(3)就是前n个单词词向量的线性运算,虽然这种模型名字里有“Neural”,但依然是传统模型。

Recurrent Neural Networks

这里开始讲到了常见的RNN模型,如下图所示
在这里插入图片描述
这种方法所需内存只和词表大小有关,而且每个词的预测都和之前所有词有关。
每个时刻的隐层表示:
h t = σ ( W ( h h ) h t − 1 + W ( h x ) x t ) h_t=\sigma(W^{(hh)}h_{t-1}+W^{(hx)}x_t) ht=σ(W(hh)ht1+W(hx)xt)
其中,

x t ∈ R d : x_t∈R^d: xtRd是时间t时输入的单词的词向量。
W ( h x ) ∈ R D h × d : W^{(hx)}∈R^{{D_h}×d}: W(hx)RDh×d用来condition输入词向量 x t x_t xt的的权值矩阵。
W ( h h ) ∈ R D h × D h : W^{(hh)}∈R^{{D_h×D_h}}: W(hh)RDh×Dh用来condition前一个时间节点隐藏层特征表示 h t − 1 h_{t−1} ht1的权值矩阵。
h t − 1 ∈ R D h : h_{t−1}∈R^{D_h}: ht1RDh: 前一个时间点 t−1 的非线性激活函数的输出, h 0 ∈ R D h h_0∈R^{D_h} h0RDh 是时间点 t=0 时的隐藏层初始状态。
σ ( ) : σ(): σ(): 非线性激活函数(sigmoid)
y t ^ = s o f t m a x ( W ( S ) h t ) : \hat{y_t}=softmax(W^{(S)}h_t) : yt^=softmax(W(S)ht)在时刻t时输出的整个词表 |V| 上的概率分布, y t ^ \hat{y_t} yt^是给定上文 h t − 1 h_{t−1} ht1和最近的单词 x ( t ) x^{(t)} x(t)预测的下一个单词。其中 W ( S ) ∈ R ∣ V ∣ × D h , y ^ ∈ R ∣ V ∣ W^{(S)}∈R^{|V|×D_h} , \hat{y}∈R^{|V|} W(S)RV×Dhy^RV
RNN的模型图也有如下画法:
在这里插入图片描述

损失函数

这里的损失函数就是常见的交叉熵,在t时刻的损失为:
J ( t ) ( θ ) = − ∑ j = 1 ∣ V ∣ y t , j × l o g ( y ^ t , j ) J^{(t)}(θ)=−\sum_{j=1}^{|V|}y_{t,j}×log(\hat{y}_{t,j}) J(t)(θ)=j=1Vyt,j×log(y^t,j)
在大小为T的整个语料上的损失:
J = 1 T ∑ t = 1 T J ( t ) ( θ ) = − 1 T ∑ t = 1 T ∑ j = 1 ∣ V ∣ y t , j × l o g ( y ^ t , j ) J=\frac{1}{T}\sum_{t=1}^{T}J^{(t)}(θ)=-\frac{1}{T}\sum_{t=1}^{T}\sum_{j=1}^{|V|}y_{t,j}×log(\hat{y}_{t,j}) J=T1t=1TJ(t)(θ)=T1t=1Tj=1Vyt,j×log(y^t,j)
如果以2为底数会得到“perplexity困惑度”,代表模型下结论时的困惑程度,越小越好:

P e r p l e x i t y = 2 J Perplexity=2^J Perplexity=2J

训练RNN困难

这里主要说了两个问题:前向传播的长距离依赖问题和反向传播的梯度消失(爆炸)问题。

长距离依赖

对比以下两个句子
“Jane walked into the room. John walked in too. Jane said hi to ___”
“Jane walked into the room. John walked in too. It was late in the day, and everyone was walking home after a long day at work. Jane said hi to ___”
对于第二个句子,RNN很难学会在空白处填上john,因为在前向传播过程中,输入x乘以很多次权重矩阵W,这样使得前面的信息被大量丢失,导致对后面影响较小,无法准确预测。

梯度消失(爆炸)

另一个问题就是反向传播的梯度消失和梯度爆炸。
整个序列的误差是每个时刻的误差之和:
∂ E ∂ W = ∑ t = 1 T ∂ E t ∂ W \frac{∂E}{∂W}=\sum_{t=1}^{T}\frac{∂E_t}{∂W} WE=t=1TWEt
同时,根据每个时刻的隐层向量 h t h_t ht的计算公式可以知道其与前一时刻的隐层向量有关,所以求梯度:
∂ E t ∂ W = ∑ k = 1 t ∂ E t ∂ y t ∂ y t ∂ h t ∂ h t ∂ h k ∂ h k ∂ W \frac{∂E_t}{∂W}=\sum_{k=1}^{t}\frac{∂E_t}{∂y_t}\frac{∂y_t}{∂h_t}\frac{∂h_t}{∂h_k}\frac{∂h_k}{∂W} WEt=k=1tytEthtythkhtWhk
熟悉RNN的都知道造成梯度消失和梯度爆炸的原因主要是公式中间的 ∂ h t ∂ h k \frac{∂h_t}{∂h_k} hkht,这是一个连乘的过程,累乘跨度是时间跨度,而且一般 h t h_t ht的激活函数的导数是小于1的,累乘之后就会造成梯度消失问题,当大于1时就会造成梯度爆炸问题。
一般来说,梯度消失问题比较常见,而梯度爆炸问题不常见而且容易解决。
课程中提到了一个梯度消失的直观例子,数据如下:
在这里插入图片描述
学习到的决策边界:
在这里插入图片描述
以上决策边界是用经典的三层网络结构训练得到的,课程中给出了不同激活函数下,不同层的梯度大小,其中蓝色是第一层梯度,绿色是第二层梯度:
sigmod激活函数下:
在这里插入图片描述
ReLU激活函数下:
在这里插入图片描述
从以上图中可以看出来,仅仅一层的差别,就会出现近乎减半的梯度的减小。

防止梯度爆炸

直观来讲,防止梯度爆炸的做法就是在梯度增长到达一定阈值时,暴力性的将其缩放到某个值,也就是梯度剪切。

防止梯度消失

这里讲到的是将参数矩阵初始化为单位矩阵,另外改变激活函数,使用ReLU这样的激活函数。当然,下图中还有LSTM这种改变RNN结构来缓解梯度消失的比较。
在这里插入图片描述
最后,课程中提到应该记录每个时刻t的误差,反向传播的时候将误差累加起来。

序列模型的应用

可以把每个词分类到NER、实体级别的情感分析(饭菜味道不错,但环境不太卫生)、意见表达。
其中,意见挖掘任务就是将每个词语归类为:
DSE:直接主观描述(明确表达观点等)
ESE:间接主观描述(间接地表达情感等)
本质上也还是分类任务
在这里插入图片描述
这种任务可以用简单的RNN实现,但是传统的RNN不能利用词语的下文进行预测,所以引出了双向RNN。
在这里插入图片描述
在双向RNN的基础上多加几个层。构成深度双向RNN
在这里插入图片描述
这里对不同层数下的结果进行了实验分析,结果表明并不是层数越多越好。
在这里插入图片描述

应用:RNN机器翻译模型

这部分讲解了机器翻译,也就是用RNN构成的常见的encoder-decoder模型。在这里插入图片描述
这里:
h t = f ( W ( h h ) h t − 1 + W ( h x ) x t ) h_t=f(W^{(hh)}h_{t-1}+W^{(hx)}x_t) ht=f(W(hh)ht1+W(hx)xt)
h t = f ( W ( h h ) h t − 1 ) h_t=f(W^{(hh)}h_{t-1}) ht=f(W(hh)ht1)
y t = s o f t m a x ( W ( S ) h t ) y_t=softmax(W^{(S)}h_t) yt=softmax(W(S)ht)
其中 W ( S ) W^{(S)} W(S)是RNN(encoder部分)最后一个单元的输出,作为后面decoder的输入。
以上方法训练效果不佳,考虑一下改进:
1.encoder和decoder使用不同的权值矩阵。也就是上述两个 W ( h h ) W^{(hh)} W(hh)不再相同。
2.改变decoder的输入,变成三个输入(前一时刻隐层、encoder最后一个隐层、前一个预测结果)
3.使用深度RNN
4.使用bi-directional encoder
5.不再用A B C→X Y作为训练实例,而是逆转原文词序:C B A→X Y。因为A更可能翻译为X,而梯度消失导致A无法影响输出,倒过来A离输出近一些。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值