RNN-循环神经网络(笔记)

循环神经网络(RNN)

循环神经网络最终要的一点是为模型增加了时序信息。

从公式上来看,他比MLP多了个时序的表达式。\mathbf{W}_{hh}\mathbf{h}_{t-1}代表的就是时序信息的计算公式。其实正真的时序信息存储在权重\mathbf{W}_{hh}中,但是这个权重要乘以上一个隐变量才能成为可以对model产生影响的有用的信息。


分类问题一般使用【交叉熵】作为损失函数,一个语言模型也可以看作是分类问题。比如中文一共有n个字符,语言模型输出的一定是其中一个字符。这个对应于做一个n类的分类问题,输出是其中一个类。

基于这种理念,语言模型也可以用【交叉熵】来衡量。-\log p(x_t|x_{t-1},...)是交叉熵公式。针对使用RNN的语言模型,它做的任务可能是通过一个词,推测接下来这个人说什么。那就设它要推测n个词,也就是推测n次,那所谓的【平均交叉熵】其实就是对每个词的交叉熵做平均(求和再除n)。


之前讲过一个叫数值稳定性的东西(可能出现梯度过小或梯度爆炸)。梯度裁剪的目的就是为了保证数值稳定,根本的原理就是\mathbf{g}\leftarrow\min\left(1,\frac\theta{\|\mathbf{g}\|}\right)\mathbf{g}。当梯度(g)小于θ,\frac\theta{\|\mathbf{g}\|}就会变大,经过min函数,g = 1 * g。如果g大于θ,\frac\theta{\|\mathbf{g}\|}就比1小,结果就是\frac\theta{\|\mathbf{g}\|} * g,得到θ,最终g = θ。这样就控制了梯度。

一般,RNN都是要做梯度剪裁的,因为隐层很多(有128的)


在实际使用RNN的时候,我们往往会采用随机采样进行训练,原因如下:

  1. 随机采样增强了RNN的模型泛化性
  2. 从理论上讲完整的输入一大段文本有助于训练,更能体现文本之间的逻辑关系。但是RNN记不住很长的序列,既然如此,不如选择随机采样,还可以增强模型泛化性。

门控循环单元(GRU)

门控单元出现的原因:RNN中有隐变量,随着时间的增长,这个隐变量所包含的信息会不断增多。但随着时间的推进,前面的时序信息会变得不重要。因此通过门控单元来调整和遗忘前面的信息。

GRU可以用在大一点的数据集上


更新门:确定哪些状态值得记录并学习。

重置门:丢弃部分隐藏状态。


Rt是重置门,Zt是更新门。


首先,R_t是一个0-1之间的数,因为它的计算公式中用了sigmoid。\odot的意思是按元素相乘(R_t\boldsymbol{H}_{t-1}是向量)。如果R_t中所有元素的值都接近0,那代表\boldsymbol{R}_t\odot\boldsymbol{H}_{t-1}的结果也接近0,这相当于把\boldsymbol{H}_{t-1}遗忘了;反之,则记住。


这个是正真的计算隐状态的公式,需要用到候选隐状态。这里的Z_t也是在0-1之间。两个极端情况:当Z_t=1的时候,H_t = H_{t-1},这时候隐状态就不更新了,直接延用上一个隐状态,即丢弃新输入的x(RNN中,当前隐状态由上一个隐状态和当前input同时组成);当Z_t=0的时候,H_t=\widetilde{H_t},现在隐状态由候选隐状态决定。极端情况下,Z_t=0,R_t=1,就变成了一个最基础的RNN。

因此,这个公式其实可以通过Z_t的不同取值来决定是否参考过去状态的隐藏层信息以及参考多少。


GRU的极端情况就是:只看当下,不管前面的所有信息;或者只看前面,不看本次的输入。

在做短文本的时候,不要用RNN,最好用GRU或者LSTM。长文本建议用注意力机制。

 长短期记忆网络(LSTM)



这里涉及到一个而候选记忆单元。这个单元的计算方法和RNN里H的计算方法是一样的。


LSTM中,用来存表示前一个时刻的状态的量有两个,一个是记忆单元Memory,一个是隐藏状态Hidden state。所以为什么前面RNN,GRU只有隐藏状态,但是还是用元组来表示,就是为了和这里统一,因为LSTM需要用元组来放这两个量。

这是GRU中隐状态的更新公式:

从式子中可以看到,两个项之间是有关联的。增大前面的权重,后面的权重就会减少。但是在LSTM中,它用了两个相互独立的变量。



这是LSTM的可视化图

遗忘门通过输入x_ts_{t-1}来判断要不要删除C,输入门同样通过x_ts_{t-1}来决定在C上增加哪些信息。

LSTM中,短期记忆链是s_t,长期记忆链是c_t.s_t每次都会更新,但是c_t可以选择是否保留。

深度循环神经网络

\mathbf{H}_t^j的上标表示行位置,下标表示列位置。


双向循环神经网络

目前的RNN只能看过去的信息(往后看),但是双向循环神经网络可以再通过未来回推(往前看)。

最后的结果o由正向的隐状态和反向的隐状态构成。

由于双向循环神经网络需要前后信息的缘故,他没法做推理。因为推理只有过去的信息。

编码器-解码器架构(Encoder-Decoder)

理解为,机器对于某种中间表达形式具有良好的学习效果(比如机器看不懂图片,但是可以看懂0/1信号),这就需要使用特征提取,或者说用编码器将输入转换成中间表达形式。

解码器的作用就是把中间表达形式转换成输出(人能看懂的),在分类问题中,就是转换为class或label。



序列到序列学习(seq2seq)

 

双向RNN可以用于编码器,但是不能用在解码器上。




束搜索

在seq2seq中,我们将每次预测可能性最大的那个词输出,当作下一个的输入。这是一种贪心的想法,每次都输出最好的,然后得到最好的结果。【左下方的那个图】

我们看右下方的那个图。在第二个时间步,没有选择最好的0.4,反而选择了0.3。因为输出变了,导致后面时间步3,4出现的内容也不一样。然后继续选最大的。计算结果会发现,第二步不选最好的,最终得到的结果反而更好。

贪心搜索的速度是最快的,每次选择局部最优解。但这种情况明显不适合用贪心。贪心要求:每次选局部最优解,最后可以得到全局最优解。但在seq2seq问题中,局部最优解不一定就适合整个序列,每次选局部最优解也不一定能得到全局最优。


贪心是最快的,但是不一定是最好的;穷举是最好的,但通常算不动。

因此,我们要取一个在两者之间的方法。


束搜索可以看作【不选择最优解】的贪心。它在贪心和穷举中找了一个平衡的方法,既有贪心的感觉,又有穷举的感觉。使用束搜索前要定义k的值,用来确定每次保留多少个候选。以上图为例,k=2,就是保留两个候选。

在第一个时间步,获得所有可能的输出及其可能性后,我们不是选择概率最大的那个,而是选择最大和第二大的作为输出。然后,整个过程会分裂成两个。

接下来,这里会变成两个部分继续进行训练(预测)。在获得输出和概率后,依旧选择概率最大的那两个【这里每次选取两个,是从所有输出中进行选择,而不是每个分支选择两个。按照后面那种方法,最后选择的输出会越来越多,最后很可能还是训练不动,变成穷举了】,然后对这两个继续进行预测。重复上述过程,直到结束。


这里看到,束搜索的时间复杂度其实挺低的。

我们必须要知道的是,使用束搜索,模型倾向于选择短句子而不是长句子。因为短句子的概率高(每个字的概率都是小于1的,很多的字连在一起构成句子,实际上进行的是概率乘法。所以句子越长,概率越低)。

在上面的这种问题下,我们对最终得分进行一些处理,来防止模型永远只选择短句子。方法是,使用\frac1{L^{\alpha}},句子越长,\frac1{L^{\alpha}}越小。由于后面取log得到的是负数。所以两者相乘,分数相对会大一些(就是负数乘分数,然后比较大小)


评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值