NLP学习笔记41-递归神经网络

一 序

   本文属于贪心NLP训练营学习笔记系列。

   为什么需要递归神经网络?

   类似天气、股票、语音这种数据,是时序数据,对于语音:同一个单词不同人说对应时长不同。

之前学习的多层感知器,假设输入是一个独立的没有上下文联系的单位,比如根据图谱识别动物类别。如果需要根据上一句话预测下一句话,就是输出必须依赖以前的输入,需要递归神经网络来实现这样的功能。

二 递归神经网络介绍

2.1 vanilla RNN 原始RNN

整体上还是:输入层=>隐藏层=>输出层  这种三层结构。 

x网络某一时刻的输入

 w_{xh} 是输入端到隐含层的权重表示,它将我们的原始输入进行抽象作为隐藏层的输入.

h_T某一时刻T的隐藏状态

\hat{y_T}某一时刻T的输出

w_{hh}隐含层到隐含层的权重,它是网络的记忆控制者,负责调度记忆。

w_{hy} 隐含层到输出层的权重,从隐藏层学习到的表示将通过它再一次抽象,并作为最终输出。

J^T(\theta ) 某一时刻T的 损失值,整个损失函数就是J求和。

h_t=f(w_{hh}h_{t-1} +w_{xh}x_t+b_1 )  其中b是bias

\hat{y}_t= g(w_{hy} \cdot h_t+b_2 )  其中b是bias

2.2 HMM VS RNN

相同点:都是通过hidden state 的变化来表示序列间的依赖关系。

不同点:隐状态的表示: hmm是onehot, RNN是分布表示,RNN的表示能力强很多,分布式表示类似于word2vec。

隐状态的演化方式: hmm是线性的,RNN是高度非线性。

剩下的不同点老师没讲,建议网上找找:以下来自网上的

HMM本质是一个概率模型,而RNN不是。另外RNN没有马尔科夫假设,可以考虑很长的历史信息。

2.3 语言模型 language model

语言模型: 一句话很多个单词,计算联合概率可以展开为计算条件概率的联乘。

这个是RNN对于语言模型的使用。计算公式跟前面是一样的。

2.4 RNN的深度

  

RNN从时间的维度看,它是深度模型。但是它有不同于CNN那种隐含层有很多的模型。

2.5 梯度爆炸与梯度消失

    RNN的反向传播,也称为基于时间的反向传播算法BPTT(back propagation through time)。跟多层感知器类似,对所有参数求损失函数的偏导,目的是损失函数最小。

我们J^T(\theta ) 某一时刻T的 损失值,例如:J^4(\theta ) 表示时间4的损失。下面看怎么计算梯度,还是使用链式法则

\frac{ \partial J^4(\theta )}{ \partial h_1 }=\frac{ \partial J^4(\theta )}{ \partial h_4 }\cdot \frac{\partial h_4 }{ \partial h_3}\cdot \frac{\partial h_3 }{ \partial h_2} \cdot \frac{\partial h_2 }{ \partial h_1}其中h_t= \sigma (w_{hh}h_{t-1} +w_{xh}x_t+b_1 ) 

可以看到,需要计算隐含层对之前隐含层的梯度。

\frac{ \partial h_{t} }{ \partial h_{t-1}} = diag( \sigma '(w_{hh}h_{t-1} +w_{xh}x_t+b_1 ))\cdot w_{hh}  其中diag部分是矩阵。

general form:

\frac{ \partial J^{(i)} (\theta ) }{ \partial h_j } =\frac{ \partial J^{(i)} (\theta ) }{ \partial h_i }\prod _{j<t<i} \frac{\partial h_t }{\partial h_{t-1} } 

存在连乘项,当时间序列足够长,即t足够大时,受w影响较大。w处于0~1之间,会导致 式子趋近于0,梯度消失(vanishing gradient)。当w的值很大(一般为初始化不当引起),就会趋近于无穷,这就造成了梯度爆炸(exploding gradient).

通常遇到的问题是梯度消失(会导致模型记不住之前的信息)。

long-term dependency

在解决RNN梯度消失的问题,先看个例子,如果记不住长距离的信息,只要最近的,会导致错误。因为句子的最关键的信息在前面。

如果这种问题使用N-Gram,会导致N小了不行,对于长句子N设为多少都不合适;另外,模型的大小和N的关系是指数级的。所以需要RNN。

Gradient Clipping(梯度裁剪) for exploding gradient

从老师画的梯度曲线图,发生梯度爆炸,那么就是学过了,会直接跳过最优解。从梯度定义

\theta ^{(t+1)}= \theta ^{(t)}-\eta _t \Delta _\theta f(\theta^{(t)} )

确定一个阈值,如果后面参数的g(t)超过了,直接裁剪。

裁剪就是类似于归一化操作。梯度乘以这个缩放因子(阈值/梯度大小)

g^{(t)}=g^{(t)}\cdot \frac{ hold}{ ||g^{(t)} ||}

得出的新的梯度,再进行梯度下降法计算。

这都是理论。还得结合代码看看代理啥参数起作用。

梯度爆炸问题容易解决,上面那种clipping 方式,但是梯度消失的问题比较难以解决。

三 LSTM

  LSTM 是一种 RNN 特殊的类型,可以学习长期依赖信息。与RNN 相比LSTM 同样是一种重复神经网络模块的链式的形式。

不同的是:LSTM使用了不同的函数去去计算隐藏层的状态。

LSTM 的关键就是细胞状态,可以把cells看作是黑盒用以保存当前输入之前的保存的状态。LSTM 有通过精心设计的称作为“门”的结构来去除或者增加信息到细胞状态的能力。

门是一种让信息选择式通过的方法,具体通过sigmod函数实现,Sigmoid 层输出0,1数值.0代表“不许任何量通过”,1就指“允许任意量通过”.

LSTM 拥有三个门,分别是forget gate\input gate\ output gate

第一步是决定我们会从细胞状态中丢弃什么信息,忘记门: f_t= \sigma (W_f \cdot [ h_{t-1},x_t] +b_f) 

会读取 h_{t-1},x_t ,输出一个在0,1 数值给每个在细胞状态C_{t-1}.

下一步是确定什么样的新信息被存放在细胞状态中。

i_t= \sigma (W_i \cdot[ h_{t-1} , x_t]+b_i )  决定什么值我们将要更新

\hat C_t=tanh (W_c \cdot [h_{t-1},x_t]+b_c ) 

tanh层创建一个新的候选值向量\hat C_t 会被加入到状态中.

接下来更新旧细胞状态C_{t-1} 更新到C_t.

C_t= f_t \odot C_{t-1}+i_t\odot \hat{C}_{t-1}   这是是element wise

我们把旧状态C_{t-1}与 f_t相乘,丢弃掉我们确定需要丢弃的信息。后面的第二项是新的候选值,根据我们决定更新每个状态的程度进行变化。

最终,我们要求出输出什么值。

O_t= \sigma (W_o[h_{t-1},x_t ] +b_o)  来确定细胞状态的哪个部分将输出出去

h_t = O_t \odot tanh(C_t) (tanh得到一个在-1,1之间的值)并将它和O_t输出相乘,最终我们仅仅会输出我们确定输出的那部分。

小结:

LSTM能选择性的保留信息,从数学角度,计算梯度有优于RNN模型,但是不能万全解决梯度消失问题。

这里老师没有展开LSTM的关于梯度消失 的推导,网上说的之前RNN的联乘问题,LSTM  约等于(类比)为sigmoid函数。

 

LSTM 应用场景

老师推荐了这篇博客:http://karpathy.github.io/2015/05/21/rnn-effectiveness/

介绍了很多有趣的应用,后来很多人沿着这些问题做了改进,

四 Bi-directional LSTM

LSTM的 问题:无法编码从后到前的信息 。Bi-directional 是前向的LSTM、后向的LSTM组合成的Bi-LSTM.

最后将前向\vec{h_t}和后向的隐向量 \leftarrow {h_t}进行拼接得到h_t .

作为补充,老师讲了一个论文,给出了一个对比 ,RNN或者LSTM效果都不如Bi-LSTM 好。

GRU

门控循环单元(gated recurrent unit,GRU)是LSTM网络的一种效果很好的变体,它较LSTM网络的结构更加简单,而且效果也很好。

在LSTM中引入了三个门函数:输入门、遗忘门和输出门来控制输入值、记忆值和输出值。而在GRU模型中只有两个门:分别是更新门和重置门。

表达式如下:

   更新门

z_t= \sigma (W_z x_t + U_zh_{t-1}+b_z ) 

    其中 x_t为第 t 个时间步的输入向量,即输入序列 X 的第 t 个分量,它会经过一个线性变换(与权重矩阵 W_z相乘)。h_{t-1}保存的是前一个时间步 t-1 的信息,它同样也会经过一个线性变换。更新门将这两部分信息相加并投入到 Sigmoid 激活函数中,因此将激活结果压缩到 0 到 1 之间。

   更新门z_t帮助模型决定到底要将多少过去的信息传递到未来,或到底前一时间步和当前时间步的信息有多少是需要继续传递的。这一点非常强大,因为模型能决定从过去复制所有的信息以减少梯度消失的风险。

重置门

r_t=\sigma (W_rx_t+U_r h_{t-1}+b_r )

重置门r_t 该表达式与更新门的表达式是一样的,重置门主要决定了到底有多少过去的信息需要遗忘。

 当前记忆内容

\hat{h_t}=tanh(W_h x_t+U_h(r_t \odot h_{t-1} ) +b_h)

其中计算重置门 r_t  与h_{t-1}的 Hadamard 乘积,即对应元素乘积。因为前面计算的重置门r_t 是一个由 0 到 1 组成的向量,它会衡量门控开启的大小。例如某个元素对应的门控值为 0,那么它就代表这个元素的信息完全被遗忘掉。该 Hadamard 乘积将确定所要保留与遗忘的以前信息。

 前面是x_t为第 t 个时间步的输入向量, 将这两部分的计算结果相加 (起到一个拼接作用)  再投入双曲正切激活函数tanh中(数据放缩到-1~1的范围内)

最终记忆

h_t= (1-z_t)h_{t-1}+ z_t \odot \hat{h_t}

网络需要计算 h_t,这里需要 将保留当前单元的信息并传递到下一个单元中。z_t是更新门的激活结果,它同样以门控的形式控制了信息的流入。

前面一项表示对原本隐藏状态的选择性“遗忘”,忘记 h_{t-1}维度中一些不重要的信息.

后面一项是表示对包含当前节点信息的\hat{h_t}进行选择性”记忆“. 综合来看,是忘记传递下来的h_{t-1}某些旧信息(也就是说需要收集的h_{t-1}信息),并加入当前节点输入的某些新信息。

关于 GRU老师只是简单讲了下表达式,具体的细节还是这篇:https://zhuanlan.zhihu.com/p/32481747

****************

理论部分结束了,下一步该找数据动手做验证。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值