任务

RNN的结构。循环神经网络的提出背景、优缺点。着重学习RNN的反向传播、RNN出现的问题(梯度问题、长期依赖问题)、BPTT算法。
双向RNN
递归神经网络
LSTM、GRU的结构、提出背景、优缺点。
针对梯度消失(LSTM等其他门控RNN)、梯度爆炸(梯度截断)的解决方案。
Memory Network(自选)
Text-RNN的原理。
利用Text-RNN模型来进行文本分类。
Recurrent Convolutional Neural Networks(RCNN)原理。
利用RCNN模型来进行文本分类。

RNN

RNN提出来的背景

大多数人造神经网络,如前馈神经网络,都没有记忆它们刚刚收到的输入。例如,如果提供前馈神经网络的字符“WISDOM”,当它到达字符“D”时,它已经忘记了它刚刚读过字符“S”,这是一个大问题。无论训练该网络是多么的辛苦,总是很难猜出下一个最有可能的字符“O”。这使得它成为某些任务的一个相当无用的候选人,例如在语音识别中,识别的好坏在很大程度上受益于预测下一个字符的能力。RNN提出来是为解决序列化的问题。
优点:

  • 加入了上一时刻隐藏层的输出,处理了时序问题

缺点:

  • 只能保存上一次比较短暂的内容,序列较长时,序列在前的信息对后面序列的作用越来越弱。

RNN结构图如下所示:
DatawhaleChina - Task8:循环和递归神经网络
有几点说明一下:

  • 左边的是一个简洁的网络,右边是展开的网络,
  • 注意细节,重点关注在一个神经元上,作用在每个神经元上的WUVW、U、V都是一样的
  • [x1,x2,x3,...,xn][x_{1},x_{2},x_{3},...,x_{n}]表示一个样本,怎么理解呢?x1x_1就是一个xt1x_{t-1},具体要看怎么应用,比如用在文本领域,xt1x_{t-1}就表示一个单词的词向量,一个句子有多个单词,一个文档有多个单词,这些单词被分词后按照先后顺序就是一个序列,也就形成了[x1,x2,x3,...,xn][x_{1},x_{2},x_{3},...,x_{n}]
  • sts_t为隐藏层的第t步的状态,它是网络的记忆单元。 st根据当前输入层的输出与上一步隐藏层的状态进行计算。st=f(Uxt+Wst1)s_t=f(U*x_t+W*s_{t−1}),其中f一般是非线性的**函数,如tanh或ReLU,在计算s0s_0时,即第一个单词的隐藏层状态,需要用到s1s_1,但是其并不存在,在实现中一般置为0向量;
  • oto_t是第t步的输出,如下个单词的向量表示,ot=softmax(Vst)o_t=softmax(V * s_t),但有写问题也需要说明:

1、你可以认为隐藏层状态sts_t是网络的记忆单元,sts_t包含了前面所有步的隐藏层状态。而输出层的输出oto_t只与当前步的sts_t有关,在实践中,为了降低网络的复杂度,往往sts_t只包含前面若干步而不是所有步的隐藏层状态,其实也保存不了所有不得隐藏状态信息;
2、在传统神经网络中,每一个网络层的参数是不共享的。而在RNN中,每输入一步,每一层各自都共享参数U,V,W。其反应者RNN中的每一步都在做相同的事,只是输入不同,因此大大地降低了网络中需要学习的参数;如果这是一个多层的传统神经网络,那么xtx_tsts_t之间的U矩阵与xt+1x_{t+1}st+1s_{t+1}之间的U是不同的,而RNNs中的却是一样的,同理对于s与s层之间的W、s层与o层之间的V也是一样的。
3、上图中每一步都会有输出,但是每一步都要有输出并不是必须的,或者说:并不是每一层的oo都是有用的,毕竟第一层的输入只有一个单词的词向量,输出没有上一层s0s_0,这个o1o_1也没有啥用。比如,我们需要预测一条语句所表达的情绪,我们仅仅需要关系最后一个单词输入后的输出,而不需要知道每个单词输入后的输出。同理,每步都需要输入也不是必须的。RNN的关键之处在于隐藏层,隐藏层能够捕捉序列的信息。

RNN反向推导

参考这几篇博客吧。
深度学习(五):循环神经网络(RNN)模型与前向反向传播算法

不过我只是很想提出一个问题,以为这些参数都是一样的,有必要每次都要去更新这些参数?

RNN存在的问题
  • 梯度消失的问题
    RNN网络的**函数一般选用双曲正切,而不是sigmod函数,(RNN的**函数除了双曲正切,RELU函数也用的非常多)原因在于RNN网络在求解时涉及时间序列上的大量求导运算,使用sigmod函数容易出现梯度消失,且sigmod的导数形式较为复杂。事实上,即使使用双曲正切函数,传统的RNN网络依然存在梯度消失问题。
    无论是梯度消失还是梯度爆炸,都是源于网络结构太深,造成网络权重不稳定,从本质上来讲是因为梯度反向传播中的连乘效应,类似于:0.99100=0.360.99^{100}=0.36,于是梯度越来越小,开始消失,另一种极端情况就是1.1100=137801.1^{100}=13780
  • 长期依赖的问题
    还有一个问题是无法“记忆”长时间序列上的信息,这个bug直到LSTM上引入了单元状态后才算较好地解决

LSTM

LSTM是针对RNN存在的问题改进而来的,主要分为如下图:
DatawhaleChina - Task8:循环和递归神经网络
LSTM确实具有删除或添加信息到细胞状态的能力,这个能力是由被称为门(Gate)的结构所赋予的。门(Gate)是一种可选地让信息通过的方式。 它由一个Sigmoid神经网络层和一个点乘法运算组成。Sigmoid神经网络层输出0和1之间的数字,这个数字描述每个组件有多少信息可以通过, 0表示不通过任何信息,1表示全部通过。

遗忘门

DatawhaleChina - Task8:循环和递归神经网络

决定了从以前的信息状态中丢弃什么信息。它查看ht1h_{t-1}(前一个输出)和xtx_t(当前输入),并为单元格状态Ct1C_{t-1}(上一个状态)中的每个数字输出0和1之间的数字。1代表完全保留,而0代表彻底删除。

输入门

DatawhaleChina - Task8:循环和递归神经网络

决定网络中应该存储什么信息, 两者的结果后面会相乘再去更新细胞状态。

输出门

DatawhaleChina - Task8:循环和递归神经网络
图中oto_t才是输出门的结果,hth_t是整个神经元的输出结果,oto_t公式中运行一个sigmoid层,它决定了我们要输出的细胞状态的哪些部分。 然后,我们将单元格状态通过tanh(将值规范化到-1和1之间),并将其乘以Sigmoid门的输出,至此我们只输出了我们决定的那些部分。

细胞状态Ct+1C^{t+1}

和RNN相比,LSTM多了一个隐状态变量 ctc_t,称为细胞状态(cell state),用来记录信息,它的更新有如下公式:
Ct+1=ftwt+itC~C_{t+1} = f_t*w_t+i_t*tilde{C}

遗忘门、输入门、输出门

ft=σ(Wf[ht1,xt]+bfit=σ(Wi[ht1,xt]+biot=σ(Wo[ht1,xt]+bof_{t} = sigma (W_f[h_{t-1},x_t]+b_f \i_{t} = sigma (W_i[h_{t-1},x_t]+b_i \o_{t} = sigma (W_o[h_{t-1},x_t]+b_o
使用相同计算方式的目的是它们都扮演了门控的角色,而使用不同参数的目的是为了误差反向传播时对三个门控单元独立地进行更新。在理解LSTM运行机制的时候,为了对图进行简化,我们不在图中标注三个门控单元的计算过程,并假定各门控单元是给定的。

梯度消失

LSTM通过门函数,将一部分梯度遗忘掉,这样就可以很大程度上减轻了梯度消失发生的概率。具体可以参考博客的内容。RNN中,每个记忆单元ht1h_{t-1}都会乘上一个W和**函数的导数,这种连乘使得记忆衰减的很快,而LSTM是通过记忆和当前输入"相加",使得之前的记忆会继续存在而不是受到乘法的影响而部分“消失”,因此不会衰减。但是这种naive的做法太直白了,实际上就是个线性模型,在学习效果上不够好,因此LSTM引入了那3个门。

梯度爆炸

不过LSTM依旧不能解决梯度“爆炸”的问题。但似乎梯度爆炸相对于梯度消失,问题没有那么严重。一般靠裁剪后的优化算法即可解决,比如gradient clipping(如果梯度的范数大于某个给定值,将梯度同比收缩)。
梯度剪裁的方法一般有两种:

  • 1.一种是当梯度的某个维度绝对值大于某个上限的时候,就剪裁为上限。
  • 2.另一种是梯度的L2范数大于上限后,让梯度除以范数,避免过大。

Text-RNN

Text-RNN 文本分类

RCNN原理

RCNN文本分类

参考博客

循环神经网络(RNN, Recurrent Neural Networks)介绍
LSTM如何解决梯度消失或爆炸的?
如何简单的理解LSTM——其实没有那么复杂