深度学习之循环神经网络(Recurrent Neural Network,RNN)

递归神经网络和循环神经网络

  • 循环神经网络(recurrent neural network):时间上的展开,处理的是序列结构的信息,是有环图
  • 递归神经网络(recursive neural network):空间上的展开,处理的是树状结构的信息,是无环图
  • 二者简称都是 RNN,但是一般提到的RNN指的是循环神经网络(recurrent neural network)。

为什么有bp神经网络、CNN、还需要RNN?

  • BP神经网络和CNN的输入输出都是互相独立的;但是实际应用中有些场景输出内容和之前的内 容是有关联的。
  • RNN引入“记忆”的概念;递归指其每一个元素都执行相同的任务,但是输出依赖于输入和“记忆”

什么是循环神经网络 RNN

我们已经学习了前馈网络的两种结构——bp神经网络和卷积神经网络。这两种结构有一个特点,就是假设输入是一个独立的没有上下文联系的单位。但是对于一些有明显的上下文特征的序列化输入,比如预测视频中下一帧的播放内容,那么很明显这样的输出必须依赖以前的输入, 也就是说网络必须拥有一定的”记忆能力”。为了赋予网络这样的记忆力,一种特殊结构的神经网络——循环神经网络(Recurrent Neural Network)便应运而生了

循环神经网络RNN的应用场景

自然语言处理(NLP)

RNNs已经被在实践中证明对NLP是非常成功的。如词向量表达、语句合法性检查、词性标注等。在RNNs中,目前使用最广泛最成功的模型便是LSTMs(Long Short-Term Memory,长短时记忆模型)模型,该模型通常比vanilla RNNs能够更好地对长短时依赖进行表达,该模型相对于一般的RNNs,只是在隐藏层做了手脚。对于LSTMs,后面会进行详细地介绍。下面对RNNs在NLP中的应用进行简单的介绍。

自然语言处理(NLP)——语言模型与文本生成

给你一个单词序列,我们需要根据前面的单词预测每一个单词的可能性。语言模型能够一个语句正确的可能性,这是机器翻译的一部分,往往可能性越大,语句越正确。另一种应用便是使用生成模型预测下一个单词的概率,从而生成新的文本根据输出概率的采样。语言模型中,典型的输入是单词序列中每个单词的词向量(如 One-hot vector),输出时预测的单词序列。当在对网络进行训练时,如果,那么第步的输出便是下一步的输入。 
  下面是RNNs中的语言模型和文本生成研究的三篇文章:

  • Recurrent neural network based language model
  • Extensions of Recurrent neural network based language model
  • Generating Text with Recurrent Neural Networks

机器翻译

机器翻译是将一种源语言语句变成意思相同的另一种源语言语句,如将英语语句变成同样意思的中文语句。与语言模型关键的区别在于,需要将源语言语句序列输入后,才进行输出,即输出第一个单词时,便需要从完整的输入序列中进行获取。机器翻译如下图所示: 

MT

RNN for Machine Translation. Image Source 。下面是关于RNNs中机器翻译研究的三篇文章:

  • A Recursive Recurrent Neural Network for Statistical Machine Translation
  • Sequence to Sequence Learning with Neural Networks
  • Joint Language and Translation Modeling with Recurrent Neural Networks

语音识别

语音识别是指给一段声波的声音信号,预测该声波对应的某种指定源语言的语句以及该语句的概率值。 

RNNs中的语音识别研究论文:

  • Towards End-to-End Speech Recognition with Recurrent Neural Networks

图像描述生成

和卷积神经网络(convolutional Neural Networks, CNNs)一样,RNNs已经在对无标图像描述自动生成中得到应用。将CNNs与RNNs结合进行图像描述自动生成。这是一个非常神奇的研究与应用。该组合模型能够根据图像的特征生成描述。如下图所示: 

GID

图像描述生成中的深度视觉语义对比. Image Source

文本相似度计算等 。。。。。

循环神经网络 RNN 结构

循环神经网络是一类用于处理序列数据的神经网络,就像卷积神经网络是专门用于处理网格化数据(如一张图像)的神经网络,循环神经网络时专门用于处理序列 x^{(1)},...,x^{(T)} 的神经网络。

同一个神经元在不同时刻的状态构成了RNN神经网络,简化版的RNN结构如下:

循环神经网络的结果相比于卷积神经网络较简单,通常循环神经网络只包含输入层、隐藏层和输出层,加上输入输出层最多也就5层

以样本 ‘我是谁’  为例,体会一下

深度学习之循环神经网络(Recurrent Neural Network,RNN)_第1张图片

将一个神经元序列按时间展开就可以得到RNN的结构

  • 网络某一时刻 t 的输入X_t,和之前介绍的 bp 神经网络的输入一样,X_t 是一个n维向量,不同的是递归网络的输入将是一整个序列,也就是X=[X_1,…,X_{t-1},X_t,X_{t+1},…X_t]。对于语言模型,每一个 X_t 代表一个词向量,一整个序列就代表一句话
  • h_t 代表时刻 t 隐神经元对于线性转换值
  • S_t 是时间 t 处的“记忆”,S_t = f(UX_t + WS_{t-1}),f() 可以是非线性转换函数,比如 tanh 等, 通常我们把 S_t 叫做一个细胞,它有两个输出
  • o_t 代表时刻t的输出(神经元激活后的输出结果),比如是预测下一个词的话,可能是 sigmoid(softmax) 输出的属于每个候选词的概率,O_t = softamx(VS_t)
  • 输入层到隐藏层直接的权重由U表示,它将我们的原始输入进行抽象作为隐藏层的输入
  • 隐藏层到隐藏层的权重W,它是网络的记忆控制者,负责调度记忆。
  • 隐藏层到输出层的权重V,从隐藏层学习到的表示将通过它再一次抽象,并作为最终输出

循环神经网络RNN-BPTT 

RNN 的训练和 CNN/ANN 训练一样,同样适用 BP算法误差反向传播算法。区别在于:RNN中的参数U\V\W是共享的,并且在随机梯度下降算法中,每一步的输出不仅仅依赖当前步的网络,并且还需要前若干步网络的状态,那么这种BP改版的算法叫做Backpropagation Through Time(BPTT);BPTT算法和BP算法一样,在多层训练过程中(长时依赖<即当前的输出和前面很长的一段序列有关,一般超过10步>),可能产生梯度消失和梯度爆炸的问题。

BPTT和BP算法思路一样,都是求偏导,区别在于需要考虑时间对step的影响。

RNN正向传播阶段

在t=1的时刻,U,V,W都被随机初始化好,h0通常初始化为0,然后进行如下计算:

\begin{aligned} h_1 &= Ux_1+Ws_0 \\ s_1 &= f(h_1) \\ o_1 &= g(Vs_1) \end{aligned}

时间就向前推进,此时的状态 h1 作为时刻 t=1 的记忆状态将参与下一次的预测活动,也就是:

\begin{aligned} h_2 &= Ux_2 + Ws_1 \\ s_2 &= f(h_2) \\ o_2 &= g(Vs_2) \end{aligned}

以此类推,可得任意时刻t,神经元的计算过程

\begin{aligned} h_t &= Ux_t + Ws_{t-1} \\ s_t &= f(h_t) \\ o_t &= g(Vs_t) \end{aligned}

其中 f 可以是 tanh,relu,sigmoid 等激活函数, g 通常是 softmax,也可以是其他。 值得注意的是,我们说循环神经网络拥有记忆能力,而这种能力就是通过 W 将以往的输入状态进行总结,而作为下次输入的辅助,可以这样理解隐藏状态:h=f(现有的输入+过去记忆总结)

RNN反向传播阶段

bp神经网络用到 误差反向传播 方法将输出层的误差总和,对各个权重的梯度 ∇U,∇V,∇W,求偏导数,然后利用梯度下降法更新各个权重。

对于每一时刻 t 的 RNN 网络,网络的输出 o_t 都会产生一定误差 e_t ,误差的损失函数,可以是交叉熵也可以是平方误差等等。那么总的误差为E=\sum_te_t,我们的目标就是要求取各个权重(U、V、W)对总误差的偏导

\begin{aligned} \bigtriangledown U &= \frac{\partial E }{\partial U} = \sum_t \frac{\partial e_t }{\partial U} \\ \bigtriangledown V &= \frac{\partial E }{\partial V} = \sum_t \frac{\partial e_t }{\partial V} \\ \bigtriangledown W &= \frac{\partial E }{\partial W} = \sum_t \frac{\partial e_t }{\partial W} \end{aligned}

求V的偏导

对于输出 o_t = g(Vs_t),任意损失函数,求∇V是非常简单的,我们可以直接求取每个时刻的 \frac{\partial e_t }{\partial V},由于它不存在和之前的状态依赖,可以直接求导取得,然后简单地求和即可。对于∇W、∇U的计算不能直接求导,需要用链式求导法则。

求w的偏导

深度学习之循环神经网络(Recurrent Neural Network,RNN)_第2张图片

深度学习之循环神经网络(Recurrent Neural Network,RNN)_第3张图片

深度学习之循环神经网络(Recurrent Neural Network,RNN)_第4张图片

深度学习之循环神经网络(Recurrent Neural Network,RNN)_第5张图片

求U的偏导

深度学习之循环神经网络(Recurrent Neural Network,RNN)_第6张图片

RNN 缺点

假如 t = 0 时刻的值,到 t = 100  时,由于前面的 W 次数过大,又可能会使其忘记 t = 0 时刻的信息,我们称之为 RNN梯度消失,但是不是真正意思上的消失,因为梯度是累加的过程,不可能为0,只是在某个时刻的梯度太小,忘记了前面时刻的内容

为了克服梯度消失的问题,LSTM和GRU模型便后续被推出了,LSTM和GRU都有特殊的方式存储”记忆”,以前梯度比较大的”记忆”不会像RNN一样马上被抹除,因此可以一定程度上克服梯度消失问题。

另一个简单的技巧 gradient clipping(梯度截取) 可以用来克服梯度爆炸的问题,也就是当你计算的梯度超过阈值c的或者小于阈值−c时候,便把此时的梯度设置成c或−c

下图所示是RNN的误差平面,可以看到RNN的误差平面要么非常陡峭,要么非常平坦,如果不采取任何措施,当你的参数在某一次更新之后,刚好碰到陡峭的地方,此时梯度变得非常大,那么你的参数更新也会非常大,很容易导致震荡问题。而如果你采取了gradient clipping,那么即使你不幸碰到陡峭的地方,梯度也不会爆炸,因为梯度被限制在某个阈值c

深度学习之循环神经网络(Recurrent Neural Network,RNN)_第7张图片

双向RNN Bidirectional RNN

Bidirectional RNN(双向RNN)假设当前t的输出不仅仅和之前的序列有关,并且还与之后的序列有关,例如:预测一个语句中缺失的词语那么需要根据上下文进行预测;Bidirectional RNN是一个相对简单的RNNs,由两个RNNs上下叠加在 一起组成。输出由这两个RNNs的隐藏层的状态决定

深度学习之循环神经网络(Recurrent Neural Network,RNN)_第8张图片

或者如下图

深度学习之循环神经网络(Recurrent Neural Network,RNN)_第9张图片

深度双向 RNN

Deep Bidirectional RNN(深度双向RNN)类似Bidirectional RNN,区别在于每个每一步的输入有多层网络,这样的话该网络便具有更加强大的表达能力和学习能力,但是复杂性也提高了,同时需要训练更多的数据。

深度学习之循环神经网络(Recurrent Neural Network,RNN)_第10张图片

你可能感兴趣的:(深度学习,rnn,深度学习,神经网络)